Reputation: 131
I want to make a chart with min and max vertical lines and bars between them. I can't find information how to set bars' X coordinate or make custom line plot with vertical 'bars' instead of points.
And also I don't understand how to scale X axis, why MAX is left-side MIN? Min=22.5, Max=24.5
let plot_options = {
showScale: true,
pointDot: true,
showLines: true,
maintainAspectRatio: false,
annotation: {
annotations: [
{
type: 'line',
mode: 'vertical',
scaleID: 'y-axis-0',
value: min,
borderColor: 'red',
borderWidth: 2,
label: {
backgroundColor: 'red',
content: 'Min',
enabled: true,
},
},
{
type: 'line',
mode: 'vertical',
scaleID: 'y-axis-0',
value: max,
borderColor: 'red',
borderWidth: 2,
label: {
backgroundColor: 'red',
content: 'MAX',
enabled: true,
},
},
]
},
title: {
display: true,
text: plotHeader,
},
responsive: true,
legend: {
display: false,
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: labelx
},
ticks: {
min: min,
max: max
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: labely
},
ticks: {
beginAtZero: true,
},
}]
},
}
data = {
barPercentage: 0.5,
barThickness: 6,
maxBarThickness: 8,
minBarLength: 2,
labels: labels,
datasets: [{
data: values,
borderColor: BLUE,
backgroundColor: BLUE
}]
}
<Bar options={plot_options} data={data} plugins={ChartAnnotation} />
Upvotes: 1
Views: 1915
Reputation: 26150
This solution is based on this answer for the positioning of the bars on a linear x-axis.
You can further use the Plugin Core API to draw the vertical min
and max
lines with their labels directly on the canvas
. The API offers a number of hooks that can be used to perform custom code. In your case, you could use the afterDraw
hook together with CanvasRenderingContext2D
.
Please take a look at the runnable code below and see how it works. It should not be too hard to make similar code work with react-chartjs-2
.
new Chart("chart", {
type: 'bar',
plugins: [{
afterDraw: chart => {
let ctx = chart.chart.ctx;
ctx.save();
let xAxis = chart.scales['x-axis-0'];
let yAxis = chart.scales['y-axis-0'];
let dataset = chart.data.datasets[0];
[dataset.min, dataset.max].forEach((v, i) => {
var x = xAxis.getPixelForValue(+v * 1000);
ctx.fillStyle = 'red';
ctx.font = '14px Arial';
ctx.textAlign = 'center';
ctx.fillText(i == 0 ? 'Min' : 'Max', x, yAxis.top + 14);
ctx.fillStyle = 'gray';
ctx.font = '12px Arial';
ctx.fillText(v, x, yAxis.bottom + 20);
ctx.beginPath();
ctx.moveTo(x, yAxis.top + 20);
ctx.strokeStyle = 'red';
ctx.lineTo(x, yAxis.bottom + 3);
ctx.stroke();
});
ctx.restore();
}
}],
data: {
datasets: [{
min: 22.5,
max: 24.5,
data: [
{ x: '22.83', y: 18 },
{ x: '23.17', y: 15 },
{ x: '23.44', y: 13 },
{ x: '24.32', y: 20 }
],
borderColor: 'blue',
backgroundColor: 'blue',
barThickness: 20
}]
},
options: {
legend: {
display: false,
},
scales: {
xAxes: [{
offset: true,
type: 'time',
time: {
parser: 'X',
unit: 'millisecond',
displayFormats: {
millisecond: 'X'
}
},
ticks: {
source: 'data',
min: '22.5',
callback: (v, i, values) => values[i].value / 1000
},
gridLines: {
display: false
},
}],
yAxes: [{
ticks: {
beginAtZero: true,
max: 22,
stepSize: 2
}
}]
}
}
});
canvas {
max-width: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script>
<canvas id="chart" height="200"></canvas>
Upvotes: 1