ChartJS V3 borderRadius only works on top - chart.js

Link to jsfiddle
Why does borderRadius only work on top?
HTML
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div>
<canvas id="canvas" height="100"></canvas>
</div>
JS
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Q0", "Q1", "Q2", "Q3", "Q4"],
datasets: [{
label: 'estimate',
data: [[2, 7], [2, 10], [1, 3], [1, 4], [4, 8]],
backgroundColor: 'lightblue',
borderRadius: 10,
},
{
label: 'actual',
data: [[5, 6], [7, 8], [2, 3], [2, 3], [7, 8]],
backgroundColor: 'red',
borderRadius: 10,
}]
},
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Estimate Histoy'
}
}
});
}
;
I've been searching for a couple of days now. Found a lot of pre-V3 that are rather complex but nothing with V3. Seem rather straightforward. I did see that if the bottom is on an axis it'll not put borderRadius.
Thanks for the help.

If you want all the borders to have a borderRadius you need to specify borderSkipped: false in your dataset

Related

Legend on chart.js

I'm trying to make a legend with a perfect box, but I don't know how, the "NĂ­vel Op. Max" is not like the others,I think the reason this happens is because it's a dotted line and the others are solid lines.
Does anyone know if there is any property in chart.js that causes the square's edge to not be dotted?
My code:
legend: {
display: true,
labels: {
fontSize: 10,
boxWidth: 10
}
The way I want:
You can provide a custom generateLabels function and dont provide the setting for making the border dashed like so:
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange',
borderDash: [2, 2]
}
]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: (chart) => {
const datasets = chart.data.datasets;
const {
labels: {
usePointStyle,
pointStyle,
textAlign,
color
}
} = chart.legend.options;
return chart._getSortedDatasetMetas().map((meta) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
const borderWidth = Chart.helpers.toPadding(style.borderWidth);
return {
text: datasets[meta.index].label,
fillStyle: style.backgroundColor,
fontColor: color,
hidden: !meta.visible,
lineCap: style.borderCapStyle,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
lineWidth: (borderWidth.width + borderWidth.height) / 4,
strokeStyle: style.borderColor,
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
borderRadius: 0,
datasetIndex: meta.index
};
})
}
}
}
}
}
}
const 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/3.6.2/chart.js"></script>
</body>

Is there a way to highlight a line on a line graph with hover?

I am going to be using chart.js to build a graph like this:
It would be very useful to be able to allow the user to hover over a line on the graph and have that line highlight in some manner. How would I go about doing that with chart.js?
Thanks!
You can use the onHover callback for this in the options:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: '#FF0000',
borderColor: '#FF0000'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
backgroundColor: '#0000FF',
borderColor: '#0000FF'
},
{
label: '# of Cars',
data: [18, 4, 12, 6, 9, 2],
backgroundColor: '#FF1493',
borderColor: '#FF1493'
}
]
},
options: {
onHover: (e, activeEls, chart) => {
if (activeEls.length === 0) {
chart.data.datasets.forEach((dataset) => {
dataset.backgroundColor = dataset.backgroundColor.length === 9 ? dataset.backgroundColor.slice(0, -2) : dataset.backgroundColor;
dataset.borderColor = dataset.borderColor.length === 9 ? dataset.borderColor.slice(0, -2) : dataset.borderColor;
});
chart.update();
return;
}
const hoveredEl = chart.getElementsAtEventForMode(e, 'point', {
intersect: true
}, true)[0]
chart.data.datasets.forEach((dataset, i) => {
dataset.backgroundColor = (hoveredEl.datasetIndex === i || dataset.backgroundColor.length === 9) ? dataset.backgroundColor : dataset.backgroundColor + '4D';
dataset.borderColor = (hoveredEl.datasetIndex === i || dataset.borderColor.length === 9) ? dataset.borderColor : dataset.borderColor + '4D';
});
chart.update();
},
}
}
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/3.4.0/chart.js"></script>
</body>

ChartJS 2.9.4 can't overlay line data on Horizontal Bar chart

