Loading...
Tooltip
是图表交互的核心组件之一,用于动态展示数据点的详细信息,帮助用户快速理解图表中特定区域的数值、分类或其他维度信息。它能够在鼠标悬停、点击或移动到图表中的某个元素(如柱状图中的柱子、折线图中的数据点)时,动态显示相关的数据信息。
chart.options({type: 'interval',tooltip: {title: 'name', // 标题items: ['genre'], // 数据项},});
并且结合 view.interaction.tooltip
去配置提示信息的渲染和额外配置。
chart.options({type: 'view',interaction: {tooltip: { series: true },},});
当该视图中只有一个标记的时候,通过 mark.interaction.tooltip
配置提示信息的渲染和额外配置也是可以的。
chart.options({type: 'line',interaction: {tooltip: { series: true },},});
如果希望不展示该 tooltip 的提示信息,可以通过下面的配置关闭。
chart.options({type: 'interval',tooltip: false,});
如果希望图表没有提示信息交互,可以通过 chart.interaction
实现。
chart.options({type: 'view',interaction: { tooltip: false },});
尝试一下
配置项分为两个部分
tooltip
是 G2 中用于展示数据点的详细信息的一个 UI 组件。当用户将鼠标悬停在图表的某个数据点上时,tooltip 会显示该数据点的相关信息,比如坐标值、度量值等。
interaction.tooltip
是 G2 的交互机制的一部分,属于 interaction(交互)模块。它是一种内置的交互行为,用于增强工具提示的功能,特别是在某些特定的交互场景下(如动态显示或隐藏工具提示)。
tooltip
和 interaction.tooltip
中的 tooltip 是两个不同维度的配置,但容易混淆。以下是它们的核心区别:
特性 | tooltip | interaction.tooltip |
---|---|---|
职责 | 定义工具提示的内容、样式和基本行为 | 定义工具提示在交互场景下的行为 |
配置方式 | 通过 chart.tooltip() 配置 | 通过 chart.interaction() 启用或自定义 |
作用范围 | 全局生效,影响整个图表 | 与特定交互行为绑定 |
典型用途 | 设置工具提示的字段、样式、内容等 | 控制工具提示的动态显示/隐藏或其他交互逻辑 |
tooltip
属性 | 描述 | 类型 | 默认值 | 适用于 |
---|---|---|---|---|
title | 设置tooltip 的标题内容:如果值为数据字段名,则会展示数据中对应该字段的数值,如果数据中不存在该字段,将该值作为 title。详见title 配置 | title | ||
nodeTitle | 设置复合图形tooltip 标题的节点title 属性 | title | 桑基图等复合图形 | |
linkTitle | 设置复合图形tooltip 标题的弦title 属性 | title | 桑基图等复合图形 | |
items | 指定tooltip 中显示的字段,默认不同图表有不同的默认字段列表。配合 channel 配置一起使用,效果更佳。详见items 配置 | items | ||
nodeItems | 设置复合图形tooltip 标题的节点items 属性 | items | 桑基图等复合图形 | |
linkItems | 设置复合图形tooltip 标题的弦items 属性 | items | 桑基图等复合图形 |
interaction.tooltip
属性 | 描述 | 类型 | 默认值 | 适用于 |
---|---|---|---|---|
body | 是否展示 tooltip | boolean | true | |
bounding | 控制Tooltip 提示框的显示边界,超出会自动调整位置 | BBox | 图表区域大小 | |
css | 设置 tooltip 样式 | css | ||
crosshairs | 配置是否显示 crosshairs,详见crosshairs 配置 | boolean | ||
crosshairsLineDash | 配置crosshairs 虚线的间隔 | crosshairs 配置 | ||
crosshairsStroke | 配置crosshairs 显示的颜色 | string | ||
crosshairsStrokeWidth | 配置crosshairs 十字辅助线的线条宽度 | number | ||
crosshairsXStroke | 配置crosshairs X 轴显示的颜色 | string | ||
crosshairsXLineDash | 配置crosshairs X 轴虚线的间隔 | crosshairs 配置 | ||
crosshairsXStroke | 配置crosshairs X 轴显示的颜色 | string | ||
crosshairsXStrokeWidth | 配置crosshairs X 轴十字辅助线的线条宽度 | number | ||
crosshairsYStroke | 配置crosshairs Y 轴显示的颜色 | string | ||
crosshairsYLineDash | 配置crosshairs Y 轴虚线的间隔 | crosshairs 配置 | ||
crosshairsYStroke | 配置crosshairs Y 轴显示的颜色 | string | ||
crosshairsYStrokeWidth | 配置crosshairs Y 轴十字辅助线的线条宽度 | number | ||
disableNative | 禁用 pointerover 和 pointerout 事件 | boolean | false | |
enterable | tooltip 是否允许鼠标滑入 | boolean | false | |
filter | item 筛选器 | (d: TooltipItemValue) => any | - | |
groupName | 是否使用 groupName | boolean | true | |
leading | 是否在时间间隔开始的时候更新提示信息 | boolean | true | |
marker | 是否展示 marker | boolean | true | |
marker${StyleAttrs} | marker 的样式 | number | string | - | |
markerType | markerType 是提示框(Tooltip)配置项中的一个属性,用于控制提示框中标记点(Marker)的样式 | 'hollow' | undefined | undefined | |
mount | 指定提示框的挂载节点 | string | HTMLElement | 图表容器 | |
position | 设置 tooltip 的固定展示位置,相对于数据点 | TooltipPosition | ||
offset | 在位置方向上的偏移量 | [number, number] ` | [10, 10] | |
render | 自定义渲染tooltip 内容[render] (#自定义渲染内容) | (event, options) => HTMLElement | string | ||
series | 是否是系列元素的 tooltip | boolean | 多条折线、多组柱状图 | |
shared | 相同 x 的元素是否共享 tooltip | boolean | false | |
sort | item 排序器 | (d: TooltipItemValue) => any | - | |
trailing | 是否在时间间隔结束的时候更新提示信息 | boolean | false | |
trailing | 是否在时间间隔结束的时候更新提示信息 | boolean | false | |
wait | 提示信息更新的时间间隔,单位为毫秒 | number | 50 |
type TooltipPosition =| 'top'| 'bottom'| 'left'| 'right'| 'top-left'| 'top-right'| 'bottom-left'| 'bottom-right';type BBox = { x: number, y: number, width: number, height: number };
crosshairs
是提示框(Tooltip)的辅助线功能,用于在图表中标记当前数据点的精确位置,通常以横向或纵向的参考线形式呈现,帮助用户更直观地定位数据。
chart.options({interaction: {legendFilter: false,elementPointMove: true,tooltip: {crosshairs: true, // 启用十字辅助线crosshairsStroke: 'red', // 辅助线颜色为红色crosshairsLineDash: [4, 4], // 辅助线为虚线样式markerType: 'hollow', // 提示框标记点为空心},},});
title
是一个用于显示当前悬停数据点的 主标题 的字段,通常用于表示数据点所属的分类或上下文信息。
title
可以直接写入一个固定显示的字符串,或者一个方法从data
中动态获取标题
chart.options({type: 'interval',tooltip: {title: (d) => (d.sold > 150 ? 'high' : 'low'), // 设置 title},});
在不需要设置 title 的时候,可以直接声明为一个数组:
chart.options({type: 'interval',tooltip: ['genre', 'sold'],});
其中完整的 title 结构如下:
细分配置项名称 | 类型 | 功能描述 |
---|---|---|
channel | string | 定义生成 title 的通道 |
field | string | 定义生成 title 的的字段 |
value | string | title 的值 |
valueFormatter | string | Function | 格式化 title |
它们的值(value)可以通过来自原始数据,通过字符串或者 title.field
指定。
chart.options({tooltip: {title: 'sold',items: ['genre'],},});
// 等价于chart.options({tooltip: {title: { field: 'sold' },items: [{ field: 'genre' }],},});
它们的值(value)可以来自通道值,通过 title.channel
指定,常常用于使用 mark.transform
生成新通道的图表。
chart.options({tooltip: {title: { channel: 'x' },items: [{ channel: 'y' }],},});
可以通过 title.valueFormatter
去指定 title 值(value)的展示,title.valueFormatter
可以是一个函数,也可以一个 d3-format 支持的字符串。
chart.options({tooltip: {title: {field: 'sold', valueFormatter: (sold) => sold.toUpperCase()}items: [{ channel: 'y', valueFormatter: '.0%' }],},});
当然对于 title 还提供了回调去获得最大的个性化配置能力。
chart.options({tooltip: {title: (datum, index, data, column) => ({value: `<span style="color: #00ff00; font-style: italic;">${d.letter}</span>`,custom: ...}),items: [(datum, index, data, column) => ({color: d.sold > 150 ? 'red' : 'blue', // 指定 item 的颜色name: index === 0 ? d.genre : `${d.genre} ${data[i].genre}`, // 指定 item 的名字value: column.y.value[i], // 使用 y 通道的值、custom: ...}),],},});
items 返回值可用作 interaction.tooltip.render
的入参,您可以设置一些自定义参数。详见自定义渲染内容
复合图形配置
复合图形在配置tooltip.title
时需要分别配置节点与弦
({tooltip: {nodeTitle: (d) => d.key,linkTitle: (d) => 'link',},});
items
是 tooltip 配置中的一个关键属性,items
是一个数组,表示工具提示中每一项的内容。每一项通常对应于一个数据字段或一个图形元素(例如柱状图的一根柱子、折线图的一个点等)。通过自定义 items
,可以灵活地控制工具提示的显示内容,包括名称、值、颜色等信息。
其中完整的 title 结构如下:
细分配置项名称 | 类型 | 功能描述 |
---|---|---|
color | string | marker 的颜色 |
field | string | 定义生成 item 的的字段 |
name | string | item 的名字 |
value | string | item 的值 |
channel | string | 定义生成 item 的值的通道 |
valueFormatter | string | Function | 格式化 item |
items
的 value
、channel
、valueFormatter
属性的配置方式与title
一致,详细配置请参考title
名称
通过name
可以便捷的修改tooltip
中item
的名字,通过channel
来匹配图标中对应的条目。
chart.options({tooltip: {items: [{name: '张三', channel: 'y1'},{name: '李四', channel: 'y2'},],},});
颜色
tooltip
会自动根据图标内容分配tooltip
item
的颜色,但是实际应用中,可能需要根据一些规则来指定某些颜色,此时就可以通过color
属性来配置。通过channel
来匹配图标中对应的条目。
chart.options({tooltip: {items: [{color: 'pink', channel: 'y1'},{color: '#f00', channel: 'y2'},],},});
复合图形配置
复合图形在配置tooltip.items
时需要分别配置节点与弦
({tooltip: {nodeItems: [(datum, index, data, column) => {return {color: 'red', // 指定 item 的颜色name: '节点', // 指定 item 的名字value: d.key, // 使用 y 通道的值content: '节点自定义属性',};},],linkItems: [(datum, index, data, column) => {return {color: 'red', // 指定 item 的颜色name: '连接线', // 指定 item 的名字value: `${d.source.key}-${d.target.key}`, // 使用 y 通道的值content: '连接线自定义属性',};},],},});
tooltip
的 cssStyle 配置项允许通过 CSS 样式直接自定义提示框的外观, 可快速实现提示框的视觉定制,适配不同主题或交互场景需求。
(() => {const chart = new G2.Chart();chart.options({type: 'interval',data: {type: 'fetch',value:'https://gw.alipayobjects.com/os/bmw-prod/f129b517-158d-41a9-83a3-3294d639b39e.csv',format: 'csv',},encode: {x: 'state',y: 'population',color: 'age',},transform: [{ type: 'sortX', by: 'y', reverse: true, reducer: 'sum', slice: 6 },{ type: 'dodgeX' },],legend: false,interaction: {tooltip: {shared: true,mount: 'body',css: {'.g2-tooltip': {background: '#eee','border-radius': ' 0.25em !important',},'.g2-tooltip-title': {'font-size': '20px','font-weight': 'bold','padding-bottom': '0.25em',},'.g2-tooltip-list-item': {background: '#ccc',padding: '0.25em',margin: '0.25em','border-radius': '0.25em',},'.g2-tooltip-list-item-name-label': {'font-weight': 'bold','font-size': '16px',},'g2-tooltip-list-item-marker': {'border-radius': '0.25em',width: '15px',height: '15px',},'.g2-tooltip-list-item-value': {'font-weight': 'bold','font-size': '16px',},},},},});chart.render();return chart.getContainer();})();
尝试一下
有时候内置的 Tooltip 无法满足需求,这时候可以通过 mark.interaction.tooltip.render
或者 view.interaction.tooltip.render
的 render 函数来渲染自定义的提示。
该 render 函数接受事件对象 event 和提示数据 tooltipData,返回一个 string 或者 DOM 对象。其中 event 是 @antv/g 抛出的鼠标对象,tooltipData 是通过 mark.tooltip
声明的 title 和 items 数据。如果返回值是一个 string,那么会作为 tooltip 容器的 innerHTML,否则会挂载该返回值。一个提示的 render 函数的定义大概如下:
function render(event, tooltipData) {const { title, items } = tooltipData;return `<div></div>`;}
下面是一个简单的例子:
(() => {const chart = new G2.Chart();chart.interval().data({type: 'fetch',value:'https://gw.alipayobjects.com/os/bmw-prod/fb9db6b7-23a5-4c23-bbef-c54a55fee580.csv',}).transform([{ type: 'sortX', by: 'y', reverse: true }]).encode('x', 'letter').encode('y', 'frequency').interaction('tooltip', {// render 回调方法返回一个innerHTML 或者 DOMrender: (event, { title, items }) => `<div><h3 style="padding:0;margin:0">${title}</h3><ul>${items.map((d) =>`<li><span style="color: ${d.color}">${d.name}</span> ${d.value}</li>`,)}</ul></div>`,});chart.render();return chart.getContainer();})();
获取自定义 render 参数
render 函数提供了强大的个性化配置能力,通过对tooltip.render
函数返回参数的配置,自定义interaction.tooltip.render
的入参
chart.options({tooltip: {items: [(datum, index, data, column) => ({color: d.sold > 150 ? 'red' : 'blue', // 指定 item 的颜色name: index === 0 ? d.genre : `${d.genre} ${data[i].genre}`, // 指定 item 的名字value: column.y.value[i], // 使用 y 通道的值、custom1: '自定义参数1',custom2: '自定义参数2'}),],},interaction: {tooltip: {// render 回调方法返回一个innerHTML 或者 DOMrender: (event, { title, items }) => {return `<div><h3 style="padding:0;margin:0">${title}</h3><ul>${items.map(({ color, name, value, custom1, custom2 }) => ...)}</ul></div>`,}}}});
桑基图这种复合图形怎么使用 data 中的补充属性实现自定义 tooltip 的展示?
和一般Mark
自定义tooltip
交互的方法类似,先在图形的tooltip.render
里返回自定义属性,然后在interaction.render
里使用。
({type: 'sankey',data: {value: {nodes: [{ id: 'a', key: '首页', des: '节点自定义属性' },{ id: 'b', key: '页面1', des: '节点自定义属性' },{ id: 'b_1', key: '页面1', des: '节点自定义属性' },{ id: 'c', key: '页面2', des: '节点自定义属性' },{ id: 'c_1', key: '页面2', des: '节点自定义属性' },{ id: 'd', key: '页面3', des: '节点自定义属性' },{ id: 'd_1', key: '页面3', des: '节点自定义属性' },],links: [{ source: 'a', target: 'b', value: 100 },{ source: 'b', target: 'c', value: 80 },{ source: 'b', target: 'd', value: 20 },{ source: 'c', target: 'b_1', value: 80 },{ source: 'b_1', target: 'c_1', value: 40 },{ source: 'b_1', target: 'd_1', value: 40 },],},transform: [{type: 'custom',callback: (data) => ({nodes: data.nodes,links: data.links,}),},],},tooltip: {nodeItems: [(datum, index, data, column) => {return {content: d.des,};z;},],linkItems: [(datum, index, data, column) => {return {color: 'red', // 指定 item 的颜色name: '连接线', // 指定 item 的名字value: `${d.source.key}-${d.target.key}`, // 使用 y 通道的值content: '连接线自定义属性',};},],},layout: {nodeId: (d) => d.id,nodeAlign: 'center',nodePadding: 0.03,iterations: 25,},style: {labelSpacing: 3,labelFontWeight: 'bold',linkFillOpacity: 0.2,linkFill: '#3F96FF',},interaction: {tooltip: {render: (e, { items, title }) => {return `<div>${items[0].content}</div>`;},},},});
chart.on() 方法将指定的监听器注册到 chart 上,当该对象触发指定的事件时,指定的回调函数就会被执行。
chart.on('tooltip:show', (event) => {console.log(event.data.data);});chart.on('tooltip:hide', () => {console.log('hide');});
尝试一下
mark.tooltip({title: 'name', // 字段});mark.tooltip({title: (d) => (d.value > 100 ? d.name : d.age), // transform});
// 单个字段mark.tooltip('a');mark.tooltip({ field: 'a' });// 单个通道mark.tooltip({ channel: 'y' });// transformmark.tooltip((d) => (d.value > 100 ? d.name : d.age));// 格式化mark.tooltip({ channel: 'y', valueFormatter: (d) => d.toFixed(1) });// d3-format 支持的字符// https://github.com/d3/d3-formatmark.tooltip({ channel: 'y', valueFormatter: '~s' });// 完整信息mark.tooltip({ name: 'name', color: 'red', value: 'color' });// 回调mark.tooltip((d, // 每一个数据项index, // 索引data, // 完整数据column, // 通道) => ({value: `${column.y.value[index]} - ${column.y1.value[index]}`,}),);// 多个 itemmark.tooltip({ channel: 'y' }).tooltip({ channel: 'x' });
mark.tooltip({title: 'a',items: [{ channel: 'x' }, { channel: 'y' }],});
对于 Interval、Point 等非系列 Mark,控制展示的方式如下:
// 条形图、点图等chart.interval().data([{ genre: 'Sports', sold: 275 },{ genre: 'Strategy', sold: 115 },{ genre: 'Action', sold: 120 },{ genre: 'Shooter', sold: 350 },{ genre: 'Other', sold: 150 },]).encode('x', 'genre').encode('y', 'sold').encode('color', 'genre');chart.render().then((chart) =>chart.emit('tooltip:show', {offsetX: 10, // 相对于 plot 区域的位置offsetX: 20, // 相对于 plot 区域的位置data: {data: { genre: 'Sports' }, // 会找从原始数据里面找到匹配的数据},}),);
对于 Line、Area 等系列 Mark,控制展示的方式如下:
chart.line().data({ type: 'fetch', value: 'data/aapl.csv' }).encode('x', 'date').encode('y', 'close');// 根据数据拾取chart.render((chart) =>chart.emit('tooltip:show', {data: {data: { x: new Date('2010-11-16') },},}),);// 根据像素拾取chart.render((chart) =>chart.emit('tooltip:show', {offsetX: 200,offsetY: 200,}),);
隐藏的方式如下:
chart.emit('tooltip:hide');
chart.emit('tooltip:disable'); // 禁用 tooltipchart.emit('tooltip:enable'); // 启用交互
默认情况下,crossharisY
是开启的,crosshairsX
是关闭的,所以如果要开启十字辅助线,有以下两种方式。
crosshairs
为true
。chart.interaction('tooltip', {crosshairs: true, // 开启十字辅助线crosshairsXStroke: 'red', // 设置 X 轴辅助线颜色为'red'crosshairsYStroke: 'blue', // 设置 Y 轴辅助线颜色为'blue'});
crosshairsX
为true
。chart.interaction('tooltip', {crosshairsX: true, // 开启crosshairsX辅助线crosshairsXStroke: 'red', // 设置 X 轴辅助线颜色为'red'crosshairsYStroke: 'blue', // 设置 Y 轴辅助线颜色为'blue'});
crosshairsX
的优先级大于crosshairs
的优先级。
chart.interaction('tooltip', {markerType: 'hollow', // 设置提示点的样式为空心圆});