Chart.js multiple datasets on one y axis - javascript

I am using chartjs v3 (latest) and I'm trying to render a graph with multiple datasets that share one y axis.
Currently I have the following code:
const buff = await defaultChartRenderer({
type: 'line',
data: {
labels: data.value.filter(v => v.type === 'online').map(v => moment(new Date(v._time)).format(data.format)),
datasets: [
{
data: allOnline,
borderColor: '#43b581',
backgroundColor: 'rgba(0,0,0,0)',
label: 'Online',
normalized: true
},
{
data: allOffline,
borderColor: '#ff0000',
backgroundColor: 'rgba(0,0,0,0)',
label: 'Offline',
normalized: true
},
{
data: allIdle,
borderColor: '#faa61a',
backgroundColor: 'rgba(0,0,0,0)',
label: 'Idle',
normalized: true
},
{
data: allDnd,
borderColor: '#f04747',
backgroundColor: 'rgba(0,0,0,0)',
label: 'DND',
normalized: true
}
]
},
options: {
scales: {
y: {
suggestedMax: Math.max(...[...allOffline, ...allOnline, ...allDnd, ...allIdle]),
suggestedMin: Math.min(...[...allOffline, ...allOnline, ...allDnd, ...allIdle]),
stacked: true,
ticks: {
beginAtZero: false,
precision: 0,
},
gridLines: {
zeroLineColor: "rgba(255, 255, 255, 0.8)",
color: "rgba(255, 255, 255, 0.4)"
},
stacked: true,
id: 0,
position: 'left'
},
},
legend: {
//display: false,
labels: {
fontColor: 'white',
fontSize: 20
}
},
tooltips: {
enabled: false
}
}
})
The defaultChartRenderer function does not modify my input at all.
The following data gets passed in as allOnline, allOffline, allIdle, and allDnd:
[
2, 2, 3, 3,
3, 2, 2
] [
4, 4, 4, 3,
4, 4, 3
] [
1, 1, 1, 1,
0, 0, 1
] [
1.5, 1, 2, 2,
2, 2, 2
]
I would expect this to output a graph with that data, but instead only the allOnline data shows properly. Everything else gets moved upwards.
Current Output: https://imgur.com/a/prGiyxy
Am I doing something wrong? I've tried adding yAxisID to all of the datasets and sharing one id between all of them, but that didn't work. I've also tried without normalize: true.

To make it work as expected, remove the option scales.y.stacked or set it to false.
For further information, please consult the chapter Stacking from the Chart.js documentation.
UPDATE
stacked: true is defined twice on your y-axis. Remove both of them, and it should work.

Related

How to draw a line in line chart for single value in Charts.JS

