How to retrieve data from mysql to chart.js - javascript

I want to create a pie chart with chart.js, but it can't display the chart. I spent a day trying to solve this problem, but there was no good result. I hope someone can help me.
My database has different companies, I need to calculate the total sales of each company and display in the pie chart.
I think the problem would be $results_sum = "SELECT SUM(total_of_gp_fee) AS Total FROM gp WHERE cshortcut=$subjectData('cshortcut')";, since there has many sales record for different company and I am not sure if that is correct code.
<?php
include_once("connection.php");
$results_sum = "SELECT cshortcut,SUM(total_of_gp_fee) AS Total FROM gp GROUP BY cshortcut";
$result_sum = mysqli_query($conn, $results_sum) or die("error to fetch data");
if ($result_sum->num_rows > 0) {
// output data of each row
$labels = $data = '';
while($row = $result_sum->fetch_assoc()) {
//get the company name separated by comma for chart labels
$labels.= '"' .$row["cshortcut"]. '",';
//get the total separated by comma for chart data
$data.= $row["Total"].',';
}
}?>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>test</title>
<script src="chart/Chart.bundle.js"></script>
</head>
<body>
<div class="container">
<canvas id="myChart" width="300" height="100"></canvas>
</div>
script part
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: [<?php echo trim($labels);?>],
datasets: [{
label: '# of Votes',
data: [<?php echo trim($data);?>],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
//Add the tooltips
tooltips: {
callbacks: {
label: function(tooltipItem) {
return "€ " + Number(tooltipItem.yLabel);
}
}
},
}
},
);
</script>

1- get the company name and SUM of total_of_gp_fee group by company.
include_once("connection.php");
//get the company name and total_of_gp_fee of that company.
$results_sum = "SELECT cshortcut,SUM(total_of_gp_fee) AS Total FROM gp GROUP BY cshortcut";
$result_sum = mysqli_query($conn, $results_sum) or die("error to fetch data");
if ($result_sum->num_rows > 0) {
// output data of each row
$labels = $data = '';
while($row = $result_sum->fetch_assoc()) {
//get the company name separated by comma for chart labels
$labels.= '"' .$row["cshortcut"]. '",';
//get the total separated by comma for chart data
$data.= $row["Total"].',';
}
}
2- Update the value of labels and data in chart.
labels: [<?php echo trim($labels);?>],
datasets: [{
label: '# of Votes',
data: [<?php echo trim($data);?>],
3- Add the tooltips for bar chart.
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
//Add the tooltips
tooltips: {
callbacks: {
label: function(tooltipItem) {
return "€" + Number(tooltipItem.yLabel);
}
}
},
}
4- Add tooltips for pie chart.
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var allData = data.datasets[tooltipItem.datasetIndex].data;
var tooltipData = allData[tooltipItem.index];
var total = 0;
for (var i in allData) {
total += allData[i];
}
var tooltipPercentage = Math.round((tooltipData / total) * 100);
return "€" + ': ' + tooltipData + ' (' + tooltipPercentage + '%)';
}
}
},

I think cshortcut holds the name of the comany, so you can do it all with one query:
$results_sum = "SELECT cshortcut,SUM(total_of_gp_fee) AS Total FROM gp GROUP BY cshortcut";
And you will get an array with to elements (cshortcut and Total) for each element in the array
Anyway, you have an error in your JS, you are using a name that doesn 't exist in your data (total_of_gp_fee) because you are using an alias (Total), you should change:
labels: [<?php while ($b = mysqli_fetch_array($result_cut)) { echo '"' . $b['cshortcut'] . '",';}?>],
datasets: [{
label: '# of Votes',
data: [<?php while ($p = mysqli_fetch_array($sum)) { echo '"' . $p['Total'] . '",';}?>],

Related

Display json format data in smarty chartjs

<script>
{literal}
var ctx = document.getElementById('myGlaciermassChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: [{/literal}
{foreach from=$glaciermass item=year name=glaciermassloop}
{if $smarty.foreach.glaciermassloop.last}
"{$year.Year}"
{else}
"{$year.Year}",
{/if}
{/foreach}
{literal}],
datasets: [{
label: 'Mean Glacier mass Level',
data: [{/literal}
{foreach from=$glaciermass item=year name=glaciermassloop}
{if $smarty.foreach.glaciermassloop.last}
"{$year.Mean-cumulative-mass-balance}"
{else}
"{$year.Mean-cumulative-mass-balance}",
{/if}
{/foreach}
{literal}],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
suggestedMax: 0,
suggestedMin:-30,
beginAtZero: true
}
}]
}
}
});
{/literal}
</script>
I am using Chart.js and the data from an API endpoint is not displaying the right Mean values on the screen. I have tried many different ways and I have even tried selecting an index, but it doesn't work.Currently the Mean values are showing only 0s on the chart for all the years instead of the actual values from the json - Here is the json itself. https://pkgstore.datahub.io/core/glacier-mass-balance/glaciers_json/data/6270342ca6134dadf8f94221be683bc6/glaciers_json.json.
<?php
$url ='https://pkgstore.datahub.io/core/glacier-mass-balance/glaciers_json/data/6270342ca6134dadf8f94221be683bc6/glaciers_json.json';
$response = file_get_contents($url);
$GlaciermassData= json_decode($response, true);
$smarty->assign('glaciermass', $GlaciermassData);
?>
Have you tried accessing each index by number?

