Chart.js – dessin d'une ligne verticale arbitraire

Comment puis-je dessiner une ligne verticale à un point particulier de l'axe des x à l'aide de Chart.js?

En particulier, je veux dessiner une ligne pour indiquer le jour en cours dans un LineChart. Voici une maquette du graphique: http://i.stack.imgur.com/VQDWR.png

Entrez la description de l'image ici

    Vous étendez le diagramme de ligne et incluez la logique pour dessiner la ligne dans la fonction de dessin.


    Aperçu

    Entrez la description de l'image ici


    HTML

    <div> <canvas id="LineWithLine" width="600" height="400"></canvas> </div> 

    Scénario

     var data = { labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"], datasets: [{ data: [12, 3, 2, 1, 8, 8, 2, 2, 3, 5, 7, 1] }] }; var ctx = document.getElementById("LineWithLine").getContext("2d"); Chart.types.Line.extend({ name: "LineWithLine", draw: function () { Chart.types.Line.prototype.draw.apply(this, arguments); var point = this.datasets[0].points[this.options.lineAtIndex] var scale = this.scale // draw line this.chart.ctx.beginPath(); this.chart.ctx.moveTo(point.x, scale.startPoint + 24); this.chart.ctx.strokeStyle = '#ff0000'; this.chart.ctx.lineTo(point.x, scale.endPoint); this.chart.ctx.stroke(); // write TODAY this.chart.ctx.textAlign = 'center'; this.chart.ctx.fillText("TODAY", point.x, scale.startPoint + 12); } }); new Chart(ctx).LineWithLine(data, { datasetFill : false, lineAtIndex: 2 }); 

    L'option propriété lineAtIndex contrôle qui pointe à tracer la ligne à.

    Fiddle – http://jsfiddle.net/dbyze2ga/14/

    Partage de ma solution pour chartjs.org version 2.5. Je voulais utiliser un plugin, pour rendre l'implémentation réutilisable.

     const verticalLinePlugin = { getLinePosition: function (chart, pointIndex) { const meta = chart.getDatasetMeta(0); // first dataset is used to discover X coordinate of a point const data = meta.data; return data[pointIndex]._model.x; }, renderVerticalLine: function (chartInstance, pointIndex) { const lineLeftOffset = this.getLinePosition(chartInstance, pointIndex); const scale = chartInstance.scales['y-axis-0']; const context = chartInstance.chart.ctx; // render vertical line context.beginPath(); context.strokeStyle = '#ff0000'; context.moveTo(lineLeftOffset, scale.top); context.lineTo(lineLeftOffset, scale.bottom); context.stroke(); // write label context.fillStyle = "#ff0000"; context.textAlign = 'center'; context.fillText('MY TEXT', lineLeftOffset, (scale.bottom - scale.top) / 2 + scale.top); }, afterDatasetsDraw: function (chart, easing) { if (chart.config.lineAtIndex) { chart.config.lineAtIndex.forEach(pointIndex => this.renderVerticalLine(chart, pointIndex)); } } }; Chart.plugins.register(verticalLinePlugin); 

    Je devais passer par la peine de trouver comment faire quelque chose de similaire avec ChartJS 2.0, donc j'ai pensé que je partagerais.

    Ceci est basé sur la nouvelle façon de remplacer un prototype graphique tel qu'expliqué ici: https://github.com/chartjs/Chart.js/issues/2321

     var ctx = document.getElementById('income-chart'); var originalDraw = Chart.controllers.line.prototype.draw; Chart.controllers.line.prototype.draw = function (ease) { originalDraw.call(this, ease); var point = dataValues[vm.incomeCentile]; var scale = this.chart.scales['x-axis-0']; // calculate the portion of the axis and multiply by total axis width var left = (point.x / scale.end * (scale.right - scale.left)); // draw line this.chart.chart.ctx.beginPath(); this.chart.chart.ctx.strokeStyle = '#ff0000'; this.chart.chart.ctx.moveTo(scale.left + left, 0); this.chart.chart.ctx.lineTo(scale.left + left, 1000000); this.chart.chart.ctx.stroke(); // write label this.chart.chart.ctx.textAlign = 'center'; this.chart.chart.ctx.fillText('YOU', scale.left + left, 200); };