I am using ChartJS annotation plugin in order to display some annotations.
I am using the box annotation, but I am not sure how I can display a border for that annotation only on the left
and right
edge, but not top and bottom?
You can use the afterDraw
hook
of the annotation to draw custom stuff over your annotation.
To have only the left and right borders, the simplest way seems to set the
borderColor
property to 'transparent'
and draw the two borders using the
intended color in the afterDraw
:
afterDraw(context){
const element = context.element,
options = element.options,
ctx = context.chart.ctx;
ctx.save();
ctx.strokeStyle = 'rgb(165, 214, 167)';
ctx.lineWidth = options.borderWidth;
ctx.beginPath();
ctx.moveTo(element.x, element.y);
ctx.lineTo(element.x, element.y2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(element.x2, element.y);
ctx.lineTo(element.x2, element.y2);
ctx.stroke();
ctx.restore();
}
This is the basic version that draw just the simple vertical lines. The following snippet implements a complete version, that takes into consideration all available annotation options like shadow, rotation, line dash; the code is based on the actual plugin source code.
const data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
type: 'line',
label: 'Dataset 1',
borderColor: 'rgb(54, 162, 235)',
borderWidth: 2,
fill: false,
data: Array.from({length: 100}, () => Math.round(Math.random() * 100))
}]
};
const annotation1 = {
type: 'box',
backgroundColor: 'rgba(165, 214, 167, 0.2)',
borderColor: 'transparent',//'rgb(165, 214, 167)',
borderShadowColor: 'gray',
shadowOffsetX: 4,
shadowOffsetY: 4,
borderWidth: 5,
label: {
display: true,
content: ['Box', 'annotation'],
textAlign: 'center'
},
rotation: 45,
xMax: 'May',
xMin: 'April',
xScaleID: 'x',
yMax: 75,
yMin: 25,
yScaleID: 'y',
afterDraw(context){
const element = context.element,
options = element.options,
ctx = context.chart.ctx;
ctx.save();
ctx.strokeStyle = 'rgb(165, 214, 167)';
ctx.lineWidth = options.borderWidth;
ctx.lineCap = options.borderCapStyle || 'butt';
ctx.lineJoin = options.borderJoinStyle || 'miter';
if(options.rotation){
const {x, y} = element.getCenterPoint();
ctx.translate(x, y);
ctx.rotate(options.rotation * Math.PI / 180);
ctx.translate(-x, -y);
}
if(options.borderDash){
ctx.setLineDash(options.borderDash);
ctx.lineDashOffset = options.borderDashOffset;
}
if(options.shadowColor !== 'transparent'){
ctx.shadowColor = options.borderShadowColor;
ctx.shadowBlur = options.shadowBlur;
ctx.shadowOffsetX = options.shadowOffsetX;
ctx.shadowOffsetY = options.shadowOffsetY;
}
ctx.beginPath();
ctx.moveTo(element.x, element.y);
ctx.lineTo(element.x, element.y2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(element.x2, element.y);
ctx.lineTo(element.x2, element.y2);
ctx.stroke();
ctx.restore();
}
};
const config = {
type: 'line',
data,
options: {
scales: {
y: {
beginAtZero: true,
min: 0,
max: 100
}
},
plugins: {
annotation: {
annotations: {
annotation1,
}
}
}
}
};
new Chart('myChart', config);
<div style="height: 300px">
<canvas id="myChart">
</canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/3.1.0/chartjs-plugin-annotation.min.js"></script>