Reputation: 5039
I have been working on integrating PhantomJS to help create images on my server that can then be used in a HTML template and saved to a PDF using mPDF. I am using Yii2 and have managed to generate and save an image using some dummy scripts. But I am unsure how to do this en masse for dynamic data.
Currently I have this very crude implementation:
shell.php
if(exec('C:\xampp\htdocs\phantomjs\bin\phantomjs C:\xampp\htdocs\ reporting\views\site\test.php')){
echo 'yes';
} else echo 'no';
My test.php
file is basically a JavaScript file just with the php extension.
test.php
var system = require('system');
var page = require('webpage').create();
var fs = require('fs');
// load JS libraries
if(page.injectJs('C:\\xampp\\htdocs\\phantomjs\\jquery.1.9.1.min.js')){
console.log('Jquery used');
}
if(page.injectJs('C:\\xampp\\htdocs\\phantomjs\\highcharts.js')){
console.log('highcharts used');
}
if(page.injectJs('C:\\xampp\\htdocs\\phantomjs\\highcharts-convert.js')){
console.log('highcharts-convert used');
}
var args = {
width: 600,
height: 500
};
var svg = page.evaluate(function(opt){
$('body').prepend('<div id="container"></div>');
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
width: opt.width,
height: opt.height
},
exporting: {
enabled: false
},
title: {
text: 'Combination chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Bananas', 'Plums']
},
yAxis: {
title: {
text: 'Y-values'
}
},
labels: {
items: [{
html: 'Total fruit consumption',
style: {
left: '40px',
top: '8px',
color: 'black'
}
}]
},
plotOptions: {
line: {
dataLabels: {
enabled: true
},
enableMouseTracking: false
},
series: {
enableMouseTracking: false,
shadow: false,
animation: false
}
},
series: [{
type: 'column',
name: 'Andrii',
data: [3, 2, 1, 3, 4]
}, {
type: 'column',
name: 'Fabian',
data: [2, 3, 5, 7, 6]
}, {
type: 'column',
name: 'Joan',
data: [4, 3, 3, 9, 0]
}, {
type: 'spline',
name: 'Average',
data: [3, 2.67, 3, 6.33, 3.33],
marker: {
lineWidth: 2,
lineColor: 'white'
}
}, {
type: 'pie',
name: 'Total consumption',
data: [{
name: 'Andrii',
y: 13,
color: '#4572A7'
}, {
name: 'Fabian',
y: 23,
color: '#AA4643'
}, {
name: 'Joan',
y: 19,
color: '#89A54E'
}],
center: [100, 80],
size: 100,
showInLegend: false,
dataLabels: {
enabled: false
}
}]
});
return chart.getSVG();
}, args);
// Saving SVG to a file
fs.write("test.svg", svg);
// Saving diagram as PDF
//setTimeout(function(){
page.render('test.png', {format: 'png', quality: '100'});
phantom.exit();
This generates and saves the png
file (although the dimensions are not set).
What I've come to realize though is that I can't use PHP within this file. The exec()
call never returns and I just end up canceling it. I'm assuming that's because PhantomJS doesn't know what to do when it encounters <?php
tags.
What is the best way to try and loop through DB data using PHP to generate and save the charts?
Upvotes: 0
Views: 692
Reputation: 16856
I have been working on integrating PhantomJS to help create images on my server that can then be used in a HTML template and saved to a PDF using mPDF.
That sounds as an overly complicated way to fulfill your task. Do you know that PhantomJS can generate PDF too?
page.render('charts.pdf');
So I'd suggest creating an ordinary HTML page (from your YII2 application) with all necessary charts on it, then simply render it to PDF with PhantomJS.
If, however, you'd like to use variables from PHP in your PhantomJS script anyway, there's of course ways to do it. You were on the right track, thinking that with PHP you can generate a script dynamically. But before passing that script to PhantomJS, it has to be processed by PHP.
Since you already use an MVC framework, I'd suggest this: create a template for your js script (that would be, essentially, a view/partial), load it like a view, pass the data for chart to it, and create a valid script, inserting dynamic variables everywhere they need to go. Something like this:
In application model/controller prepare your data accordingly (pseudocode, I haven't done Yii):
$series = array();
foreach ($data as $line)
{
$series[] = array(
"type" => 'column',
"name" => $line['name'],
"data" => $line['data']
);
}
$this->view->params['series'] = $series;
Then pass it to view and use like so:
var chart = new Highcharts.Chart({
...
series: <?php echo json_encode($this->params['series']); ?>
...
});
Then instead of sending output to browser, catch it and save to a temporary file and then pass filename of that as argument to PhantomJS.
Upvotes: 4