When using chart.js to draw a line chart, if the peak is between two x values instead of "at a x value" - chart.js

As the example shows the peak of the black line is between 3 and 4, and I don't know how to do it.
The close I can get from w3c school example is:
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<body>
<canvas id="myChart" style="width:100%;max-width:600px"></canvas>
<script>
var xValues = [0,1,2,3,4,5];
new Chart("myChart", {
type: "line",
data: {
labels: xValues,
datasets: [{
data: [80,120,300,40,0,0],
borderColor: "orange",
fill: false
}, {
data: [2,5,20,150,250,50],
borderColor: "black",
fill: false
}]
},
options: {
legend: {display: false}
}
});
</script>
Thanks for reading through.

const labels = [0, '', '', '', 10, '', '', '', 20, '', '', '', 30, '', '', '', 40, '', '', '', 50];
Set the X labels this way; it will work.

Related

Chart.Js vers2 multiline to version 3

I try to create a multi axis chart using chart.js ver 3.6.0 but it look nothing like the one displayed in their example found here chart
This is the code I use.
<canvas id="canvas"></canvas>
<script>
const ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.height = 200;
const labels = "11/1/2021,11/2/2021,11/3/2021,11/4/2021,11/5/2021,11/6/2021,11/7/2021,11/8/2021,11/9/2021,11/10/2021";
const data = {
labels: labels,
datasets: [
{
label: "South",
data: "6,4,2,4,3,1,0,9,3,0",
borderColor: "#0d47a1",
backgroundColor: "#2196f3",
yAxisID: "y",
},
{
label: "North",
data: "72,97,88,143,102,0,0,153,100,0",
borderColor: "#e65100",
backgroundColor: "#ff9800",
yAxisID: "y1",
},
],
};
const config = {
type: "line",
data: data,
options: {
responsive: true,
interaction: {
mode: "index",
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: "Test",
},
},
scales: {
y: {
type: "linear",
display: true,
position: "left",
},
y1: {
type: "linear",
display: true,
position: "right",
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
x: {
ticks: {
maxRotation: 65,
minRotation: 65,
fontSize: 11,
},
},
},
},
};
window.myLine = new Chart(ctx, config);
</script>
Why is the lines not connected, and why is the y axis not displaying each datasets max value?
Mine looks like this..
This is because you provide the labels and data as strings while it should be an array with strings for the labels, same goes for the data field:
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
<script>
const ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.height = 200;
const labels = ['11/1/2021', '11/2/2021', '11/3/2021', '11/4/2021', '11/5/2021', '11/6/2021', '11/7/2021', '11/8/2021', '11/9/2021', '11/10/2021'];
const data = {
labels: labels,
datasets: [{
label: 'South',
data: ['6', '4', '2', '4', '3', '1', '0', '9', '3', '0'],
borderColor: '#0d47a1',
backgroundColor: '#2196f3',
yAxisID: 'y',
},
{
label: 'North',
data: ['72', '97', '88', '143', '102', '0', '0', '153', '100', '0'],
borderColor: '#e65100',
backgroundColor: '#ff9800',
yAxisID: 'y1',
}
]
};
const config = {
type: 'line',
data: data,
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: 'Test'
}
},
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
},
y1: {
type: 'linear',
display: true,
position: 'right',
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
x: {
ticks: {
maxRotation: 65,
minRotation: 65,
fontSize: 11
}
}
}
},
};
new Chart(ctx, config);
</script>

charts js have a bar spanning negative/positive on y-axis

Is there a way in chartjs to have a bar span across the zero line? As an example,
lets say I have a bar with
data:[x:1, y:100]
How do I tell it to span the y-axis from -100 to 100 (instead of from 0 to 100)?
I have sort of a playground here where I can do either negative or positive per bar, but not both for one bar.
https://jsbin.com/dufonoceja/1/edit?js,output
This can be done since Chart.js v2.9.0, which now supports floating bars. Individual bars can now be specified with the syntax [min, max].
<html>
<head>
<title>Floating Bars</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>
<canvas id="canvas" height="120"></canvas>
</div>
<script>
var chartData = {
labels: [1,2,3,4,5,6],
datasets: [{
type: 'bar',
label: 'Red Bar',
borderColor: 'black',
borderWidth: 1,
backgroundColor: 'rgba(128,0,0,0.2)',
data: [[0, 100], [-100, 100], [-30, 40], 0, 0, 0],
}, {
type: 'bar',
label: 'Green Bar',
backgroundColor: 'rgba(0,128,0,0.2)',
borderColor: 'black',
borderWidth: 1,
data: [0, 0, 0, 0, [-50, 70], 100],
}
]
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
scaleBeginAtZero: false,
responsive: true,
spanGaps: true,
tooltips: {
mode: 'index',
intersect: true
},
scales: {
xAxes: [{
gridLines: {
display: false
},
}],
yAxes: [{
type: 'linear',
ticks: {
beginAtZero: false,
min:-100,
max:100,
stepSize:30
}
}],
}
}
});
};
</script>
</body>
</html>

Adding line over stacked line chart with ChartJS

