I am using Chart.js and it is propagated with data from a MySQL database that will be always growing. Here is my code:
function getPromoChartData() {
var city = document.getElementById("cityselect").value;
$.ajax({
type: 'GET',
url: 'getpromochart.php',
dataType: 'json',
data: { city:city, },
success: function(response) {
//console.log (response);
function collate(d) {
return d.reduce(function(prev, cur, index) {
var ret = {};
for (var prop in cur) {
if (index === 0) {
ret[prop] = [];
} else {
ret[prop] = prev[prop];
}
ret[prop].push(cur[prop]);
}
return ret;
}, {});
}
var reduced = collate(response);
var ctx = document.getElementById('promoChart').getContext('2d');
var chartColors = window.chartColors;
var color = Chart.helpers.color;
var promoChart = new Chart(ctx, {
type: 'polarArea',
data: {
labels: reduced.codes,
datasets: [{
label: 'Promo Codes',
data: reduced.count,
backgroundColor: [
color(chartColors.red).alpha(0.5).rgbString(),
color(chartColors.orange).alpha(0.5).rgbString(),
color(chartColors.yellow).alpha(0.5).rgbString(),
color(chartColors.green).alpha(0.5).rgbString(),
color(chartColors.blue).alpha(0.5).rgbString(),
],
}]
},
options: {
responsive: true,
}
});
promoChart.update();
$('#promocharttitle').html("Promo Data ("+cityfancy+")");
}
});
}
The way I have it now, after the first 5 entires are filled up the rest of them will be grey, which totally sucks. I just want that color scheme to repeat. How can I make that happen?
First you could define an array of colors. Once you know the size of your data, you can determine the background colors as follows:
var colors = ['red', 'orange', 'yellow', 'green', 'blue'];
...
var bgColors = [];
for (var i = 0; i < data.length; i++) {
bgColors.push(colors[i % colors.length]);
}
This is a simplified example:
<html>
<head>
<title>Polar Area Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width: 90%">
<canvas id="canvas"></canvas>
</div>
<script>
var colors = ['red', 'orange', 'yellow', 'green', 'blue'];
var data = [4, 5, 4, 2, 8, 7, 6, 8, 5, 4, 1, 3, 7];
window.onload = function() {
var bgColors = [];
for (var i = 0; i < data.length; i++) {
bgColors.push(colors[i % colors.length]);
}
var ctx = document.getElementById('canvas').getContext('2d');
window.myChart = new Chart(ctx, {
type: 'polarArea',
data: {
datasets: [{
label: 'Promo Codes',
data: data,
backgroundColor: bgColors
}]
},
options: {
responsive: true,
}
});
};
</script>
</body>
</html>
Related
I am beginner on this Chart.js and wanna ask, How can I hide the labels and 0 values in the bar Chart. I cannot just hide the whole Dataset since I am using a SQL Table to get the Values "into" Chart.Js. I just want the bar chart show only if the labels have the value. Need your help
sample chart
{
{
$.post("datachartasr.php",
function (data)
{
console.log(data);
var intake = [];
var active = [];
var inactive = [];
var deffered = [];
var widthdrawn = [];
var dis_ter_dereg = [];
var missing = [];
for (var i in data) {
intake.push(data[i].intake);
active.push(data[i].active);
inactive.push(data[i].inactive);
deffered.push(data[i].deffered);
widthdrawn.push(data[i].widthdrawn);
dis_ter_dereg.push(data[i].dis_ter_dereg);
missing.push(data[i].missing);
}
var chartdata = {
labels: intake,
datasets: [
{
label: 'Active Status',
backgroundColor: '#1E90FF',
borderColor: '#1E90FF',
hoverBackgroundColor: '#1E90FF',
hoverBorderColor: '#666666',
data: active
},
{
label: 'Deferred Status',
backgroundColor: '#708090',
borderColor: '#708090',
hoverBackgroundColor: '#708090',
hoverBorderColor: '#666666',
data: deffered
},
.....
.....
.....
]
};
var graphTarget = $("#graphCanvas");
var barGraph = new Chart(graphTarget, {
type: 'bar',
data: chartdata,
});
});
}
}
You can have the below function inside data labels to hide the Zero value:
options: {
plugins: {
datalabels: {
display: function(context) {
return context.dataset.data[context.dataIndex] !== 0; // or >= 1 or ...
}
}
}
}
See more on this issue here https://github.com/chartjs/chartjs-plugin-datalabels/issues/6
I have strange behaviour from bars or risers in a dynamically built Chartjs chart.
They don't begin at point 0 on the y-axis and not all of them show.
I have tried a variety of ways as found here or other forums, but no success.
Please help.
The code to build it is from json ex ajax to MVC Controller/Action.
chartSetup.jsonDataSets = new List<ChartDataset>();
ChartDataset jsonDataSets = new ChartDataset
{
data = "[408, 547, 675, 534]",
label = "Actual",
backgroundColor = "#8e5ea2"
};
chartSetup.jsonDataSets.Add(jsonDataSets);
jsonDataSets = new ChartDataset
{
data= "[350, 447, 725, 534]",
label = "Budgeted",
backgroundColor = "red"
};
chartSetup.jsonDataSets.Add(jsonDataSets);
If I hardcode particularly the datasets, for the chart, then no problem.
var type = 'bar';
var xLabels = ["May", "Jun", "Jul", "Aug", "Sept"];
var topTitle = { display: true, text: 'Maintenance Costs', fontStyle: 'bold', fontSize: 18, fontColor: 'white' };
var canvasTyreCostsChart = $("#canvasMaintenanceBar").get(0).getContext("2d");
var datasources = [
{
label: "Budgeted",
backgroundColor: 'red',
data: [133, 221, 783, 1078]
},
{
label: "Actual",
backgroundColor: "#8e5ea2",
data: [408, 547, 675, 734]
}
];
var regionalCountCostBar = new Chart(canvasTyreCostsChart,
{
type: type,
data: {
labels: xLabels,
datasets: datasources,
},
options:
{
responsive: true,
title: topTitle,
legend: { position: 'bottom' },
}
});
But done dynamically the bars float above the zero point on the y axis.
Here's the code.
datasources = jsonData['jsonDataSets'];
var dynamicChartCanvas = $("#canvas-" + columnID).get(0).getContext("2d");
var xLabelsArr = [];
$.each(xLabels, function (key, val)
{
var rec = xLabels[key];
xLabelsArr.push(rec['label']);
});
var label;
var backgroundColor;
var data2 = "";
var data3 = [];
var DS = [];
var dataSource2;
// Extract the individual elements
$.each(datasources, function (key, val)
{
var rec = datasources[key];
$.each(rec, function (key, val)
{
if (key == "label")
{
label = val;
}
if (key == "backgroundColor")
{
backgroundColor = val;
}
if (key == "data")
{
data2 = rec[key];
var xx = data2.replace("[", "").replace("]","").split(",");
data3.push(xx);
}
});
dataSource2 =
{
label: label,
backgroundColor: backgroundColor,
data: data3,
}
console.log("ds label " + JSON.stringify(label));
console.log("data3 " + JSON.stringify(data3));
data3 = [];
DS.push(dataSource2);
});
console.log("DS " + JSON.stringify(DS));
var tempData2 = {
labels: xLabelsArr,
datasets: DS,
};
var topTitle = { display: true, text: 'Maintenance Costs', fontStyle: 'bold', fontSize: 18, fontColor: 'white' };
var chart = new Chart(dynamicChartCanvas,
{
type: type,
data: tempData2,
options:
{
responsive: responsive,
title: topTitle,
legend: { position: 'bottom' },
}
});
The object array as logged:
DS [{"label":"Actual","backgroundColor":"#8e5ea2","data":[["408"," 547"," 675"," 534"]]},{"label":"Budgeted","backgroundColor":"red","data":[["350"," 447"," 725"," 534"]]}]
What was required, was a further iteration thru the JSON array in the data object, getting each value and building it into a js array.
if (key == "data")
{
var dataRec = rec[key];
var jsonData = JSON.parse(dataRec);
xValuesArray = [];
for (var i = 0; i < jsonData.length; i++)
{
var value = jsonData[i];
xValuesArray.push(value);
}
}
});
chartDataset =
{
label: label,
backgroundColor: backgroundColor,
data: xValuesArray,
}
chartDatasets.push(chartDataset);
I am using Chart.js (https://www.chartjs.org) to make a chart, but after you switch the chart data to a new dataset and roll over the chart with the cursor it glitches out and reverts back to the old dataset. Here is my code:
<li class="breadcrumb-item"><select id="cityselect" onchange="changeCity();">
<option value="la">Los Angeles</option>
<option value="oc">Orange County</option>
<option value="sf">San Francisco</option>
</select></li>
<div class="bottommargin divcenter" style="max-width: 90%; min-height: 350px;">
<canvas id="resChart"></canvas>
</div>
function changeCity(){
var ctx = document.getElementById('resChart');
var resChart = new Chart(ctx);
resChart.destroy();
getResChartData();
}
function getResChartData() {
var city = document.getElementById("cityselect").value;
$.ajax({
type: 'GET',
url: 'getreschart.php',
dataType: 'json',
data: { city:city, },
success: function(response) {
//console.log (response);
function collate(d) {
return d.reduce(function(prev, cur, index) {
var ret = {};
for (var prop in cur) {
if (index === 0) {
ret[prop] = [];
} else {
ret[prop] = prev[prop];
}
ret[prop].push(cur[prop]);
}
return ret;
}, {});
}
var reduced = collate(response);
var ctx = document.getElementById('resChart').getContext('2d');
var resChart = new Chart(ctx, {
type: 'line',
data: {
labels: reduced.mmyy,
datasets: [{
label: 'Fulfilled Reservations',
data: reduced.fulfilledreservations,
backgroundColor: window.chartColors.orange,
borderColor: window.chartColors.orange,
fill: false
},
{
label: 'Unfulfilled Reservations',
data: reduced.unfulfilledreservations,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
fill: false
},
{
label: 'All Reservations',
data: reduced.allreservations,
backgroundColor: window.chartColors.gray,
borderColor: window.chartColors.gray,
fill: false
}]
},
options: {
responsive: true,
elements: {
line: {
tension: 0 // disables bezier curves
}
}
}
});
}
});
}
As you can see I have destroyed the chart and I have updated it property (I think) - what gives?
we should use the
if(myChart)
myChart.destroy()
method before assigning new datasets as described in the following link
ChartJs line chart repaint glitch while hovering over
I've made this bar chart http://imageshack.com/a/img901/7186/cnOfhh.png, and the code for it is:
//compute & mark average color
for (var i = 0; i < zdata.length; i++) {
if (zdata[i].TargetTime == null) zdata[i].TargetTime = 0;
if (zdata[i].TimePlayed == null) zdata[i].TimePlayed = 0;
if (zdata[i].TargetTime >= zdata[i].TimePlayed) {
zdata[i]['Color'] = 'green';
} else {
zdata[i]['Color'] = 'red';
}
}
//localsitelist
var element = {
rt: 'D',
Id: rid,
courselist: clist,
selcourseId: selCid,
selcourse: selCname,
cartlist: wData,
selSiteId: lsid,
selsite: sitename,
dataList: zdata
}; //, carts: _mVM.availableCarts()}; //
//if rid exists, is update, else its new
var found = -1;
for (var k = 0; k < document.pvm.rapArray().length; k++) {
if (document.pvm.rapArray()[k].Id() == rid) {
document.pvm.rapArray()[k].update(element);
//build chart data
var values = []; //, series = Math.floor(Math.random() * 6) + 6;
for (var i = 0; i < zdata.length; i++) {
values[i] = {
data: [
[zdata[i].HoleSequence, zdata[i].TimePlayed]
],
color: zdata[i].Color
};
}
//var data = [{ data: [[0, 1]], color: "red" }, { data: [[1, 2]], color: "yellow" },{ data: [[2, 3]], color: "green" }];
BarChart('#ChartD-Overview' + rid, values);
found = 1;
break;
}
}
if (found == -1) {
var rvm = new panelViewModel(element);
document.pvm.rapArray.push(rvm);
//build chart data
var values = []; //, series = Math.floor(Math.random() * 6) + 6;
for (var i = 0; i < zdata.length; i++) {
values[i] = {
data: [
[zdata[i].HoleSequence, zdata[i].TimePlayed]
],
color: zdata[i].Color
};
}
BarChart('#ChartD-Overview' + rvm.Id(), values);
}
and the BarChart function:
function BarChart(id, data) {
$.plot(id, data, {
series: {
bars: {
show: true,
barWidth: 0.6,
align: "center"
}
},
stack: true,
xaxis: {
mode: "categories",
tickLength: 0
}
});
}
The problem is that I can't manage to get something like this https://imageshack.us/i/expGGpOkp, the little line should be zdata[i].TargetTime. I've tried something using stacked bar chart idea but the result was way different... What am I doing wrong? Can anyone help me with a suggestion to start with to get the same bar chart like in the last image?
Here is something like your second picture using another bar dataseries where the start and end of the bars are the same thereby reducing them to lines, you don't need to stack any of the bars just give them the right y-values (fiddle):
$(function () {
var dataBarsRed = {
data: [
[2, 3], ],
label: 'Bars in Red',
color: 'red'
};
var dataBarsGreen = {
data: [
[1, 2],
[3, 1],
[4, 3]
],
label: 'Bars in Green',
color: 'green'
};
var dataLines = {
data: [
[1, 3, 3],
[2, 3.5, 3.5],
[3, 1.5, 1.5],
[4, 2.5, 2.5]
],
label: 'Lines',
color: 'navy',
bars: {
barWidth: 0.5
}
};
var plot = $.plot("#placeholder", [dataBarsRed, dataBarsGreen, dataLines], {
points: {
show: false
},
lines: {
show: false
},
bars: {
show: true,
align: 'center',
barWidth: 0.6
},
grid: {
hoverable: true,
autoHighlight: true
},
xaxis: {
min: 0,
max: 5
},
yaxis: {
min: 0,
max: 5
}
});
});
I've made this bar chart http://imageshack.com/a/img901/7186/cnOfhh.png, and the code for it is:
//compute & mark average color
for (var i = 0; i < zdata.length; i++) {
if (zdata[i].TargetTime == null) zdata[i].TargetTime = 0;
if (zdata[i].TimePlayed == null) zdata[i].TimePlayed = 0;
if (zdata[i].TargetTime >= zdata[i].TimePlayed) {
zdata[i]['Color'] = 'green';
} else {
zdata[i]['Color'] = 'red';
}
}
//localsitelist
var element = {
rt: 'D',
Id: rid,
courselist: clist,
selcourseId: selCid,
selcourse: selCname,
cartlist: wData,
selSiteId: lsid,
selsite: sitename,
dataList: zdata
}; //, carts: _mVM.availableCarts()}; //
//if rid exists, is update, else its new
var found = -1;
for (var k = 0; k < document.pvm.rapArray().length; k++) {
if (document.pvm.rapArray()[k].Id() == rid) {
document.pvm.rapArray()[k].update(element);
//build chart data
var values = []; //, series = Math.floor(Math.random() * 6) + 6;
for (var i = 0; i < zdata.length; i++) {
values[i] = {
data: [
[zdata[i].HoleSequence, zdata[i].TimePlayed]
],
color: zdata[i].Color
};
}
//var data = [{ data: [[0, 1]], color: "red" }, { data: [[1, 2]], color: "yellow" },{ data: [[2, 3]], color: "green" }];
BarChart('#ChartD-Overview' + rid, values);
found = 1;
break;
}
}
if (found == -1) {
var rvm = new panelViewModel(element);
document.pvm.rapArray.push(rvm);
//build chart data
var values = []; //, series = Math.floor(Math.random() * 6) + 6;
for (var i = 0; i < zdata.length; i++) {
values[i] = {
data: [
[zdata[i].HoleSequence, zdata[i].TimePlayed]
],
color: zdata[i].Color
};
}
BarChart('#ChartD-Overview' + rvm.Id(), values);
}
and the BarChart function:
function BarChart(id, data) {
$.plot(id, data, {
series: {
bars: {
show: true,
barWidth: 0.6,
align: "center"
}
},
stack: true,
xaxis: {
mode: "categories",
tickLength: 0
}
});
}
The problem is that I can't manage to get something like this https://imageshack.us/i/expGGpOkp, the little line should be zdata[i].TargetTime. I've tried something using stacked bar chart idea but the result was way different... What am I doing wrong? Can anyone help me with a suggestion to start with to get the same bar chart like in the last image?
Here is something like your second picture using another bar dataseries where the start and end of the bars are the same thereby reducing them to lines, you don't need to stack any of the bars just give them the right y-values (fiddle):
$(function () {
var dataBarsRed = {
data: [
[2, 3], ],
label: 'Bars in Red',
color: 'red'
};
var dataBarsGreen = {
data: [
[1, 2],
[3, 1],
[4, 3]
],
label: 'Bars in Green',
color: 'green'
};
var dataLines = {
data: [
[1, 3, 3],
[2, 3.5, 3.5],
[3, 1.5, 1.5],
[4, 2.5, 2.5]
],
label: 'Lines',
color: 'navy',
bars: {
barWidth: 0.5
}
};
var plot = $.plot("#placeholder", [dataBarsRed, dataBarsGreen, dataLines], {
points: {
show: false
},
lines: {
show: false
},
bars: {
show: true,
align: 'center',
barWidth: 0.6
},
grid: {
hoverable: true,
autoHighlight: true
},
xaxis: {
min: 0,
max: 5
},
yaxis: {
min: 0,
max: 5
}
});
});