Basically I have chartJS based line chart, with two lines. X axis has dates, and Y axes has price.
There is two lines (one for average price and one for minimum price).
So I was wondering, if it is at all possible to so that lets say I hover over a point for minimum price, the average price point's label pops up as well, and vice versa.
Or if that is not possible, maybe it is possible to make it so each label contains both values (the min and average price for that particular day).
Here is the code, I have so far:
var ctx = document.getElementById('price-history').getContext('2d');
ctx.height = 150;
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: <?= json_encode($priceChangeData['labels']); ?>,
datasets: [
{
label: 'Minimali kaina',
backgroundColor: 'rgb(64, 127, 178)',
borderColor: 'rgb(64, 127, 178)',
borderWidth: 1,
data: <?= json_encode($priceChangeData['line']['price_min']); ?>,
fill: false
},
{
label: 'Vidutinė kaina',
backgroundColor: '#686868',
borderColor: '#686868',
borderWidth: 1,
data: <?= json_encode($priceChangeData['line']['price_avg']); ?>,
fill: false
}
],
},
options: {
responsive: true,
layout: {
padding: {
left: 20,
right: 15
}
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: false,
labelString: 'Data'
}
}],
yAxes: [{
display: true,
stacked: false,
scaleLabel: {
display: false,
labelString: 'Kaina'
}
}]
}
}
});
I am assuming you are talking about the tooltip's label. In that case, you can set tooltips mode to index in your chart's options config, like so :
options: {
tooltips: {
mode: 'index'
},
...
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
var ctx = document.getElementById('price-history').getContext('2d');
ctx.height = 150;
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], //<?= json_encode($priceChangeData['labels']); ?>,
datasets: [{
label: 'Minimali kaina',
backgroundColor: 'rgb(64, 127, 178)',
borderColor: 'rgb(64, 127, 178)',
borderWidth: 1,
data: [3, 1, 4, 2, 5], //<?= json_encode($priceChangeData['line']['price_min']); ?>,
fill: false
}, {
label: 'Vidutinė kaina',
backgroundColor: '#686868',
borderColor: '#686868',
borderWidth: 1,
data: [2, 4, 1, 5, 3], //<?= json_encode($priceChangeData['line']['price_avg']); ?>,
fill: false
}],
},
options: {
responsive: true,
tooltips: {
mode: 'index'
},
layout: {
padding: {
left: 20,
right: 15
}
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: false,
labelString: 'Data'
}
}],
yAxes: [{
display: true,
stacked: false,
scaleLabel: {
display: false,
labelString: 'Kaina'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script>
<canvas id="price-history"></canvas>
Related
I'm graphing some stocks data and I wanted to put the volume in a smaller gray bar dataset at the bottom, like in Yahoo Finance.
What I want:
The small grey dataset is at the bottom.
What I get:
Three different Y scales and the size of the volume dataset is the same a the other.
My code:
When I create the chart:
new Chart(context, {
type: 'line',
data: {
labels: timestamps.map(n =>
(new Date(n * 1000)).toLocaleString()
),
datasets: [
dataset,
vdataset
]
},
options: {
maintainAspectRatio: false,
scales: {
xAxis: {
// type: 'time'
ticks: {
//autoSkip: true,
maxTicksLimit: 10
}
},
yAxes: [{
id: 'volume',
display: false
}],
y: {
beginAtZero: false
},
},
animation: {
duration: 0
},
plugins: {
autocolors: false,
annotation: {
annotations
}
},
tooltips: {
mode: 'nearest'
},
hover: {
intersect: false
}
}
});
The volume dataset:
{
type: 'bar',
label: `Volume`,
data: ...,
backgroundColor: 'transparent',
borderColor: 'grey',
fill: 'origin',
pointRadius: 0,
borderWidth: 2,
yAxisID: 'volume'
}
you need to give every dataset a yAxisID and then you should name your axis with that id like this:
Data:
var data = {
labels: labels,
datasets: [{
label: 'My First Dataset',
data: generateTestSeries(),
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1,
yAxisID: "something",
},
{
label: 'My Second Dataset',
data: generateTestSeries(),
fill: false,
borderColor: 'rgb(182, 50, 192)',
tension: 0.1,
yAxisID: "volume",
},
]
};
Scales:
scales: {
volume: {
axis: "y",
min: -80,
max: 60,
position: 'right',
},
something: {
axis: "y",
min: -20,
max: 70,
position: 'left',
}
}
Also you shouldn't have the list yAxes, that was how axes were defined in chartjs 2.x
Here is a fiddle to see this in use: JSFiddle
edit: If you want an invisible axis just set display to false as seen in the now updated Fiddle.
in chart.js I'd like to have 2 charts (one under another) with ticks syncronized. Currently it looks so
as you can see dates are not aligned. Setting equal min-max values is impossible here since values are too different.
I think the solution would be to set equal width to both y-axes. The case is complicated by the second y-axes in upper chart, but may be it's possible to place an empty right scale on the bottom chart?
My current options for the top chart are
options: {
tooltips: {
enabled: true,
trigger: 'axis',
intersect: false,
mode : 'index'
},
responsive: true,
maintainAspectRatio: false,
layout: {
padding: {
// left: 500,
right: 0,
top: 0,
bottom: 0,
},
},
scales: {
xAxes: [
{
boundaryGap : false,
gridLines: {
display: false,
},
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return value.split('.').slice(0,2).join('.');
}
},
},
],
yAxes: [
{
id: keys[0],
position: "left",
gridLines: {
drawBorder: false,
zeroLineColor: "rgba(147, 147, 147, 0.2)",
color: "rgba(147, 147, 147, 0.2)",
},
ticks: {
padding: 20,
fontColor: "#2C71C3",
beginAtZero: false,
},
}, {
id: keys[1],
position: "right",
gridLines: {
drawBorder: false,
color: "rgba(147, 147, 147, 0)",
},
ticks: {
padding: 20,
fontColor: "#C6C6C6",
beginAtZero: false,
},
},
],
},
and for the bottom one
options: {
tooltips: {
enabled: true,
trigger: 'axis',
intersect: false,
mode : 'index'
},
responsive: true,
maintainAspectRatio: false,
layout: {
padding: {
// left: 500,
right: 0,
top: 0,
bottom: 0,
},
},
scales: {
yAxes: [
{
ticks: {
reverse: true,
},
},
],
xAxes: [
{
gridLines: {
display: false,
},
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return value.split('.').slice(0,2).join('.');
}
},
},
],
},
I dont know how to or if it is even possible to define a width for a scale, but what you can do is add a second Y axis on the right with the grid dissabled and the callback returning a few spaces for spacing
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
position: 'left'
},
{
position: 'right',
gridLines: {
display: false
},
ticks: {
callback: () => (' ')
}
}
]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
Little late to the party, but it is possible to set a fixed width. I updated #LeeLenalee snippet with an example (both y axis have a 100px width in this case). This way, it is possible to align both graphs without any problem. Make sure to set a width that isn't too small for the labels though!
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
position: 'left',
afterFit: (scaleInstance) => scaleInstance.width = 100,
},
{
position: 'right',
afterFit: (scaleInstance) => scaleInstance.width = 100,
gridLines: {
display: false
},
ticks: {
callback: () => ''
}
}
]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
i have a problem when i want to assign output into array string i already use str repace, etc but still not working..
i have output like this (in time)
$grapDate output = 09:00:0001:00:0012:00:0011:00:0010:00:0001:00:0000:00:0023:00:0022:00:00
date('H:i', strtotime($graph['Date'])
and the output become = 09:0001:0012:0011:0010:0001:0000:0023:0022:00
but i want to assign that become e.g $date = ['09:00','01:00', '12:00', etc]
because i want to use graph chart like this in my body
script type="text/javascript">
var ctx = document.getElementById('myChart2').getContext('2d');
var myChart2 = new Chart(ctx, {
type: 'line',
data: {
labels: ['$label'], //Jamnya
datasets: [{
backgroundColor: 'rgba(232,72,163,0.2)',
borderColor: '#e848a3',
label: '29 May 2020',
data: [807,657,600,578,565,576,611,855,625,573,571,584,607,647,771,943,920,647,622,608,722,832,902,1062],
fill: true,
pointRadius: 5,
pointHoverRadius: 10,
showLine: true
}]
}, options: {
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: 'Total Online Yesterday',
position: 'top',
fontSize: 15,
fontStyle: 'bold'
},
legend: {
display: false
},
elements: {
point: {
pointStyle: 'circle'
}
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'TIME'
},
ticks: {
major: {
fontStyle: 'bold',
fontColor: '#FF0000'
}
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'TOTAL ONLINE'
}
}]
},
tooltips:{
callbacks: {
title: function(tooltipItem, data) {
return '29 May 2020 '+data['labels'][tooltipItem[0]['index']];
},
label: function(tooltipItem, data) {
return 'TOTAL : '+data['datasets'][0]['data'][tooltipItem['index']]+'';
},
},
titleFontSize: 15,
bodyFontSize: 15,
displayColors: false
}
}
});
</script>
i still thinking how to assign parameter labels in class Chart become ['value', 'value', 'value']
First make each separate & print in JSON format.
$str = "09:0001:0012:0011:0010:0001:0000:0023:0022:00";
$date = json_encode(str_split($str, 5));
I am using a chart and I am using type: 'logarithmic', passing the max value like this:
max: scalesMax.toFixed(2),
But that gives me 8e+2
How can I fix it?
I'm using chart.js
This how I get my values for each charts, I have one chart next to the other to compare each values form 2 datasets
var scalesMaxTotalCasesTrend = Math.max(...customConfirmed);
var scalesMaxTotalPositiveTrend = Math.max(...totPositivi);
var scalesMaxIsolationTrend = Math.max(...totIsolamento);
var scalesMaxHospitalizationTrend = Math.max(...totRicoverati);
var scalesMaxHospitalizationWithSymptomsTrend = Math.max(...totRicoveratiConSintomi);
var scalesMaxIntensiveCareTrend = Math.max(...totTerapiaIntensiva);
function setConfigurationGraph(dataGraphType, labels, data, scalesMax) {
configAllDateGraph.push({
dataGraphType: dataGraphType,
type: 'line',
data: {
labels: labels,
datasets: [{
fill: true,
backgroundColor: "rgba(250, 250, 250, 1)",
data: data,
borderColor: "#fafafa",
borderDash: [5, 5],
backgroundColor: "#fafafa",
pointBackgroundColor: "#fafafa",
pointBorderColor: "#fafafa",
pointHoverBackgroundColor: "#fafafa",
pointHoverBorderColor: "#fafafa"
}]
},
options: {
responsive: true,
title: {
display: true
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
gridLines: {
color: "#fafafa"
},
ticks: {
fontColor: "#fafafa"
}
}],
yAxes: [{
display: true,
type: 'logarithmic',
gridLines: {
color: "#fafafa"
},
ticks: {
fontColor: "#fafafa",
beginAtZero: true,
max: scalesMax.toFixed(2),
min: 0
}
}]
},
legend: {
display: false
}
}
});
}
This automatically happens in JS i believe.
You can use toFixed() max limit of 20;
Have you tried this
max: scalesMax.toFixed(20)
I'm using Chart.js to create the following chart:
The issue is that I want to make the scale at the bottom only show 0 and the maximum number (here being 12).
JavaScript:
<script>
new Chart(document.getElementById("leads-bar"), {
type: 'horizontalBar',
data: {
labels: ["Hot", "Warm", "Cold"],
datasets: [
{
backgroundColor: ["#d23232", "#ff9347", "#bbbbbb"],
data: [7, 9, 11]
}
]
},
options: {
legend: {
display: false
},
tooltips: {
display: false
},
title: {
display: false
},
scales: {
xAxes: [{
stacked: true,
gridLines: {
display: false,
drawBorder: false,
},
scaleShowLabels: false,
}],
yAxes: [{
stacked: false,
gridLines: {
color: ["#eeeeee"]
}
}]
}
}
});
var dataArr = [154.23, 203.21, 429.01, 637.41];
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: [154.23, 203.21, 429.01, 637.41],
datasets: [{
label: 'LINE',
data: dataArr,
backgroundColor: 'rgba(0, 119, 290, 0.2)',
borderColor: 'rgba(0, 119, 290, 0.6)',
fill: false,
tension: 0
}]
},
options: {
scales: {
xAxes: [{
ticks: {
min: Math.min.apply(this, dataArr),
max: Math.max.apply(this, dataArr),
callback: function(value, index, values) {
if (index === values.length - 1) return Math.min.apply(this, dataArr);
else if (index === 0) return Math.max.apply(this, dataArr);
else return '';
}
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>