I'm trying to recreate this below chart with a stacked option on my background lines
But my attempts were unsuccessful with this image below as result
$(function() {
var areaChartCanvas = $('#areaChart').get(0).getContext('2d')
var areaChartData = {
labels: ['', '', ''],
datasets: [{
backgroundColor: 'transparent',
borderColor: 'black',
pointRadius: false,
data: [32, 12, 28],
type: 'line'
}, {
backgroundColor: 'red',
pointRadius: false,
data: [20, 20, 20]
}, {
backgroundColor: 'orange',
pointRadius: false,
data: [40, 40, 40]
}, {
backgroundColor: 'cyan',
pointRadius: false,
data: [60, 60, 60]
}]
}
var areaChartOptions = {
maintainAspectRatio: false,
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [{
gridLines: {
display: true,
}
}],
yAxes: [{
gridLines: {
display: true,
},
stacked: true
}]
}
}
var areaChart = new Chart(areaChartCanvas, {
type: 'line',
data: areaChartData,
options: areaChartOptions
})
})
<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.8.0/Chart.min.js"></script>
<canvas id="areaChart" style="height:250px"></canvas>
ideally, I want to be able to create 'AREAS' with different colors that will be stacked according to the interval I pass to it.
e.g:
cyan - 20
orange - 20
red - 20
but currently, I'm doing
cyan - 60
orange - 40
red - 20
If I understand you correctly, I thought about different approach and extends the chart with Plugin[1] (Inspired by https://stackoverflow.com/a/49303362/863110)
Chart.pluginService.register({
beforeDraw: function (chart, easing) {
if (chart.config.options.fillColor) {
var ctx = chart.chart.ctx;
var chartArea = chart.chartArea;
ctx.save();
let delta = 0;
const chartHeight = chartArea.bottom - chartArea.top;
const bottomBarHeight = chart.height - chartHeight - chartArea.top;
chart.config.options.fillColor.map(color => {
const colorHeight = chartHeight * (color[0] / 100);
const colorBottom = chartArea.bottom + colorHeight;
ctx.fillStyle = color[1];
const x = chartArea.left,
y = chart.height - bottomBarHeight - colorHeight - delta,
width = chartArea.right - chartArea.left,
height = colorHeight;
delta += height;
ctx.fillRect(x, y, width, height);
ctx.restore();
})
}
}
});
var chartData = {
labels: ['a', 'b', 'c', 'd'],
datasets: [{
label: 'value',
borderColor: 'blue',
data: [30, 50, 25, 10]
}]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myBar = new Chart(ctx, {
type: 'line',
data: chartData,
options: {
scales: {
yAxes: [{ ticks: { max: 60 } }]
},
legend: { display: false },
fillColor: [
[20, 'red'],
[20, 'blue'],
[20, 'green'],
[20, 'pink'],
[20, 'yellow'],
]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="myChart" height="300" width="500"></canvas>
https://jsbin.com/lisuvuq/2/edit?js,output
[1] - With Plugin you can custom the chart's behaviour. When you use Plugin you get an API so you can "listen" to life cycle events of the chart (beforeDraw for example) and call your own code. The API calls your function and gives you data about the chart so you can use it in your code.In this example, we're using the API to (1) Run a code before the chart been drawing (2) Using the data to calculate the areas of the different colors. (3) Draw additional shapes (ctx.fillRect) based on the calculation.

Chart JS not showing all data

I am working on the following chart. My plan is to use it to display live data every 1 second with a buffer of 600 points. I want it to display initial data (the entire 600 points) fetches data (simulated through setInterval) then puts it and shift. The problem is that it only displays 12 points.
Question 1: Can you help me what am I missing or is it impossible with ChartJS? Question 2: Is this buffer reasonable with ChartJS?
<!DOCTYPE html>
<html>
<head>
<title>Hello World!!</title>
</head>
<script src="/socket.io/socket.io.js"></script>
<script src="Chart.min.js"></script>
<script>
var socket = io();
socket.on('pv_changed', function(data) { document.getElementById('pv').innerHTML = data.value });
</script>
<style>
</style>
<body>
Hello World!!!<br/>
<label>PV Value: </lable>
<label id="pv">hi</lablel>
<div class="container">
<div>
<canvas id="myChart" height=130px></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S', 'W', 'T', 'F', 'S', 'S'],
datasets: [{
label: 'Test',
data: Array.apply(null, Array(600)).map(Number.prototype.valueOf,0),
backgroundColor: "rgba(255,153,0,0.4)",
animation: true
}]
},
options: {
responsive: true,
scales: {
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
},
ticks: {
beginAtZero: true,
min: -5,
max: 25,
stepsize: 5
}
}],
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Hello'
},
ticks: {
beginAtZero: true,
min: 0,
max: 600,
stepsize: 50
}
}]
}
}
});
var top = 20;
var now = 0;
setInterval(function() {
myChart.data.datasets[0].data.shift();
myChart.data.datasets[0].data.push(now);
myChart.update();
now = now + 1;
if(now == 20)
now = 0;
}, 1000);
</script>
</div>
</div>
</body>
</html>
It seems that you can't update datasets with myChart.update(). try to create temporary object and then assign that object to myChart.data.datasets. you then need to redraw your chart again. I had the same issue with using chart.js in my angular project link. Did you check link?

How to set bar width

Please help out how to set bar width for dynamic values. I want fixed width for single value:
var config = {
type: 'bar',
data: {
labels: ["January"],
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: "red",
data: [65, 4, 30, 20, 70],
}, {
type: 'bar',
label: 'Dataset 3',
backgroundColor: "blue",
data: [-65]
}]
},
options: {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
}
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.0/Chart.bundle.min.js"></script>
<div style="width:600px">
<canvas id="myChart"></canvas>
</div>