Chartjs not displaying data from a dynamic stored variable - chart.js

I am having issue in representing two datasets on my chartjs chart when both of my data is from a stored variable. When both of my data {inbound & outbound} is from a stored(and unique) variable, It shows two line graph but having similar data with the inbound data list inheriting the outbound data list. The inbound and outbound data list are two separate data and should be shown as two unique datasets on the chart.
My code is this
var inbound = InboundSmsCountList;
var outbound = OutboundSmsCountList;
var ff = MonthDaysList;
var combined_arraysx = [InboundSmsCountList,OutboundSmsCountList];
var max2 = combined_arraysx.reduce(function(final, current) {
for (var i = 0; i < final.length; ++i) {
if (current[i] > final[i]) {
final[i] = current[i];
}
}
return final;
});
var maxValue = Math.max.apply(Math, max2);
console.log(maxValue);
var ctx6 = document.getElementById('chartBar6').getContext('2d');
var gradient1x = ctx6.createLinearGradient(0, 350, 0, 0);
gradient1x.addColorStop(0, 'rgba(241, 0, 117,0)');
gradient1x.addColorStop(1, 'rgba(241, 0, 567,.5)');
var gradient2x = ctx6.createLinearGradient(0, 280, 0, 0);
gradient2x.addColorStop(0, 'rgba(86, 87, 255,0)');
gradient2x.addColorStop(1, 'rgba(34, 45, 255,.5)');
var config = {
type: 'line',
data: {
labels: ff,//['May-01', 'May-02', 'May-03', 'May-04', 'May-05', 'May-06', 'May-07', 'May-08', 'May-09', 'May-10', 'May-11', 'May-12', 'May-13', 'May-14', 'May-15', 'May-16', 'May-17', 'May-18', 'May-19', 'May-20', 'May-21', 'May-22', 'May-23', 'May-24', 'May-25', 'May-26', 'May-27', 'May-28', 'May-29', 'May-30', 'May-31'],
datasets: [{
label: 'Outbound',
data: outbound,//[1, 2, 0, 0, 84, 0, 10, 16, 8, 0, 0, 0, 4, 4, 1, 0, 0, 0, 1, 5, 0, 1, 0, 0, 0, 0, 71, 0, 0, 0, 0],
borderColor: '#00cccc',
borderWidth: 1,
backgroundColor: gradient2x,
},{
label: 'Inbound',
data: inbound,//[0, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0],
borderColor: '#00cccc',
borderWidth: 1,
backgroundColor: gradient1x,
}]
},
options: {
maintainAspectRatio: false,
legend: {
display: true,
position:"top",
labels: {
display: true
}
},
scales: {
xAxes: [{
//stacked: true,
barPercentage: 0.5,
ticks: {
beginAtZero:true,
fontSize: 11
},
gridLines: {
display: false,
drawBorder: true
},
}],
yAxes: [{
//stacked: true,
ticks: {
fontSize: 10,
color: '#97a3b9',
min: 0,
max: maxValue
},
gridLines: {
display: false,
drawBorder: true
},
}]
}
}
};
new Chart(ctx6, config );
when both data is from stored variable - see image
data: {
labels: ff,//['May-01', 'May-02', 'May-03', 'May-04', 'May-05', 'May-06', 'May-07', 'May-08', 'May-09', 'May-10', 'May-11', 'May-12', 'May-13', 'May-14', 'May-15', 'May-16', 'May-17', 'May-18', 'May-19', 'May-20', 'May-21', 'May-22', 'May-23', 'May-24', 'May-25', 'May-26', 'May-27', 'May-28', 'May-29', 'May-30', 'May-31'],
datasets: [{
label: 'Outbound',
data: outbound,
borderColor: '#00cccc',
borderWidth: 1,
backgroundColor: gradient2x,
},{
label: 'Inbound',
data: inbound,
borderColor: '#00cccc',
borderWidth: 1,
backgroundColor: gradient1x,
}]
}
when outbound data is a stored variable while the inbound data is raw list/array it shows correct graph-two separate datasets - see image
data: {
labels: ff,//['May-01', 'May-02', 'May-03', 'May-04', 'May-05', 'May-06', 'May-07', 'May-08', 'May-09', 'May-10', 'May-11', 'May-12', 'May-13', 'May-14', 'May-15', 'May-16', 'May-17', 'May-18', 'May-19', 'May-20', 'May-21', 'May-22', 'May-23', 'May-24', 'May-25', 'May-26', 'May-27', 'May-28', 'May-29', 'May-30', 'May-31'],
datasets: [{
label: 'Outbound',
data: outbound,
borderColor: '#00cccc',
borderWidth: 1,
backgroundColor: gradient2x,
},{
label: 'Inbound',
data: [0, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0],
borderColor: '#00cccc',
borderWidth: 1,
backgroundColor: gradient1x,
}]
}
Can someone advise how to fix this?
Thank you.