I need to plot a single value in line chart. Currently i am using charts.JS library for line graph purpose.
The data will be varied some times i'll get the single data inside the data set at that time i need to plot the single value in the line chart.
I had tried with the charts.js annotation plugin but it didn't meet my requirements. which is like it wis overlapping the plotted point in the graph area.
My code
createLineChart() {
this.lineChart = new Chart(this.lineCanvas.nativeElement, {
type: "line",
data: {
labels:[],
datasets: [
{
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white", // wite point fill
pointBorderWidth: 1, // point border width
lineTension: 0,
pointBorderColor: "blue",
pointRadius: 4,
},
],
},
options: {
scales: {
yAxes: [
{
ticks: {
padding: 20,
beginAtZero: true,
min: 0,
stepSize: 100,
},
gridLines: {
drawBorder: false,
},
},
],
xAxes: [
{
// offset: true,
ticks: {
display: false,
//beginAtZero: true,
min: 0,
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false,
},
//offset:true,
},
],
legend: {
display: false,
},
tooltips: {
enabled: false,
},
},
drawTime: "afterDraw", // (default)
} as ChartOptions,
// plugins: [ChartAnnotation]
},
});
}
To plot the data dynamically:
generateRandomDataSet(size) {
let yaxisArr = [];
let xaxisArr = [];
let random_data:any = this.getRandomData(size)
let maxYTickVal = Math.max.apply(Math, random_data.map((val) => {return val.yaxis}));
let maxVal = Math.ceil((maxYTickVal+1) / 10) * 10
for(let data of random_data) {
yaxisArr.push(data.yaxis)
xaxisArr.push(data.xaxis)
}
this.lineChart.data.datasets[0].data = yaxisArr
this.lineChart.config.data.labels = []
this.lineChart.config.data.labels = xaxisArr
this.lineChart.config.options.scales.yAxes[0].ticks.max =maxVal
this.lineChart.config.options.scales.yAxes[0].ticks.stepSize = maxVal/2
this.lineChart.update()
}
What i required
What i am getting
Thankyou.
There exists different approaches to solve this problem.
According to the answer I gave to a similar question, you can define an animation.onComplete function to draw the line.
In a comment on before mentioned answer, Lakshmansundeep suggested an approach where he defines the same data value three times but makes sure, pointRadius for the leading and ending data point is zero.
datasets: [{
data: [120, 120, 120],
...
pointRadius: [0, 4, 0],
pointHoverRadius: [0, 4, 0],
}],
For the second approach, please have a look at the code below.
new Chart('line-chart', {
type: "line",
data: {
labels: [null, 'A', null],
datasets: [{
data: [120, 120, 120],
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white",
pointBorderWidth: 1,
lineTension: 0,
pointBorderColor: "blue",
pointRadius: [0, 4, 0],
pointHoverRadius: [0, 4, 0],
}],
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
ticks: {
padding: 20,
min: 0,
stepSize: 100
},
gridLines: {
drawBorder: false
}
}],
xAxes: [{
ticks: {
display: false
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="line-chart" height="80"></canvas>

Chart.js: Fill background between two lines

I have line chart with two lines. First line is static, second line builds dynamically. I need to fill area between first and second line if y value of second line above a y value of first line.
I used Charts.js library for chart building
Currently I have next result (Fill between two lines):
Expected result:
Very hackish way but it gives the expected result :D!
Fiddle -> http://jsfiddle.net/Lzo5g01n/28/
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Yellow", "Blue", "Green", "Orange", "Pink"],
datasets: [{
fill: false,
data: [0, 10, , 10, 0],
backgroundColor: 'black',
borderColor: 'black',
borderWidth: 1
}, {
data: [10, 10, 10, 10, 10],
fill: true,
backgroundColor: 'white',
borderColor: 'black',
borderWidth: 1
}, {
data: [, 10, 18, 10, ],
backgroundColor: 'black',
borderColor: 'black',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
display: false,
ticks: {
beginAtZero: true
}
}],
xAxes: [{
display: false
}]
},
legend: {
display: false
},
tooltips: {
enabled: false
},
elements: {
point: {
radius: 0
}
}
}
});

beginAtZero not working on mixed chart

I am trying to make a chart with multiple lines and bars but they need to start at 0 and it works fine for the bar's but not one the lines.
I tried setting a id for the options setting options in the dataset but nothings works
Here is my code:
<canvas id="barLine" width="400" height="400"></canvas>
#section('js')
#parent
<script>
var ctx = document.getElementById("barLine");
new Chart(ctx, {
type: 'bar',
data: {
labels: ['contacten', 'orders', 'logistiek'],
datasets: [{
label: 'Aantal',
data: [5.3, 5.5, 5.7],
backgroundColor: colors,
borderColor: colors,
borderWidth: 1
}, {
label: 'Aantal',
data: [5.7, 6.5, 6],
backgroundColor: colors,
borderColor: colors,
borderWidth: 1
}, {
label: 'Aantal',
data: [7.8, 5, 7],
backgroundColor: colors,
borderColor: colors,
borderWidth: 1
}, {
label: 'Target 2016',
data: [5.0, 5.0, 5.0],
type: 'line',
fill: false,
pointHitRadius: 10,
pointRadius: 0,
pointStyle: 'rect'
}, {
label: 'Target 2017',
data: [7.5, 7.5, 7.5],
type: 'line',
fill: false,
pointHitRadius: 10,
pointRadius: 0,
pointStyle: 'rect'
}, {
label: 'Target 2018',
data: [7, 7, 7],
type: 'line',
fill: false,
pointHitRadius: 10,
pointRadius: 0,
pointStyle: 'rect',
backgroundColor:'purple',
borderColor:'purple',
beginAtZero:true
}]
},
options: {
scales: {
yAxes: [{
ticks: {
max: 10,
min: 0
},
scaleLabel: {
display: true,
labelString: "Cijfer"
}
}]
}
}
});
</script>
#stop
So it needs to work that the lines (target 2016......) need to start at 0. I can make it work with just a line but with mixed I cannot make it so.
beginAtZero is an attribute of ticks so you need to put it inside ticks, which is part of options:
options:{
scales:{
yAxes:[{
ticks:{
beginAtZero: true
}
}]
}
}

Is there any way to remove extra space and Horizontal line from Bar chart of Chart.js?

