ChartJS - How can I skip certain minutes on the X-Axis - chart.js

I'm using ChartJS to visualize a database (that I have transformed into an array here)
The problem is that I have various time differences between every point.
Current visualization of my data.
My question is, how can I add space on my X axis, based on the time difference between the two data samples? Thanks.
EDIT: I was not very clear about what I wanted to achieve with my question, let me clarify:
I currently have this code:
var worldctx = document.getElementById('worldChart').getContext('2d');
var worldChart = new Chart(worldctx, {
type: 'line',
data: {
labels: worldArrayTime,
datasets: [{
data: worldArrayData,
label: "WORLD",
borderColor: "#3e95ce",
backgroundColor: "#3e95ce",
fill: false
}
]
},
options: {
responsive: true,
title: {
display: true,
text: 'Taric Ranking'
},
scales:{
xAxes:[{
ticks:{
callback: function(dataLabel,index){
let a = Math.floor(worldArrayData.length/10)
return index % a == 0 ? dataLabel : '';
}
}
}],
yAxes:[{
ticks:{
min: Math.floor(Math.min.apply(Math,worldArrayData)-2),
max: Math.floor(Math.max.apply(Math,worldArrayData)+2)
}
}]
}
}
});
}
It gives me this Chart, but the X axis doesn't match the time spent between each point, how can I make it so that it represents accurately the time on the X axis?

