chartjs show nearest point on hover - chart.js

I'm currently trying to reproduce the chart you can see on https://discordstatus.com/ for the API Response Time.
However I'm unable to always show the nearest label depending on the mouse position on the X axis. I've tried different configurations for interactions (Chart.js Interactions) but fail to get the desired outcome.
Also it would be nice to show a vertical line dependent on the current active point. As well as always show the tooltip at the top left.
Is this possible with the default chart.js library or do i have to add a plugin or some own modifications?
Here is my current configuration:
const data = {
datasets: [{
label: 'RTT',
backgroundColor: '#C00122',
borderColor: '#C00122',
borderWidth: 2,
}]
};
const config = {
type: 'line',
data: data,
options: {
animation: false,
maintainAspectRatio: false,
pasing: false,
plugins: {
legend: false
},
elements: {
point: {
radius: 1
}
},
scales: {
x: {
type: 'time',
time: {
unit: 'second',
displayFormats: {
'second': 'H:mm:ss',
}
},
ticks: {
minRotation: 0,
maxRotation: 0,
maxTicksLimit: 5
}
},
y: {
min: 0,
ticks: {
stepSize: 10
}
}
},
hover: {
mode: 'index'
}
}
};
EDIT: My datasets are filled dynamically as described here: Updating Charts

Related

ChartJS 'Line chartjs' does not show output in NodeRED?

My requirement is to output 2 y-axis chart with real-time data readings in NodeRED. I have installed ChartJS package in NodeRED and now according to the documentation of the package there should be PATH, Title, X-Axis, Y-Axis, Payload. But I couldn't find the Payload tab anywhere in the Line Chartjs node?
Ref : https://www.npmjs.com/package/node-red-contrib-chartjs
So I assumed that I have to add the code which belonged to Payload inside a function node before the Line Chartjs node.
What I have tried : (my function node)
var left = {payload : msg.payload.readResults[0].v };
var right = {payload : msg.payload.readResults[1].v };
//return [[left,right]];
const labels = [1,2,3,4,5,6,7,8,9,10];
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: left,
borderColor: '#ff0000',
backgroundColor: '#ff0000',
yAxisID: 'leftCamber',
},
{
label: 'Dataset 2',
data: right,
borderColor: '#0000ff',
backgroundColor: '#0000ff',
yAxisID: 'rightCamber',
}
]
};
const config = {
type: 'line',
data: data,
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Multi Axis'
}
},
scales: {
leftCamber: {
type: 'linear',
display: true,
position: 'left',
},
rightCamber: {
type: 'linear',
display: true,
position: 'right',
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
}
},
};
const actions = [
{
name: 'CamberGraph',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = chart.data.labels.length
});
chart.update();
}
},
];
Here I have tried to get the 2 HTTP outputs I've named as left and right as my datasets(2 y-axis) vs hardcoded x-axis(1 through 10) which will be Footage later on.
PS : I have returned the left and right using return statement and it's outputting the values as I expected.
Currently I do not get any output in my debug window as well as in my ChartJS Line Chart when I inject the node. Using what I've tried so far can anybody show where I've done wrong or add/remove anything to make the graph work?
Thank you!

Why does x axis not increment 'monthly' chart.js. Also, XAxis not taking title

https://water.sas.usace.army.mil/chart.htm
https://water.sas.usace.army.mil/chart.png
See the Code Above, (View Source)
The code builds a time-series chart.
The scales section has unit set to month, however chart does not display with monthly increment on x axis.
Also Y axis will not display title.
The main problem is that config is not properly formatted, options.plugins is not closed by a }, hence the entire scales section is not considered by Chart.js.
Further, you should also define a time.parser to let the date adapter know how to parse the provided date strings.
Be careful to choose the correct date-fns formats for time.parser as well as for time.displayFormats.
Therefore, if you define config as follows, it should work.
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
legend: {
display: true,
position: 'bottom'
},
title: {
display: true,
text: "HARTWELL PROJECT",
font: {
size: 20
}
},
},
scales: {
x: {
type: 'time',
time: {
parser: 'MM/dd/yyyy',
unit: 'month',
displayFormats: {
month: 'MMM yyyy'
}
},
title: {
display: true,
text: 'Date'
}
},
y: {
title: {
position: 'left',
display: true,
text: 'Elevation (FT-MSL)'
}
}
},
chartAreaBorder: {
borderColor: 'black',
borderWidth: 10,
//borderDash: [5, 5],
borderDashOffset: 5
},
imgPlugin: {}
},
plugins: [chartAreaBorder, imgPlugin, GradientBgPlugin]
};

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',
}
}
}
}

Chart.js plot not aligned with xAxis labels

I have the following Scatter plot chart created with Chart.js and for some reason, the green dots are not aligned with the xAxis labels. Note that I am doing this in a Vue.js app using vue-chart.js but I don't think this is the reason. Any idea of how I could align plots and xAxis labels?
data: {
labels: this.sessionLabels, // Example: ["2020-02-07T13:57:43", "2020-02-07T13:57:43", "2020-02-07T13:57:43", "2020-02-07T13:57:43", "2020-02-07T16:42:39", "2020-02-07T16:42:39"...]
datasets: [
{
label: "Session",
backgroundColor: "#42b983",
data: this.sessions // Example: [{x:1, y:0}, {x:2, y:0}, {x:3, y:0}, ...]
}
]
},
options: {
title: {
display: true,
text: "Sessions executed over the last 7 days",
fontColor: "#ffffff",
fontSize: "14",
fontStyle: "normal"
},
legend: {
display: false
},
scales: {
xAxes: [
{
ticks: {
callback: function(value, index, values) {
return this.sessionLabelsAlias[index];
}.bind(this)
}
}
],
yAxes: [
{
ticks: {
max: 100,
min: 0,
stepSize: 10
}
}
]
}
}
The main problems is that your sessionLabels contains identical values.
Also when explicitly defining labels, your data should simply be an array of values, each one corresponding to the label at the same position.
[0, 0, 0, 0, 0 ...]

ChartJs annotation does not work with Tooltip

I have a requirement where on hover i need to show one horizontal line like in below fiddle.
but tool-tip is getting disappeared once on hover horizontal line is drawn.
Can anyone help how i can get tool-tip along with horizontal line.
Please note in below fiddle we have issue on hover it takes time but in my actual project hover is working fine , i just have issue that after hover tool-tip does not work after some time.
https://jsfiddle.net/h8ow63be/
var option = {
legend: false,
title: {
display: true,
},
onHover: function(evt) {
var item = myLineChart.getElementAtEvent(evt);
if (item.length) {
updateChart(data.datasets[0].data[item[0]._index].y)
}
},
animation: {
duration: 0
},
annotation: {
annotations: lines
},
scales: {
xAxes: [{
id: 'x-axis',
type: 'linear',
position: 'bottom',
ticks: {
max: 12,
min: 1,
stepSize: 1
}
}],
yAxes: [{
id: 'y-axis',
type: 'linear',
}],
}
};