悬停时如何在chart.js中的特定点添加水平线?

Posted

技术标签:

【中文标题】悬停时如何在chart.js中的特定点添加水平线?【英文标题】:How to add a horizontal line at a specific point in chart.js when hovering? 【发布时间】:2018-07-08 10:40:46 【问题描述】:

我希望能够添加多个点作为可以显示水平线的参考位置。

这是我想要实现的目标的图像:

我还想这样做,以便当您不将鼠标悬停在某个点上时,它的不透明度会降低,而当您将鼠标悬停在它上面时,不透明度是正常的。我也不确定如何添加正方形并在悬停悬停时使正方形更大,并添加“哇”文本。感谢您的帮助。

【问题讨论】:

【参考方案1】:

您可以使用chart.js annotations plugin 在特定值处绘制水平线,然后您可以实现适当的onHover 回调(整个图表上的事件)来显示/隐藏这些线。

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"
            
        
    ]
,

参见我的小提琴示例: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"  ></canvas>

更新:

如果你需要动画注解悬停在它们上面,这里是另一个例子:

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"  ></canvas>

【讨论】:

更新后的答案正是我所需要的,非常感谢。现在我可以用这个了:) 我想在水平线上添加shadowBlur: 10shadowColor: "black",你知道怎么做吗? 不,chartjs-plugin-annotation 不支持这些 CSS 属性,请参阅github.com/chartjs/chartjs-plugin-annotation 实现此功能的最佳方式是什么? @海狸 你可以fork github项目并修改line类的draw()函数:见github.com/chartjs/chartjs-plugin-annotation/blob/master/src/…

以上是关于悬停时如何在chart.js中的特定点添加水平线?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Chart.js 的饼图中(顶部)添加切片的大小?

如何在 Chart.js 2.9.3 中绘制具有动态厚度的水平条(在浏览器窗口高度调整大小时自动调整大小)?

Chart.js - 鼠标悬停时自定义css到数据集

在 v2 上的 chart.js 中的图表上绘制水平线

Chart Js显示鼠标悬停时的旧数据

如何在 Chart.js v2 中格式化 x 轴时间刻度值