使用Chart.js检测图表部分上的悬停事件

时间:2015-03-26 19:23:16

标签: javascript chart.js

我使用Chart.js创建了一个饼图,我想检测一个片段何时悬停。我已经找到了大量关于操作悬停在片段上时出现的工具提示的文档,但没有关于在工具提示出现时做其他事情的事情。这可能吗?

6 个答案:

答案 0 :(得分:15)

我知道这已经得到了一个公认的答案,我不确定这是否满足您的使用案例,但Chart js发布了一个允许自定义工具提示的更新(可能是一个月前左右)。这允许在通常绘制工具提示时运行自定义函数。他们在git hub的样本部分有一个例子

简而言之,您定义了一个自定义函数

 Chart.defaults.global.customTooltips = function(tooltip){//do what you want}

这是他们在示例中给出的示例,其中添加了一些额外的文本到html工具提示。我看到的唯一令人讨厌的事情是,不提供触发此工具提示的段/点/栏,这将非常方便,因为您可以在知道此信息的图表上做一些事情但是您会得到工具提示数据,这意味着您可以用它做点什么。

Chart.defaults.global.customTooltips = function (tooltip) {
      // Tooltip Element
      var tooltipEl = $('#chartjs-tooltip');
      // Hide if no tooltip
      if (!tooltip) {
          tooltipEl.css({
              opacity: 0
          });
          return;
      }
      // Set caret Position
      tooltipEl.removeClass('above below');
      tooltipEl.addClass(tooltip.yAlign);
      // Set Text
      tooltipEl.html(tooltip.text+ " anythign custom you want");
      // Find Y Location on page
      var top;
      if (tooltip.yAlign == 'above') {
          top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
      } else {
          top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
      }
      // Display, position, and set styles for font
      tooltipEl.css({
          opacity: 1,
          left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
          top: tooltip.chart.canvas.offsetTop + top + 'px',
          fontFamily: tooltip.fontFamily,
          fontSize: tooltip.fontSize,
          fontStyle: tooltip.fontStyle,
      });
  };
  var pieData = [{
      value: 300,
      color: "#F7464A",
      highlight: "#FF5A5E",
      label: "Red"
  }, {
      value: 50,
      color: "#46BFBD",
      highlight: "#5AD3D1",
      label: "Green"
  }, {
      value: 100,
      color: "#FDB45C",
      highlight: "#FFC870",
      label: "Yellow"
  }, {
      value: 40,
      color: "#949FB1",
      highlight: "#A8B3C5",
      label: "Grey"
  }, {
      value: 120,
      color: "#4D5360",
      highlight: "#616774",
      label: "Dark Grey"
  }];

  var ctx1 = document.getElementById("chart-area1").getContext("2d");
  window.myPie = new Chart(ctx1).Pie(pieData);
  var ctx2 = document.getElementById("chart-area2").getContext("2d");
  window.myPie = new Chart(ctx2).Pie(pieData);
#canvas-holder {
       width: 100%;
       margin-top: 50px;
       text-align: center;
   }
   #chartjs-tooltip {
       opacity: 1;
       position: absolute;
       background: rgba(0, 0, 0, .7);
       color: white;
       padding: 3px;
       border-radius: 3px;
       -webkit-transition: all .1s ease;
       transition: all .1s ease;
       pointer-events: none;
       -webkit-transform: translate(-50%, 0);
       transform: translate(-50%, 0);
   }
   #chartjs-tooltip.below {
       -webkit-transform: translate(-50%, 0);
       transform: translate(-50%, 0);
   }
   #chartjs-tooltip.below:before {
       border: solid;
       border-color: #111 transparent;
       border-color: rgba(0, 0, 0, .8) transparent;
       border-width: 0 8px 8px 8px;
       bottom: 1em;
       content:"";
       display: block;
       left: 50%;
       position: absolute;
       z-index: 99;
       -webkit-transform: translate(-50%, -100%);
       transform: translate(-50%, -100%);
   }
   #chartjs-tooltip.above {
       -webkit-transform: translate(-50%, -100%);
       transform: translate(-50%, -100%);
   }
   #chartjs-tooltip.above:before {
       border: solid;
       border-color: #111 transparent;
       border-color: rgba(0, 0, 0, .8) transparent;
       border-width: 8px 8px 0 8px;
       bottom: 1em;
       content:"";
       display: block;
       left: 50%;
       top: 100%;
       position: absolute;
       z-index: 99;
       -webkit-transform: translate(-50%, 0);
       transform: translate(-50%, 0);
   }
<script src="https://raw.githack.com/chartjs/Chart.js/v1.1.1/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-holder">
    <canvas id="chart-area1" width="50" height="50" />
</div>
<div id="canvas-holder">
    <canvas id="chart-area2" width="300" height="300" />
</div>
<div id="chartjs-tooltip"></div>

答案 1 :(得分:5)

否...

ChartJS API中没有任何内容可以覆盖或扩展工具提示,

但是,解决方法......

您可以修改draw课程的Chart.Tooltip方法。这将允许你做其他事情&#34;当工具提示通常由ChartJS呈现时。

您想要绑定的绘制方法从源的第1351行开始:

https://github.com/nnnick/Chart.js/blob/master/src/Chart.Core.js

答案 2 :(得分:5)

对于v2.0版本:

Chart.defaults.global.hover.onHover = function(x) {
  if(x[0]) {
    var index = x[0]._index;
    // Place here your code
  }
};

答案 3 :(得分:4)

我这样做的方式稍微简单一些: 假设您已经有一些定义画布的代码 canvas = document.getElementById("chart");和你的饼图是 window.myPie。您可以使用onmousemove javascript事件或jQuery hover

canvas.onmousemove = function(evt) {
    var el = window.myPie.getElementsAtEvent(evt);
    //do something with the el object to display other information
    //elsewhere on the page
}

在我的例子中,根据el[0]._index

的值突出显示一个表格行

答案 4 :(得分:2)

如果使用customTooltip发现了一个小技巧。如果用户使用鼠标移动到值并显示工具提示,我搜索了获取事件的解决方案。主要是我喜欢在不同的框架中呈现除原始Plot值之外的一些细节信息。

var options = {            
  customTooltips: function (tooltip)
  {
    if (!tooltip) return;

    tooltip.custom = false;
    tooltip.draw();
    OnEntrySelected(tooltip.title);
    tooltip.custom = this;
  }
}

使用tooltip.draw()绘制自定义工具提示,但这会调用自定义方法。我将其设置为false以避免递归循环,调用默认行为并获取我的回调所需的数据(OnEntrySelected),在这种情况下是x-Axis标签的字符串。只要显示工具提示,就会触发此事件。

答案 5 :(得分:2)

UPDATE 2020:对于Chartjs 3.5

这是我与Chartjs 3.5一起使用的快速修复程序,用于触发将鼠标悬停在Donut或Pie部件上的事件。它依赖于使用现有的view in editor

onHover : (event, activeElements) => {

    if (activeElements.length > 0) {

            // get active chart element
            let elt = activeElements[0];

            // retrieve element label
            let lbl = elt._model.label;

            // Get element value
            let elt_index = elt._chart.tooltip._data.labels.indexOf(lbl);
            let val = elt._chart.tooltip._data.datasets[0].data[elt_index];

           // trigger your event here :
           // ex for vuejs : this.$emit('element-hovered', { label : lbl, value : val });

       }
       else {
           // No active elements
       }

   }

到目前为止工作正常:)