How to insert php in data chart.js

I'm trying to add a php variable in data: in chart.js. The examples say data: [<?php echo $dates ?>], This will do, but when I try to do this, it immediately gives me an error that < is an unexpected token. which in a way makes sense. I put it in a string ["<?php echo $dates ?>"], but then I do not get any results.
while ($stelling = mysqli_fetch_array($records1)){
$Timer = date('M, Y', strtotime($stelling['Timer']));
$Wheight = $stelling['Wheight'];
$Title = $stelling['Title'];
$Timers = '';
$Wheights = '';
$Titles = '';
$Timers = $Timers.'"'.$Timer.'",';
$Wheights = $Wheights.$Wheight.',';
$Titles = $Titles.$Title.',';
$Timers = trim($Timers, ",");
$Wheights = trim($Wheights, ",");
$Titles = trim($Titles, ",");
}
echo '<script src="script/graph.js"></script>';
The script file:
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'Time',
data: ["<?php echo $Timers ?>"],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}
I expect the graph to show the data that is stored in the variables
Adding to the previous comments, PHP Array are not the same thing as JavaScript array. There are lots of ways this can be done, one is to loop through the $timers array in PHP and then convert that to corresponding JavaScript
Assuming the time contains array('label'=>'Today','data'=>55);
then you can use foreach or for to build the corresponding JavaScript array
<script type='text/javascript'>
let data=[];// this is a javascript array
<?php
$timersCount=count($timers);
for($i=0; $i<$timersCount i++){
?>
data.push({
data:<?php echo $timers[$i]['data']?>,
label:<?php echo $timers[$i]['label']?>
});
<?php
}?>
</script>
There might be typo, i just typed it but you get the idea.
I am assuming you are running the script in a PHP view file.

The Implode function in PHP isn't showing up my results in a js chart