You should define the xAxis as a time cartesian axis. Also you can use property displayFormats according to Display Formats from Chart.js documentation. See Moment.js for the allowed format strings.
To do so, add the following to your xAxis inside the chart options.
xAxes: [{
type: 'time',
time: {
displayFormats: {
minute: 'DD/MM hh:mm'
}
},
...
Please note that Chart.js uses Moment.js for the functionality of the
time axis. Therefore you should use the bundled version of Chart.js that includes Moment.js in a single file.
const worldArray = [{ time: 1583593111036, rank: 665 }, { time: 1583593163490, rank: 665 }, { time: 1583593233697, rank: 665 }, { time: 1583594921644, rank: 666 }, { time: 1583595055581, rank: 665 }, { time: 1583595404573, rank: 665 }, { time: 1583596247042, rank: 665 }, { time: 1583598655437, rank: 666 }, { time: 1583600457443, rank: 667 }, { time: 1583601460665, rank: 668 }, { time: 1583602660570, rank: 665 }, { time: 1583604281776, rank: 668 }, { time: 1583605854175, rank: 669 }, { time: 1583606447275, rank: 668 }, { time: 1583607161055, rank: 667 }, { time: 1583607882093, rank: 666 }, { time: 1583608179707, rank: 667 }, { time: 1583609744777, rank: 668 }, { time: 1583609860652, rank: 669 }, { time: 1583610648775, rank: 670 }, { time: 1583613344874, rank: 671 }, { time: 1583613459587, rank: 672 }];
const worldArrayTime = worldArray.map(o => o.time);
const worldArrayData = worldArray.map(o => o.rank);
var worldctx = document.getElementById('worldChart').getContext('2d');
var worldChart = new Chart(worldctx, {
type: 'line',
data: {
labels: worldArrayTime,
datasets: [{
data: worldArrayData,
label: "WORLD",
borderColor: "#3e95ce",
backgroundColor: "#3e95ce",
fill: false
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Taric Ranking'
},
scales: {
xAxes: [{
type: 'time',
time: {
tooltipFormat: 'DD/MM hh:mm',
displayFormats: {
minute: 'DD/MM hh:mm'
}
},
ticks: {
maxTicksLimit: worldArrayData.length
}
}],
yAxes: [{
ticks: {
min: Math.floor(Math.min.apply(Math, worldArrayData) - 2),
max: Math.floor(Math.max.apply(Math, worldArrayData) + 2)
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="worldChart" height="150"></canvas>

I decided to use Chartist.js since it offers an easier implementation of moment.js
If you know how to answer the question, i'm still interested tho.

Related

chart.js horizontal stack bar not showing expcected result

i have a project in real time calculation project does not stack correctly ,i have 3 dataset stack one by one but it shows only two data in my chart
<div class="graph_container">
<canvas ref="myChart" width="400" height="400"></canvas>
</div>
Option for horizontal stack bar format with time
var options={
responsive:true,
maintainAspectRatio: false,
indexAxis: 'y',
scales: {
x: {
offset: true,
stacked: true,
type: 'time',
time: {
unit:'hour'
},
min: moment(String(todayStartTime)),
max: moment(String(todayEndTime))
// max: moment().add(8, 'hours')
},
y: {
stacked: true,
offset: true
}
}
}
My Dataset
const data = {
datasets: [
{
label: "T1"+moment(todayStartTime).add(0.5,'hours'),
data: [
{
x: moment(todayStartTime).add(0.5,'hours'),
y: 0
},
],
backgroundColor: "red"
},
{
label: "T2"+moment(todayStartTime).add(2,'hours'),
data: [{
x: moment(todayStartTime).add(2,'hours'),
y: 0
}],
backgroundColor: "blue"
},
{
label: "T3"+moment(todayStartTime).add(3,'hours'),
data: [
{
x: moment(todayStartTime).add(3,'hours'),
y: 0
}],
backgroundColor: "orange"
},
]
};
Chart js
var $vm=this;
const ctx =this.$refs.myChart;
var todayStartTime=new moment('2022-10-19 08:00:00 am')
var todayEndTime=new moment('2022-10-19 03:00:00 pm')
const config = {
type: 'bar',
data,
options
};
new Chart(ctx,config);
Output (First Dataset only Correct)
it showing only first dataset is correct other dataset wrong and some missing
This is because you have a stacked x axis, this means that instead of the value starting at the origin it starts where the first bar ends. To resolve this issue you need to set the options.scales.x.stacked to false or dont set it since false is the default.
Example:
var todayStartTime = new moment('2022-10-19 08:00:00');
var todayEndTime = new moment('2022-10-19 15:00:00');
var options = {
responsive: true,
maintainAspectRatio: false,
indexAxis: 'y',
scales: {
x: {
offset: false,
type: 'time',
time: {
unit: 'hour'
},
min: todayStartTime,
max: todayEndTime
},
y: {
stacked: true,
offset: true
}
}
};
const data = {
datasets: [{
label: "T1" + moment(todayStartTime).add(0.5, 'hours'),
data: [{
x: moment(todayStartTime).add(0.5, 'hours'),
y: 0
}],
backgroundColor: "red"
},
{
label: "T2" + moment(todayStartTime).add(2, 'hours'),
data: [{
x: moment(todayStartTime).add(2, 'hours'),
y: 0
}],
backgroundColor: "blue"
},
{
label: "T3" + moment(todayStartTime).add(3, 'hours'),
data: [{
x: moment(todayStartTime).add(3, 'hours'),
y: 0
}],
backgroundColor: "orange"
},
]
};
const ctx = document.getElementById('myChart').getContext('2d');
const config = {
type: 'bar',
data,
options
};
new Chart(ctx, config);
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment#2.29.4/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#1.0.0/dist/chartjs-adapter-moment.min.js"></script>
<canvas id="myChart" width="600" height="400" />
Credits go to Stockinail that answered this question already on github: https://github.com/chartjs/Chart.js/issues/10815

How to display linear day ticks on x time-axe in Chartjs

I have dataset width random time moments and I'd like to display round dates on x axe like
| | | | |
12 13 14 15 16
oct oct oct oct oct
Looks like time.round iss the proper option, but it not works, my code
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: chart_labels,
datasets: [{
label: 'Время доступа',
data: chart_values,
borderColor: ["#03A9F5"],
borderWidth: 1,
fill: true,
backgroundColor: "#03A9F522",
pointRadius: 1,
pointHoverRadius: 5,
}]
},
options: {
interaction: {
intersect: false,
mode: 'index',
},
tension: 0.4,
scales: {
x: {
type: 'time',
'time.round': 'day',
},
y: {
title: {
display: true,
stacked: true,
text: 'Секунды',
beginAtZero: true
}
}
},
}
});
And ticks go by 3 hours: 5pm 8pm 11pm...
Edited
time: {round: 'day'} is not a correct parameter, it moves dots to the beginning of a day, when I need to keep dots where they are but draw ticks on the begining of the days.
https://jsfiddle.net/7y2L9ueq/
I think the issue is that you are using round option in the time.
For what you need, you should use unit option, which is defining the time unit on the axis.
scales: {
x: {
type: 'time',
time: {
unit: 'day' // <-- to use
}
},
y: {
title: {
display: true,
stacked: true,
text: 'Секунды',
beginAtZero: true
}
}
}

chartjs : uncaught exception: 0 and X are too far apart with stepSize of Y

I am plotting data on a graph with chartjs. It used to work but I don't know why I am continuously getting uncaught exception: 0 and 1587533402000 are too far apart with stepSize of 1 hour, although neither 0 nor 1587533402000 are part of the data I plot.
Here is how I plot the graph :
var chart_temperature = new Chart(ctx_temperature, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: timeXValues,
fill: false, // no inner color
datasets: [{
label: 'Temperature',
borderColor: 'rgb(255, 99, 132)',
data: temperatureData
}]
},
// Configuration options go here
options: {
responsive: true,
layout: {
padding: {
bottom: 50
}
},
elements: {
point: {
radius: 0 // don't show points
},
line: {
fill: false
}
},
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'hour',
displayFormats: {
hour: 'DD/MM/YYYY HH:mm'
}
},
ticks: {
beginAtZero: false // tried true, and also removed all this as it used to be
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'T°C'
}
}]
},
showLines: true, // the points will be connected
// Optimization
animation: {
duration: 0 // general animation time
},
hover: {
animationDuration: 0 // duration of animations when hovering an item
},
responsiveAnimationDuration: 0 // animation duration after a resize
}
});
Why is chartjs using 0 whereas the chart is not starting at 0 ? Where should I look at ?
Any help appreciated :-)
Edit :
Commenting the following line (in scales.xAxes) makes the chart displayed :
// type: 'time',
But the X Axis becomes then useless since timestamps are displayed.
A genius idea finally spurted! Searching against are too far apart with stepSize in chartjs git repository showed that time scale min option was wrongly set to 0.
Adding these min max to time option of xAxes solved the issue.
And even as time min max options are deprecated, ticks.min and ticks.max should be used:
ticks: {
min: startTimestamp,
max: endTimestamp
}
For me, I needed to update my type time to "minute" instead of "second".
xAxes: [ {
type: 'time',
time: {
unit: 'minute'
},
In my case, that because the data from x is not 'int' but 'string'.
data from Backend:
data: [{
x: "1626414792000", //1626414792000
y: 2
}, {
x: 1626414873000, // 14:00:00
y: 3
}, {
x: 1626415500000, // 13:00:00
y: 5
}]
}],
Then, I parse x data before chart.js use it.
My full code:
var obj = {
type: 'line',
data: {
datasets: [{
label: 'First dataset',
data: [{
x: "1626414792000",
y: 2
}, {
x: 1626414873000,
y: 3
}, {
x: 1626415500000,
y: 5
}]
}],
},
options: {
title: {
text: 'Chart',
display: true,
},
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'minute',
/* parsing x data before chart.js use it */
parser: function(dt){
console.log(dt)
return parseInt(dt);
}
}
}]
}
}
}
In my case, the issue happened when zooming.
It was caused by wrong properties of the zoom plugin option used with a chart type 'time'. The following works options works fine:
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
suggestedMin: 0,
},
}],
xAxes: [{
type: 'time',
time: {
unit: 'day',
tooltipFormat: 'MMM DD YYYY',
},
}],
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'xy'
},
zoom: {
enabled: true,
mode: 'xy',
}
}
}
}

