working on a Chart.JS line chart. Renders fine, tooltips are fine, but when I hover over a line (not the chart as a whole, just a line) I get
Chart.js:1647 Uncaught TypeError: this.setValues is not a function
at new Color (Chart.js:1647)
at Color (Chart.js:1629)
at Object.helpers$1.color (Chart.js:10902)
at helpers$1.getHoverColor (Chart.js:10909)
at ChartElement.setHoverStyle (Chart.js:6137)
at Chart.updateHoverStyle (Chart.js:10143)
at Chart.handleEvent (Chart.js:10241)
at Chart.eventHandler (Chart.js:10167)
at listener (Chart.js:10100)
at HTMLCanvasElement.proxies.<computed> (Chart.js:7830)
This is using the lib inside a React functional component with import {Chart} from 'chart.js' and rendering in a hook, so:
useEffect(() => {
lineChart = new Chart(canvasRef.current, {
type: 'line',
options: {
title: {
display: true,
text: props.unitCode,
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
maintainAspectRatio: false,
scales: {
xAxes: [
{
scaleLabel: {
display: true,
labelString: 'Time'
},
type: 'time',
distribution: 'linear',
}
],
yAxes: [
{
scaleLabel: {
display: true,
labelString: 'Mw'
}
}
]
}
},
data: {
datasets: [
{
label: 'PN Mw',
data: series[MetricType.Pn],
borderColor: 'rgb(0, 0, 0)',
fill: 'rgb(0, 0, 0)',
backgroundColor: 'rgb(0, 0, 0)',
pointRadius: 0,
borderWidth: 1,
lineTension: 1,
showLine: true,
},
{
label: 'MEL Mw',
data: series[MetricType.Mel],
borderColor: 'rgb(255, 0, 0)',
fill: 'rgb(255, 0, 0)',
backgroundColor: 'rgb(255, 0, 0)',
pointRadius: 0,
borderWidth: 2,
lineTension: 1,
showLine: true
},
{
label: 'Mil Mw',
data: series[MetricType.Mil],
borderColor: 'rgb(0, 0, 255)',
fill: 'rgb(0, 0, 255)',
backgroundColor: 'rgb(0, 0, 255)',
pointRadius: 0,
borderWidth: 2,
lineTension: 1,
showLine: true
}
]
}
});
})
The latest version of ChartJS, React, Chrome. Also happens in Firefox, so not browser-specific.
Ideas welcome :-)
Thanks
Related
My chart has 100 labels. These labels are from 0 to 10. Some labels are decimal. But i just want to see integers on my chart. How can i hide decimals? You can check my picture and code below.
chart
var timeLabels = [];
for (let j = 0; j <= scheduling.totalPeriod; j++) {
timeLabels.push(j / 10);
}
var schedulingChart = new Chart(ctx, {
type: 'line',
data: {
labels: timeLabels,
datasets: [{
steppedLine: true,
label: scheduling.process[i].name,
data: scheduling.process[i].chart,
backgroundColor: ['rgba(255, 255, 255, 0.5)'],
borderColor: ['rgba(255, 255, 255, 1)'],
borderWidth: 1,
pointBackgroundColor: 'green',
pointBorderColor: 'black',
pointRadius: 4
}]
},
options: {
maintainAspectRatio: false,
scales: {
yAxes: [{
gridLines: {
color: 'rgba(0, 0, 0, 0.5)',
},
ticks: {
stepSize: 1,
fontColor: 'rgba(255, 255, 255, 1)'
}
}],
xAxes: [{
gridLines: {
color: 'rgba(0, 0, 0, 0.5)',
},
ticks: {
fontColor: 'white',
}
}]
}
}
});
New for other problem
I have a very simple (horizontal) bar chart using Chart.js latest version.
https://codepen.io/decho/pen/abZYrxO
It has 3 datasets, Foo, Bar & Baz. The problem is that when I hover with the mouse over a bar (dataset), all 3 of them get highlighted instead of just the one that mouse is over at.
Current behavior:
Expected behavior:
I have tried playing with the tooltip settings, but couldn't quite figure it out. So any idea on how can I achieve this?
Here is my current Chart configuration, also on Codepen:
const ctx = document.getElementById('canvas').getContext('2d');
new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['Test'],
datasets: [
{
label: 'Foo',
data: [1],
backgroundColor: 'rgba(23, 83, 139, 0.5)',
borderColor: '#17538b',
borderWidth: 2,
hoverBackgroundColor: "#17538b",
hoverBorderColor: "#4444442b",
},
{
label: 'Bar',
data: [2],
backgroundColor: 'rgba(255, 85, 33, 0.5)',
borderColor: '#ff5521',
borderWidth: 2,
hoverBackgroundColor: "#ff5521",
hoverBorderColor: "#4444442b",
},
{
label: 'Baz',
data: [3],
backgroundColor: 'rgba(62, 211, 241, 0.5)',
borderColor: '#3ed3f1',
borderWidth: 2,
hoverBackgroundColor: "#3ed3f1",
hoverBorderColor: "#4444442b",
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'bottom',
},
tooltips: {
mode: 'dataset',
intersect: true
},
scales: {
xAxes: [
{
display: true,
ticks: {
beginAtZero: true,
},
},
],
yAxes: [{
display: false,
ticks: {
beginAtZero: true,
},
}],
}
},
});
Any help is kindly appreciated.
Solved this myself: Apparently there is a a global option for hover modes:
options: {
hover: {
mode: 'dataset',
}
}
If anyone wonders as me, how this could be done for chart of type: 'line', just add these options:
options: {
elements: {
point: {
hitRadius: 1,
}
},
tooltips: {
mode: 'single',
},
hover: {
mode: 'dataset',
intersect: false
}
}
and also don´t forget to add colors for highlighting (for each dataset obviously):
datasets: [
{
label: "A",
data: [12, 19, 3, 5, 2, 3],
borderWidth: 3,
borderColor: '#ec5e5f',
hoverBorderColor: '#e41a1c',
pointHoverBackgroundColor: "#fff",
lineTension: 0.5,
}
]
For full example check out this codepen
Here is an example of one run of my chart:
Chart configuration:
At the moment I just set a maximum tick value, i.e. max: 100000000. I figure I need to pass some function that adjusts the maximum value whenever the largest exceeds the largest value of the y axis. How can this be done?
_chart.chart_3.config = {
type: 'line',
data: {
labels: ['Harvest 1', 'Harvest 2', 'Harvest 3', 'Harvest 4','Harvest 5'],
datasets: [{
lineTension: 0,
label: 'Bill',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(54, 162, 235)",
borderColor: "rgb(54, 162, 235)",
},
{
lineTension: 0,
label: 'Ann',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(255, 99, 132)",
borderColor: "rgb(255, 99, 132)",
},
{
lineTension: 0,
label: 'Bill (Sharing)',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(4, 0, 255)",
borderColor: "rgb(4, 0, 255)",
},
{
lineTension: 0,
label: 'Ann (Sharing)',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(255, 0, 0)",
borderColor: "rgb(255, 0, 0)",
},
{
lineTension: 0,
label: 'Pool',
data: [],
fill: false,
fillColor : "rgba(0, 0, 0, 1)",
strokeColor : "rgba(0, 0, 0, 1)",
backgroundColor: "rgb(128,36,171)",
borderColor: "rgb(128,36,171)",
}]
},
options: {
responsive: true,
title: {
display: true,
text: ''
},
tooltips: {
enabled: false,
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'KG',
},
type: 'logarithmic',
position: 'left',
ticks: {
min: 0, //minimum tick
max: newMax(value), //maximum tick
callback: function (value, index, values) {
return Number(value.toString()); //pass tick values as a string into Number function
}
}
}]
}
}
};
New max function:
newMax = function(values) {
max = Math.max(values)
max = max * 1.2
return Number(max.toString())
}
I'm not sure what your data looks like, but I'm assuming it's an array of values with numbers, all you'd need to do is find the max number than add a little buffer on the end to keep the graph looking pretty, so the max number it goes to, then add a little on the end.
function getMax(arr) {
const max = Math.max(...arr).toString();
const newMax = 1 + "0".repeat(max.length);
return newMax
}
max: getMax(values)
I'm using http://www.chartjs.org/ library for charts where I try to display 6 different data points on Y axis.
It's a bit mess when everything is displayed at the same time, but I do not want to split it into multiple charts as all these data correlate.
I wonder if it's possible to set which data should be hidden when the chart loads and then I could show the remaining ones myself.
Also is it possible to save these settings somehow? Let's say I want to display only 3 types of data and after I reload the page it would remember my preference.
EDIT: Here is the current code if it helps..
<canvas id="statsByDayChart" width="400" height="300"></canvas>
<script>
var ctx = document.getElementById('statsByDayChart').getContext('2d');
var profit = {
label: "Profit",
data: {!! json_encode($profit) !!},
borderColor: 'rgba(73, 189, 138, 1)',
borderWidth: 3,
backgroundColor: 'rgba(219, 242, 232, 0)',
pointBorderWidth: 4,
pointBackgroundColor: '#128ffb',
yAxisID: 'y-axis-profit',
type: 'line'
};
var cost = {
label: "Cost",
data: {!! json_encode($cost) !!},
borderColor: 'rgba(255, 0, 0, 1)',
borderWidth: 2,
backgroundColor: 'rgba(255, 0, 0, 0)',
pointBorderWidth: 4,
pointBackgroundColor: '#128ffb',
yAxisID: 'y-axis-cost',
type: 'line'
};
var ctr = {
label: "CTR",
data: {!! json_encode($ctr) !!},
borderColor: 'rgba(255, 126, 0, 1)',
borderWidth: 3,
backgroundColor: 'rgba(255, 126, 0, 0)',
pointBorderWidth: 4,
pointBackgroundColor: '#128ffb',
yAxisID: 'y-axis-ctr',
type: 'line'
};
var holds = {
label: "Holds",
data: {!! json_encode($holds) !!},
borderColor: 'rgb(175, 26, 245, 1)',
backgroundColor: 'rgb(175, 26, 245, 1)',
borderWidth: 4,
pointBorderWidth: 4,
pointBackgroundColor: '#128ffb',
yAxisID: 'y-axis-holds',
type: 'bar',
fill: true
};
var conversions = {
label: "Conversions",
data: {!! json_encode($conversions) !!},
borderColor: 'rgb(54, 162, 235, 1)',
backgroundColor: 'rgb(54, 162, 235, 1)',
borderWidth: 5,
pointBorderWidth: 4,
pointBackgroundColor: '#128ffb',
yAxisID: 'y-axis-conversions',
type: 'bar',
fill: true
};
var impressions = {
label: "Impressions",
data: {!! json_encode($displays) !!},
borderColor: 'rgba(254, 206, 96, 1)',
backgroundColor: 'rgba(255, 231, 175, 0.8)',
borderWidth: 6,
pointBorderWidth: 4,
borderDash: [20, 6],
pointBackgroundColor: '#128ffb',
yAxisID: 'y-axis-impressions',
type: 'line',
fill: true
};
var chartData = {
labels: {!! json_encode($days) !!},
datasets: [profit, cost, ctr, holds, conversions, impressions]
};
var lineChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
legend: {display: true},
responsive: true,
maintainAspectRatio: false,
elements: { line: { tension: 0.05 } },
scales: {
xAxes: [{ gridLines: { display: true, offsetGridLines: false }, barPercentage: 1, categoryPercentage: 0.4 }],
yAxes: [
{
id: 'y-axis-profit',
type: 'linear',
gridLines: { display: true },
ticks: { beginAtZero: true, min: {{ $profit->min() }}, max: {{ $profit->max() }} },
display: true
},
{
id: 'y-axis-cost',
type: 'linear',
gridLines: { display: false },
ticks: { beginAtZero: true, min: {{ $cost->min() }}, max: {{ $cost->max() }} },
display: false
},
{
id: 'y-axis-ctr',
type: 'linear',
gridLines: { display: false },
ticks: { beginAtZero: true, min: {{ $ctr->min() }}, max: {{ $ctr->max() }} },
display: false
},
{
id: 'y-axis-holds',
type: 'linear',
gridLines: { display: false },
ticks: { beginAtZero: true, min: {{ $holds->min() }}, max: {{ $holds->max() }} },
display: false,
},
{
id: 'y-axis-conversions',
type: 'linear',
gridLines: { display: false },
ticks: { beginAtZero: true, min: {{ $conversions->min() }}, max: {{ $conversions->max() }} },
display: false,
},
{
id: 'y-axis-impressions',
type: 'linear',
gridLines: { display: false },
ticks: { beginAtZero: true, min: {{ $displays->min() }}, max: {{ $displays->max() }} },
display: false
}
]
},
tooltips: { mode: 'index', intersect: false },
hover: { mode: 'nearest', intersect: true },
}
});
</script>
I'm using Chart.js for line charts and I have the legend as below.
The problem is that the legend only has an outline color, I want the legend box to have the whole thing colored. I haven't found anything in the documentation to see why mine only has the border. I'm at a bit of a loss, here's an example of my setup:
var LinuxDistributionsCombined = document.getElementById('LinuxDistributionsCombined');
var myChart = new Chart.Line(LinuxDistributionsCombined, {
type: 'line',
data: {
labels: ['Jul-2016', 'Sep-2016', 'Oct-2016', 'Dec-2016', 'Jan-2017', 'Feb-2017', 'Mar-2017', 'Apr-2017', 'May-2017', 'Jun-2017', 'Jul-2017', 'Aug-2017', 'Sep-2017', 'Oct-2017'],
datasets: [{
label: 'Ubuntu-based',
fill: true,
data: [0, 0, 0, 0, 51.37, 51.04, 50.64, 50.29, 49.6, 48.32, 47.95, 47.03, 46.42, 46.21],
borderColor: '#a6cee3',
borderWidth: 1
}, {
label: 'Arch-based',
fill: true,
data: [0, 0, 0, 0, 28.52, 28.53, 28.75, 29.02, 29.16, 30.42, 30.65, 31.29, 31.53, 31.93],
borderColor: '#1f78b4',
borderWidth: 1
}, {
label: 'Solus',
fill: true,
data: [0, 0, 0, 0, 0.42, 0.45, 0.61, 0.64, 0.92, 1.12, 1.08, 1.21, 1.23, 1.46],
borderColor: '#6a3d9a',
borderWidth: 1
}]
},
options: {
legend: {
display: true
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Percentage of users'
}
}]
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
var label = data.datasets[tooltipItem.datasetIndex].label;
return label + ' ' + value + '%';
}
},
},
}
});
You have to set the backgroundColor property for each of your datasets as well, as that is correspondent to legend box's fill color.
...
datasets: [{
label: 'Ubuntu-based',
fill: true,
data: [0, 0, 0, 0, 51.37, 51.04, 50.64, 50.29, 49.6, 48.32, 47.95, 47.03, 46.42, 46.21],
backgroundColor: '#a6cee3',
borderColor: '#a6cee3',
borderWidth: 1
}, {
label: 'Arch-based',
fill: true,
data: [0, 0, 0, 0, 28.52, 28.53, 28.75, 29.02, 29.16, 30.42, 30.65, 31.29, 31.53, 31.93],
backgroundColor: '#1f78b4',
borderColor: '#1f78b4',
borderWidth: 1
}, {
label: 'Solus',
fill: true,
data: [0, 0, 0, 0, 0.42, 0.45, 0.61, 0.64, 0.92, 1.12, 1.08, 1.21, 1.23, 1.46],
backgroundColor: '#6a3d9a',
borderColor: '#6a3d9a',
borderWidth: 1
}]
...
var ct = document.getElementById('myChart').getContext('2d');
var Chart = new Chart(ct, {
type: 'line',
data: {
datasets: [{
label: 'test',
data:[1,10],
backgroundColor: "rgb(0, 0, 0, 0)",
borderColor: "rgb(0, 0, 255)",
pointBackgroundColor: "rgb(0, 0, 255)",
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
},
yAxes: [{
scaleLabel: {
display: true,
labelString: 'test'
}
}]
}
},
plugins: [{
beforeDraw: function(c) {
var legends = c.legend.legendItems;
legends.forEach(function(e) {
e.fillStyle = 'red';
});
}
}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="myChart" width="400" height="300"></canvas>