Generate Chart With 2 Datasets Charts.js - javascript

I can get my chart to display with 1 dataset no problem, but adding in the second one to the syntax below gives me an error of
Uncaught Syntax Error: Unexpected Token }
This is my syntax - what is causing the issue?
var ctx = document.getElementById('canvas').getContext('2d');
var chart = new Chart(ctx, {
datasets: [{
type: 'bar',
labels: labelsarr,
label: 'Red Team',
backgroundColor: 'rgba(0, 129, 214, 0.8)',
data: [values]
}, {
type: 'line',
label: 'Green Team',
backgroundColor: 'rgba(0,129, 218, 0.8)',
data: [values1]
}, {
options: {
tooltips: {
callbacks: {
label: function (t, d) {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel >= 1000 ? '$' + t.yLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '$' + t.yLabel;
return xLabel + ': ' + yLabel;
}
}
},
legend: {
display: false,
position: 'top',
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function (value, index, values) {
if (parseInt(value) >= 1000) {
return '$' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else { return '$' + value; }
}
}
}]
}
},
plugins: [{
beforeDraw: function (chart) {
var labels = chart.data.labels;
}
}]
}
}]
);

The second last line of your code }] is backwards. It should be ]}
reconfigured structure:
var ctx = document.getElementById('canvas').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [
{
label: 'Red Team',
data: values,
backgroundColor: 'rgba(0, 129, 214, 0.8)',
},
{
label: 'Green Team',
data: values1,
type: 'line',
backgroundColor: 'rgba(0,129, 218, 0.8)',
}
],
labels: labelsarr
},
options: {
callbacks: {
label: function (t, d) {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel >= 1000 ? '$' + t.yLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '$' + t.yLabel;
return xLabel + ': ' + yLabel;
}
},
legend: {
display: false,
position: 'top'
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function (value, index, values) {
if (parseInt(value) >= 1000) {
return '$' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else { return '$' + value; }
}
}
}]
}
},
plugins: [{
beforeDraw: function (chart) {
var labels = chart.data.labels;
}
}]
});

Related

How to disable converting decimal number to exponential?

