From 8a104298434b91f342c9f7b2b70d50198b2013e3 Mon Sep 17 00:00:00 2001 From: MiniPear Date: Tue, 19 Sep 2023 11:22:37 +0800 Subject: [PATCH] feat(tooltip): support css (#5563) --- .../step0.html | 278 ++++++++++++++++++ __tests__/plots/tooltip/index.ts | 1 + .../stateages-interval-custom-style.ts | 59 ++++ site/docs/manual/core/tooltip.zh.md | 70 ++++- site/docs/spec/interaction/tooltip.zh.md | 41 +-- .../component/tooltip/demo/tooltip-style.ts | 90 +++--- src/interaction/tooltip.ts | 24 +- src/spec/interaction.ts | 1 + 8 files changed, 478 insertions(+), 86 deletions(-) create mode 100644 __tests__/integration/snapshots/tooltip/state-ages-interval-custom-style/step0.html create mode 100644 __tests__/plots/tooltip/stateages-interval-custom-style.ts diff --git a/__tests__/integration/snapshots/tooltip/state-ages-interval-custom-style/step0.html b/__tests__/integration/snapshots/tooltip/state-ages-interval-custom-style/step0.html new file mode 100644 index 0000000000..5d7f9f3d2b --- /dev/null +++ b/__tests__/integration/snapshots/tooltip/state-ages-interval-custom-style/step0.html @@ -0,0 +1,278 @@ +
+
+ CA +
+ +
\ No newline at end of file diff --git a/__tests__/plots/tooltip/index.ts b/__tests__/plots/tooltip/index.ts index b54831af42..025b0085f2 100644 --- a/__tests__/plots/tooltip/index.ts +++ b/__tests__/plots/tooltip/index.ts @@ -64,3 +64,4 @@ export { provincesLineGroupName } from './provinces-line-group-name'; export { pointsPointRegressionQuad } from './points-point-regression-quad'; export { alphabetIntervalTooltipRenderUpdate } from './alphabet-interval-tooltip-render-update'; export { mockIntervalShared } from './mock-interval-shared'; +export { stateAgesIntervalCustomStyle } from './stateages-interval-custom-style'; diff --git a/__tests__/plots/tooltip/stateages-interval-custom-style.ts b/__tests__/plots/tooltip/stateages-interval-custom-style.ts new file mode 100644 index 0000000000..9a84358d07 --- /dev/null +++ b/__tests__/plots/tooltip/stateages-interval-custom-style.ts @@ -0,0 +1,59 @@ +import { G2Spec } from '../../../src'; +import { tooltipSteps } from './utils'; + +export function stateAgesIntervalCustomStyle(): G2Spec { + return { + type: 'interval', + transform: [ + { type: 'sortX', by: 'y', reverse: true, reducer: 'sum', slice: 6 }, + { type: 'dodgeX' }, + ], + data: { + type: 'fetch', + value: 'data/stateages.csv', + }, + legend: false, + encode: { + x: 'state', + y: 'population', + color: 'age', + }, + interaction: { + tooltip: { + shared: true, + 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', + }, + }, + }, + }, + }; +} + +stateAgesIntervalCustomStyle.steps = tooltipSteps(0); diff --git a/site/docs/manual/core/tooltip.zh.md b/site/docs/manual/core/tooltip.zh.md index 2fb03ea40a..99dd8201ab 100644 --- a/site/docs/manual/core/tooltip.zh.md +++ b/site/docs/manual/core/tooltip.zh.md @@ -216,7 +216,7 @@ G2 默认打开 Tooltip 交互 ,如果需要配置 Tooltip 属性,可以通 })(); ``` -## 关闭 tooltip +## 关闭 Tooltip 如果希望不展示该 Mark 的提示信息,可以通过 `mark.tooltip` 实现。 @@ -243,3 +243,71 @@ chart.interval().tooltip(false); ```js chart.interaction('tooltip', false); ``` + +## 设置 Tooltip 样式 + +```js | ob +(() => { + 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(); +})(); +``` diff --git a/site/docs/spec/interaction/tooltip.zh.md b/site/docs/spec/interaction/tooltip.zh.md index 1a05611cf5..d29615c0b4 100644 --- a/site/docs/spec/interaction/tooltip.zh.md +++ b/site/docs/spec/interaction/tooltip.zh.md @@ -33,26 +33,27 @@ chart.render(); ## 选项 -| 属性 | 描述 | 类型 | 默认值 | -| ------------------------- | -------------------------------------------- | ------------------------------------------- | ------------ | -| wait | 提示信息更新的时间间隔,单位为毫秒 | `number` | 50 | -| leading | 是否在时间间隔开始的时候更新提示信息 | `boolean` | true | -| trailing | 是否在时间间隔结束的时候更新提示信息 | `boolean` | false | -| shared | 相同 x 的元素是否共享 tooltip | `boolean` | false | -| series | 是否是系列元素的 tooltip | `boolean` | - | -| body | 是否展示 tooltip | `boolean` | true | -| marker | 是否展示 marker | `boolean` | true | -| groupName | 是否使用 groupName | `boolean` | true | -| position | tooltip 位置 | `TooltipPosition` | - | -| mount | tooltip 渲染的 dom 节点 | `string` \| `HTMLElement` | 图表容器 | -| bounding | tooltip 渲染的限制区域,超出会自动调整位置 | `BBox` | 图表区域大小 | -| crosshairs | 是否暂时指示线 | `boolean` | - | -| `crosshairs${StyleAttrs}` | 指示线的样式 | `number \| string` | - | -| `marker${StyleAttrs}` | marker 的样式 | `number \| string` | - | -| render | 自定义 tooltip 渲染函数 | `(event, options) => HTMLElement \| string` | - | -| sort | item 排序器 | `(d: TooltipItemValue) => any` | - | -| filter | item 筛选器 | `(d: TooltipItemValue) => any` | - | -| disableNative | 是否响应原生事件(pointerover 和 pointerout) | true | `boolean` | +| 属性 | 描述 | 类型 | 默认值 | +| ------------------------- | ----------------------------------------------------------------- | ------------------------------------------- | --------------------- | +| wait | 提示信息更新的时间间隔,单位为毫秒 | `number` | 50 | +| leading | 是否在时间间隔开始的时候更新提示信息 | `boolean` | true | +| trailing | 是否在时间间隔结束的时候更新提示信息 | `boolean` | false | +| shared | 相同 x 的元素是否共享 tooltip | `boolean` | false | +| series | 是否是系列元素的 tooltip | `boolean` | - | +| body | 是否展示 tooltip | `boolean` | true | +| marker | 是否展示 marker | `boolean` | true | +| groupName | 是否使用 groupName | `boolean` | true | +| position | tooltip 位置 | `TooltipPosition` | - | +| mount | tooltip 渲染的 dom 节点 | `string` \| `HTMLElement` | 图表容器 | +| bounding | tooltip 渲染的限制区域,超出会自动调整位置 | `BBox` | 图表区域大小 | +| crosshairs | 是否暂时指示线 | `boolean` | - | +| `crosshairs${StyleAttrs}` | 指示线的样式 | `number \| string` | - | +| `marker${StyleAttrs}` | marker 的样式 | `number \| string` | - | +| render | 自定义 tooltip 渲染函数 | `(event, options) => HTMLElement \| string` | - | +| sort | item 排序器 | `(d: TooltipItemValue) => any` | - | +| filter | item 筛选器 | `(d: TooltipItemValue) => any` | - | +| disableNative | 是否响应原生事件(pointerover 和 pointerout) | true | `boolean` | +| css | 设置容器的 [css](/examples/component/tooltip/#tooltip-style) 样式 | - | `Record` | ```ts type TooltipPosition = diff --git a/site/examples/component/tooltip/demo/tooltip-style.ts b/site/examples/component/tooltip/demo/tooltip-style.ts index 2f4af9dfbe..1e52fcc58b 100644 --- a/site/examples/component/tooltip/demo/tooltip-style.ts +++ b/site/examples/component/tooltip/demo/tooltip-style.ts @@ -1,53 +1,5 @@ import { Chart } from '@antv/g2'; -insetCss(` - .g2-tooltip { - background: #eee !important; - border-radius: 0.25em !important; - } - - .g2-tooltip-title { - font-size: 20px !important; - font-weight: bold !important; - padding-bottom: 0.25em !important; - } - - .g2-tooltip-list { - background: #ddd !important; - padding: 0.25em !important; - border-radius: 0.25em !important; - } - - .g2-tooltip-list-item { - background: #ccc !important; - padding: 0.25em !important; - margin: 0.25em !important; - border-radius: 0.25em !important; - } - - .g2-tooltip-list-item-name { - background: #bbb !important; - padding: 0 0.25em !important; - border-radius: 0.25em !important; - } - - .g2-tooltip-list-item-name-label { - font-weight: bold !important; - font-size: 16px !important; - } - - .g2-tooltip-list-item-marker { - border-radius: 0.25em !important; - width: 15px !important; - height: 15px !important; - } - - .g2-tooltip-list-item-value { - font-weight: bold !important; - font-size: 16px !important; - } -`); - const chart = new Chart({ container: 'container', }); @@ -67,14 +19,38 @@ chart .encode('color', 'age') .scale('y', { nice: true }) .axis('y', { labelFormatter: '~s' }) - .interaction('tooltip', { shared: true }); + .interaction('tooltip', { + shared: true, + 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(); - -function insetCss(css) { - const style = document.createElement('style'); - const container = document.getElementById('container'); - style.type = 'text/css'; - style.innerHTML = css; - container.append(style); -} diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts index 7197ff4ce9..6af3434594 100644 --- a/src/interaction/tooltip.ts +++ b/src/interaction/tooltip.ts @@ -63,7 +63,16 @@ function createTooltip( enterable, bounding, containerOffset, + css = {}, ) { + const defaults = { + '.g2-tooltip': {}, + '.g2-tooltip-title': { + overflow: 'hidden', + 'white-space': 'nowrap', + 'text-overflow': 'ellipsis', + }, + }; const tooltipElement = new TooltipComponent({ className: 'tooltip', style: { @@ -79,14 +88,7 @@ function createTooltip( template: { prefixCls: 'g2-', }, - style: { - '.g2-tooltip': {}, - '.g2-tooltip-title': { - overflow: 'hidden', - 'white-space': 'nowrap', - 'text-overflow': 'ellipsis', - }, - }, + style: deepMix(defaults, css), }, }); container.appendChild(tooltipElement.HTMLTooltipElement); @@ -103,6 +105,7 @@ function showTooltip({ single, position = 'right-bottom', enterable = false, + css, mount, bounding, }) { @@ -123,6 +126,7 @@ function showTooltip({ enterable, b, containerOffset, + css, ), } = parent as any; const { items, title = '' } = data; @@ -431,6 +435,7 @@ export function seriesTooltip( disableNative = false, marker = true, style: _style = {}, + css = {}, ...rest }: Record, ) { @@ -597,6 +602,7 @@ export function seriesTooltip( enterable, mount, bounding, + css, }); } @@ -733,6 +739,7 @@ export function tooltip( shared = false, body = true, disableNative = false, + css = {}, }: Record, ) { const elements = elementsof(root); @@ -780,6 +787,7 @@ export function tooltip( enterable, mount, bounding, + css, }); } diff --git a/src/spec/interaction.ts b/src/spec/interaction.ts index 9bc125b169..e2d9b71435 100644 --- a/src/spec/interaction.ts +++ b/src/spec/interaction.ts @@ -180,6 +180,7 @@ export type TooltipInteraction = { position?: TooltipStyleProps['position']; bounding?: BBox; mount?: string | HTMLElement; + css?: Record; // @todo // enterable?: boolean; sort?: (d: TooltipItemValue) => any; filter?: (d: TooltipItemValue) => any;