Related

How we can draw a circle in bar chart

I am new to chart.js I want to draw a circle inside bar charts or at baseline like the picture circle in blue color below how can I achieve this
help me thanks in advance
In your existing bar chart configuration, you can define a second dataset of type: 'scatter' as follows:
{
type: 'scatter',
data: [0, 0, 0, 0, 0, 0, 0],
backgroundColor: "rgb(0, 0, 255)",
borderColor: "rgb(255, 255, 255)",
pointRadius: 7,
pointHoverRadius: 7,
borderWidth: 2
}
Please take a look at the runnable code below and see how it works.
new Chart("chart", {
type: "bar",
data: {
labels: ["A", "B", "C", "D", "E", "F", "G"],
datasets: [{
data: [65, 59, 80, 81, 56, 55, 40],
barPercentage: 0.5,
backgroundColor: "rgba(201, 203, 207, 0.2)",
borderColor: "rgb(201, 203, 207)",
borderWidth: 1
},
{
type: 'scatter',
data: [0, 0, 0, 0, 0, 0, 0],
backgroundColor: "rgb(0, 0, 255)",
borderColor: "rgb(255, 255, 255)",
pointRadius: 7,
pointHoverRadius: 7,
borderWidth: 2
}
]
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
canvas {
max-width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="chart" height="200"></canvas>

ChartJs - Angle line and ticks 'on top'

I have a chart as shown below. I have two expectation, firstly as you can see the tick number (1,2,3,4,5) hidden behind the background color of dump datasets (I need that background colors, that's why I am using fake datasets). I need to show them like using z-index or something. I wrote tick numbers in red color for sample.
Secondly I need the show angle line on top also.
var test2 = [2, 2, 2, 2, 2];
var test3 = [3, 3, 3, 3, 3];
var test4 = [4, 4, 4, 4, 4];
var test5 = [5, 5, 5, 5, 5];
new Chart(document.getElementById("myChart"), {
type: 'radar',
data: {
labels: sectionDescriptions,
datasets: [
{
label: "2050",
fill: true,
borderColor: "rgba(0,0,0,1)",
borderWidth: "4",
pointRadius: 3,
pointBorderWidth: 3,
pointBackgroundColor: "cornflowerblue",
pointBorderColor: "rgba(0,0,200,0.6)",
pointHoverRadius: 10,
data: sectionPoints
},
{
radius: 0,
fill: true,
backgroundColor: "rgba(240,0,0,1)",
data: test2
},
{
radius: 0,
fill: true,
backgroundColor: "rgba(255,190,4,1)",
data: test3
},
{
radius: 0,
fill: true,
backgroundColor: "rgba(255,250,5,1)",
data: test4
},
{
radius: 0,
fill: true,
backgroundColor: "rgba(0,180,233,1)",
data: test5
}
]
},
options: {
title: {
display: true,
text: 'Chart'
},
scale: {
gridLine: {
color : "white"
},
ticks: {
beginAtZero: true,
min: 0,
max: 5,
stepSize: 1,
fontColor: 'black',
backDropColor: 'black'
},
pointLabels: {
fontSize: 13,
//fontStyle: 'bold'
}
},
legend: {
display: false
}
}
});

Select All and Unselect Option for chart.js

I'm Working on Chart.js, wanted to implement Select All and Unselect All option for labels. I'm trying to find it out but couldn't get anything such.
Please do help me out if anything such feature can be implemented.
If you need to show/hide charts selecting/unselecting all labels here is an example:
var barChartData = {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32],
datasets: [{
label: 'One',
backgroundColor: 'rgba(206, 0, 23, 1)',
data: [0, 1, 3, 0, 2, 0, 0, 2, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 2, 1, 0, 1, 2, 1, 1, 0, 0, 0, 2, 2, 0, 3]
}, {
label: 'Two',
backgroundColor: 'rgba(206, 0, 23, 0.75)',
data: [0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1]
}, {
label: 'Three',
backgroundColor: 'rgba(206, 0, 23, 0.5)',
data: [0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 1]
}]
};
var ctx = document.getElementById('canvas').getContext('2d');
var chartInstance = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title: {
display: false,
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
$("#toggle").click(function() {
chartInstance.data.datasets.forEach(function(ds) {
ds.hidden = !ds.hidden;
});
chartInstance.update();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<button id="toggle">show/hide all</button>
<canvas id="canvas" height="500" width="800"></canvas>
Jsfiddle: https://jsfiddle.net/beaver71/00q06vjp/
Credits: see https://github.com/chartjs/Chart.js/issues/3009
Update: for pie chart use "meta", see: https://jsfiddle.net/beaver71/u0y0919b/
For ChartJS 2.9.3, this works as requested by David in the comments:
const chart = ...
chart.data.datasets.forEach(dataset => {
Object.keys(dataset._meta).forEach(key => {
const current = !dataset._meta[key].hidden
dataset._meta[key].hidden = current || null
})
})
chart.update()
Toggles all with a button, while playing nicely with the individual toggling in the chart legend.
V3 Answer
You can use a custom generateLabels function together with a custom onClick to get it as an extra legendItem like so:
const defaultLegendClickHandler = Chart.defaults.plugins.legend.onClick;
const pieDoughnutLegendClickHandler = Chart.controllers.doughnut.overrides.plugins.legend.onClick;
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange'
}
]
},
options: {
plugins: {
legend: {
onClick: (evt, legendItem, legend) => {
const type = legend.chart.config.type;
let allLegendItemsState = [];
if (legendItem.text === 'hide all datasets' || legendItem.text === 'show all datasets') {
if (typeof legend.hideAll === 'undefined') {
legend.hideAll = false;
}
legend.chart.data.datasets.forEach((dataset, i) => {
legend.chart.setDatasetVisibility(i, legend.hideAll)
});
legend.hideAll = !legend.hideAll;
legend.chart.update();
return;
}
if (type === 'pie' || type === 'doughnut') {
pieDoughnutLegendClickHandler(evt, legendItem, legend)
} else {
defaultLegendClickHandler(evt, legendItem, legend);
}
allLegendItemsState = legend.chart.data.datasets.map((e, i) => (legend.chart.getDatasetMeta(i).hidden));
if (allLegendItemsState.every(el => !el)) {
legend.hideAll = false;
legend.chart.update();
} else if (allLegendItemsState.every(el => el)) {
legend.hideAll = true;
legend.chart.update();
}
},
labels: {
generateLabels: (chart) => {
const datasets = chart.data.datasets;
const {
labels: {
usePointStyle,
pointStyle,
textAlign,
color
}
} = chart.legend.options;
const legendItems = chart._getSortedDatasetMetas().map((meta) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
return {
text: datasets[meta.index].label,
fillStyle: style.backgroundColor,
fontColor: color,
hidden: !meta.visible,
lineCap: style.borderCapStyle,
lineDash: style.borderDash,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
strokeStyle: style.borderColor,
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
datasetIndex: meta.index
};
});
legendItems.push({
text: (!chart.legend.hideAll || typeof chart.legend.hideAll === 'undefined') ? 'hide all datasets' : 'show all datasets',
fontColor: color,
fillStyle: 'turquoise', // Box color
strokeStyle: 'turquoise', // LineCollor around box
});
return legendItems;
}
}
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
</body>
The correct answer result in :
chart.data.datasets.forEach((obj, index) => {
let meta = this.eval_chart.getDatasetMeta(index);
meta.hidden = !meta.hidden || null;
});
chart.update();
As wrote in the documentation : https://www.chartjs.org/docs/latest/configuration/legend.html#custom-on-click-actions

how to set chart.js grid color for line chart

I want to change the grids color of my line chart using options field but I have no idea from where to begin.
I First tried to change the canvas backgroud colors using gradient but the results weren't good.
canvas{
background:linear-gradient(top, #ea1a07 0%, #f4b841 75%,#f2dd43 100%);
}
However, I didn't get what I want because as you see in the above image, not only the grids were colored but also the x values, y labels and the chart legend were colored too.
Picture of the result I'm getting with this css code
Example of what I want to get
my chart.js options are
options = {
scales: {
xAxes: [{
gridLines: {
color: 'rgba(171,171,171,1)',
lineWidth: 1
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
max: 100,
min: 0,
stepSize: 10
},
gridLines: {
color: 'rgba(171,171,171,1)',
lineWidth: 0.5
}
}]
},
responsive: true
};
So, is there a way to set only the grid's background to 3 different colors (with gradient or not)?
NB: I'm using chart.js with angular 2 (ng2-charts)
The easiest way to do this is to use the chartjs-plugin-annotation plugin and configure 3 box annotations bound to your Y axis (each box would have a different color).
Here is an example below (and you can see it in action with this codepen).
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'Points',
data: [
{x: 0, y: 2},
{x: 1, y: 3},
{x: 2, y: 2},
{x: 1.02, y: 0.4},
{x: 0, y: -1}
],
backgroundColor: 'rgba(123, 83, 252, 0.8)',
borderColor: 'rgba(33, 232, 234, 1)',
borderWidth: 1,
fill: false,
}],
},
options: {
title: {
display: true,
text: 'Chart.js - Gridline Background',
},
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
ticks: {
min: -1,
max: 8,
stepSize: 1,
fixedStepSize: 1,
},
gridLines: {
color: 'rgba(171,171,171,1)',
lineWidth: 1
}
}],
yAxes: [{
afterUpdate: function(scaleInstance) {
console.dir(scaleInstance);
},
ticks: {
min: -2,
max: 4,
stepSize: 1,
fixedStepSize: 1,
},
gridLines: {
color: 'rgba(171,171,171,1)',
lineWidth: 0.5
}
}]
},
annotation: {
annotations: [{
type: 'box',
yScaleID: 'y-axis-0',
yMin: 1,
yMax: 4,
borderColor: 'rgba(255, 51, 51, 0.25)',
borderWidth: 2,
backgroundColor: 'rgba(255, 51, 51, 0.25)',
}, {
type: 'box',
yScaleID: 'y-axis-0',
yMin: -1,
yMax: 1,
borderColor: 'rgba(255, 255, 0, 0.25)',
borderWidth: 1,
backgroundColor: 'rgba(255, 255, 0, 0.25)',
}, {
type: 'box',
yScaleID: 'y-axis-0',
yMin: -2,
yMax: -1,
borderColor: 'rgba(0, 204, 0, 0.25)',
borderWidth: 1,
backgroundColor: 'rgba(0, 204, 0, 0.25)',
}],
}
}
});
It's important to note that the annotations are painted on top of the chart, so your annotation color needs to contain some transparency to see the stuff behind it.
There is no problem using this plugin with ng2-charts. Just add the source in a <script> in your app's html file and add the annotation property into your options object. Here is an Angular2 / ng2-charts example demonstrating how to use the annotations plugin.

