Has anyone got an example of how to zoom a Y axis on a time series graph built with chartjs? Does anyone know if it's even possible?
I've been using chartjs-plugin-zoom. I've spent hours experimenting, searching for solutions and looking at the chartjs-plugin-zoom source.
Examples I've so far found show bar charts being zoomed, not a time series or X-Y charts.
I've implemented a hacky Y-axis zoom for now by setting the min and max of the Y scale. This works to a degree, but by doing this, you lose the ability to pan and see any data outside of the chart. And anyway, having to do this seems a bodge.
Grateful for an example of a working X-Y zoomable chart.
Answered my own question eventually. Basically, the example at https://codepen.io/anon/pen/PGabEK (linked from https://npmjs.com/package/chartjs-plugin-zoom) can be re-done as a time series.
Example HTML below.
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{
data: [
{ t: '2018-03-29 08:48', y: 20.2 },
{ t: '2018-03-29 16:24', y: 23.1 },
{ t: '2018-04-09 18:24', y: 20.7 },
{ t: '2018-04-10 02:10', y: 24.2 },
{ t: '2018-04-10 09:16', y: 24.2 }
],
type: 'line',
radius: 1,
hitRadius: 3,
fill: false,
backgroundColor: 'black',
borderWidth: 2,
label: 'Some label'
},
{
data: [
{ t: '2018-03-29 08:48', y: 22.5 },
{ t: '2018-03-29 16:24', y: 22.3 },
{ t: '2018-03-30 00:00', y: 21.5 },
{ t: '2018-03-30 07:36', y: 21.5 },
{ t: '2018-03-30 15:12', y: 21.5 }
],
type: 'line',
radius: 1,
hitRadius: 3,
fill: false,
backgroundColor: 'black',
borderWidth: 2,
label: 'Another label'
}
]
},
options: {
pan: {
enabled: true,
mode: 'xy'
},
zoom: {
enabled: true,
mode: 'xy'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/0.6.6/chartjs-plugin-zoom.min.js"></script>
<div id="chartDiv">
<canvas class="my-4 chartjs-render-monitor" id="myChart" style="display:block;"></canvas>
</div>
I have a graph with multiple data points / lines. Currently, if you hover near a data point, it will display the label/value for that point.
What I'd like is the following: when you hover anywhere on the chart, it will display the labels + values for all data points at that x-value simultaneously in a single label.
For example, let's take the given datasets:
Date (x-labels): ['Jan 01','Jan 02','Jan 03']
Apples Sold: [3,5,1]
Oranges Sold: [0,10,2]
Gallons of Milk Sold: [5,7,4]
When you hover over the middle of the graph, above the 'Jan 02' vertical space, the label should display:
Jan 02
-----------------------
Apples Sold: 5
Oranges Sold: 10
Gallons of Milk Sold: 7
Is there a simple way to accomplish this?
Thanks.
Is there a simple way to accomplish this?
YES !! There is a quite straightforward way to accomplish this. If you would have read the documentation, you could have found that pretty easily.
Anyway, basically you need to set the tooltips mode to index in your chart options, in order to accomplish the behavior you want.
...
options: {
tooltips: {
mode: 'index'
}
}
...
Additionally, you probably want to set the following:
...
options: {
tooltips: {
mode: 'index',
intersect: false
},
hover: {
mode: 'index',
intersect: false
}
}
...
This will make it so all of the expected hover/label interactions will occur when hovering anywhere on the graph at the nearest x-value.
From the Documentation :
# 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, in the x direction, is used to
determine the index.
Here is a working example :
var ctx = document.getElementById('canvas').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan 01', 'Jan 02', 'Jan 03'],
datasets: [{
label: 'Apples Sold',
data: [3, 5, 1],
borderColor: 'rgba(255, 99, 132, 0.8)',
fill: false
}, {
label: 'Oranges Sold',
data: [0, 10, 2],
borderColor: 'rgba(255, 206, 86, 0.8)',
fill: false
}, {
label: 'Gallons of Milk Sold',
data: [5, 7, 4],
borderColor: 'rgba(54, 162, 235, 0.8)',
fill: false
}]
},
options: {
tooltips: {
mode: 'index',
intersect: false
},
hover: {
mode: 'index',
intersect: false
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="canvas"></canvas>
For Chart.js 3.3.2, you can use #baburao's approach with a few changes. You can check the documentation. Put tooltip in plugins. Example:
...
options: {
plugins: {
tooltip: {
mode: 'nearest',
intersect: false
}
}
}
...
I know this is an old post, but in a time I needed to divide a bar on multiple datasets, but the labels to be keeped as original values:
eg:
dataset 1: Totals: 10 15 10
dataset 2: Red: 4 5 9
dataset 3: Blue: 4 2 1
In my chart I want to show the "Totals" bar and to collor a part of it in red/blue or "the rest" (which is Totals color). I'll don't write the code to modify the datasets, but I'll complete #busterroni answer for chartjs v3+
plugins: {
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: (item) => item.dataset.label + ': ' +
this.originalValues[item.datasetIndex].data[item.dataIndex]
}
}
}
You can achieve this after plotting the data like this:
Html
<div class="container">
<h2>Chart.js — Line Chart Demo</h2>
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js">
</script>
CSS
.container {
width: 80%;
margin: 15px auto;
}
Javascript
var ctx = document.getElementById('myChart').getContext('2d');
function convert(str) {
var date = new Date(str),
mnth = ("0" + (date.getMonth() + 1)).slice(-2),
day = ("0" + date.getDate()).slice(-2);
return [date.getFullYear(), mnth, day].join("-");
}
var date = ["Tue Jun 25 2019 00:00:00 GMT+0530 (India Standard Time)"];
var y1 = [12];
var y2 = [32];
var y3 = [7];
var dataPoints1 = [], dataPoints2 = [], dataPoints3 = [], datep=[];
console.log(date.length)
if(date.length=="1"){
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["",convert(date[0]),""],
datasets: [{
label:"Tweets",
backgroundColor: "rgba(153,255,51,0.4)",
fill:false,
borderColor:"rgba(153,255,51,0.4)",
data: [null,y1[0],null]
}, {
label:"Retweets",
backgroundColor: "rgba(255,153,0,0.4)",
fill:false,
borderColor:"rgba(255,153,0,0.4)",
data: [null,y2[0],null]
},{
label:"Favourites",
backgroundColor: "rgba(197, 239, 247, 1)",
fill:false,
borderColor:"rgba(197, 239, 247, 1)",
data:[null,y3[0],null]
}
]
},
options: {
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
ticks: {
display: true
},
gridLines: {
display: false,
// drawBorder: false //maybe set this as well
}
}]
},
}
});}
else{
for (var i = 0; i < date.length; i++) {
datep.push(convert(date[i]))
dataPoints1.push(y1[i]);
dataPoints2.push(y2[i]);
dataPoints3.push(y3[i]);
}
console.log(datep)
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: datep,
datasets: [{
label:"Tweets",
backgroundColor: "rgba(153,255,51,0.4)",
fill:false,
borderColor:"rgba(153,255,51,0.4)",
data: dataPoints1
}, {
label:"Retweets",
backgroundColor: "rgba(255,153,0,0.4)",
fill:false,
borderColor:"rgba(255,153,0,0.4)",
data: dataPoints2
},{
label:"Favourites",
backgroundColor: "rgba(197, 239, 247, 1)",
fill:false,
borderColor:"rgba(197, 239, 247, 1)",
data:dataPoints3
}
]
},
options: {
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
ticks: {
display: true
},
gridLines: {
display: false,
// drawBorder: false //maybe set this as well
}
}]
},
}
});
}
or chk this fiddle https://jsfiddle.net/gqozfb4L/
You could try using JavaScript to track the users mouse and based on the position, return the data at that vertice.
document.querySelector('.button').onmousemove = (e) => {
const x = e.pageX - e.target.offsetLeft
const y = e.pageY - e.target.offsetTop
e.target.style.setProperty('--x', `${ x }px`)
e.target.style.setProperty('--y', `${ y }px`)
}
I saw your post regarding,
Instead of just "Stock" at the left, is there anyway to put a separate label for each bar, eg 18, 82, 22, 80 going down the y-axis?
Below is the link which I'm referring ...
ChartJS bar chart with legend which corresponds to each bar
You are looking for something like the following:
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: [18, 82, 22, 80],
datasets: [{
data: [1, 2, 3, 4],
backgroundColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff'],
borderColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff']
}]
},
options: {
scales: {
xAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
labels: {
generateLabels: function(chart) {
var labels = chart.data.labels;
var dataset = chart.data.datasets[0];
var legend = labels.map(function(label, index) {
return {
datasetIndex: 0,
text: label,
fillStyle: dataset.backgroundColor[index],
strokeStyle: dataset.borderColor[index],
lineWidth: 1
}
});
return legend;
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>
My last column does not show, I use chart.js 2.5,the framework is used laravel 5.4,the data has been confirmed into the incoming.
Look at this figure:
data has been into the incoming :
var ctxBar = $('#barChart');
var data2 = {
labels: {!!json_encode($project_names, JSON_UNESCAPED_UNICODE) !! },
datasets: [{
backgroundColor: [
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)'
],
borderWidth: 2,
data: {!!json_encode(TasksCountArray($projects), JSON_UNESCAPED_UNICODE) !! }
}]
};
var myBarChart = new Chart(ctxBar, {
type: 'bar',
data: data2,
options: {
responsive: true,
title: {
display: true,
text: 'Projects Tasks'
},
legend: {
display: false
},
fullWidth: true
}
});
I'm in need of some help. I'm using chart.js graphics, with the "doughnut" model. I need the values to be printed on the chart, both the absolute value and its percentage in relation to the amount (as shown in the model below).
Please could someone help
var ctx = document.getElementById("tempoGastoNaLoja");
var myDoughnutChart2 = new Chart(ctx, {
type: 'doughnut',
data: {
labels: [
"10min",
"30min",
"45min",
"1h",
"1h30",
"2h+"
],
datasets: [
{
data: [80, 42, 38, 21, 15, 18],
backgroundColor: [
"#ffd833",
"#f4b12d",
"#e88b28",
"#dd6422",
"#d13e1d",
"#c61717"
],
hoverBackgroundColor: [
"#ffd833",
"#f4b12d",
"#e88b28",
"#dd6422",
"#d13e1d",
"#c61717"
]
}],
options: {
responsive: true,
maintainAspectRatio: false,
}
}
});