Incorrect time chart Chart.js - chart.js

I am trying to generate a time chart with some positive values and some negative. I am trying to achieve something like this. The issue occurs when I set the chart xAxes type as time.
But what I get is
Sample fiddle here with chart configurations.
xAxes: [{
type: 'time',
unitStepSize: 1,
time: {
'unit': 'day'
},
displayFormats: {
'day': 'MMM DD'
},
distribution: 'series',
gridLines: {
display: true,
drawBorder: true,
drawOnChartArea: true,
tickMarkLength: 15
}
}],

Time series was not in correct order. Since it is a time chart, labels should be in either ascending or descending order.
changing the time to the below order fixed the issue
data: {
labels: [
"2018-12-04 00:00:14.000000"
"2018-12-05 11:45:14.000000",
"2018-12-05 12:00:14.000000",
"2018-12-05 13:00:15.000000",
"2018-12-05 14:00:14.000000",
],

Related

How can I skip data/labels in a period of time in Chartjs?

Can you show me how I can skip data in a period of time in Chartjs?
e.g I have data from 10->11h30 am and 1h -> 2h pm. I built the chart in time type but I want to skip/remove the line from 11h30->1h or 2hpm -> 10h.
options = {
responsive: true,
title: {
display: true,
text: 'Chart.js Time Point Data'
},
scales: {
xAxes: [{
type: 'time',
display: true,
stacked: true,
scaleLabel: {
display: true,
labelString: 'Date'
},
ticks: {
major: {
fontStyle: 'bold',
fontColor: '#FF0000'
},
},
}],
yAxes: [{
stacked: true,
display: true,
scaleLabel: {
display: true,
labelString: 'value'
},
}]
},
};
Issue
Expecting
Thanks
Well, Chart.JS will show whatever labels and data contain. Therefore you can create a function to remove a certain range.
Here is a sample with a line chart: https://codepen.io/adelriosantiago/pen/xxRGVPW?editors=0010
The function rangeWithSkips will basically filter the input array between startSkip and endSkip. Later in the code you select the new range with:
data: {
labels: rangeWithSkips(3, 10).labels, // Pick the starting and end range here
datasets: [
{
label: "Volume",
data: rangeWithSkips(3, 10).data // Pick the starting and end range here too
}
]
}
Here is an updated version with that does exactly the same with a 2 inputs: https://codepen.io/adelriosantiago/pen/yLVNOGX?editors=1011

How to create multiple y-axis time series chart

I am trying to map multiple charts where x-axis (time) is fixed but y-axis can take multiple values like CPU%, RAM, IO-RATE and so on. If I try to build individual graphs things seems pretty easy but I have this weird requirement where I need to map everything on to same chart. I have been trying out things with chartjs library and I could see that Cartesian axes is capable of handling multiple axes. But the examples I find around Cartesian mostly have x-axis with some fixed label values. In my case it's time and I wonder how to do the same for time series. I also found this example for multiple time series but that doesn't seem to create multiple y-axis. What is required is something like this but I am having hard time trying to figure out how to achieve this.
I am using django for backend and I am open to try out any library out there that does this and can easily integrate with django. Currently I have been exploring things with chartjs.
First you need to define a unique xAxis and define it as a time cartesian axis.
xAxes: [{
type: 'time',
time: {
unit: 'minute',
tooltipFormat: 'HH:mm:ss'
}
}],
Then you define a linear cartesian yAxis for each dataset and make sure, the value of the yAxis.id matches the corresponding dataset.yAxisID. Use 'yAxis.position' to define whether the axis shall appear left or right of the chart.
Optionally you may also define the following Plugin Core API beforeLayout function that makes sure that an yAxis is also hidden when it's data set is hidden through a mouse click on a legend label.
plugins: [{
beforeLayout: chart => chart.data.datasets.forEach((ds, i) => chart.config.options.scales.yAxes[i].display = !ds._meta[0].hidden)
}],
Please have a look at below runnable code snippet that illustrates how it can be done.
const now = new Date().getTime();
const timestamps = new Array(10).fill().map((v, i) => now - i * 60000).reverse();
new Chart('chart', {
type: 'line',
plugins: [{
beforeLayout: chart => chart.data.datasets.forEach((ds, i) => chart.config.options.scales.yAxes[i].display = !ds._meta[0].hidden)
}],
data: {
labels: timestamps,
datasets: [{
label: 'CPU',
yAxisID: 'yAxis-CPU',
data: [68, 70, 71, 72, 75, 75, 76, 77, 79, 76],
borderColor: 'red',
fill: false
},
{
label: 'RAM',
yAxisID: 'yAxis-RAM',
data: [22, 23, 23, 23, 22, 20, 22, 22, 23, 25],
borderColor: 'blue',
fill: false
},
{
label: 'IO-RATE',
yAxisID: 'yAxis-IO-RATE',
data: [0.5, 0.6, 0.7, 0.8, 0.8, 0.2, 0.1, 0.1, 0.2, 0.2],
borderColor: 'green',
fill: false
}
]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'minute',
displayFormats: {
minute: 'HH:mm'
},
tooltipFormat: 'HH:mm:ss'
}
}],
yAxes: [{
id: 'yAxis-CPU',
type: 'linear',
position: 'left',
scaleLabel: {
display: true,
labelString: 'CPU %'
},
gridLines : {
display: false
},
ticks: {
beginAtZero: true
}
},
{
id: 'yAxis-RAM',
type: 'linear',
position: 'left',
scaleLabel: {
display: true,
labelString: 'RAM %'
},
gridLines : {
display: false
},
ticks: {
beginAtZero: true
}
},
{
id: 'yAxis-IO-RATE',
type: 'linear',
position: 'right',
scaleLabel: {
display: true,
labelString: 'IO-Rate %'
},
gridLines : {
display: false
},
ticks: {
beginAtZero: true
}
}
]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="chart" height="90"></canvas>

Chart.js bars have non uniform widths

I have a simple bar graph, but every bar has a different width. Is there any way to make the bars' widths uniform and match the x axis units/grid spacing?
This is how my chart is defined:
var chart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
annotation: {
annotations: []
},
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'day',
stepSize: 1,
},
ticks: {
maxTicksLimit: 21,
autoSkip: true
}
}]
}
}
});
Turns out my chart.js version was slightly out of date. After I replaced it with the latest version (2.7.3) the bars suddenly looked fine.
Problem solved :-)

