# 交互

命名空间: options.interaction,全局交互配置在 Chart.defaults.interaction。 要配置哪些事件触发图表交互,请参阅 events

名称 类型 默认 描述
mode string 'nearest' 设置哪些元素出现在交互中。 详见 交互模式
intersect boolean true 如果为 true,交互模式仅在鼠标位置与图表上的项目相交时适用。
axis string 'x' 可设置为 'x''y''xy''r' 以定义计算距离时使用的方向。 'index' 模式默认为 'x'dataset'nearest' 模式默认为 'xy'
includeInvisible boolean false 如果为 true,则在评估交互时也将包括图表区域之外的不可见点。

默认情况下,这些选项适用于悬停和工具提示交互。 可以在 options.hover 命名空间中设置相同的选项,在这种情况下它们只会影响悬停交互。 同样,可以在 options.plugins.tooltip 命名空间中设置选项以独立配置工具提示交互。

# 事件

以下属性定义图表如何与事件交互。 命名空间: options

名称 类型 默认 描述
events string[] ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'] events 选项定义图表应监听的浏览器事件。 这些事件中的每一个都会触发悬停并传递给插件。 more...
onHover function null 当任何事件在 chartArea 上触发时调用。 传递事件、一组活动元素(条、点等)和图表。
onClick function null 如果事件是 chartArea 上的 'mouseup''click' 或 '`'contextmenu 类型,则调用。 传递事件、活动元素数组和图表。

# 事件选项

例如,要让图表只响应点击事件,你可以这样做:

const chart = new Chart(ctx, {
  type: 'line',
  data: data,
  options: {
    // This chart will not respond to mousemove, etc
    events: ['click']
  }
});

每个插件的事件可以通过在插件选项中定义(允许的)事件数组来进一步限制:

const chart = new Chart(ctx, {
  type: 'line',
  data: data,
  options: {
    // All of these (default) events trigger a hover and are passed to all plugins,
    // unless limited at plugin options
    events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
    plugins: {
      tooltip: {
        // Tooltip will only receive click events
        events: ['click']
      }
    }
  }
});

不在 chartArea 上触发的事件,如 mouseout,可以使用一个简单的插件捕获:

const chart = new Chart(ctx, {
  type: 'line',
  data: data,
  options: {
    // these are the default events:
    // events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
  },
  plugins: [{
    id: 'myEventCatcher',
    beforeEvent(chart, args, pluginOptions) {
      const event = args.event;
      if (event.type === 'mouseout') {
        // process the event
      }
    }
  }]
});

有关插件的更多信息,请参阅 插件

# 将事件转换为数据值

一个常见的事件是采取一个事件,例如点击,并在图表上找到事件发生的数据坐标。 Chart.js 提供的辅助程序使这个过程变得简单。

const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        onClick: (e) => {
            const canvasPosition = Chart.helpers.getRelativePosition(e, chart);
            // Substitute the appropriate scale IDs
            const dataX = chart.scales.x.getValueForPixel(canvasPosition.x);
            const dataY = chart.scales.y.getValueForPixel(canvasPosition.y);
        }
    }
});

使用打包器时,必须单独导入辅助函数,如需完整说明,请前往 integration 页面

# 模式

通过 interactionhovertooltips 配置与图形的交互时,可以使用多种不同的模式。

options.hoveroptions.plugins.tooltipoptions.interaction 继承而来。 因此,如果仅在 options.interaction 中配置了 modeintersect 或任何其他常用设置,则悬停和工具提示都将遵循该设置。

下面详细介绍了这些模式以及它们如何与 intersect 设置结合使用。

查看不同模式如何与 工具提示交互示例 中的工具提示一起使用

# point

查找与该点相交的所有项目。

const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        interaction: {
            mode: 'point'
        }
    }
});

# nearest

获取距离该点最近的项目。 最近的项目是根据到图表项目(点、条)中心的距离来确定的。 你可以使用 axis 设置来定义在距离计算中考虑哪些坐标。 如果 intersect 为真,则仅当鼠标位置与图中的项目相交时才会触发。 这对于点隐藏在条形后面的组合图表非常有用。

const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        interaction: {
            mode: 'nearest'
        }
    }
});

# index

在同一索引处查找项目。 如果 intersect 设置为真,则第一个相交项用于确定数据中的索引。 如果 intersect 为假,则使用 x 方向上最近的项目来确定索引。

const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        interaction: {
            mode: 'index'
        }
    }
});

要在水平柱状图等图表中使用索引模式,我们沿 y 方向搜索,你可以使用 v2.7.0 中引入的 axis 设置。 通过在 y 方向上将此值设置为 'y' 来使用。

const chart = new Chart(ctx, {
    type: 'bar',
    data: data,
    options: {
        interaction: {
            mode: 'index',
            axis: 'y'
        }
    }
});

# dataset

在同一数据集中查找项目。 如果 intersect 设置为真,则第一个相交项用于确定数据中的索引。 如果 intersect 为 false,则使用最近的项目来确定索引。

const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        interaction: {
            mode: 'dataset'
        }
    }
});

# x

返回仅基于位置的 X 坐标相交的所有项目。 对于垂直游标实现很有用。 请注意,这仅适用于笛卡尔图表。

const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        interaction: {
            mode: 'x'
        }
    }
});

# y

返回将基于位置的 Y 坐标相交的所有项目。 这对于水平游标实现很有用。 请注意,这仅适用于笛卡尔图表。

const chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        interaction: {
            mode: 'y'
        }
    }
});

# 自定义交互模式

可以通过向 Chart.Interaction.modes 映射添加功能来定义新模式。 你可以使用 Chart.Interaction.evaluateInteractionItems 函数来帮助实现这些。

例子:

import { Interaction } from 'chart.js';
import { getRelativePosition } from 'chart.js/helpers';
/**
 * Custom interaction mode
 * @function Interaction.modes.myCustomMode
 * @param {Chart} chart - the chart we are returning items from
 * @param {Event} e - the event we are find things at
 * @param {InteractionOptions} options - options to use
 * @param {boolean} [useFinalPosition] - use final element position (animation target)
 * @return {InteractionItem[]} - items that are found
 */
Interaction.modes.myCustomMode = function(chart, e, options, useFinalPosition) {
  const position = getRelativePosition(e, chart);
  const items = [];
  Interaction.evaluateInteractionItems(chart, 'x', position, (element, datasetIndex, index) => {
    if (element.inXRange(position.x, useFinalPosition) && myCustomLogic(element)) {
      items.push({element, datasetIndex, index});
    }
  });
  return items;
};
// Then, to use it...
new Chart.js(ctx, {
    type: 'line',
    data: data,
    options: {
        interaction: {
            mode: 'myCustomMode'
        }
    }
})

如果你使用的是 TypeScript,你还需要注册新模式:

declare module 'chart.js' {
  interface InteractionModeMap {
    myCustomMode: InteractionModeFunction;
  }
}