Sending reporting mail with chart - php

the question I am asking is from a code-architecture point of view. I am preparing a report in php which is built with a string $message and then send via a php mail function.
For example the report is built in the php file like that(basically concatenates strings):
$message .= <<<HTML
</td>
</tr>
</tbody>
</table>
HTML;
Further, I would like to include a chart. However, trying the following example and sending it per mail I get no chart and an empty <div style="width:900px;min-height:500px"></div> ==$0 value.
$message.=<<<HTML
<tr valign="top" align="center">
<script type="text/javascript">
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Element', 'Density', { role: 'style' }],
['Copper', 8.94, '#b87333', ],
['Silver', 10.49, 'silver'],
['Gold', 19.30, 'gold'],
['Platinum', 21.45, 'color: #e5e4e2' ]
]);
var options = {
title: "Density of Precious Metals, in g/cm^3",
bar: {groupWidth: '95%'},
legend: 'none',
};
var chart_div = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(chart_div);
// Wait for the chart to finish drawing before calling the getImageURI() method.
google.visualization.events.addListener(chart, 'ready', function () {
chart_div.innerHTML = '<img src="' + chart.getImageURI() + '">';
console.log(chart_div.innerHTML);
});
chart.draw(data, options);
}
</script>
<div id='chart_div'></div>
</tr>
HTML;
My guess is that javascript is not accepted by f.ex. GMail. Hence, I am trying to create a png beforehand which is then included in the report.
My preferred way of doing this would be the google charts library, however, it has no support for php and is entirely based on JavaScript.
Hence, my questions are:
How can I use the google chart library in my code?
Any other suggestions if above does not work?
I appreciate if you could provide an example!
Thx in advance!

Email clients strip Javascript, SVG, and other formats, so you can't use a chart library directly in email.
Your options include:
Use getImageURI to generate a PNG of your chart and send it to your server to be emailed. This is probably the best solution if you know a client will load every chart before it needs to be emailed.
Use a tool like wkhtmltoimage to "headlessly" render a webpage that displays your charts and save it as an image.
Use a chart image rendering web service like QuickChart to generate the chart image (fyi: this is an open-source project that I started).
QuickChart in particular is built on Chart.js, so you'd have to create a Chart.js chart definition as a string:
$chartConfig = "{
type: 'bar',
data: {
labels: ['Copper', 'Silver', 'Gold', 'Platinum'],
datasets: [{
data: [8.94, 10.49, 19.30, 21.45],
backgroundColor: ['#b87333', 'silver', 'gold', '#e5e4e2'],
}]
},
options: {
title: {
display: true,
text: 'Density of Precious Metals, in g/cm^3',
},
legend: {
display: false
}
}
}";
I've used a static string to match your example, but you can include dynamic variables like in any other PHP string.
Then encode this string into a URL:
$chartUrl = 'https://quickchart.io/chart?c=' . urlencode($chartConfig);
This URL returns a chart that looks like this:
Finally, add the chart to your email body as an HTML image tag:
$message .= "<img src=\"$chartUrl\"/>";

Related

ChartJSPlugins Issue

