Skip to content

Commit 4d720b4

Browse files
authored
Merge pull request #3687 from VisActor/feat/label-tooltip
Feat/label tooltip
2 parents e7b83ad + 6dc4364 commit 4d720b4

File tree

6 files changed

+76
-5
lines changed

6 files changed

+76
-5
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@visactor/vchart",
5+
"comment": "feat: label support triggering mark tooltip, #3634",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@visactor/vchart"
10+
}

docs/assets/option/en/component/label.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,10 @@ Used for filtering stacked group data
403403

404404
- 'min' displays labels for the maximum value in the stacked group
405405
- 'max' displays labels for the minimum value in the stacked group
406+
407+
#${prefix} showRelatedMarkTooltip(boolean)=false
408+
409+
Available since version 1.13.5.
410+
411+
The default value is `false`, which means hovering over the label will not trigger the tooltip.
412+
When set to `true`, hovering over the label will trigger the mark tooltip of its associated graphic.

docs/assets/option/zh/component/label.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,10 @@ const layout = (attribute, text, getRelatedGraphic) => {
401401

402402
- 'min' 对堆积分组中的最大值展示标签
403403
- 'max' 对堆积分组中的最小值展示标签
404+
405+
#${prefix} showRelatedMarkTooltip(boolean)=false
406+
407+
自 1.13.5 开始生效
408+
409+
默认值为 `false`,即鼠标悬浮在标签上不会触发 tooltip。
410+
当设置为 `true` 时,鼠标悬浮在标签上会触发其关联图形的 tooltip。

packages/vchart/src/component/label/interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ export interface ILabelSpec extends IComponentSpec, ILabelAnimationSpec {
9696
* @since 1.9.0
9797
*/
9898
syncState?: boolean;
99+
/**
100+
* 是否显示标签关联图元的 mark tooltip
101+
* @default false
102+
* @since 1.13.5
103+
*/
104+
showRelatedMarkTooltip?: boolean;
99105
}
100106

101107
export type ILabelAnimationSpec = Pick<

packages/vchart/src/component/label/label.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type { IComponentMark, ILabelMark } from '../../mark/interface';
1111
import { MarkTypeEnum } from '../../mark/interface/type';
1212
import { mergeSpec } from '@visactor/vutils-extension';
1313
import { eachSeries } from '../../util/model';
14-
import type { ISeries } from '../../series/interface';
14+
import type { ISeries, SeriesMarkNameEnum } from '../../series/interface';
1515
import type { IGroupMark, ILabel, IMark as IVGrammarMark } from '@visactor/vgrammar-core';
1616
// eslint-disable-next-line no-duplicate-imports
1717
import { registerLabel as registerVGrammarLabel } from '@visactor/vgrammar-core';
@@ -29,6 +29,7 @@ import { registerLabelMark } from '../../mark/label';
2929
import type { IChartSpecInfo } from '../../chart/interface';
3030
import type { IChartSpec } from '../../typings';
3131
import { LabelSpecTransformer } from './label-transformer';
32+
import type { IGraphic } from '@visactor/vrender-core';
3233

3334
export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {
3435
static type = ComponentTypeEnum.label;
@@ -141,7 +142,7 @@ export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {
141142
if (!mark) {
142143
continue;
143144
}
144-
markLabelSpec[markName].forEach((spec: TransformedLabelSpec, index: number) => {
145+
markLabelSpec[markName as SeriesMarkNameEnum].forEach((spec: TransformedLabelSpec, index: number) => {
145146
if (spec.visible) {
146147
const info = this._labelInfoMap.get(region);
147148
const labelMark = this._createMark(
@@ -151,6 +152,9 @@ export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {
151152
},
152153
{ noSeparateStyle: true, attributeContext: series.getMarkAttributeContext() }
153154
) as ILabelMark;
155+
if (spec.showRelatedMarkTooltip) {
156+
series.tooltipHelper?.activeTriggerSet.mark?.add(labelMark);
157+
}
154158
labelMark.setTarget(mark);
155159
info.push({
156160
labelMark,
@@ -353,14 +357,30 @@ export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {
353357

354358
getVRenderComponents() {
355359
const labels: any[] = [];
356-
this._labelComponentMap.forEach((info, component) => {
360+
this._labelComponentMap.forEach((infoFunc, component) => {
357361
const graphicItem = component.getProduct().getGroupGraphicItem();
358362
if (graphicItem) {
359363
labels.push(graphicItem);
360364
}
361365
});
362366
return labels;
363367
}
368+
369+
getLabelInfoByTextGraphic(text: IGraphic): ILabelInfo {
370+
let labelInfo: ILabelInfo;
371+
const vrenderLabel = text?.parent;
372+
const vrenderDataLabel = vrenderLabel?.parent;
373+
if (vrenderDataLabel) {
374+
const labelIndex = vrenderDataLabel.getChildren().indexOf(vrenderLabel as any);
375+
this._labelComponentMap.forEach((infoFunc, component) => {
376+
const graphicItem = component.getProduct().getGroupGraphicItem();
377+
if (graphicItem === vrenderDataLabel) {
378+
labelInfo = array(infoFunc())[labelIndex];
379+
}
380+
});
381+
}
382+
return labelInfo;
383+
}
364384
}
365385

366386
export const registerLabel = () => {

packages/vchart/src/component/tooltip/processor/mark-tooltip.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { BaseTooltipProcessor } from './base';
66
import type { ISeries } from '../../../series/interface';
77
import { IContainPointMode } from '@visactor/vrender-core';
88
import type { IDimensionData } from '../../../event/events/dimension/interface';
9+
import type { Label } from '../../label';
910

1011
export class MarkTooltipProcessor extends BaseTooltipProcessor {
1112
activeType: TooltipActiveType = 'mark';
@@ -49,6 +50,7 @@ export class MarkTooltipProcessor extends BaseTooltipProcessor {
4950

5051
const newParams: TooltipHandlerParams = {
5152
...(params as any),
53+
model: series, // 在 label 支持 mark tooltip 后,eventParam.model 可能是 label 组件,而 tooltip 中需要的是 series
5254
changePositionOnly,
5355
tooltip: this.component
5456
};
@@ -72,8 +74,9 @@ export class MarkTooltipProcessor extends BaseTooltipProcessor {
7274
let info: MarkTooltipInfo | undefined;
7375
let ignore: boolean | undefined;
7476

77+
const modelType = params.model?.modelType;
7578
// 处理mark info
76-
if (params.model?.modelType === 'series') {
79+
if (modelType === 'series') {
7780
const series = params.model as ISeries;
7881
const helper = series.tooltipHelper;
7982
const activeTriggers = helper?.activeTriggerSet.mark;
@@ -87,8 +90,26 @@ export class MarkTooltipProcessor extends BaseTooltipProcessor {
8790
} else if (ignoreTriggers?.has(params.mark)) {
8891
ignore = true;
8992
}
93+
} else if (modelType === 'component') {
94+
const model = params.model as Label;
95+
const node = params.node;
96+
if (model.name === 'label' && node) {
97+
const labelInfo = model.getLabelInfoByTextGraphic(node);
98+
const { baseMark, series, labelMark } = labelInfo ?? {};
99+
const helper = series.tooltipHelper;
100+
const activeTriggers = helper?.activeTriggerSet.mark;
101+
const ignoreTriggers = helper?.ignoreTriggerSet.mark;
102+
if (activeTriggers?.has(labelMark)) {
103+
info = {
104+
mark: baseMark as any, // 标签的 tooltip 与其关联图元保持一致
105+
datum: (node.attribute as any).data,
106+
series
107+
};
108+
} else if (ignoreTriggers?.has(labelMark)) {
109+
ignore = true;
110+
}
111+
}
90112
}
91-
92113
return {
93114
tooltipInfo: info,
94115
ignore

0 commit comments

Comments
 (0)