chart.js 3 and time axis displays wrong date data - javascript

I have a very hard time to get chart.js running with time axis.
I have following simplified code:
<html>
<head>
<!--
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.js"></script>
-->
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
</head>
<body>
<canvas id="chart" width="800" height="400"></canvas>
<script type="text/javascript">
window.onload = function () {
var ctx = document.getElementById('chart').getContext('2d');
var myChart = new Chart(ctx,{
type: 'line',
data: {
datasets:[ {
data: [
{ x: '2017-01-06', y: 50 },
{ x: '2017-01-15', y: 45 },
{ x: '2017-03-07', y: 35 },
]
} ]
},
options: {
scales: {
xAxes: [ { type: 'time', } ]
}
}
});
};
</script>
</body>
</html>
When including the latest 3.4.0 chart.js the time axis is not correctly formatted (the datapoints are evenly distributed on the x-axis). However when using the 2.9.3 version, it is displayed correctly (datapoints are not evenly distributed).
Fiddle not working (using 3.4.0): https://jsfiddle.net/ungoq8j6/1/
Fiddle working (using 2.9.3): https://jsfiddle.net/ungoq8j6/2/
According to the docs (which are completly vague about that topic) you have to include a date library and an adapter (here moment.js + chartjs-adapter-moment).
The script is used only on the client side, so no node.js/npm is available.

Your config is wrong, in v3 the way you have to define scales have changed, please read the migration guide: https://www.chartjs.org/docs/master/getting-started/v3-migration.html#scales
Working example:
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
</head>
<body>
<canvas id="chart" width="800" height="400"></canvas>
<script type="text/javascript">
window.onload = function() {
var ctx = document.getElementById('chart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
data: [{
x: '2017-01-06',
y: 50
},
{
x: '2017-01-15',
y: 45
},
{
x: '2017-03-07',
y: 35
},
]
}]
},
options: {
scales: {
x: {
type: 'time',
}
}
}
});
};
</script>
</body>
</html>

Related

ChartJs: Chart not display in VF page

I'm using Chart.Js to draw a scatter chart in VF page but in the preview, the chart is not displayed. Not getting any errors but the chart is not displayed. Below is my VF page code.Appreciate your help
<apex:page showHeader="true" sidebar="false" id="page" docType="html-5.0">
<html>
<head>
<meta charset="utf-8"/>
<title>Chart.js demo</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js" type="text/javascript"></script>
</head>
<body>
<h1>Chart.js Sample</h1>
<canvas id="myChart" width="600" height="400"></canvas>
<script>
var ctx= document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
type: 'scatter',
data: {
datasets: [{
label: 'Scatter Dataset',
backgroundColor: 'green',
data: [{
x: -10,
y: 0
}, {
x: 0,
y: 10
}, {
x: 10,
y: 5
}]
}]
},
options: {
scales: {
x: {
type: 'linear',
position: 'bottom'
}
}
}
});
</script>
</body>
</html>
</apex:page>
you are using a very old version of chart.js (as a matter of fact, the first ever released).
You could solve this by replacing:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js" type="text/javascript"></script>
with
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
Fixed versions can also be found, e.g. here.
working codepen

How to do automatic pan with Chart.js