I am using Bar chart of Chart.js which is creating unwanted spacing on left and right side. I have tried to remove that by making canvas width and height to 100% as mentioned chartjs-is-there-any-way-to-remove-blank-space-around-pie-charts here. But it's not removing in my case.
I also need to remove horizontal line below the chart. Is there any way to do so?
Here's what i tried:
//Bar Chart
var bar = document.getElementById("bar-canvas");
var barChart = new Chart(bar, {
type: 'bar',
data: {
labels: ["Jackets", "Pants", "Headwear", "Shirts", "Footwear"],
datasets: [{
label: 'Dataset 1',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF'
],
borderColor: [
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF'
],
borderWidth: 1
},
{
label: 'Dataset 2',
data: [20, 19, 10, 52, 2, 13],
backgroundColor: [
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE'
],
borderColor: [
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE'
],
borderWidth: 1
}]
},
responsive: true,
options: {
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem) {
return tooltipItem.yLabel;
}
}
},
scales: {
xAxes: [{
stacked: true,
gridLines: {
color: "rgba(0, 0, 0, 0)"
},
ticks: {
fontColor: '#0071bc'
},
barThickness: 110
}],
yAxes: [{
stacked: true,
gridLines: {
color: "rgba(0, 0, 0, 0)"
},
scaleLabel: {
display: false
},
ticks: {
display: false
}
}
]
}
}
});
<canvas id="bar-canvas"></canvas>
Managed to remove the bottom line, but somehow could not remove the padding, - commented an area, which removes a little bit, but then you lose the ticks (which is obviously bad)
Just adding a fiddle, hope it helps at least somehow!
https://jsfiddle.net/aokzss3c/1/
..xAxes..
ticks: {
display: true, // removing this
fontColor: '#0071bc',
},

How to fix the distance between horizontal points (x-axis) in chartJS

Problem: Hi all! i am using chart.js to draw the charts. chart is a dynamic sometimes shows 10 points and sometimes can be more than thousand i have applied a panel successfully so that my points can be shown at some distance to read them easily.
Right now i want to know if there is any option to set the distance between points in x-axis grid. right now it automatically adjust the points.
What i tried:
i tried to do the stepsize and scalewidth by searching other stackoverflow answers but did not succeed. Any kind of help would be much appreciated.
P.S: i m using chart.js2
This is my chartjs dataset
var data = {
labels: data.graph_date,
datasets: [
{
label: 'Assay Values',
fill: false,
lineTension: 0,
backgroundColor: "rgba(255, 0, 0,1)",
borderColor: "rgba(255, 0, 0,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderWidth: 1,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(255, 0, 0,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(255, 0, 0,1)",
pointHoverBorderColor: "rgba(255, 0, 0,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: data.assay_value,
spanGaps: false
},var options = {
responsive: false,
title: {
display: true,
position: "top",
text: label,
fontSize: 18,
fontColor: "#111"
},
legend: {
display: true,
position: "bottom",
labels: {
fontColor: "#333",
fontSize: 16
}
},
tooltips: {
enabled: true,
mode: 'single',
callbacks: {
label: function(tooltipItems, data) {
var multistringText = ['Assay Value: '+tooltipItems.yLabel];
multistringText.push('Assigned Value: '+assigned_value[tooltipItems.index]);
multistringText.push('Sample ID: '+sample_id[tooltipItems.index]);
return multistringText;
}
}
},
scales:{
yAxes:[{
ticks:{
min:graph_min
}
}],
xAxes: [{
gridLines: {
display:false
}
}]
}
};
if(new_chart[ctx.canvas.id] != null)
new_chart[ctx.canvas.id].destroy();
new_chart[ctx.canvas.id] =new Chart(ctx, {
type: 'line',
data: data,
options: options
});
In x-axis there is data like this
[19-Aug-2015,21-Aug-2015,21-Aug-2015,21-Aug-2015,21-Aug-2015,22-Aug-2015,27-Aug-2015,29-Aug-2015,1-Sep-2015,2-Sep-2015,3-Sep-2015,]
in y-axis data is like this
[0.1,0.05,0.89,0.89,0.79,0.58,0.68,0.25,0.98]
The way to control distance between points it to set the X and Y axis with a min, max, and step size so that they never change regardless of the number of points that are in the chart.
Here is an example that sets the scales so that they will never change. Regardless of how many points appear on the chart everything will stay the same.
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,
showLine: false,
}],
},
options: {
title: {
display: true,
text: 'Chart.js - Fixed X and Y Axis',
},
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
ticks: {
min: -1,
max: 8,
stepSize: 1,
fixedStepSize: 1,
}
}],
yAxes: [{
ticks: {
min: -2,
max: 4,
stepSize: 1,
fixedStepSize: 1,
}
}]
}
}
});
Here is a codepen example that demonstrates what this looks like

Categories

Resources