How to add a horizontal line at a specific point in chart.js when hovering?

前端 未结 1 784
猫巷女王i
猫巷女王i 2020-12-12 04:05

I want to be able to add multiple points as a reference place where I can show the horizontal line.

Here is an image of what I\'m trying to achieve:

<
相关标签:
1条回答
  • 2020-12-12 04:37

    You can use chart.js annotations plugin to draw horizontal lines at specific values, then you can implement a proper onHover callback (events on the whole chart) to show/hide those lines.

    annotation : {
        drawTime : "afterDraw",
        annotations : [{
                id : "line1",
                type : "line",
                mode : "horizontal",
                scaleID : "y-axis",
                value : 4.5,
                borderWidth : 2,
                borderColor : "red",
                label : {
                    content : "threshold 1",
                    enabled : true,
                    position : "right"
                }
            }
        ]
    },
    

    See my fiddle exemplifying the approach: https://jsfiddle.net/beaver71/5jg4wgdh/

    var data_set = [{x: 1, y: 12}, {x: 2, y: 3}, {x: 3, y: 2}, {x: 4, y: 1}, {x: 5, y: 8}, {x: 6, y: 8}, {x: 7, y: 2}, {x: 8, y: 2}, {x: 9, y: 3}, {x: 10, y: 5}, {x: 11, y: 11}, {x: 12, y: 1}];
    var labels = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
    
    var lines = [], id = 0;
    var linesOn = false;
    
    var data = {
      labels: labels,
      datasets: [{
        label: "My First dataset",
        backgroundColor: "rgba(255,99,132,0.2)",
        borderColor: "rgba(255,99,132,1)",
        borderWidth: 2,
        hoverBackgroundColor: "rgba(255,99,132,0.4)",
        hoverBorderColor: "rgba(255,99,132,1)",
        data: data_set,
      }]
    };
    
    var option = {
      legend: false,
      title: {
        display: true,
      },
      onHover: function(evt) {
      	console.log("onHover", evt.type);
        if (evt.type == 'mousemove' && linesOn == false) {
        	linesOn = true;
          myLineChart.options.annotation.annotations = lines;
          myLineChart.update();
        } else if (evt.type == 'mouseout' && linesOn == true) {
        	linesOn = false;
        	myLineChart.options.annotation.annotations = [];
        	myLineChart.update();
        }
        var item = myLineChart.getElementAtEvent(evt);
        if (item.length) {
          console.log(">item", item);
          console.log(">data", item[0]._index, data.datasets[0].data[item[0]._index]);
        }
      },
      onClick: function(evt) {
        var el = myLineChart.getElementAtEvent(evt);
        console.log("onClick", el, evt);
      },
      annotation: {
        drawTime: "afterDraw",
        annotations: lines
      },
      scales: {
        xAxes: [{
          id: 'x-axis',
          type: 'linear',
          position: 'bottom',
          ticks: {
            max: 12,
            min: 1,
            stepSize: 1,
            callback: function(value, index, values) {
              return data.labels[index];
            }
          }
        }],
        yAxes: [{
          id: 'y-axis',
          type: 'linear',
        }],
      }
    
    };
    
    var myLineChart = Chart.Line('myChart', {
      data: data,
      options: option
    });
    
    // define two lines (these code must be after chart creation)
    addLine(3.5);
    addLine(7);
    
    function addLine(value) {
      id++;
      var ln = {
        id: "line" + id,
        type: "line",
        mode: "horizontal",
        scaleID: "y-axis",
        value: value,
        borderWidth: 2,
        borderColor: "red",
        label: {
          content: "threshold " + id,
          enabled: true,
          position: "right"
        }
      };
      lines.push(ln);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/0.5.7/chartjs-plugin-annotation.min.js"></script>
    
    <canvas id="myChart" width="400" height="200"></canvas>

    Update:

    If you need to animate annotation hovering on them, here is another example:

    https://jsfiddle.net/beaver71/yxy402rk/

    var data_set = [{x: 1, y: 12}, {x: 2, y: 3}, {x: 3, y: 2}, {x: 4, y: 1}, {x: 5, y: 8}, {x: 6, y: 8}, {x: 7, y: 2}, {x: 8, y: 2}, {x: 9, y: 3}, {x: 10, y: 5}, {x: 11, y: 11}, {x: 12, y: 1}];
    var labels = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
    
    var lines = [], id = 0;
    var linesOn = false;
    
    var data = {
      labels: labels,
      datasets: [{
        label: "My First dataset",
        backgroundColor: "rgba(255,99,132,0.2)",
        borderColor: "rgba(255,99,132,1)",
        borderWidth: 2,
        hoverBackgroundColor: "rgba(255,99,132,0.4)",
        hoverBorderColor: "rgba(255,99,132,1)",
        data: data_set,
      }]
    };
    
    var option = {
      legend: false,
      title: {
        display: true,
      },
      onHover: function(evt) {
        var item = myLineChart.getElementAtEvent(evt);
        if (item.length) {
          console.log(">item", item);
          console.log(">data", item[0]._index, data.datasets[0].data[item[0]._index]);
        }
      },
      onClick: function(evt) {
        var el = myLineChart.getElementAtEvent(evt);
        console.log("onClick", el, evt);
      },
      annotation: {
        drawTime: "afterDraw",
        events: ['click','mouseenter','mouseleave'],
        annotations: lines
      },
      scales: {
        xAxes: [{
          id: 'x-axis',
          type: 'linear',
          position: 'bottom',
          ticks: {
            max: 12,
            min: 1,
            stepSize: 1,
            callback: function(value, index, values) {
              return data.labels[index];
            }
          }
        }],
        yAxes: [{
          id: 'y-axis',
          type: 'linear',
        }],
      }
    
    };
    
    addLine(3.5);
    addLine(7);
    
    var myLineChart = Chart.Line('myChart', {
      data: data,
      options: option
    });
    
    console.log(myLineChart.annotation.elements.line1);
    myLineChart.annotation.elements.line1.hidden = true;
    myLineChart.update();
    
    function addLine(value) {
      id++;
      var ln = {
        id: "line" + id,
        type: "line",
        mode: "horizontal",
        scaleID: "y-axis",
        value: value,
        borderWidth: 2,
        borderColor: "rgba(0,0,255,0.3)",
        label: {
          content: "threshold " + id,
          enabled: true,
          position: "right",
          backgroundColor: 'rgba(0,0,0,0.3)',
        },
        onMouseenter: function(e) {
        	console.log("onMouseenter", e, this);
          this.options.borderColor = "rgba(0,0,255,0.8)";
          this.options.label.backgroundColor = 'rgba(0,0,0,0.8)';
          myLineChart.update();
        },
        onMouseleave: function(e) {
        	console.log("onMouseleave", e);
          this.options.borderColor = "rgba(0,0,255,0.3)";
          this.options.label.backgroundColor = 'rgba(0,0,0,0.3)';
          myLineChart.update();
        },
      };
      lines.push(ln);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/0.5.7/chartjs-plugin-annotation.min.js"></script>
    
    <canvas id="myChart" width="400" height="200"></canvas>

    0 讨论(0)
提交回复
热议问题