I'm using chart.js to plot data in real time. Currently, as new data points come in and are drawn, the old ones remain which increases the amount of points chart.js has to plot every iteration. I'd like to have a maximum number of visible points, say 20 and after 20 points are on the graph, to pan every iteration. I'm using the zoom and pan plugin. Here's my code right now
if (ticks > 20) {
flukeChart.pan({x: 1, y: 0}, 'active');
flukeChart.update();
}
ticks is an integer that get's incremented every time new data comes in.
Another thing to note, the X axis is timestamps. I'm using the timestamp from the incoming data source and not calculating the current time in JS. I have a feeling the delta in the .pan method shouldn't be 1 because the x axis isn't integers but timestamps.
You can get the pixel for the values of the timestamps. If you then subtract the first and second visable ones you can pan the chart with that amount of pixels.
const options = {
type: 'line',
data: {
datasets: [{
label: '# of Votes',
data: [],
borderColor: 'pink'
}]
},
options: {
scales: {
x: {
type: 'time'
}
},
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
let dataPointsCounter = -1;
const interVal = setInterval(() => {
chart.data.datasets[0].data.push({
x: new Date(),
y: Math.random()
});
dataPointsCounter++;
if (dataPointsCounter > 20) {
const diff = chart.scales.x.getPixelForValue(chart.data.datasets[0].data[dataPointsCounter - 21].x) - chart.scales.x.getPixelForValue(chart.data.datasets[0].data[dataPointsCounter - 20].x)
chart.pan({
x: diff
}, undefined, 'default');
}
chart.update();
}, 500)
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdn.jsdelivr.net/npm/hammerjs#2.0.8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.1.1/chartjs-plugin-zoom.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
</body>
Edit:
It is not exactly what you want but you can also use the streaming plugin that handles scolling and updating for you:
const options = {
type: 'line',
data: {
datasets: [{
label: '# of Votes',
data: [],
borderColor: 'pink'
}]
},
options: {
scales: {
x: {
type: 'realtime',
realtime: {
duration: 7500,
refresh: 1000,
delay: 2000,
onRefresh: (chart) => {
chart.data.datasets[0].data.push({
x: new Date(),
y: Math.random()
})
}
}
}
},
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdn.jsdelivr.net/npm/hammerjs#2.0.8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.1.1/chartjs-plugin-zoom.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming#2.0.0"></script>
</body>

How to set correct hourly ticks of time-scale X-axis on chart.js

I have a problem with chart.js (2.8.0). Probably I am doing something wrong, but can't find myself.
I want to set hourly ticks on time scale X-axis and set the time as
unit: 'hour',
displayFormats: { hour: 'HH:MM'}
I expected to have x-axis ticks such as 18:00, 19:00, 20:00, ...
However what I got is 18:01, 19:01, 20:01, ...
How can I correct and remove this extra one minute?
My html file is as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/moment#2.24.0/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0/dist/Chart.min.js"></script>
</head>
<body>
<div id="canvas-container" style="width: 400px">
<canvas id="myCanvas" width="400" height="400"></canvas>
</div>
<script src="script.js"></script>
</body>
</html>
and script.js is as follows:
var ctx = document.getElementById('myCanvas').getContext('2d');
var myData = {
type: 'line',
data: {
datasets: [{
data: [
{x:'2019-01-01 18:20', y:20},
{x:'2019-01-01 19:50', y:45},
{x:'2019-01-01 21:15', y:25},
{x:'2019-01-01 21:45', y:30}
]
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
position: 'bottom',
time: {
unit: 'hour',
displayFormats: {
hour: 'HH:MM'
},
min: '2019-01-01 18:00',
max: '2019-01-01 22:00'
},
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
};
var myChart = new Chart(ctx, myData);

Chart.js tooltip not showing on line chart

I'm at a loss as to why my chart's tooltips aren't displaying... can anybody show me what I'm doing wrong?
The tooltips work fine if I set the chart type to "bar" but for some reason don't work with "line". I'm relatively new to chart.js and am probably making some basic newbie mistake?
Here's my current code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script>
</head>
<body onLoad="ready()">
<canvas id="myChart" width="250" height="150"></canvas>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels:[],
datasets: [{
label: 'Applicants',
data: [],//start empty
backgroundColor: [
'rgba(10, 168, 196, 0.2)'
],
borderColor: [
'rgba(10, 168, 196, 1)'
],
}]
},
options: {
tooltips: {
enabled: true
},
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
// time: {
// unit: 'day'
// }
}],
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
onClick: handleClick
}
});
window.onmessage = function(event){
myChart.data.datasets[0].data = event.data.data;
myChart.data.labels = event.data.labels;
myChart.update();
};
function handleClick(e){
var activeBars = myChart.getElementAtEvent(e);
var value = myChart.config.data.datasets[activeBars[0]._datasetIndex].data[activeBars[0]._index];
var label = activeBars[0]._model.label;
window.parent.postMessage({
"type":"click",
"label":label,
"value":value
} , "*");
}
function ready(){
window.parent.postMessage({"type":"ready"}, "*");
}
</script>
</body>
</html>
For anyone having problems with this using Chartjs v3, you need to make sure you have registered the Tooltip plugin:
import { Chart, Tooltip } from 'chart.js'
Chart.register([Tooltip])

Creating charts from input data in html tables?

I found many plugins based on jquery and javascript which generate charts from the tables but all the table values are hard-coded. But my table values are inputs from the user and I need to generate the charts on the fly. Any idea how I can do this?
Currently I am using canvasjs.
<!DOCTYPE HTML>
<html>
<head>
<title>My Chart</title>
<script src="https://code.jquery.com/jquery-1.11.1.min.js" integrity="sha256-VAvG3sHdS5LqTT+5A/aeq/bZGa/Uj04xKxY8KM/w9EE=" crossorigin="anonymous"></script>
<script type="text/javascript" src="jquery.canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function hello() {
//Better to construct options first and then pass it as a parameter
var options = {
title: {
text: "My Chart"
},
animationEnabled: true,
data: [
{
type: "column", //change it to line, area, bar, pie, etc
dataPoints: [
{ x:25, y: 10 },
{ x: 20, y: 11 },
{ x: 30, y: 14 },
{ x: 40, y: 16 },
{ x: 50, y: 19 },
{ x: 60, y: 15 },
{ x: 70, y: 12 },
{ x: 80, y: 10 }
]
}
]
};
$("#chartContainer").CanvasJSChart(options);
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
</body>
</html>
Then I tried using document.getElementById() to get the variable value from the input and assigning it to the variable in the hello() function. But it is giving the error.
HELP!! :-)
you can try with
Jquery
var test = $('#inputValue').val()
javascript
var test = document.getElementById("inputValue").value;
or you can show me the error for try to help
Prathamesh,
You can use document.getElementById("inputValue").value and document.getElementById("buttonID").onclick if you like to add dataPoint on-click of button. Or document.getElementById("inputValue").onchangeif you like to add on change of value.
Check this example where values are added on click of button.

Categories

Resources