ChartJS: Full Date for xAxis Labels?

I was been working on a timescale line chart, and noticed that when the all the data points are close enough together, the xAxis labels automatically convert to just time. I have tried different xAxis time units with no success.
Here is a simply codepen example in which the xAxis labels are by hour. If you change a moment to be March instead of April, the xAxis labels are by date.
Is there a way to force the xAxis labels to always be date AND time?
xAxes: [{
type: 'time',
time: {
parser: timeFormat,
// unit: 'day',
// unit: 'hour',
tooltipFormat: 'll HH:mm'
},
https://codepen.io/ccwakes/pen/abvzewW
Thanks
You can use property time.displayFormats according to Display Formats from Chart.js documentation. See Moment.js for the allowable format strings.
time: {
unit: 'hour',
displayFormats: {
hour: 'MMM DD HH:mm'
},
tooltipFormat: 'MMM DD HH:mm'
}
Please have a look at your amended code below.
new Chart(document.getElementById('canvas'), {
type: 'line',
data: {
datasets: [{
label: 'Dataset 1',
backgroundColor: 'red',
borderColor: 'red',
fill: false,
data: [
{ x: '2020-04-10 13:00', y: 60 },
{ x: '2020-04-12 06:00', y: 100 },
{ x: '2020-04-12 13:00', y: 5 }
],
}, {
label: 'Dataset 2',
backgroundColor: 'blue',
borderColor: 'blue',
fill: false,
data: [
{ x: '2020-04-10 13:00', y: 45 },
{ x: '2020-04-11 13:00', y: 65 },
{ x: '2020-04-12 06:00', y: 80 },
{ x: '2020-04-12 13:00', y: 65 }
]
}]
},
options: {
title: {
text: 'Time Scale'
},
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'hour',
displayFormats: {
hour: 'MMM DD HH:mm'
},
tooltipFormat: 'MMM DD HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="canvas" height="90"></canvas>

Chart with Time axis only displaying first grid line and tick label (unitStepSize)

I am trying to display a simple line chart of temperatures versus time. The dataset has temperatures and times in ten minute intervals. Times are in HH:mm format.
The graph is displaying correctly but only the left axis, right axis and first tick time value and grid line are displaying.
My data looks like this:
12:00 20.1
12:10 20.3
12:20 20.5
...
13:20 21
13:30 21.4
I get the left axis labelled as 12:00 then one label at 12:10 with grid line, and then nothing until 13:30 on the right axis.
If I leave out the unitStepSize I get ticks and gridlines every minute (crowded). So obviously I am missing something to do with this parameter.
var myChart = new Chart(ctx,
{
type: 'line',
data: data,
options :
{
responsive:false,
maintainAspectRatio: false,
scales:
{
xAxes: [
{
type: 'time',
scaleLabel:
{
display: true,
labelString: 'Time'
},
time:
{
unit: 'minute',
unitStepSize: '10',
format: "HH:mm",
displayFormats:
{
minute: 'HH:mm',
hour: 'HH:mm'
}
}
}],
yAxes: [
{
scaleLabel:
{
display: true,
labelString: 'Temp'
},
ticks: {
max: 25,
min: 15,
stepSize: 1
}
}]
}
}
});
The issue you are currently facing is causing because, you are passing the unitStepSize value as a string.
It should be a number, with no quotes ('') around it.
var ctx = document.querySelector('#canvas').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['12:00', '12:10', '12:20', '13:20', '13:30'],
datasets: [{
label: 'Temperatures',
data: [20, 21, 22, 21, 23],
backgroundColor: 'rgba(75,192,192, 0.4)',
borderColor: '#4bc0c0',
pointBackgroundColor: 'black',
tension: 0,
fill: false
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
scaleLabel: {
display: true,
labelString: 'Time'
},
time: {
unit: 'minute',
unitStepSize: 10,
format: "HH:mm",
displayFormats: {
minute: 'HH:mm',
hour: 'HH:mm'
}
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Temp'
},
ticks: {
max: 25,
min: 15,
stepSize: 1
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="canvas"></canvas>