How to add a horizontal line at a specific point i

2019-01-20 17:10发布

问题:

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:

I want to also make it so that when you dont hover over a point its opacity gets reduced and when you hover over it the opacity is normal. I'm also not sure how to add the square and make the square bigger when hovered hover and it adds the 'wow' text. I appreciate any help thank you. :)

回答1:

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>