javascript Chart.js悬停在标签上

jc3wubiy  于 2023-02-15  发布在  Java
关注(0)|答案(3)|浏览(235)
    • bounty将在5天后过期**。回答此问题可获得+50声望奖励。Software Dev希望引起更多人关注此问题。

我在Chart.js中有一个条形图(使用最新版本),当鼠标悬停在类别标签上时,我想做一些视觉上的改变。我应该如何实现以下视觉上的改变?
1.将光标悬停在标签上时使其成为指针。
1.使标签在悬停时显示为不同的颜色。
这里有一个相关的问题:How to detect click on chart js 3.7.1 axis label?.不过,我的问题是关于悬停在一个标签上,而不是点击标签。
在下面的例子中,我希望当鼠标悬停在这些文本上时会发生一些事情:一米零一米零一米零一米零一米零一米零一米零一米零一米零二米零一米零。

window.onload = function() {
  var ctx = document.getElementById('myChart').getContext('2d');
  window.myBar = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Item A', 'Item B', 'Item C'],
      datasets: [{
        data: [1, 2, 3],
        backgroundColor: 'lightblue'
      }]
    },
    options: {
      responsive: true,
      indexAxis: 'y',
      plugins: {
        legend: {
          display: false
        },
        tooltip: {
          enabled: false
        },
      }
    }
  });
};
.chart-container {
  position: relative;
  height: 90vh;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.2.0"></script>

<div class="chart-container">
  <canvas id="myChart"></canvas>
</div>
ncgqoxb0

ncgqoxb01#

您可以使用该问题中的自定义插件,忽略除mousemove事件以外的所有事件,而不是忽略除click事件以外的所有事件:

const findLabel = (labels, evt) => {
  let found = false;
  let res = null;

  labels.forEach(l => {
    l.labels.forEach((label, index) => {
      if (evt.x > label.x && evt.x < label.x2 && evt.y > label.y && evt.y < label.y2) {
        res = {
          label: label.label,
          index
        };
        found = true;
      }
    });
  });

  return [found, res];
};

const getLabelHitboxes = (scales) => (Object.values(scales).map((s) => ({
  scaleId: s.id,
  labels: s._labelItems.map((e, i) => ({
    x: e.translation[0] - s._labelSizes.widths[i],
    x2: e.translation[0] + s._labelSizes.widths[i] / 2,
    y: e.translation[1] - s._labelSizes.heights[i] / 2,
    y2: e.translation[1] + s._labelSizes.heights[i] / 2,
    label: e.label,
    index: i
  }))
})));

const plugin = {
  id: 'customHover',
  afterEvent: (chart, event, opts) => {
    const evt = event.event;

    if (evt.type !== 'mousemove') {
      return;
    }

    const [found, labelInfo] = findLabel(getLabelHitboxes(chart.scales), evt);

    if (found) {
      console.log(labelInfo);
    }

  }
}

Chart.register(plugin);

const options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderColor: 'pink'
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderColor: 'orange'
      }
    ]
  },
  options: {}
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>
ni65a41a

ni65a41a2#

若要在将光标悬停在Chart.js条形图中的类别标签上时将光标更改为指针,可以将以下代码添加到图表选项中:

options: {
  plugins: {
    tooltip: {
      mode: 'index',
      intersect: false
    },
  },
  interaction: {
    mode: 'index',
    intersect: false
  },
  onHover: function(evt, elements) {
    if (elements.length) {
      document.getElementById("myChart").style.cursor = "pointer";
    } else {
      document.getElementById("myChart").style.cursor = "default";
    }
  },
  // ...
}

若要更改悬停在标签上时标签的颜色,可以将以下代码添加到图表选项中:

options: {
  plugins: {
    tooltip: {
      mode: 'index',
      intersect: false
    },
  },
  interaction: {
    mode: 'index',
    intersect: false
  },
  onHover: function(evt, elements) {
    if (elements.length) {
      var chart = evt.chart;
      var datasetIndex = elements[0].datasetIndex;
      var index = elements[0].index;
      chart.data.labels[index] = '<span style="color: red;">' + chart.data.labels[index] + '</span>';
      chart.update();
    } else {
      var chart = evt.chart;
      chart.data.labels = ['Item A', 'Item B', 'Item C'];
      chart.update();
    }
  },
  // ...
}

请注意,onHover函数用于检测鼠标何时悬停在标签上。函数内的代码将光标更改为指针或默认光标,并使用具有内联样式的HTML span标记将标签的颜色更改为红色。最后,在图表上调用update方法以应用更改。

4szc88ey

4szc88ey3#

如果你对你的javascript代码做一些修改来解决你的任务,这将会有所帮助:
将图表上下文"ctx"更改为:

var ctx = document.getElementById('myChart').getContext('2d');

改为:

var ctx = document.getElementById('myChart');

要使光标在悬停在标签上时成为指针,可以尝试在触发悬停时为event.native.target.style.cursor分配CSS光标值。可以将该逻辑放入图表的options(源代码)中的onHover事件

...
onHover: (event, chartElement) => {
  event.native.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
  ...
}
...

要使标签在悬停时显示为不同的颜色,您可以尝试在ctx.onmousemove回调函数中创建一个逻辑,并使用以下命令更改标签颜色:

myChart.config.options.scales.y.ticks.color = hoverColors; // 'red', 'green', '#ffffff', etc

看看下面的代码:

window.onload = function() {
  var ctx = document.getElementById('myChart');
  const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Item A', 'Item B', 'Item C'],
      datasets: [{
        data: [1, 2, 3],
        backgroundColor: 'lightblue'
      }]
    },
    options: {
      responsive: true,
      indexAxis: 'y',
      plugins: {
        legend: {
          display: false
        },
        tooltip: {
          enabled: false
        },
      },
      onHover: (event, chartElement) => {
        // change cursor to be pointer
        event.native.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
        // update chart when hover is triggered
        event.chart.update();
      }
    }
  });
  
  ctx.onmousemove = function(mousemove) {
    // your hover color here
    // const hoverColor = '#ff0000';
    const hoverColor = 'red';
    
    const points = myChart.getElementsAtEventForMode(mousemove, 'nearest', {intersect: true}, true);
    const hoverColors = [];
    if(points[0]) {
      const dataset = points[0].datasetIndex;
      const datapoint = points[0].index;
      const backgroundColors = myChart.data.datasets[dataset].backgroundColor;
      const backgroundColor = backgroundColors[datapoint];
      for(let i=0; i < backgroundColors.length; i++) {
        if (datapoint === i) {
          hoverColors.push(hoverColor);
        } else {
          hoverColors.push(backgroundColor);
        }
      }
    }
    
    // change label to your hover color
    myChart.config.options.scales.y.ticks.color = hoverColors;
  };
};
.chart-container {
  position: relative;
  height: 90vh;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.2.0"></script>

<div class="chart-container">
  <canvas id="myChart"></canvas>
</div>
    • 更新**

感谢LeeLenalee给出了几乎正确的answer。我已经编辑了上面的代码,使其符合问题的要求。不要忘记将HTML中的库源代码更改为:

https://cdn.jsdelivr.net/npm/chart.js@4.2.0

致:

https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js

更新代码:
一个9个1x一个10个1x一个11个1x

相关问题