Im using the implode() function for 2 items in a bar chart:
1.) For the checkPoint (Which is an integer value and this gives the bar chart the values data which is held under data in the js code). Which works perfectly
2.) For the module names (which is just Strings, the names of the module). which I paste under labels
However the names of the columns in my bar chart (module names) under the labels is not showing up, however in the inspect element of my web page, they are being shown there. The error is the console is: SyntaxError: Unexpected identifier 'ManagementCareer'. Expected either a closing ']' or a ',' following an array element.
The code:
$query = "SELECT `module`.`ModuleName`,`userTakingModule`.`checkPoint` FROM `userTakingModule` JOIN `module`ON `userTakingModule`.`ModuleID`= `module`.`ModuleID` JOIN `users`ON `userTakingModule`.`idUsers`=`users`.`idUsers` WHERE `userTakingModule`.`idUsers`= '".$_SESSION['id']."' ";
//Execute
$result = $conn -> query($query);
$moduleCheckPoint = Array();
$moduleName = Array();
while($row = $result -> fetch_assoc())
{
$moduleCheckPoint[] = $row['checkPoint'];
$moduleName[] = $row['ModuleName'];
}
<?php
$modCheckPoint = implode(',',$moduleCheckPoint);
$modName = implode(',', $moduleName);
?>
<script type="text/javascript">
var ctx = document.getElementById("my3Chart");
var myBarChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [<?php echo $modName ?>],
datasets: [{
label: 'Module Tracker',
data: [<?php echo $modCheckPoint ?>],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
</script>
The module check point is working fine and populating the bar chart, however the module names are not appearing at all. Please can someone highlight what I've done incorrectly?
What should be appearing (moduleNames):
Under Inspect Element they are showing:
Correct approach here is to use json_encode function:
$modCheckPoint = json_encode($moduleCheckPoint);
// though `$moduleName` is array of numbers - you can leave `implode`
// but in case of array strings - always use `json_encode`
$modName = implode(',', $moduleName);
Also:
labels: <?php echo $modName ?>, // remove [] here, as `json_encode` returns them already.

ChartJS: Get value from another another Chart

I have two charts, First chart shows the breakup of Shirt sales.
Second is the comparison of Blue Shirt vs Blue Trouser sales.
I want to import the Blue Shirt value from the first Chart to Second chart.
Here is the Code with two charts:
var ctx = document.getElementById("myChart1").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: 'Shirts',
data: [10, 10, 15, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
}
});
var ctx = document.getElementById("myChart2").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Blue Shirts", "Blue Trousers"],
datasets: [{
label: 'Sales',
data: [10, 8],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
}
});
Here is the JSFiddle (https://jsfiddle.net/kingBethal/L8x790fn/15/).
I found this thread describing getting data from click events: Click events on Pie Charts in Chart.js
I made also made a new fiddle here where it logs a chart object containing the chart data on chart click: https://jsfiddle.net/btnL9d2a/16/
myChart1Canvas.onclick = function(evt) {
var activePoints = myChart.getElementsAtEvent(evt);
if (activePoints[0]) {
var chartData = activePoints[0]['_chart'].config.data;
// `chartData` will be an object in the format {'Labels' : Array, 'datasets' : Array}.
console.log(chartData);
}
};
chartData.datasets[0].data is an array of the clicked-on chart's data.

Chart.js passing value data dynamic

I am want to use data and level dynamic by ajax, so i am using as below but not working.
My ajax return data in json_encode of php.
My code is:
success: function (result) {
result = JSON.parse(result);
var labels = result['labels'];
var data = result['data'];
//console.log(data);
var ctx = document.getElementById("chartbtc");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [labels],
datasets: [{
label: 'Market Price (USD)',
data: [data],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
}
}
});
}
But chart is not generating:
Ajax result is:
{"labels":"13-Nov-2017, 14-Nov-2017, 15-Nov-2017, 16-Nov-2017, 17-Nov-2017, 18-Nov-2017, 19-Nov-2017, 20-Nov-2017, 21-Nov-2017, 22-Nov-2017, 23-Nov-2017, 24-Nov-2017, 25-Nov-2017, 26-Nov-2017, 27-Nov-2017, 28-Nov-2017, 29-Nov-2017, 30-Nov-2017, 01-Dec-2017, 02-Dec-2017, 03-Dec-2017, 04-Dec-2017, 05-Dec-2017, 06-Dec-2017, 07-Dec-2017, 08-Dec-2017, 09-Dec-2017, 10-Dec-2017, 11-Dec-2017, 12-Dec-2017","data":"6550.22, 6635.41, 7301.42, 7815.03, 7786.88, 7817.14, 8007.65, 8255.59, 8059.8, 8268.03, 8148.94, 8250.97, 8707.4, 9284.14, 9718.29, 9952.5, 9879.32, 10147.37, 10883.91, 11071.36, 11332.62, 11584.82, 11878.43, 13540.98, 16501.97, 16007.43, 15142.83, 14869.8, 16762.11, 17276.39"}
Since you have provided your ajax result, this will not work with the chart generation. In your case result["labels"] is a string and you are just making a list with 1 element which is the whole string(which is not valid for the labels property and will not work). What you should do is split the string, format it correctly and then supply it as a list to the labels property. Easiest way would be to use the split() function, and in your case you could split by ", ". Although I would recommend to implement a better response if its possible (have it something like so: {"labels": ["13-Nov-2017", "14-Nov-2017", ...]}).
Hope this helps!
For the first time you can fill the chart with your own value, but when it is coming for dynamically appending data then you should remove the canvas element and regenerate it. So that your data will get appended dynamically on chart.
You can try something like this.
<canvas id="chartbtc" class="canvasChart"></canvas>
<script>
dynamicDataAppendOnChart(labels, data); // On page loading you will be having your own data so you can pass them, or if you want that to be happen with ajax when page loading itself you can trigger the click event.
$('#btnClick').trigger('click');
// You will be calling the function with click event...
$('#btnClick').on('click', function () {
var data = '', labels = '';
$.ajax({
url: url,
type: "POST",
data: data,
async: isAsync,
success: function (result) {
result = JSON.parse(result);
labels = result['labels'];
data = result['data'];
}
});
dynamicDataAppendOnChart(labels, data); // Now you can call the function by passing labels and data
});
function dynamicDataAppendOnChart() {
$('#chartbtc').remove();
$('#appendTheCanvasElement').append('<canvas id="chartbtc" class="canvasChart"><canvas>'); // This would create new canvas element every time and removes the older one.
var ctx = document.getElementById("chartbtc");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [labels],
datasets: [{
label: 'Market Price (USD)',
data: [data],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
}
}
});
}
</script>
Try This.
Declare label and data as
var labels = result['labels'].split(","); // Return Array of Strings Of labels
var data = JSON.parse("[" + result['data'] + "]");// return array of data
Chage
labels: [labels],
data: [data],
to
labels: labels,
data: data,
Because it already in array

Categories

Resources