Chart.js - How to Add Text in the Middle of the Chart?

I'm using Chart.js to create this line chart:
But I need to label the zones, something like this:
Any Ideas?
You extend the chart which you used and then write the labels using the helper methods
HTML
<canvas id="myChart" width="500" height="400"></canvas>
In the below JS, note that the parameter to calculateY is the y value, while for calculateX, it is label index
Chart.types.Line.extend({
name: "LineAlt",
draw: function(){
Chart.types.Line.prototype.draw.apply(this, arguments);
this.chart.ctx.textAlign = "center"
// y value and x index
this.chart.ctx.fillText("ZONE1", this.scale.calculateX(3.5), this.scale.calculateY(20.75))
this.chart.ctx.fillText("ZONE2", this.scale.calculateX(11.5), this.scale.calculateY(13))
this.chart.ctx.fillText("ZONE3", this.scale.calculateX(2), this.scale.calculateY(9.75))
this.chart.ctx.fillText("ZONE4", this.scale.calculateX(14.5), this.scale.calculateY(22.75))
}
});
var data = {
labels: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
datasets: [{
data: []
}]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myBarChart = new Chart(ctx).LineAlt(data, {
scaleOverride: true,
scaleSteps: 16,
scaleStepWidth: 1,
scaleStartValue: 8,
animation: false
});
Fiddle - https://jsfiddle.net/bpfvvxpn/
Not sure how you created the line chart, so didn't add it to the fiddle
This is how I write inside a pie to create a gauge:
var start=0;
var stop=100;
var part=(stop-start)/3;
var pi_value=4.999;
var pi_name="مدت توقف";
var pi_unit="(روز)";
var pi_data=[30, 30, 20, 1, 9];
var inner={
backgroundColor: [
"rgba(0, 0, 0, 0)",
"rgba(0, 0, 0, 0)",
"rgba(0, 0, 0, 0)",
"rgba(0, 0, 0, 1)",
"rgba(0, 0, 0, 0)"
],
borderWidth: 0,
hoverBackgroundColor: [
"rgba(0, 0, 0, 0)",
"rgba(0, 0, 0, 0)",
"rgba(0, 0, 0, 0)",
"rgba(0, 0, 0, 1)",
"rgba(0, 0, 0, 0)"
],
hoverBorderWidth: 0
};
angular.module('PIR').controller("DoughnutCtrl", ['$scope', function ($scope) {
var originalDraw = Chart.controllers.doughnut.prototype.draw;
Chart.controllers.doughnut.prototype.draw = function(ease) {
if(this.index == 1){
let x = (this.chart.boxes[this.index].right)/2;
this.chart.chart.ctx.textAlign = "center";
this.chart.chart.ctx.fillText(pi_value, x, x*3/2);
this.chart.chart.ctx.fillText(start, 4*this.chart.boxes[this.index].left, x*3/2);
this.chart.chart.ctx.fillText(stop, this.chart.boxes[this.index].right-3*this.chart.boxes[this.index].left, x*3/2);
}
originalDraw.call(this, ease);
};
$scope.data = [pi_data, pi_data];
$scope.datasetOverride = [
{
backgroundColor: [
"rgb(255, 69, 96)",
"rgb(206, 148, 73)",
"rgb(153, 223, 89)",
"rgba(0, 0, 0, 1)",
"rgb(153, 223, 89)"
],
borderWidth: 0,
hoverBackgroundColor: [
"rgb(255, 69, 96)",
"rgb(206, 148, 73)",
"rgb(153, 223, 89)",
"rgba(0, 0, 0, 1)",
"rgb(153, 223, 89)"
],
hoverBorderWidth: 0,
},
inner
];
$scope.options = {
cutoutPercentage: 0,
rotation: -3.1415926535898,
circumference: 3.1415926535898,
legend: {
display: false
},
tooltips: {
enabled: false
},
title: {
display: true,
text: pi_name + ' ' + pi_unit,
fontSize: 14,
fontFamily: 'yekan',
position: 'bottom'
}
};
}]);
http://jtblin.github.io/angular-chart.js/
https://github.com/chartjs/Chart.js/issues/2874#issuecomment-273839993