window.chartColors = {
red: '#ffb5c5',
orange: '#FFA500',
yellow: '#F0E68C',
green: '#aee0e0',
blue: '#87CEFA',
purple: '#EE82EE',
grey: '#C0C0C0'
};
$(document).ready(function() {
var data = [{
"tc": "1.25173997",
"trf": "0.00000024",
"nc": "1.00139199",
"formatted_date": "temmp1",
"from_date": "2019-02-01 00:00:00",
"to_date": "2019-02-08 23:59:59"
}, ];
var formatted_date = [];
var tcs = [];
var trps = [];
var ncs = [];
// var data = $.parseJSON(data);
$.each(data, function(index, item) {
formatted_date.push(item.formatted_date);
tcs.push(item.tc);
trps.push(item.trf);
ncs.push(item.nc);
});
refData = [{
label: 'C',
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: tcs,
fill: false,
/* cubicInterpolationMode: 'monotone' */
},
{
label: 'R P',
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: trps,
fill: false
},
{
label: 'N C',
backgroundColor: window.chartColors.green,
borderColor: window.chartColors.green,
data: ncs,
fill: false
},
];
var chartdata = {
labels: formatted_date,
datasets: refData
};
//console.log(chartdata);
var graphTarget = $("#myChart");
var Graph = new Chart(graphTarget, {
type: 'line',
data: chartdata,
options: {
responsive: true,
title: {
display: true,
text: 'R P'
},
scales: {
xAxes: [{
// stacked: true,
display: true,
scaleLabel: {
display: true,
labelString: 'Duration'
}
}],
yAxes: [{
// stacked: true,
display: true,
scaleLabel: {
display: true,
labelString: 'Amt'
},
ticks: {
min: 0, // it is for ignoring negative step.
}
}]
},
},
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<div style="width:75%;">
<canvas id="myChart"></canvas>
</div>
As you can see for R P 0.00000024 is getting converted into 2.4e-7. But I want it show as is i.e. 0.00000024.
For other decimals numbers, it's perfectly fine, but for the above-mentioned decimal, it's converting into exponential. Is there any option to set? Is this possible?
With the help of this solution, I patched my problem. If anyone got better solution let me know.
Number.prototype.noExponents = function() {
var data = String(this).split(/[eE]/);
if (data.length == 1) return data[0];
var z = '',
sign = this < 0 ? '-' : '',
str = data[0].replace('.', ''),
mag = Number(data[1]) + 1;
if (mag < 0) {
z = sign + '0.';
while (mag++) z += '0';
return z + str.replace(/^\-/, '');
}
mag -= str.length;
while (mag--) z += '0';
return str + z;
}
window.chartColors = {
red: '#ffb5c5',
orange: '#FFA500',
yellow: '#F0E68C',
green: '#aee0e0',
blue: '#87CEFA',
purple: '#EE82EE',
grey: '#C0C0C0'
};
$(document).ready(function() {
var data = [{
"tc": "1.25173997",
"trf": "0.00000024",
"nc": "1.00139199",
"formatted_date": "temmp1",
"from_date": "2019-02-01 00:00:00",
"to_date": "2019-02-08 23:59:59"
}, ];
var formatted_date = [];
var tcs = [];
var trps = [];
var ncs = [];
// var data = $.parseJSON(data);
$.each(data, function(index, item) {
formatted_date.push(item.formatted_date);
tcs.push(item.tc);
trps.push(item.trf);
ncs.push(item.nc);
});
refData = [{
label: 'C',
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: tcs,
fill: false,
/* cubicInterpolationMode: 'monotone' */
},
{
label: 'R P',
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: trps,
fill: false
},
{
label: 'N C',
backgroundColor: window.chartColors.green,
borderColor: window.chartColors.green,
data: ncs,
fill: false
},
];
var chartdata = {
labels: formatted_date,
datasets: refData
};
//console.log(chartdata);
var graphTarget = $("#myChart");
var Graph = new Chart(graphTarget, {
type: 'line',
data: chartdata,
options: {
responsive: true,
title: {
display: true,
text: 'R P'
},
scales: {
xAxes: [{
// stacked: true,
display: true,
scaleLabel: {
display: true,
labelString: 'Duration'
}
}],
yAxes: [{
// stacked: true,
display: true,
scaleLabel: {
display: true,
labelString: 'Amt'
},
ticks: {
min: 0, // it is for ignoring negative step.
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
label += tooltipItem.yLabel.noExponents();
return label;
}
}
}
},
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<div style="width:75%;">
<canvas id="myChart"></canvas>
</div>

How can I hide tooltip in Chart.js on a specific data label?

I am trying to hide a tooltip in Chart.js whenever the name of a clicked object is "Something". I have already tried this:
this.doughnutChart = new Chart(this.doughnutCanvas.nativeElement, {
type: 'doughnut',
data: {
datasets: [{
label: _.map(this.dataService.AmTimeSlots, 'ProjectName'),
data: _.map(this.dataService.AmTimeSlots, 'Duration'),
backgroundColor: _.map(this.dataService.AmTimeSlots, 'Color'),
hoverBackgroundColor: _.map(this.dataService.AmTimeSlots, 'HoverColor'),
borderColor: _.map(this.dataService.AmTimeSlots, 'BorderColor'),
borderWidth: 1.5
},
{
label: _.map(this.dataService.PmTimeSlots, 'ProjectName'),
data: _.map(this.dataService.PmTimeSlots, 'Duration'),
backgroundColor: _.map(this.dataService.PmTimeSlots, 'Color'),
hoverBackgroundColor: _.map(this.dataService.PmTimeSlots, 'HoverColor'),
borderColor: _.map(this.dataService.PmTimeSlots, 'BorderColor'),
borderWidth: 1.5
}],
},
options: {
elements: {
arc: {
roundedCornersFor: 0
}
},
segmentShowStroke: false,
responsive: true,
maintainAspectRatio: true,
legend: {
display: false
},
onClick: this.chartClick.bind(this),
cutoutPercentage: 65,
tooltips: {
filter: function (tooltipItem) {
if (tooltipItem.xLabel == "Free Slot") {
return false;
} else {
return true;
}
},
callbacks: {
label: function (tooltipItems, data) {
return data.datasets[tooltipItems.datasetIndex].label[tooltipItems.index];
},
afterLabel: function (tooltipItems, data) {
return Math.floor(data.datasets[tooltipItems.datasetIndex].data[tooltipItems.index] / 6) + 'h ' + data.datasets[tooltipItems.datasetIndex].data[tooltipItems.index] * 10 % 60 + 'm';
}
}
}
},
config: {
data: this.dataService,
settings: this.settingsService
}
});
And this code above is working fine. It’s successfully hiding the text of tooltip, but the problem is that the black label/border still remains. How can I hide it?
You can simply filter tooltips:
options: {
tooltips: {
filter: function (tooltipItem, data) {
var label = data.labels[tooltipItem.index];
if (label == "Red") {
return false;
} else {
return true;
}
}
}
}
See this jsfiddle: https://jsfiddle.net/beaver71/ndc2uao2/
Update for Chart.js 3:
options: {
plugins: {
tooltip: {
filter: function (tooltipItem, data) {
return tooltipItem.label === "Red";
}
}
}
}

Chart.JS Not Formatting Y-Axis-1 Properly

I am utilizing the below syntax to format the display points as $ and %. Well so I thought. My issue is that both the display points are displayed as $, it's almost like the y-axis-1 is not being picked up at all. Am I missing a closing bracket or something silly in the syntax? What is causing the % to not be applied to the line graph?
var labelsarr = ["Richard 14", "Richard 15", "Jason 14", "Jason 15", "Jack 14", "Jack 15"];
var ctx = document.getElementById('canvas1').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: labelsarr,
datasets: [{
type: 'line',
fill: false,
label: 'Sale Total',
backgroundColor: 'rgba(255,0,0,1)',
borderColor: 'rgba(255,0,0,1)',
data: values1,
yAxisID: 'y-axis-1'
}, {
label: 'Sale Total',
backgroundColor: 'rgba(0, 129, 214, 0.8)',
data: values
}]
},
options: {
tooltips: {
callbacks: {
label: function (t, d) {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel >= 1000 ? '$' + t.yLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '$' + t.yLabel;
return xLabel + ': ' + yLabel;
}
}
},
legend: {
display: false,
position: 'top',
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function (value, index, values) {
if (parseInt(value) >= 1000) {
return '$' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return '$' + value;
}
}
}
}, {
id: 'y-axis-1',
position: 'right',
ticks: {
beginAtZero: true,
callback: function (value, index, values) {
return value + '%';
}
}
}]
}
}
});
This is because, you are returning same tooltip label for both the datasets.
You should rather use the following tooltips callback function :
callbacks: {
label: function(t, d) {
if (t.datasetIndex === 0) {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel;
return xLabel + ': ' + yLabel + '%';
} else {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel >= 1000 ? '$' + t.yLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '$' + t.yLabel;
return xLabel + ': ' + yLabel;
}
}
}
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ
var labelsarr = ["Richard 14", "Richard 15", "Jason 14", "Jason 15", "Jack 14", "Jack 15"];
var values = [1, 2, 3, 4, 5, 6];
var values1 = [1, 2, 3, 4, 5, 6];
var ctx = document.getElementById('canvas1').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: labelsarr,
datasets: [{
type: 'line',
fill: false,
label: 'Sale Total',
backgroundColor: 'rgba(255,0,0,1)',
borderColor: 'rgba(255,0,0,1)',
data: values1,
yAxisID: 'y-axis-1'
}, {
label: 'Sale Total',
backgroundColor: 'rgba(0, 129, 214, 0.8)',
data: values
}]
},
options: {
tooltips: {
callbacks: {
label: function(t, d) {
if (t.datasetIndex === 0) {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel;
return xLabel + ': ' + yLabel + '%';
} else {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel >= 1000 ? '$' + t.yLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '$' + t.yLabel;
return xLabel + ': ' + yLabel;
}
}
}
},
legend: {
display: false,
position: 'top',
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function(value, index, values) {
if (parseInt(value) >= 1000) {
return '$' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return '$' + value;
}
}
}
}, {
id: 'y-axis-1',
position: 'right',
ticks: {
beginAtZero: true,
callback: function(value, index, values) {
return value + '%';
}
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="canvas1"></canvas>

Can not read property 'Concat' of Undefined

I am attempting to use the charts.js plug-in and do a combo chart, but I want the line to be on top of the bar. This is the syntax that I am using, and both my arrays linedata & bardata are populated but whenever I run this syntax I get an error of
Uncaught TypeError: Cannot read property 'concat' of undefined
at n (Chart.min.js:11)
at t.update (Chart.min.js:11)
at t.construct (Chart.min.js:11)
at new t (Chart.min.js:12)
at trends:507
This is the syntax I utulize - where is the error?
var ctx = document.getElementById('canvas').getContext('2d');
var chart = new Chart(ctx, {
data: {
labels: labelsarr,
datasets: [{
type: 'line',
fill: false,
label: 'Line Example',
backgroundColor: 'rgba(255,0,0,1)',
borderColor: 'rgba(255,0,0,1)',
data: linedata
}, {
type: 'bar',
label: 'Bar Example',
backgroundColor: 'rgba(0, 129, 214, 0.8)',
data: bardata
}]
},
options: {
tooltips: {
callbacks: {
label: function (t, d) {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel >= 1000 ? '$' + t.yLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '$' + t.yLabel;
return xLabel + ': ' + yLabel;
}
}
},
legend: {
display: false,
position: 'top',
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function (value, index, values) {
if (parseInt(value) >= 1000) {
return '$' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return '$' + value;
}
}
}
}]
}
},
plugins: [{
beforeDraw: function(chart) {
var labels = chart.data.labels;
}
}]
});
Edit
This is how the arrays are being populated - values passed from php
var ldata = <?php echo $ldata; ?>;
var values = [];
for (var i = 0; i < ldata.length; i++) {
values.push(ldata[i]);
}
var bdata = <?php echo $bdata; ?>;
var values1 = [];
for (var i = 0; i < bdata.length; i++) {
values1.push(bdata[i]);
}
You would have to set the chart type in the main chart option, not inside the dataset (the second one) :
var chart = new Chart(ctx, {
type: 'bar',
data: {
...
Here is the working version of your code :
var labelsarr = ['A', 'B', 'C'];
var linedata = [2, 5, 3];
var bardata = [4, 2, 6];
var ctx = document.getElementById('canvas').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar', //<-- set here
data: {
labels: labelsarr,
datasets: [{
type: 'line',
fill: false,
label: 'Line Example',
backgroundColor: 'rgba(255,0,0,1)',
borderColor: 'rgba(255,0,0,1)',
data: linedata
}, {
label: 'Bar Example',
backgroundColor: 'rgba(0, 129, 214, 0.8)',
data: bardata
}]
},
options: {
tooltips: {
callbacks: {
label: function(t, d) {
var xLabel = d.datasets[t.datasetIndex].label;
var yLabel = t.yLabel >= 1000 ? '$' + t.yLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : '$' + t.yLabel;
return xLabel + ': ' + yLabel;
}
}
},
legend: {
display: false,
position: 'top',
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function(value, index, values) {
if (parseInt(value) >= 1000) {
return '$' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return '$' + value;
}
}
}
}]
}
},
plugins: [{
beforeDraw: function(chart) {
var labels = chart.data.labels;
}
}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="canvas"></canvas>

Hide/Show yaxis on series hide/show event

I'm making a multiple panel chart, and I'm trying to hide the y-axis on the hide event of the axis serie.
I tried setting the axis height and redrawing it (didn't work), set extremes, nothing worked. I also tryed this solution but didn't work, I beleave it didn't work beacause I'm using highstock and the "solution" use Highcharts, does that make sense?
I also have to resize the others y-axis when one is hidden, but this is another problem. But if someone has a tip on how to do it automatically would be thankful
Here is my JSFiddle code.
$(function () {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function (data) {
var data1 = [ [100,0], [200,0], [300,1], [400,0], [500,1] ];
var data2 = [ [100,1], [200,0], [300,1], [400,0], [500,0] ];
var data3 = [ [100,1], [200,1], [300,0], [400,0], [500,1] ];
var data4 = [ [100,0], [200,1], [300,1], [400,0], [500,0] ];
// create the chart
var chart = $('#container').highcharts('StockChart', {
title: {
text: 'AAPL Historical'
},
legend: {
enabled: true
},
plotOptions: {
series: {
events: {
hide: function (event) {
console.log(this.yAxis)
//Hide
},
show: function (event) {
console.log(this.yAxis)
//Display
}
}
}
},
tooltip: {
pointFormatter: function() {
var state = (this.y == 1 ? "Active" : "Inactive");
var tooltip = '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + state + '</b><br/>'
return tooltip;
}
},
yAxis: [{
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false}
}, {
top: '25%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "aaa"
}
}, {
top: '50%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false}
}, {
top: '75%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false}
}],
series: [{
name: 'Data1',
data: data1,
step: true,
yAxis: 0
}, {
name: 'Data2',
data: data2,
step: true,
yAxis: 1
}, {
name: 'Data3',
data: data3,
step: true,
yAxis: 2
}, {
name: 'Data4',
data: data4,
step: true,
yAxis: 3
}]
});
});
});
I worked more on solution and I found A way to hide the y-axis, by changing its height to 0% on the series hide event. I'm also increasing the axis height back to 25% in the series show event.
plotOptions: {
series: {
events: {
hide: function (event) {
this.yAxis.update({
height: '0%'
});
},
show: function (event) {
this.yAxis.update({
height: '25%'
});
}
}
}
},
Full code
Edit:
I found a way to resize the others y-axis when one of them is hidden or one the axis is displayed.
You can check the full code.
$(function () {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function (data) {
var data1 = [ [100,0], [150,1], [150,0], [200,0], [300,1], [400,0], [500,1] ];
var data2 = [ [100,1], [200,0], [300,1], [400,0], [500,0] ];
var data3 = [ [100,1], [200,1], [300,0], [400,0], [500,1] ];
var data4 = [ [100,0], [200,1], [300,1], [400,0], [500,0] ];
// create the chart
var chart = $('#container').highcharts('StockChart', {
title: {
text: 'AAPL Historical'
},
legend: {
enabled: true
},
plotOptions: {
series: {
marker: {
enabled: true,
radius : 2
},
events: {
hide: function (event) {
var serieYAxis = this.yAxis;
serieYAxis.visivel = false;
serieYAxis.update({
height: '0%',
title: {
style: {"display":"none"}
}
});
var axis = this.chart.yAxis.filter(
function (axis) {
return axis.visivel == null || axis.visivel;
}
);
resizeAxis(axis);
},
show: function (event) {
this.yAxis.visivel = true;
this.yAxis.update({
title: {
style: {"display":"initial"}
}
});
var axis = this.chart.yAxis.filter(
function (axis) {
return axis.visivel == null || axis.visivel;
}
);
resizeAxis(axis);
}
}
}
},
tooltip: {
pointFormatter: function() {
var state = (this.y == 1 ? "Active" : "Inactive");
var tooltip = '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + state + '</b><br/>'
return tooltip;
}
},
yAxis: [{
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y0"
}
}, {
top: '25%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y1"
}
}, {
top: '50%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y2"
}
}, {
top: '75%',
height: '25%',
offset: 0,
lineWidth: 2,
labels: {enabled: false},
title : {
text: "y3"
}
}],
series: [{
name: 'Data1',
data: data1,
step: true,
yAxis: 0
}, {
name: 'Data2',
data: data2,
step: true,
yAxis: 1
}, {
name: 'Data3',
data: data3,
step: true,
yAxis: 2
}, {
name: 'Data4',
data: data4,
step: true,
yAxis: 3
}]
});
});
});

Categories