We have an issue where we can not overlay multiple graph types on top of each other with ChartJS 2.9.4 . We have narrowed this down specifically to HorizontalBar chart types.
I can't see what's wrong with the script code below, but the ChartJS persists in not showing anything when any line type is added. The current dual horizontalBar work perfectly.
Also frustratingly ChartJS seems to show by default to show no errors or notice information at all in any way to the console.
Solution attempts :
Lots of rearranging of layout, including ordering of data array.
Confirming all options and settings.
Putting "type" data in different areas (Chart/datasets/data)
Reading lots of Stack Overflow on vaguely related issues
Finding that the system does work with 'bar' rather than 'horizontalBar'
This question
Changing "drawing order"
Making it default to "line" and then setting HorizontalBar as the exception value (set within the data array)
Aim:
Code:
<script>
Chart.platform.disableCSSInjection = true;
var ctx = document.getElementById("historicChart");
var historicChart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: ["Mar 2017","Mar 2016","Mar 2015","Mar 2014","Mar 2013","Mar 2012","Mar 2011"],
datasets: [
{
type: "line",
label: "Visits",
data: ["3", "4", "1", "5", "6","0"],
pointBackgroundColor: '#FFC900',
pointRadius: 8,
pointStyle: 'circle',
showLine: true
},
{
label: "Applicants",
data: ["2","4","5","8","9","4","3"],
backgroundColor: "#436B94",
borderWidth: 0
},
{
label: "Intakes",
data: ["1","1","0","1","3","0","1"],
backgroundColor: "#C40500",
borderWidth: 0
}
]
},
options: {
scales: {
xAxes: [{
stacked: false,
ticks: {
stepSize: 1
}
}],
yAxes: [{
stacked: false
}]
}
}
}
);
</script>
<div class='graphbox'>
<h3>Applicants & Intakes over time</h3>
<canvas id="historicChart"></canvas>
</div>
How can I achieve this?
They fixed this issue in v3 so upgrading to that is 1 solution, the other one is downgrading to version 2.8, in a git issue on their repo someone posted a workaround but that only works till version 2.8.
V3:
HorizontalBar has been removed as a type, use bar chart instead and set the index axis to y in your options
Example:
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
type: 'line',
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
indexAxis: 'y'
}
}
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/3.2.0/chart.js"></script>
</body>
V2 solutions, for if stuck on v2 with plugin support
To achieve this in 2.8 you will have to specify your data as objects and specify the x and y coordinates
Example:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
datasets: [{
label: "Clients Signed",
data: [2, 0, 3, 5, 1, 3, 6, 5, 3, 10]
}, {
label: "Quota",
data: [{
x: 2,
y: 'Q2 2015'
}, {
x: 2,
y: 'Q3 2015'
}, {
x: 2,
y: 'Q4 2015'
}, {
x: 2,
y: 'Q1 2016'
}, {
x: 2,
y: 'Q2 2016'
}, {
x: 2,
y: 'Q3 2016'
}, {
x: 2,
y: 'Q4 2016'
}, {
x: 2,
y: 'Q1 2017'
}, {
x: 2,
y: 'Q2 2017'
}, {
x: 2,
y: 'Q3 2017'
}],
type: 'line'
}],
labels: ["Q2 2015", "Q3 2015", "Q4 2015", "Q1 2016", "Q2 2016", "Q3 2016", "Q4 2016", "Q1 2017", "Q2 2017", "Q3 2017"]
},
options: {
barPercentage: 1.0,
categoryPercentage: 1.0
}
});
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
<script src="https://npmcdn.com/chart.js#2.8.0/dist/Chart.bundle.min.js"></script>
</body>
Git issue: https://github.com/chartjs/Chart.js/issues/4096

Chartjs - Line between two dots on the Y axis

The goal is to link 2 dots by a line.
Dots's datas are from 2 different arrays.
Here an image to help understand
https://i.stack.imgur.com/pe3WU.png
You can use a custom plugin for this:
const customLine = {
id: 'customLine',
beforeDatasetsDraw: (chart, args, options) => {
const {
ctx,
scales: {
x,
y
}
} = chart;
chart.data.datasets[0].data.forEach((dataPoint, i) => {
ctx.strokeStyle = options.lineColor || 'black';
ctx.lineWidth = options.lineWidth || 1;
ctx.beginPath();
ctx.moveTo(x.getPixelForValue(chart.data.labels[i]), y.getPixelForValue(dataPoint));
ctx.lineTo(x.getPixelForValue(chart.data.labels[i]), y.getPixelForValue(chart.data.datasets[1].data[i]));
ctx.stroke();
})
}
}
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,
showLine: false,
backgroundColor: 'red'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1,
showLine: false,
backgroundColor: 'blue'
}
]
},
options: {
plugins: {
customLine: {
lineColor: 'pink',
lineWidth: 3
}
}
},
plugins: [customLine]
}
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/3.3.0/chart.js"></script>
</body>

How scale sector in doughnut chartjs on hover?

How scale sector in doughnut chartjs on hover?
Example:
The simplest solution would be to define different borderWidth and hoverBorderWidth on your dataset as follows.
new Chart(document.getElementById('myChart'), {
type: 'doughnut',
data: {
labels: ['red', 'green', 'gray', 'blue'],
datasets: [{
label: 'My First dataset',
backgroundColor: ['red', 'green', 'gray', 'blue'],
borderColor: 'white',
data: [3, 4, 5, 3],
borderWidth: 4,
hoverBorderWidth: 0,
borderAlign: 'center'
}]
},
options: {
responsive:true,
cutoutPercentage: 65
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart"></canvas>