`<script>
Chart.pluginService.register({
beforeDraw: function (chart) {
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
ctx.restore();
var fontSize = (height / 114).toFixed(2);
ctx.font = fontSize + "em sans-serif";
ctx.textBaseline = "middle";
var text = chart.config.options.elements.center.text,
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY);
ctx.save();
}
});
// chart1
var data = {
labels: ["Red", "Blue"],
datasets: [{
data: [50],
backgroundColor: ["#BEFF60", "#36A2EB"],
hoverBackgroundColor: ["#BEFF60", "#36A2EB"]
}]
};
var promisedDeliveryChart = new Chart(document.getElementById('myChart1'), {
type: 'doughnut',
data: data,
options: {
title: {
display: true,
text: 'OEE Chart'
},
elements: {
center: {
text: parseInt(<?php echo json_encode($OEE); ?>) + '%', //set as you wish
}
},
cutout Percentage: 85,
legend: {
display: false
}
}
});
</script>
`
I have few questions here.
I have already created Plugins Service and doughnut chart code where I standardize everything including having a text in between the doughnut chart - how can I small changes the Plugin Service so that where I can add picture send towards backwards and bring the text infront?? - Is it possible this same Plugin Service used after modification answers given by anyone where for other charts but dont want to add the picture and text as other charts will be either bar graph or line chart etc... can anyone guide me with these kind of things. I'm not sure how to do it.. any advice??
If lets say I want to do chartsJS for stepped line chart how is that?? I tried using the same Plugin Service but failed. if if each type of chart need to use different plugins I can do it... but the issue I will create their separate files and call them in PHP index folder (as the main file running the website but when I add the JavaScript link and add call the name from the JS file into the PHP index file failed. Hopefully someone can guide me or advice me on this
when i use the same PluginService(which is used for doughnut chart) i cannot show the results for barchart , line chart etc using the same PluginService when i pass <php json() file ?> from the database file i created to pass the data into data[] in chartJS
-dscsccsss\\\\\\

How to Save and retrieve HTML 5 canvas (Fabric.js) into MySQL blob

I want to save and retrieve HTML 5 canvas that I have drawn using Fabric.js, a JavaScript library, into MySQL table using PHP that has a field namely cnvs_obj of BLOB type. I have seen a lot of tuts and Q/A sessions but none has step by step way of teaching. How can I do this, would be very much thankful to you. Here is my canvas example.
EDIT:
Here is my complete code:
<canvas id="c" style="border:1px solid black;" width="500px" height="300px" ></canvas>
<button onclick="myFunction()" id="btn2">Click me</button>
<script type="text/javascript" src="fabric.min.js"></script>
<script type="text/javascript">
var canvas = new fabric.Canvas('c');
$(function () {
//canvas.stateful = true;
var wel = new fabric.Text('Welcome to FabricJs', {
fontFamily: 'Delicious_500',
backgroundColor: 'red',
left: 80,
top: 100
});
canvas.add(wel);
});
canvas.renderAll();
function myFunction() {
console.log(JSON.stringify(canvas));
var str_json = JSON.stringify(canvas);
// send JSON to PHP
$.ajax({
type: 'POST',
url: 'hallo_json.php',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: { hallo_str: JSON.stringify(str_json) },
});
alert(str_json);
}
</script>
Here is PHP code:
<?php
header('Content-type: text/html');
print_r(json_decode($_POST['str_json']));
Now I can generate JSON, but error 200 arises. I don't where is the error.
You can use canvas method toDataUrl. It returns string with data type and format followed by base64 encoded image data. This data you can send to server to decode and save as image.
If you "want to save and retrieve HTML 5 canvas that I have drawn using Fabric.js", then JSON is fine, by passing JSON between client and server as Text string, you can easily to restore/save the canvas content by loadFromJSON/toJSON, or loadFromDataLessJSON/toDatalessJSON.
By BLOB, it is just saving string to binary format, it won't have issue to do with string in PHP.
In your code, you just want to save all canvas to a JSON string, by that, as there is no native way in browser to build canvas and its content from the JSON string, you will have to build your own method to restore canvas content.
// add Text here, state A
...
// export to json
var json = JSON.stringify(canvas.toJSON());
// add another Tex here, state B
...
// here canvas will go back to the state A
// because it will load JSON data from state A and restore that state
canvas.clear();
canvas.loadFromJSON(JSON.parse(json), canvas.renderAll.bind(canvas));

Issue with highchart data display when parsing JSON data

I am trying to dynamically fetch the data from a PhP module, load it as JSON data into javascript and use this data to generate a Pie chart using HighCharts. The Pie chart is generating properly when I am using some static data but not loading when I am parsing JSON data and feeding that as input to the Highchart series object. I am sure this is something to do with the formatting of data while inputting to Highcharts but I am not able to figure that out for sometime now :( So thought would just reach out to you guys . I have attached the code here and the sample json output generated by the php module for your reference.
Sample JSON input generated from PhP module : [{"skill":"html","count":"158"},{"skill":"css","count":"134"}]. Need to parse this JSON input and feed as input to my HighCharts series object to generate a pie-chart showing "html" and "css" as pie-slices.
Any guidance would be appreciated.
Thanks.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Top Skills Analytics</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="highcharts.js"></script>
</head>
<body>
<table>
<tr>
<td colspan="2" align="center"><u><b><font size="4">Top Skills Analysis</font></b></u>
</td>
</tr>
<tr>
<td>
<div id="container" style="height: 500px; width: 500px; margin-bottom: 1em;"></div>
</td>
</tr>
</table>
<script type="text/javascript">
// Creates the HighChart using the dynamically generated data from PhP module
function loadCharts() {
// Parses the JSON data and returns an array of an array
var result = [];
// json from php is like : [{"skill":"html","count":"158"},{"skill":"css","count":"134"}]
$.getJSON('test.php', function (json) {
$.each(json, function (i, entry) {
result.push(entry.skill, entry.count);
});
});
//result = [["html",158],["css",134]]; --> this works
var options1 = {
"series": [{
"name": "Jobs",
"type": "pie",
"sliced": true,
"data": result, // works when populated with static value like [["html",158],["css",134]]
"pointWidth": 15,
"color": "#C6D9E7",
"borderColor": "#8BB6D9",
"shadow": true,
}],
"title": {
"text": "Top Skills Analytics"
},
"legend": {
"layout": "vertical",
"style": {
"left": "auto",
"bottom": "auto",
"right": "auto",
"top": "auto"
}
},
"chart": {
"renderTo": "container"
},
"credits": {
"enabled": false
}
};
var chart1 = new Highcharts.Chart(options1);
}
// Load the charts when the webpage loads for the first time
$(document).ready(function () {
loadCharts();
});
</script>
</body>
It works with static data because the count is an int
["html",158]
And it doesn't work with dynamic data because it returns a string count
{"skill":"html","count":"158"}
Notice the double quotes around the second code line?
You need to either cast your string to an int in php or in javascript before passing it to highcharts
And another thing, if you run the code highcharts should complain with an error
Uncaught Highcharts error #14: www.highcharts.com/errors/14
If you visit the link it basically says the same thing about strings.
There is another thing wrong with the code
[["html",158],["css",134]]
As you can see here we have an array of arrays and when we run your code with string to int parsing we get
["html", 158, "css", 134]
Notice the problem? We have an array of four elements.
What you need to do is:
result.push([entry.skill, entry.count]);
Push an array of two elements to the result variable and don't forget that count must be an int
Try this,
result.push([entry.skill, parseInt(entry.count)]);

jQuery Highcharts: change chart type using dropdown list

i'm trying to change the value of chart as following
<!doctype html>
<head>
<script>
var chart1; // globally available
$(document).ready(function() {
var chart = 'pie'
$("select").change(function(){
chart = $('#chart').val();
alert(chart);
});
chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: chart
},
yAxis: {
title: {
text: 'Temprature'
}
},
series: [{
name: 'mach_1',
data: [<?php
foreach($chart as $`row) {
echo $row['temp'].",";
}
?>]
}]
});
});
</script>
</head>
<body>
<div id="form">
<label>Select a chart : </label>
<select id="chart">
<option>pie</option>
<option>column</option>
</select>
</div>
<div id="container"></div>
</body>
</html>
i know this will change the value of chart on select, but it doesn't change the chart itself. Any ideas?
Your original question was very difficult to read and interpret; some of stackoverflow's code editor tags were intertwined with the code you attempted to post. In the future, it may help to put an example of your code on jsfiddle.
If I'm understanding the question correctly, you are looking to change the type of chart displayed. Show a pie chart of the data; now show a bar graph of the data; now show a line chart, etc.
When you have a Highcharts question, it's a good bet someone else has asked that question before on the Highcharts forum. In your case, I think this is true: "Change chart type dynamically?" - http://highslide.com/forum/viewtopic.php?f=9&t=5501&p=26274&hilit=switch+chart+types#p26274
In the Highcharts forum question linked above, Highcharts author Torstein Honsi answers the question and includes a fiddle you may find to be a useful starting point, as he's changing the chart type in it. http://jsfiddle.net/tccpT/ Later on, a Highcharts support team member includes a fiddle where we see another example of changing the chart type. http://jsfiddle.net/2hLr5/
When a pie chart involves more than two pieces of data, it is generally advisable to not use a pie chart as a means of visualizing data. The more values a pie chart has, the more difficult it becomes to perceive the relationships between those pieces of data.

highcharts dynamic data from php

I am trying to plot a chart (Spline) using data that is dynamically generated from PHP. The JavaScript library I am using for this purpose is HighCharts.
The PHP generates an array of values in the format like
array(
array("1304294461000",69,"1304899261000",28),
array("1304294431000",3,"1304899161000",32)
)
which I am then passing onto a javascript array using json_encode. However, when I push these values as data, it doesn't seem to be working.
For example, here's an example with relevant code snippets like -
var namesArr = <?php echo json_encode($namesArr); ?>;
var progressTrendsData = <?php echo json_encode($progressTrendsData); ?>;
var chart;
var options = {
chart: {
renderTo: 'trendsDiv',
type: 'spline'
},
series: [{
name: '',
data: []
}]
};
for(var i=0;i<namesArr.length;i++) {
options.series.push({
name: namesArr[i],
data: progressTrendsData[i]
});
}
chart = new Highcharts.Chart(options);
The options contain other relevant data needed for the chart of course.
However, the only thing the above code is doing is plotting a single value at the date January 1 irrespective of the actual data that is being pushed.
I would tend to agree w/Mark on this. It is hard to tell exactly your data is supposed to end up looking like though. Try looking at the data loading portion of the ajax data example on the highcharts demo page.
UPDATE:
Try the following pseudocode:
var chart;
var options = {
chart: {
renderTo: 'trendsDiv',
type: 'spline'
},
series: [{
name: '',
data: []
}]
};
var seriesInfo=[];
seriesInfo[0]={"name":"Series A","data":[]};
seriesInfo[1]={"name":"Series B","data":[]};
//Loop over the series and populate the data
seriesInfo[0].data.push({x:<insert Series A timestamp>,y:<insert Series A y value>});
seriesInfo[1].data.push({x:<insert Series B timestamp>,y:<insert Series B y value>});
options.series.push(seriesInfo[0]);
options.series.push(seriesInfo[1]);
chart = new Highcharts.Chart(options);

Categories