Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vchart",
"comment": "feat: support label of boxPlot",
"type": "none"
}
],
"packageName": "@visactor/vchart"
}
45 changes: 44 additions & 1 deletion packages/vchart/src/component/label/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Direction } from '../../typings/space';
import type { BaseLabelAttrs, LabelItem, OverlapAttrs, Strategy } from '@visactor/vrender-components';
import { SeriesTypeEnum, type ICartesianSeries } from '../../series/interface';
import { isBoolean, isFunction, isObject, isString } from '@visactor/vutils';
import type { IGlyph, IGraphic, IText } from '@visactor/vrender-core';
import { createText } from '@visactor/vrender-core';
import type { IWaterfallSeriesSpec } from '../../series/waterfall/interface';
import type { ILabelInfo, ILabelSpec } from './interface';
Expand All @@ -22,7 +23,8 @@ export const labelRuleMap = {
rect3d: barLabel,
arc3d: pieLabel,
treemap: treemapLabel,
venn: vennLabel
venn: vennLabel,
boxPlot: boxPlotLabel
};

export function defaultLabelConfig(rule: string, labelInfo: ILabelInfo) {
Expand Down Expand Up @@ -463,3 +465,44 @@ function sankeyLabelOverlapStrategy(series: ICartesianSeries) {

return strategy;
}

export function boxPlotLabel(labelInfo: ILabelInfo) {
return {
customLayoutFunc: (labels: LabelItem[], texts: IText[], getRelatedGraphic: (item: LabelItem) => IGraphic) => {
for (let i = 0; i < texts.length; i++) {
const text = texts[i];
const textData = labels[i];
if (!text || !textData) {
continue;
}

const baseBoxPlot = getRelatedGraphic(textData) as IGlyph;
const meadianLineIndex = baseBoxPlot.getSubGraphic().findIndex(sub => sub.name === 'median');

if (meadianLineIndex !== -1) {
const bbox = baseBoxPlot.getSubGraphic()[meadianLineIndex].AABBBounds;

if ((labelInfo.series as ICartesianSeries).direction === 'horizontal') {
text.setAttributes({
x: bbox.x2 + text.AABBBounds.width() / 2,
y: (bbox.y1 + bbox.y2) / 2
});
} else {
text.setAttributes({
x: (bbox.x1 + bbox.x2) / 2,
y: bbox.y2 + text.AABBBounds.height() / 2
});
}
} else {
const bbox = baseBoxPlot.AABBBounds;
text.setAttributes({
x: (bbox.x1 + bbox.x2) / 2,
y: (bbox.y1 + bbox.y2) / 2
});
}
}

return texts;
}
};
}
4 changes: 4 additions & 0 deletions packages/vchart/src/mark/box-plot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ export class BoxPlotMark
}
}

setDataLabelType() {
return 'symbol';
}

protected _getDefaultStyle() {
const defaultStyle: IMarkStyle<IBoxPlotMarkSpec> = {
...super._getDefaultStyle(),
Expand Down
12 changes: 12 additions & 0 deletions packages/vchart/src/series/box-plot/box-plot-transformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { BaseSeriesSpecTransformer } from '../base';
import { SeriesMarkNameEnum } from '../interface';
import type { IBoxPlotSeriesSpec, IBoxPlotSeriesTheme } from './interface';

export class BoxPlotSeriesSpecTransformer<
T extends IBoxPlotSeriesSpec = IBoxPlotSeriesSpec,
K extends IBoxPlotSeriesTheme = IBoxPlotSeriesTheme
> extends BaseSeriesSpecTransformer<T, K> {
protected _transformLabelSpec(spec: T): void {
this._addMarkLabelSpec(spec, SeriesMarkNameEnum.boxPlot);
}
}
19 changes: 18 additions & 1 deletion packages/vchart/src/series/box-plot/box-plot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { registerBoxPlotMark } from '../../mark/box-plot';
import { registerSymbolMark } from '../../mark/symbol';
import { boxPlotSeriesMark } from './constant';
import { Factory } from '../../core/factory';
import type { IBoxPlotMark, IGlyphMark, IMark, ISymbolMark } from '../../mark/interface';
import type { IBoxPlotMark, IGlyphMark, IMark, ISymbolMark, ITextMark } from '../../mark/interface';
import { merge, isNumber, isValid, isNil, array, last } from '@visactor/vutils';
import { getGroupAnimationParams } from '../util/utils';
import { registerCartesianLinearAxis, registerCartesianBandAxis } from '../../component/axis/cartesian';
Expand All @@ -35,6 +35,7 @@ import { registeBoxPlotScaleAnimation } from './animation';
import { boxPlot } from '../../theme/builtin/common/series/box-plot';
import { getActualNumValue } from '../../util/space';
import { isContinuous } from '@visactor/vscale';
import { BoxPlotSeriesSpecTransformer } from './box-plot-transformer';

const DEFAULT_STROKE_WIDTH = 2;
const DEFAULT_SHAFT_FILL_OPACITY = 0.5;
Expand All @@ -51,6 +52,9 @@ export class BoxPlotSeries<T extends IBoxPlotSeriesSpec = IBoxPlotSeriesSpec> ex
static readonly builtInTheme = { boxPlot };
static readonly mark: SeriesMarkMap = boxPlotSeriesMark;

static readonly transformerConstructor = BoxPlotSeriesSpecTransformer as any;
readonly transformerConstructor = BoxPlotSeriesSpecTransformer;

protected _bandPosition = 0;
protected _minField: string;
getMinField() {
Expand Down Expand Up @@ -272,6 +276,19 @@ export class BoxPlotSeries<T extends IBoxPlotSeriesSpec = IBoxPlotSeriesSpec> ex
}
}

initLabelMarkStyle(textMark: ITextMark) {
if (!textMark) {
return;
}
this.setMarkStyle(textMark, {
fill: this.getColorAttribute(),
text: (datum: Datum) => {
return datum[this.getMedianField()];
},
z: this._fieldZ ? this.dataToPositionZ.bind(this) : null
});
}

initData(): void {
super.initData();
if (!this._data) {
Expand Down
Loading