Skip to content

Commit

Permalink
Merge pull request #3687 from VisActor/feat/label-tooltip
Browse files Browse the repository at this point in the history
Feat/label tooltip
  • Loading branch information
xile611 authored Jan 26, 2025
2 parents e7b83ad + 6dc4364 commit 4d720b4
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vchart",
"comment": "feat: label support triggering mark tooltip, #3634",
"type": "none"
}
],
"packageName": "@visactor/vchart"
}
7 changes: 7 additions & 0 deletions docs/assets/option/en/component/label.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,10 @@ Used for filtering stacked group data

- 'min' displays labels for the maximum value in the stacked group
- 'max' displays labels for the minimum value in the stacked group

#${prefix} showRelatedMarkTooltip(boolean)=false

Available since version 1.13.5.

The default value is `false`, which means hovering over the label will not trigger the tooltip.
When set to `true`, hovering over the label will trigger the mark tooltip of its associated graphic.
7 changes: 7 additions & 0 deletions docs/assets/option/zh/component/label.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,10 @@ const layout = (attribute, text, getRelatedGraphic) => {

- 'min' 对堆积分组中的最大值展示标签
- 'max' 对堆积分组中的最小值展示标签

#${prefix} showRelatedMarkTooltip(boolean)=false

自 1.13.5 开始生效

默认值为 `false`,即鼠标悬浮在标签上不会触发 tooltip。
当设置为 `true` 时,鼠标悬浮在标签上会触发其关联图形的 tooltip。
6 changes: 6 additions & 0 deletions packages/vchart/src/component/label/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ export interface ILabelSpec extends IComponentSpec, ILabelAnimationSpec {
* @since 1.9.0
*/
syncState?: boolean;
/**
* 是否显示标签关联图元的 mark tooltip
* @default false
* @since 1.13.5
*/
showRelatedMarkTooltip?: boolean;
}

export type ILabelAnimationSpec = Pick<
Expand Down
26 changes: 23 additions & 3 deletions packages/vchart/src/component/label/label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { IComponentMark, ILabelMark } from '../../mark/interface';
import { MarkTypeEnum } from '../../mark/interface/type';
import { mergeSpec } from '@visactor/vutils-extension';
import { eachSeries } from '../../util/model';
import type { ISeries } from '../../series/interface';
import type { ISeries, SeriesMarkNameEnum } from '../../series/interface';
import type { IGroupMark, ILabel, IMark as IVGrammarMark } from '@visactor/vgrammar-core';
// eslint-disable-next-line no-duplicate-imports
import { registerLabel as registerVGrammarLabel } from '@visactor/vgrammar-core';
Expand All @@ -29,6 +29,7 @@ import { registerLabelMark } from '../../mark/label';
import type { IChartSpecInfo } from '../../chart/interface';
import type { IChartSpec } from '../../typings';
import { LabelSpecTransformer } from './label-transformer';
import type { IGraphic } from '@visactor/vrender-core';

export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {
static type = ComponentTypeEnum.label;
Expand Down Expand Up @@ -141,7 +142,7 @@ export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {
if (!mark) {
continue;
}
markLabelSpec[markName].forEach((spec: TransformedLabelSpec, index: number) => {
markLabelSpec[markName as SeriesMarkNameEnum].forEach((spec: TransformedLabelSpec, index: number) => {
if (spec.visible) {
const info = this._labelInfoMap.get(region);
const labelMark = this._createMark(
Expand All @@ -151,6 +152,9 @@ export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {
},
{ noSeparateStyle: true, attributeContext: series.getMarkAttributeContext() }
) as ILabelMark;
if (spec.showRelatedMarkTooltip) {
series.tooltipHelper?.activeTriggerSet.mark?.add(labelMark);
}
labelMark.setTarget(mark);
info.push({
labelMark,
Expand Down Expand Up @@ -353,14 +357,30 @@ export class Label<T extends IChartSpec = any> extends BaseLabelComponent<T> {

getVRenderComponents() {
const labels: any[] = [];
this._labelComponentMap.forEach((info, component) => {
this._labelComponentMap.forEach((infoFunc, component) => {
const graphicItem = component.getProduct().getGroupGraphicItem();
if (graphicItem) {
labels.push(graphicItem);
}
});
return labels;
}

getLabelInfoByTextGraphic(text: IGraphic): ILabelInfo {
let labelInfo: ILabelInfo;
const vrenderLabel = text?.parent;
const vrenderDataLabel = vrenderLabel?.parent;
if (vrenderDataLabel) {
const labelIndex = vrenderDataLabel.getChildren().indexOf(vrenderLabel as any);
this._labelComponentMap.forEach((infoFunc, component) => {
const graphicItem = component.getProduct().getGroupGraphicItem();
if (graphicItem === vrenderDataLabel) {
labelInfo = array(infoFunc())[labelIndex];
}
});
}
return labelInfo;
}
}

export const registerLabel = () => {
Expand Down
25 changes: 23 additions & 2 deletions packages/vchart/src/component/tooltip/processor/mark-tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { BaseTooltipProcessor } from './base';
import type { ISeries } from '../../../series/interface';
import { IContainPointMode } from '@visactor/vrender-core';
import type { IDimensionData } from '../../../event/events/dimension/interface';
import type { Label } from '../../label';

export class MarkTooltipProcessor extends BaseTooltipProcessor {
activeType: TooltipActiveType = 'mark';
Expand Down Expand Up @@ -49,6 +50,7 @@ export class MarkTooltipProcessor extends BaseTooltipProcessor {

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

const modelType = params.model?.modelType;
// 处理mark info
if (params.model?.modelType === 'series') {
if (modelType === 'series') {
const series = params.model as ISeries;
const helper = series.tooltipHelper;
const activeTriggers = helper?.activeTriggerSet.mark;
Expand All @@ -87,8 +90,26 @@ export class MarkTooltipProcessor extends BaseTooltipProcessor {
} else if (ignoreTriggers?.has(params.mark)) {
ignore = true;
}
} else if (modelType === 'component') {
const model = params.model as Label;
const node = params.node;
if (model.name === 'label' && node) {
const labelInfo = model.getLabelInfoByTextGraphic(node);
const { baseMark, series, labelMark } = labelInfo ?? {};
const helper = series.tooltipHelper;
const activeTriggers = helper?.activeTriggerSet.mark;
const ignoreTriggers = helper?.ignoreTriggerSet.mark;
if (activeTriggers?.has(labelMark)) {
info = {
mark: baseMark as any, // 标签的 tooltip 与其关联图元保持一致
datum: (node.attribute as any).data,
series
};
} else if (ignoreTriggers?.has(labelMark)) {
ignore = true;
}
}
}

return {
tooltipInfo: info,
ignore
Expand Down

0 comments on commit 4d720b4

Please sign in to comment.