Is it possible to combine two Y axes into a single tooltip with ChartJS 2?

Suppose I have two Y axes, labeled "foo" and "bar". These axes correspond to points along the same interval, e.g. weekly aggregates of foos and bars in say the last 12 weeks. Ideally you would mouseover one of these points along the line chart and the tooltip would display the data of the week in question for both foo and bar; this is how it works if you don't have more than one Y axes. In practice you have you mouseover the individual point to see only the data for that specific point.
For clarity, this is what my chart options look like:
const CHART_OPTIONS = {
scales:
{
xAxes: [{
ticks: {
display: false,
},
}],
yAxes: [
{
type: 'linear',
id: 'y-axis-0',
display: false,
position: 'left',
},
{
type: 'linear',
id: 'y-axis-1',
display: false,
position: 'right',
},
],
},
};
The chart data specifies a yAxisID of y-axis-0 and y-axis-1 respectively.
For those who haven't seen a chart with two Y axes, I've prepared a simple example.
So my question is if this can be done with Chart.js 2?
References:
Chartjs Docs: Tooltip Configuration - Interaction Modes
mode : index - Finds item at the same index. If the intersect setting is true,
the first intersecting item is used to determine the index in the
data. If intersect false the nearest item is used to determine the
index.
Update the chart options to include the tooltips configurations. Set the mode to index
tooltips : {
mode : 'index'
},
The updated options would look like this.
const CHART_OPTIONS = {
tooltips : {
mode : 'index'
},
scales:
{
xAxes: [{
ticks: {
display: false,
},
}],
yAxes: [
{
type: 'linear',
id: 'y-axis-0',
display: false,
position: 'left',
},
{
type: 'linear',
id: 'y-axis-1',
display: false,
position: 'right',
},
],
},
};
Check updated sample which include tooltips mode set to index

Horizontal bar chart in chart.js

I am trying to draw a horizontal bar chart using chart.js 2.3.0 -
var MeSeContext = document.getElementById("MeSeStatusCanvas").getContext("2d");
var MeSeData = {
labels: [
"ME",
"SE"
],
datasets: [
{
label: "Test",
data: [100, 75],
backgroundColor: ["#669911", "#119966" ],
hoverBackgroundColor: ["#66A2EB", "#FCCE56"]
}]
};
var MeSeChart = new Chart(MeSeContext, {
type: 'horizontalBar',
data: MeSeData,
options: {
scales: {
yAxes: [{
stacked: true
}]
}
}
});
But it only shows one bar. What did I miss here?
You can see only one chart because the lowest value of your data (75 here) is the scale's left limit.
As shown in the following screenshot of your code's result, if you hover on the scale, you can still see the associated data, which means it is here.
You have two ways to fix this :
Set the min property of the xScale ticks to the value you want (enough to see it of course) :
var MeSeChart = new Chart(MeSeContext, {
type: 'horizontalBar',
data: MeSeData,
options: {
scales: {
xAxes: [{
ticks: {
min: 60 // Edit the value according to what you need
}
}],
yAxes: [{
stacked: true
}]
}
}
});
You can see the result with a min set to 60 on this jsFiddle :
Set the beginAtZero property to true, which is the same as setting min to 0 :
xAxes: [{
ticks: {
beginAtZero: true
}
}],
You can see the result with the beginAtZero property set to true on this jsFiddle.