使用chart.js将鼠标悬停在图表上时移动垂直线

kch*_*hoi 12 chart.js chart.js2

当我将鼠标悬停在图表上时,我一直在尝试添加一条显示工具提示的垂直线.但是我使用的是chart.js 2.6,而且1.x的语法似乎已经过时了.

我有以下代码适用于1.x.

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
});
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/dbyze2ga/658/

任何人都知道如何使其适用于2.6 https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js

ɢʀᴜ*_*ᴜɴᴛ 37

ChartJS 2.6.0的解决方案

ꜱᴄʀɪᴘᴛ(ᴇxᴛᴇɴᴅɪɴɢʟɪɴᴇᴄʜᴀʀᴛ)

Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
   draw: function(ease) {
      Chart.controllers.line.prototype.draw.call(this, ease);

      if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
         var activePoint = this.chart.tooltip._active[0],
             ctx = this.chart.ctx,
             x = activePoint.tooltipPosition().x,
             topY = this.chart.scales['y-axis-0'].top,
             bottomY = this.chart.scales['y-axis-0'].bottom;

         // draw line
         ctx.save();
         ctx.beginPath();
         ctx.moveTo(x, topY);
         ctx.lineTo(x, bottomY);
         ctx.lineWidth = 2;
         ctx.strokeStyle = '#07C';
         ctx.stroke();
         ctx.restore();
      }
   }
});
Run Code Online (Sandbox Code Playgroud)

您还需要设置intersect: false工具提示.

ᴡᴏʀᴋɪɴɢᴡᴏʀᴋɪɴɢxᴀᴍᴘʟᴇ⧩

Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
   draw: function(ease) {
      Chart.controllers.line.prototype.draw.call(this, ease);

      if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
         var activePoint = this.chart.tooltip._active[0],
             ctx = this.chart.ctx,
             x = activePoint.tooltipPosition().x,
             topY = this.chart.scales['y-axis-0'].top,
             bottomY = this.chart.scales['y-axis-0'].bottom;

         // draw line
         ctx.save();
         ctx.beginPath();
         ctx.moveTo(x, topY);
         ctx.lineTo(x, bottomY);
         ctx.lineWidth = 2;
         ctx.strokeStyle = '#07C';
         ctx.stroke();
         ctx.restore();
      }
   }
});

var chart = new Chart(ctx, {
   type: 'LineWithLine',
   data: {
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
      datasets: [{
         label: 'Statistics',
         data: [3, 1, 2, 5, 4, 7, 6],
         backgroundColor: 'rgba(0, 119, 204, 0.8)',
         borderColor: 'rgba(0, 119, 204, 0.3)',
         fill: false
      }]
   },
   options: {
      responsive: false,
      tooltips: {
         intersect: false
      },
      scales: {
         yAxes: [{
            ticks: {
               beginAtZero: true
            }
         }]
      }
   }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx" height="200"></canvas>
Run Code Online (Sandbox Code Playgroud)

  • @ Atav32 v2.7.0中引入了一个可解决此问题的设置。您可以在options.tooltips.axis中设置“ axis:'x'”。这是一个使用v2.8.0并设置了该设置的小提琴:https://jsfiddle.net/hg5873zm/2/ @ɢʀᴜɴᴛ如果您可以更新答案,建议您这样做:) (4认同)
  • 如果将线堆叠在Y轴上,似乎有问题。 (2认同)
  • 它怎么会显示(x,y)距离最近点的工具提示,而不是x值显示最近的垂直线的工具提示?例如,如果将鼠标悬停在图形上方,则工具提示将从“ Jan”跳到“ Apr”。 (2认同)

小智 6

尝试这个:

var ctx = this.$refs.canvas.getContext("2d");
      // new Chart(ctx, config);
      var originalLineDraw = Chart.controllers.line.prototype.draw;
      Chart.helpers.extend(Chart.controllers.line.prototype, {
        draw: function() {
          originalLineDraw.apply(this, arguments);

          var chart = this.chart;
          var ctx = chart.chart.ctx;

        if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
          var activePoint = this.chart.tooltip._active[0];
          var ctx = this.chart.ctx;
          var x = activePoint.tooltipPosition().x;
          var topY = this.chart.scales['y-axis-0'].top;
          var bottomY = this.chart.scales['y-axis-0'].bottom;

         // draw line
          ctx.save();
          ctx.beginPath();
          ctx.moveTo(x, topY);
          ctx.lineTo(x, bottomY);
          ctx.lineWidth = 0.5;
          ctx.strokeStyle = '#eeeeee';
          ctx.stroke();
          ctx.restore();
       }
      }});
Run Code Online (Sandbox Code Playgroud)

这肯定会帮助你。


Teo*_*cci 5

这个问题已经五年了。如今,在这种情况下,我们可以使用plugins钩子调用beforeTooltipDraw来捕​​获tooltip.caretX. 我们也可以使用内置交互选项来实现这一点。

该实现适用于ChartJS 3.x 和 4.0.1 版本

const $chart = document.getElementById('chart')

const plugin = {
    id: 'verticalLiner',
    afterInit: (chart, args, opts) => {
      chart.verticalLiner = {}
    },
    afterEvent: (chart, args, options) => {
        const {inChartArea} = args
        chart.verticalLiner = {draw: inChartArea}
    },
    beforeTooltipDraw: (chart, args, options) => {
        const {draw} = chart.verticalLiner
        if (!draw) return

        const {ctx} = chart
        const {top, bottom} = chart.chartArea
        const {tooltip} = args
        const x = tooltip?.caretX
        if (!x) return

        ctx.save()
        
        ctx.beginPath()
        ctx.moveTo(x, top)
        ctx.lineTo(x, bottom)
        ctx.stroke()
        
        ctx.restore()
    }
}

const 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]
  }]
}

const options = {
  type: 'line',
  data,
  options: {
    maintainAspectRatio: false,
    interaction: {
      mode: 'index',
      intersect: false,
    },
    plugins: {
      verticalLiner: {}
    }
  },
  plugins: [plugin]
}

const chart = new Chart($chart, options)
Run Code Online (Sandbox Code Playgroud)
<div class="wrapper" style="width: 98vw; height:180px">
  <canvas id="chart"></canvas>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
Run Code Online (Sandbox Code Playgroud)