Plotting datetime fields using chartjs - chart.js

I have managed to plot a scatter graph of some temperature values against sequence number, however now I want to replace the sequence number by a datetime field from my database.
I included moment.js in my directory, replaced the x value directly by the datetime field and formatted the xAxes for time.
{{-- Temperature Graph --}}
<script>
var ctx_temperature = document.getElementById('temperature').getContext('2d');
var temperature = new Chart(ctx_temperature, {
type: 'scatter',
data: {
datasets: [{
label: 'Scatter Dataset',
data: [{ x: '2019-07-01 00:01:01', y: 100}, { x: '2019-07-01 00:12:01', y: 200 }],
borderColor: '#191970',
backgroundColor: '#191970',
borderWidth: 2,
pointBackgroundColor: '#d1d1e2',
pointBorderColor: '#191970',
pointRadius: 3,
pointHoverRadius: 5,
fill: false,
showLine: true
}]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{ type: 'time', time: { unit: 'minute' }, distribution: 'series' }]
}
}
});
</script>

Related

ChartJS : How to display two "y axis" scales on a chart

I have a chart that shows various data points.
Some of these data points are high numbers and some are low numbers.
The low numbers (visits) I can scale to a different scale and this new scale can be put on the "X" axis (It's the "Y" axis and then rotated 90degrees). But the problem is:
The grid remains even when removed
The
How can I extrapolate the poistion on the graph without adjusting the label data on hover?2 I have search Stackoverflow and ChartJS documentation but can't see how this can be done.
I was trying to use the "other" axis (in this case the top horizontal bar of the chart) so that the scale would be relative and raw data editing would not be needed but I can't get that to work and can't find documentation on this. I'm sure it's possible but I can't see how where.
I have found this question but this related only to ChartJS V2 .
Current version used is ChartJS 3.2.1
Original Version:
var ctx = document.getElementById("historicChart");
var historicChart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: [2022,2021,2020,2019,2018,2017,2016],
datasets: [
{
type: 'line',
label: 'Visits',
data: ["1","7","493","163","467","88","48"],
backgroundColor: '#FFC900',
pointBackgroundColor: '#FFC900',
pointRadius: 8,
pointStyle: 'circle',
showLine: false,
order: 1,
hoverRadius: 10
},
{
type: 'bar',
label: 'Applied',
data: ["486","800","704","1084","532","618","543"],
backgroundColor: '#436BFF',
borderWidth: 0,
order: 2,
barPercentage: 0.9,
stack: 'stack 0',
},
{
type: 'bar',
label: 'Accepted',
data: ["1","147","290","521","233","306","271"],
backgroundColor: '#C40500',
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 1',
order: 4
},
{
type: 'bar',
label: 'Declined',
data: ["616","4273","3998","3400","922","1225","1184"],
/*backgroundColor: '#03570c', /* emerald */
backgroundColor: '#006545', /* jade */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 5
},
{
type: 'bar',
label: 'Processing',
data: ["6","13","22","1","34","2","1"],
backgroundColor: '#65ccD3', /* aqua + blue */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 3
},
]
},
options: {
responsive: true,
interaction: {
intersect: false,
mode: 'index',
axis: 'y'
},
indexAxis: 'y',
scales: {
xAxes: [{
stacked: true,
ticks: {
stepSize: 1
},
beginAtZero: true
}],
yAxes: [{
stacked: true
}]
}
}
}
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="historicChart"></canvas>
UPDATE:
I have tried to add a custom secondary axis as per this example from the CHartJS documentation, but it doesn't quite do as I need; the grid lines remain and the axis scale is on the "wrong" side (two scales on one size (bottom) and zero scales on the other side (top)
var ctx = document.getElementById("historicChart");
var historicChart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: [2022,2021,2020,2019,2018,2017,2016],
datasets: [
{
type: 'line',
label: 'Visits',
data: ["1","7","493","163","467","88","48"],
backgroundColor: '#FFC900',
pointBackgroundColor: '#FFC900',
pointRadius: 8,
pointStyle: 'circle',
showLine: false,
order: 1,
hoverRadius: 10,
xAxisID:'xTwo'
},
{
type: 'bar',
label: 'Applied',
data: ["486","900","724","1084","532","618","543"],
backgroundColor: '#436BFF',
borderWidth: 0,
order: 2,
barPercentage: 0.9,
stack: 'stack 0',
},
{
type: 'bar',
label: 'Accepted',
data: ["1","147","290","511","253","306","271"],
backgroundColor: '#C40500',
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 1',
order: 4
},
{
type: 'bar',
label: 'Declined',
data: ["616","4373","3998","3400","922","1205","1184"],
/*backgroundColor: '#03570c', /* emerald */
backgroundColor: '#006545', /* jade */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 5
},
{
type: 'bar',
label: 'Processing',
data: ["6","23","22","1","4","2","1"],
backgroundColor: '#65ccD3', /* aqua + blue */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 3
},
]
},
options: {
responsive: true,
interaction: {
intersect: false,
mode: 'index',
axis: 'y'
},
indexAxis: 'y',
scales: {
xAxes: [{
stacked: true,
ticks: {
stepSize: 1
},
beginAtZero: true
}],
yAxes: [{
stacked: true
}],
xTwo: [{
type: 'linear',
display: true,
position: 'top',
grid: {
display: false,
drawOnChartArea: false,
ticks: {
display: false
}
}
}]
}
}
}
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="historicChart"></canvas>
The issue appears to be with the scale; "xTwo";
xTwo: [{
type: 'linear',
display: true,
position: 'top',
grid: {
display: false,
drawOnChartArea: false,
ticks: {
/* trying to even just hide the ticks here fails */
display: false,
}
}
}]
How can I fix this to hide the grid lines and put the scale on the correct side of the graph?
You can use a custom label callback for this in the tooltip config, also your scale config was wrong. It was in V2 style. For all changes please read the migration guide
var ctx = document.getElementById("historicChart");
var historicChart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: [2022, 2021, 2020, 2019, 2018, 2017, 2016],
datasets: [{
type: 'line',
label: 'Visits',
data: ["5", "35", "2465", "815", "2335", "440", "240"],
backgroundColor: '#FFC900',
pointBackgroundColor: '#FFC900',
pointRadius: 8,
pointStyle: 'circle',
showLine: false,
order: 1,
hoverRadius: 10
},
{
type: 'bar',
label: 'Applied',
data: ["486", "800", "704", "1084", "532", "618", "543"],
backgroundColor: '#436BFF',
borderWidth: 0,
order: 2,
barPercentage: 0.9,
stack: 'stack 0',
},
{
type: 'bar',
label: 'Accepted',
data: ["1", "147", "290", "521", "233", "306", "271"],
backgroundColor: '#C40500',
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 1',
order: 4
},
{
type: 'bar',
label: 'Declined',
data: ["616", "4273", "3998", "3400", "922", "1225", "1184"],
/*backgroundColor: '#03570c', /* emerald */
backgroundColor: '#006545',
/* jade */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 5
},
{
type: 'bar',
label: 'Processing',
data: ["6", "13", "22", "1", "34", "2", "1"],
backgroundColor: '#65ccD3',
/* aqua + blue */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 3
},
]
},
options: {
responsive: true,
interaction: {
intersect: false,
mode: 'index',
axis: 'y'
},
indexAxis: 'y',
plugins: {
tooltip: {
callbacks: {
label: (ttItem) => {
const label = ttItem.dataset.label;
const val = Number(ttItem.raw);
let res = `${label}: ${label === 'Visits' ? val / 5 : val}`;
return res
}
}
}
},
scales: {
x: {
stacked: true,
ticks: {
stepSize: 1
},
beginAtZero: true
},
y: {
stacked: true
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="historicChart"></canvas>
UPDATE:
You tried adding a second scale, in chart.js V3 all scales are their own objects and not arrays anymore, for all changes see migration guide linked above. Changing the scales to objects fixes your issue in your updated approach without needing to multiply values :
var ctx = document.getElementById("historicChart");
var historicChart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: [2022, 2021, 2020, 2019, 2018, 2017, 2016],
datasets: [{
type: 'line',
label: 'Visits',
data: ["1", "7", "493", "163", "467", "88", "48"],
backgroundColor: '#FFC900',
pointBackgroundColor: '#FFC900',
pointRadius: 8,
pointStyle: 'circle',
showLine: false,
order: 1,
hoverRadius: 10,
xAxisID: 'xTwo'
},
{
type: 'bar',
label: 'Applied',
data: ["486", "900", "724", "1084", "532", "618", "543"],
backgroundColor: '#436BFF',
borderWidth: 0,
order: 2,
barPercentage: 0.9,
stack: 'stack 0',
},
{
type: 'bar',
label: 'Accepted',
data: ["1", "147", "290", "511", "253", "306", "271"],
backgroundColor: '#C40500',
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 1',
order: 4
},
{
type: 'bar',
label: 'Declined',
data: ["616", "4373", "3998", "3400", "922", "1205", "1184"],
/*backgroundColor: '#03570c', /* emerald */
backgroundColor: '#006545',
/* jade */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 5
},
{
type: 'bar',
label: 'Processing',
data: ["6", "23", "22", "1", "4", "2", "1"],
backgroundColor: '#65ccD3',
/* aqua + blue */
borderWidth: 0,
barPercentage: 0.9,
stack: 'stack 0',
order: 3
},
]
},
options: {
responsive: true,
interaction: {
intersect: false,
mode: 'index',
axis: 'y'
},
indexAxis: 'y',
scales: {
x: {
stacked: true,
ticks: {
stepSize: 1000
},
beginAtZero: true
},
y: {
stacked: true
},
xTwo: {
type: 'linear',
display: true,
position: 'top',
grid: {
display: false,
ticks: {
display: false
}
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.1/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="historicChart"></canvas>

Draw stacked horizontal bar chart with Average line using ChartJS

I am trying to create a stacked horizontal bar chart with an average line on each bar using the ChartJS library. I tried several times and searched on the Internet but I did not find out any satisfying answers. I appreciate your helping. Thanks.
Example:
.
In this example, the red line on each bar implies the average value of its group.
To create the stacked horizontal bar chart, please see
https://jsfiddle.net/lamtn862004/9wm1krqf/10/.
var data = {
labels: ["January", "February", "March"],
datasets: [
{
label: "Dogs",
backgroundColor: "rgba(237, 192, 169)",
data: [20, 10, 25],
stack: 1,
xAxisID: 'x-axis-0',
yAxisID: 'y-axis-0'
},
{
label: "Cats",
backgroundColor: "rgba(253, 234, 175)",
data: [70, 85, 65],
stack: 1,
xAxisID: 'x-axis-0',
yAxisID: 'y-axis-0'
},
{
label: "Birds",
backgroundColor: "rgba(179, 211, 200)",
data: [10, 5, 10],
stack: 1,
xAxisID: 'x-axis-0',
yAxisID: 'y-axis-0'
},
]
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
type: 'groupableHBar',
data: data,
options: {
scales: {
yAxes: [{
stacked: true,
type: 'category',
id: 'y-axis-0'
}],
xAxes: [{
stacked: true,
type: 'linear',
ticks: {
beginAtZero:true
},
gridLines: {
display: false,
drawTicks: true,
},
id: 'x-axis-0'
},
{
stacked: true,
position: 'top',
type: 'linear',
ticks: {
beginAtZero:true
},
id: 'x-axis-1',
gridLines: {
display: true,
drawTicks: true,
},
display: false
}]
}
}
});
Now, I want to add the average line to each bar (as shown in the image).
Also, do you know the other solutions with open-source libraries for doing this?
The lines can be drawn using floating bars tied to the separate axis y2. To do so, you need to add another dataset as follows (I don't exactly understand what values you want to display, hence I randomly chose 40, 65 and 55):
{
label: "Lines",
backgroundColor: "rgb(255, 0, 0)",
data: [40, 65, 55].map(v => [v - 0.3, v + 0.3]),
yAxisID: 'y2',
order: -1
}
Further you must define a new scales option as shown below:
y2: {
display: false
}
Please take a look at your amended runnable code and see how it works.
var data = {
labels: ["January", "February", "March"],
datasets: [{
label: "Dogs",
backgroundColor: "rgba(237, 192, 169)",
data: [20, 10, 25]
},
{
label: "Cats",
backgroundColor: "rgba(253, 234, 175)",
data: [70, 85, 65]
},
{
label: "Birds",
backgroundColor: "rgba(179, 211, 200)",
data: [10, 5, 10]
},
{
label: "Lines",
backgroundColor: "rgb(255, 0, 0)",
data: [40, 65, 55].map(v => [v - 0.3, v + 0.3]),
yAxisID: 'y2',
order: -1
}
]
};
new Chart('myChart', {
type: 'bar',
data: data,
options: {
indexAxis: 'y',
plugins: {
legend: {
display: false
}
},
scales: {
y: {
stacked: true,
grid: {
display: false
}
},
y2: {
display: false
},
x: {
stacked: true,
beginAtZero: true,
grid: {
display: false
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>

break y axis in line chart chart.js

I am trying to render a line graph with two datasets
My sample chart
<canvas id="myChart"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'My First dataset',
borderColor: 'rgb(255, 99, 132)',
fill: false,
data: [9000, 9020, 9010, 9004, 9011, 9040, 9050]
},
{
label: 'My Second dataset',
borderColor: 'rgb(0, 99, 132)',
fill: false,
data: [1000, 1020, 1010, 1004, 1011, 1040, 1050]
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
stepSize: 10
}
}]
}
}
});
</script>
This is how it looks currently current result
This the graph will be easy to read if it has axis break like this
expected result
There is no build in way to do this. The best thing you can do is use a second Y axes and link the second dataset to the other axes.
datasets: [
{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
yAxisID: 'first'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1,
yAxisID: 'second'
}
]
options: {
scales: {
yAxes: [{
id: 'first'
},{
id: 'second'
}]
}
}

Chart.js line chart looking as area chart with smooth lines but not sharp

The chartjs line chart is showing like an area chart and with smooth lines. I want to make the chart a simple line chart with sharp points. I have tried some options but all in vain.
var AreaChart = new Chart(AreaCharts, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Required',
data: [],
backgroundColor: '#f39233',
hoverBorderWidth: 2,
hoverBorderColor: '#054564',
},
{
label: '2nd',
data: [],
backgroundColor: '#b8de6f',
hoverBorderWidth: 2,
hoverBorderColor: '#054564',
}
]
},
options: {
bezierCurve: false,
scaleShowValues: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
autoSkip: true,
padding: 10,
fontSize: 10
}
}]
},
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: ''
},
},
});
This is the code. I am filling up the data and the labels from other function.
The line should be sharp and there should be just the line not any area. I did read the documentation but it is confusing for me.
I have posted a solution here: http://jsfiddle.net/srux4971/
Most important parts are
data: {
...
datasets: [{
...
fill: false, //no fill
lineTension:0, //straight lines
In order to convert the area chart into a line chart, add the option fill: false to each dataset.
I you also define the option borderColor, the lines will appear with the desired color.
Please take a look at your amended code and see how it works.
new Chart('myChart', {
type: 'line',
data: {
labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
datasets: [{
label: 'Required',
data: [3, 2, 4, 5, 6, 4, 3],
backgroundColor: '#f39233',
borderColor: '#f39233',
hoverBorderWidth: 2,
hoverBorderColor: '#054564',
fill: false
},
{
label: '2nd',
data: [4, 1, 3, 5, 3, 4, 2],
backgroundColor: '#b8de6f',
borderColor: '#b8de6f',
hoverBorderWidth: 2,
hoverBorderColor: '#054564',
fill: false
}
]
},
options: {
bezierCurve: false,
scaleShowValues: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
autoSkip: true,
padding: 10,
fontSize: 10
}
}]
},
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: ''
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>

Chartjs: Why do I have 2 Y Axis labels?

My chart data is working, but I would like the Y axis to start below my lowest value and extend just a bit above the largest value and I was looking at the yAxes-> ticks-> min/max to do this. But when I add this to the options, a second second Y axis label is added with a scale of -1.0 to 1.0; I'm not sure how to get rid of that. I have attached some screen shots and some mocked up js code. Thanks
var chartData = {
labels: ['January', 'February', 'March'],
datasets: [{
type: 'line',
label: 'Dataset 1',
borderColor: 'blue',
borderWidth: 2,
fill: false,
data: [
85, 80, 75
]
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: 'red',
data: [
90, 85, 80
],
borderColor: 'white',
borderWidth: 2
}, {
type: 'bar',
label: 'Dataset 3',
backgroundColor: 'green',
data: [
95, 90, 85
]
}]
};
var ctx = document.getElementById('canvas').getContext('2d');
window.myMixedChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
title: {
display: true,
text: 'A Funky Label'
},
tooltips: {
mode: 'index',
intersect: false
},
responsive: true,
scales: {
xAxes: [{
stacked: false
}],
yAxes: [
{
ticks: {
max: 100,
min: 50,
stepSize: 10,
callback: function (value, index, values) {
return value + " HP";
}
}
},
{
stacked: false
}
]
},
layout: {
padding: {
left: 10,
right: 10,
top: 0,
bottom: 0
}
}
}
});
}
I discovered the answer:
I was trying to determine if I wanted a stacked bar chart or regular bar chart with multiple series chart. Anyway, after deciding to stick with the regular bar chart with multiple series I removed this from my options section:
stacked: false
Once removed the second Y axis disappeared