Using chart.js, I have a line chart that is displaying datasets compiled in a .net web app.
Is it possible to set a line as hidden/disabled once the data is loaded, based on the label name?
There is a hidden flag in chart.js that enables a dataset to be hidden on load, but this is set when initially defining the dataset. As the data has already been defined within the view, I cannot use this flag. E.g.
var viewsByMonthChartCtx = new Chart(viewsByMonthChartCtx, {
type: 'line',
data: {
labels: ['February 2017','March 2017'],
datasets:
[ { label: 'Home', data: [100,120 ] }, // I want to set 'hidden: true' to the Home dataset post initialization
{ label: 'Search', data: [200,240 ] } ]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
}
});
If you want to hide a dataset after the chart has been initialized (and rendered), then you still use the dataset hidden: true property. You simply just have to access the dataset from your chart instance and set the property to true.
Here is an example where a dataset matching a label is hidden 5 seconds after the page loads.
// the dataset label we want to hide after chart is initialized
var hiddenLabel = 'My Second Dataset';
var timerDuration = 5;
// hide a dataset after X seconds
setTimeout(function() {
var indexToHide = -1;
// find which dataset matches the label we want to hide
myLine.config.data.datasets.forEach(function(e, i) {
if (e.label === hiddenLabel) {
indexToHide = i;
}
});
// get the dataset meta object so we can hide it
var meta = myLine.getDatasetMeta(indexToHide);
// hide the dataset and re-render the chart
meta.hidden = true;
myLine.update();
}, timerDuration * 1000);
As you can see, you can just iterate over the datasets to find the index of the dataset with the matching label, then you simply set the hidden property to true and update the chart.
Here is a codepen that demonstrates a full working example.
With that said, it's not clear why you would want to do this after the chart is hidden. If you already know which dataset you want hidden at page load time, then you could just assemble your data and options chart config dynamically and set the hidden flag to true programmatically. Here is an example.
// the dataset label we want to hide
var hiddenLabel = 'My Second Dataset';
// build our data and options config (if needed you could build the datasets dynamically from dynamic data (this example is static)
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First Dataset",
backgroundColor: chartColors.red,
borderColor: chartColors.red,
data: [5, 10, 25, 15, 10, 20, 30],
fill: false,
}, {
label: "My Second Dataset",
fill: false,
backgroundColor: chartColors.blue,
borderColor: chartColors.blue,
data: [5, 0, 12, 5, 25, 35, 15],
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Hide Dataset Matching "My Seconds Dataset" After 3 Seconds'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
}
}
};
// iterate over our datasets to find the one we want to hide
config.data.datasets.forEach(function(e) {
if (e.label === hiddenLabel) {
e.hidden = true;
}
});
// instantiate the chart
var myLine = new Chart($('#canvas'), config);
Related
I am trying to create a series of line chart dynamically and then update them once the data has been updated for a particular user in real-time.
I am running into difficulty because I can only get the most recent one to render.
I think this is because when the following code runs it overwrites the ctx variable and I lose the earlier charts.
I tried the following technique with dynamic variables so no two ctx variables would be the same, but it doesn't work.
Thanks in advance for your help.
window['ctx_'+userid] = document.getElementById("forceCurveGraph_"+userid).getContext("2d");
window['myLineChart'+userid] = new Chart(window['ctx_'+userid], {
type: 'line', data: {
datasets: [{
label: "Force Curve",
data: forcecurvedata, backgroundColor: ['rgba(57,118,251, 0.8)']
}],
labels: labels
}, options: {
backgroundColor: ['rgba(40, 84, 141, 0.3)'],
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
max: graphMax
}
}],
xAxes: [{
ticks: {
display: false
}
}]
}
}
})
I am making a simple bar chart using Chartjs 3.x
I make requests to a server to fetch json data and then store certain parts of it into arrays, here is the code for this:
serverData = JSON.parse(http.responseText);
console.log(serverData);
stundenProjekt = serverData.abzurechnen.nachProjekt.map((s) => {
return s.second.summe;
});
labelsP = serverData.abzurechnen.nachProjekt.map((p) => {
return p.first;
});
I then want to use these arrays in the data and label fields of the chart. I'm using stundenProjekt as data and it works fine, but when I use labelsP as label for the chart, it doesn't work. Here is the code of the chart:
const data = {
labels: labelsP,
datasets: [{
label: 'Projekte',
data: stundenProjekt,
backgroundColor: [
'#f4f40b',
],
borderColor: [
'#B1B101',
],
borderWidth: 3,
}]
};
if (barChartProjekt) {
data.datasets.forEach((ds, i) => {
barChartProjekt.data.datasets[i].data = ds.data;
barChartProjekt.labels = newLabelsArray;
})
barChartProjekt.update();
} else {
barChartProjekt = new Chart(chart, {
type: 'bar',
data: data,
options: {
responsive: true,
plugins: {
legend: {
labels: {
color: "white",
font: {
size: 18
}
}
}
},
scales: {
y: {
ticks: {
color: "white",
font: {
size: 18,
},
stepSize: 1,
beginAtZero: true
}
},
x: {
ticks: {
color: "white",
font: {
size: 14
},
stepSize: 1,
beginAtZero: true
}
}
}
}
});
}
The only workaround I have found is to copy the contents of labelsP and paste them in the label field. These are the contents of labelsP and how I did the workaround:
["nexnet-SB-Cloud", "AUTEC - PSK-System²", "Fritzsche", "nexnet-eBalance", "IfT - Neuentwicklung", "wattform", "Migration", "Fahrwerkregelkreis", "bmp greengas", "nexnet-SQL-Abfragen über API", "lambda9", "Nord Stadtwerke", "edifact", "SOLVIT", "BürgerGrünStrom", "SOLVCPM", "lambda captis", "SOLVEDI", "green city power", "max.power"]
const data = {
labels: ["nexnet-SB-Cloud", "AUTEC - PSK-System²", "Fritzsche", "nexnet-eBalance", "IfT - Neuentwicklung", "wattform", "Migration", "bmp greengas", "Fahrwerkregelkreis", "nexnet-SQL-Abfragen über API", "lambda9", "Nord Stadtwerke", "edifact", "SOLVIT", "BürgerGrünStrom", "SOLVCPM", "lambda captis", "SOLVEDI", "green city power", "max.power"],
datasets: [{
label: 'Projekte',
data: stundenProjekt,
backgroundColor: [
'#f4f40b',
],
borderColor: [
'#B1B101',
],
borderWidth: 3,
}]
};
In this way, the chart works and everything shows up as it should, however, I want to use it as shown in the first snippet of code, as labelsP gets updated every some seconds with new data extracted from the server. So, why is it that if I put labelsP alone in the label field it doesn't work, but if I copy and paste the contents of labelsP in the label field, it does work?
The problem is that you add the labels to the wrong position in the chart configuration.
Instead of...
barChartProjekt.labels = newLabelsArray;
try this...
barChartProjekt.data.labels = newLabelsArray;
I use Chart.js (https://www.chartjs.org/) on several pages of my site to display different charts
To simplify the addition and modification of these charts I added lines in my script to configure Chart.js differently from the basic options
Chart.defaults.scale.gridLines.display = true
Chart.defaults.scale.gridLines.drawBorder = true
Chart.defaults.scale.gridLines.color = '#f5f5f5'
Chart.defaults.global.legend.display = true;
Chart.defaults.global.legend.labels.fontSize = 13
Chart.defaults.global.legend.labels.fontColor = '#373d3f'
....
The problem is that on some options I want different values for the x and y axis, for example for the drawOnChartArea option
And I don't know how to do it, because it doesn't work:
Chart.defaults.scale.xAxes.gridLines.drawOnChartArea = false
Chart.defaults.scale.yAxes.gridLines.drawOnChartArea = true
So, I am still forced to add in the options of all my graphics these lines:
options: {
scales: {
xAxes: [{
gridLines: {
drawOnChartArea: false,
}
}],
yAxes: [{
gridLines: {
drawOnChartArea: true,
}
}],
},
}
How to create a different global configuration between the x axis and the y axis?
Is there another way to create a global configuration (cleaner? More efficient?) for Chart.js?
Chart.defaults contains chart type specific sections that include the scales option. You can use console.log(Chart.defaults) to find out how it looks like.
Chart.defaults.bar for example is defined as follows:
"bar": {
"hover": {
"mode": "label"
},
"scales": {
"xAxes": [{
"type": "category",
"offset": true,
"gridLines": {
"offsetGridLines": true
}
}],
"yAxes": [{
"type": "linear"
}]
}
}
If the parent object of a nested property is already defined, you can directly assign its value.
Chart.defaults.bar.scales.xAxes[0].gridLines.drawOnChartArea = false;
If however the parent object is not yet defined, you need to assign the property together with its parent object or object hierarchy. When you do this, make sure to also take over previously existing default values.
Chart.defaults.bar.legend = { display: false };
Please have a look at below code sample.
Chart.defaults.bar.legend = {
display: false
};
Chart.defaults.bar.scales.xAxes[0].gridLines.drawOnChartArea = false;
Chart.defaults.bar.scales.yAxes[0] = {
type: 'linear',
gridLines: {
drawOnChartArea: false
},
ticks: {
beginAtZero: true
}
};
new Chart(document.getElementById("myChart"), {
type: 'bar',
data: {
labels: ["A", "B", "C", "D"],
datasets: [{
data: [25, 18, 8, 13],
backgroundColor: ['red', 'blue', 'green', 'orange']
}]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
<canvas id="myChart" height="90"></canvas>
https://jsfiddle.net/uL9jm103/
I've got a problem with chart.js: When the first data value is set to 12, it isn't shown on the graph. It is just 0. When the second is also 12, it isn't shown either. But when I change the first value to 11, both are shown.
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'radar',
data: {
labels: ['Running','Swimming','Eating','Cycling'],
datasets: [{
data: [12,12,20,30]
}]
},
options: {
legend: {
display: false
}
}
});
BeginAtZero is set to false per default.
Just add
options: {
scale: {
ticks: {
beginAtZero: true
}
}
}
and you're fine.
So its my first time using chartjs. Im trying to use stacked horizontal charts. I have 2 values which I calculate using some sort function. I do console.logs to check if values are correct and they are both as expected. But when i try to update the chart only the first value shows in the canvas, and the 2nd value shows 0 but my chart gridlines adjusts correctly. Im not too sure what is happening.
Here is where I declare my chart data
var eventDays1 = 0;
var eventDays2 = 0;
var barChartData = {
labels: ['Events'],
datasets: [{
label: eventName1,
backgroundColor: "#E5C1BD",
data:[eventDays1]
}, {
label: eventName2,
backgroundColor: "#D2D0BA",
data:[eventDays2]
}
]};
Here is the actual chart
myBarChart = new Chart(ctx, {
type: 'horizontalBar',
data: barChartData,
options: {
legend: {
display: true,
labels: {
fontColor: 'black',
fontSize:20,
}
},
responsive: true,
scales: {
xAxes: [{ stacked: false,
ticks:{
fontColor:"black"
},
scaleLabel: {
display: true,
labelString: 'Days',
fontColor:"black"
}
}],
yAxes: [{
ticks: {
beginAtZero:true,
max:365,
fontColor:"black"
},
stacked: true,
}]
}
},
});
Here is my updateChart function that I call. Note that the console.logs
are values that I expect already.
function updateChart(newList){
eventDays1 = newList[0];
if(newList.length == 2){
eventDays2 = newList[1];
}
myBarChart.data.datasets[0].data[0] = eventDays1;
myBarChart.data.datasets[0].data[1] = eventDays2;
console.log("data 1 "+eventDays1);
console.log("data 2 "+eventDays2);
myBarChart.update();
}