Skip to content

Commit

Permalink
refactor: walkthrough label (#2981)
Browse files Browse the repository at this point in the history
Co-authored-by: xinming <xinming.lxj@antfin.com>
  • Loading branch information
visiky and xinming authored Nov 9, 2020
1 parent 4dcf6c9 commit 49051d4
Show file tree
Hide file tree
Showing 16 changed files with 418 additions and 142 deletions.
16 changes: 8 additions & 8 deletions docs/api-zh/legend.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ _legendOption_ 配置如下:

背景框配置项。_LegendBackgroundCfg_ 配置如下:

| 参数名 | 类型 | 是否必选 | 默认值 | 描述 |
| ------- | ------------------- | -------- | ------ | -------------- |
| padding | number \| number[] | | - | 背景的留白 |
| style | [ShapeAttrs](shape) | | - | 背景样式配置项 |
| 参数名 | 类型 | 默认值 | 描述 |
| ------- | ------------------- | ------ | -------------- |
| padding | number \| number[] | - | 背景的留白 |
| style | [ShapeAttrs](shape) | - | 背景样式配置项 |

### legendOption.flipPage

Expand All @@ -81,10 +81,10 @@ _legendOption_ 配置如下:

适用于 <tag color="cyan" text="连续图例">连续图例</tag>,滑块的配置项。_ContinueLegendHandlerCfg_ 配置如下:

| 参数名 | 类型 | 是否必选 | 默认值 | 描述 |
| ------ | ------------------- | -------- | ------ | -------------- |
| size | number | | - | 滑块的大小 |
| style | [ShapeAttrs](shape) | | - | 滑块的样式设置 |
| 参数名 | 类型 | 默认值 | 描述 |
| ------ | ------------------- | ------ | -------------- |
| size | number | - | 滑块的大小 |
| style | [ShapeAttrs](shape) | - | 滑块的样式设置 |

### legendOption.itemHeight

Expand Down
4 changes: 4 additions & 0 deletions examples/gallery/area/demo/area4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/gas-import-export.js
position: [2040, 6.3],
content: '出口至墨西哥',
style: {
fill: '#eee',
fontWeight: 300,
textAlign: 'end',
textBaseline: 'center'
Expand All @@ -47,6 +48,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/gas-import-export.js
position: [2040, 5],
content: '出口至加拿大',
style: {
fill: '#eee',
fontWeight: 300,
textAlign: 'end',
textBaseline: 'center'
Expand All @@ -59,6 +61,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/gas-import-export.js
position: [2040, 2],
content: '来自40个州的液化天然气出口',
style: {
fill: '#eee',
fontWeight: 300,
textAlign: 'end',
textBaseline: 'center'
Expand All @@ -70,6 +73,7 @@ fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/gas-import-export.js
position: [2015, -1.5],
content: '从加拿大进口',
style: {
fill: '#eee',
fontWeight: 300,
textAlign: 'start',
textBaseline: 'center'
Expand Down
3 changes: 1 addition & 2 deletions examples/pie/basic/demo/innerlabel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,12 @@ chart
.position('percent')
.color('item')
.label('percent', {
offset: -40,
offset: '-30%',
style: {
textAlign: 'center',
fontSize: 16,
shadowBlur: 2,
shadowColor: 'rgba(0, 0, 0, .45)',
fill: '#fff',
},
})
.tooltip('item*percent', (item, percent) => {
Expand Down
2 changes: 1 addition & 1 deletion examples/pie/basic/demo/pie-size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ chart
.color('type')
.shape('slice-shape')
.label('type', {
offset: -130,
offset: '-70%',
layout: {
type: 'limit-in-shape',
},
Expand Down
32 changes: 8 additions & 24 deletions src/component/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { AnimateOption, GeometryLabelLayoutCfg } from '../interface';
import { doAnimate } from '../animate';
import { getGeometryLabelLayout } from '../geometry/label';
import { getlLabelBackgroundInfo } from '../geometry/label/util';
import { getReplaceAttrs, polarToCartesian } from '../util/graphics';
import { polarToCartesian } from '../util/graphics';
import { rotate, translate } from '../util/transform';
import { FIELD_ORIGIN } from '../constant';
import { updateLabel } from './update-label';

/**
* Labels 实例创建时,传入构造函数的参数定义
Expand Down Expand Up @@ -81,31 +82,14 @@ export default class Labels {
const data = shape.get('data');
const origin = shape.get('origin');
const coordinate = shape.get('coordinate');
const currentShape = lastShapesMap[id]; // 已经在渲染树上的 shape
const currentAnimateCfg = shape.get('animateCfg');
currentShape.set('data', data);
currentShape.set('origin', origin);
currentShape.set('animateCfg', currentAnimateCfg);
currentShape.set('coordinate', coordinate);

const updateAnimateCfg = get(currentAnimateCfg, 'update');
const currentChildren = currentShape.getChildren();
shape.getChildren().map((child, index) => {
const currentChild = currentChildren[index] as IShape;
currentChild.set('data', data);
currentChild.set('origin', origin);
currentChild.set('animateCfg', currentAnimateCfg);
currentChild.set('coordinate', coordinate);

const newAttrs = getReplaceAttrs(currentChild, child);
if (updateAnimateCfg) {
doAnimate(currentChild, updateAnimateCfg, {
toAttrs: newAttrs,
coordinate,
});
} else {
currentChild.attr(newAttrs);
}
const currentShape = lastShapesMap[id]; // 已经在渲染树上的 shape
updateLabel(currentShape, shapesMap[id], {
data,
origin,
animateCfg: currentAnimateCfg,
coordinate,
});

this.shapesMap[id] = currentShape; // 保存引用
Expand Down
68 changes: 68 additions & 0 deletions src/component/update-label.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Coordinate } from '@antv/coord';
import { IGroup, IShape } from '@antv/g-base';
import { each, get } from '@antv/util';
import { doAnimate } from '../animate';
import { getReplaceAttrs } from '../util/graphics';

/** label 的必要配置 */
type Cfg = {
data: any;
origin: any;
animateCfg: any;
coordinate: Coordinate;
};

/**
* @desc 更新 label (目前没有根据 id 索引,还是会存在一点小问题的,只能根据 idx 索引)
* @done shape 属性更新
* @done shape delete
* @done shape append
*
* @param fromShape old labelShape
* @param toShape new labelShape
* @param cfg
*/
export function updateLabel(fromShape: IGroup, toShape: IGroup, cfg: Cfg): void {
const { data, origin, animateCfg, coordinate } = cfg;
const updateAnimateCfg = get(animateCfg, 'update');

fromShape.set('data', data);
fromShape.set('origin', origin);
fromShape.set('animateCfg', animateCfg);
fromShape.set('coordinate', coordinate);

fromShape.getChildren().forEach((fromChild, idx) => {
const toChild = toShape.getChildByIndex(idx) as IShape;
if (!toChild) {
fromShape.removeChild(fromChild);
fromChild.remove(true);
} else {
fromChild.set('data', data);
fromChild.set('origin', origin);
fromChild.set('animateCfg', animateCfg);
fromChild.set('coordinate', coordinate);

const newAttrs = getReplaceAttrs(fromChild as IShape, toChild);
if (updateAnimateCfg) {
doAnimate(fromChild as IShape, updateAnimateCfg, {
toAttrs: newAttrs,
coordinate,
});
} else {
fromChild.attr(newAttrs);
}
if (toChild.isGroup()) {
updateLabel(fromChild as any, toChild as any, cfg);
}
}
});

// append
each(toShape.getChildren(), (child, idx) => {
if (idx >= fromShape.getCount()) {
if (!child.destroyed) {
fromShape.add(child);
}
}
});
}
76 changes: 37 additions & 39 deletions src/geometry/label/base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deepMix, each, get, isArray, isFunction, isNil, isUndefined } from '@antv/util';
import { deepMix, each, get, isArray, isFunction, isNil, isNumber, isString, isUndefined } from '@antv/util';

import { FIELD_ORIGIN } from '../../constant';
import { Scale } from '../../dependents';
Expand Down Expand Up @@ -76,7 +76,6 @@ export default class GeometryLabel {

public render(mapppingArray: MappingDatum[], isUpdate: boolean = false) {
const labelItems = this.getLabelItems(mapppingArray);

const labelsRenderer = this.getLabelsRenderer();
const shapes = this.getGeometryShapes();
// 渲染文本
Expand Down Expand Up @@ -106,28 +105,20 @@ export default class GeometryLabel {
/**
* 获取 label 的默认配置
*/
protected getDefaultLabelCfg() {
return get(this.geometry.theme, 'labels', {});
}

/**
* 获取当前 label 的最终配置
* @param labelCfg
*/
protected getThemedLabelCfg(labelCfg: LabelCfg) {
protected getDefaultLabelCfg(offset?: number, position?: string) {
const geometry = this.geometry;
const defaultLabelCfg = this.getDefaultLabelCfg();
const { type, theme } = geometry;
let themedLabelCfg;

if (type === 'polygon' || (labelCfg.offset < 0 && !['line', 'point', 'path'].includes(type))) {
// polygon 或者 offset 小于 0 时,文本展示在图形内部,将其颜色设置为 白色
themedLabelCfg = deepMix({}, defaultLabelCfg, theme.innerLabels, labelCfg);
} else {
themedLabelCfg = deepMix({}, defaultLabelCfg, theme.labels, labelCfg);
if (
type === 'polygon' ||
(type === 'interval' && position === 'middle') ||
(offset < 0 && !['line', 'point', 'path'].includes(type))
) {
// polygon 或者 (interval 且 middle) 或者 offset 小于 0 时,文本展示在图形内部,将其颜色设置为 白色
return get(theme, 'innerLabels', {});
}

return themedLabelCfg;
return get(theme, 'labels', {});
}

/**
Expand All @@ -145,25 +136,23 @@ export default class GeometryLabel {
) {}

/**
* 获取文本默认偏移量
* @param offset
* @returns
* @desc 获取 label offset
*/
protected getDefaultOffset(offset: number) {
protected getLabelOffset(offset: number | string): number {
const coordinate = this.getCoordinate();
const vector = this.getOffsetVector(offset);
return coordinate.isTransposed ? vector[0] : vector[1];
}

/**
* 获取每个 label 的偏移量
* 获取每个 label 的偏移量 (矢量)
* @param labelCfg
* @param index
* @param total
* @returns
* @return {Point} offsetPoint
*/
protected getLabelOffset(labelCfg: LabelCfg, index: number, total: number) {
const offset = this.getDefaultOffset(labelCfg.offset);
protected getLabelOffsetPoint(labelCfg: LabelCfg, index: number, total: number): Point {
const offset = labelCfg.offset;
const coordinate = this.getCoordinate();
const transposed = coordinate.isTransposed;
const dim = transposed ? 'x' : 'y';
Expand Down Expand Up @@ -249,7 +238,7 @@ export default class GeometryLabel {
// 如果 label 支持 position 属性
this.setLabelPosition(label, mappingData, index, labelCfg.position);
}
const offsetPoint = this.getLabelOffset(labelCfg, index, total);
const offsetPoint = this.getLabelOffsetPoint(labelCfg, index, total);
label.start = { x: label.x, y: label.y };
label.x += offsetPoint.x;
label.y += offsetPoint.y;
Expand All @@ -268,7 +257,7 @@ export default class GeometryLabel {
let align: TextAlign = 'center';
const coordinate = this.getCoordinate();
if (coordinate.isTransposed) {
const offset = this.getDefaultOffset(item.offset);
const offset = item.offset;
if (offset < 0) {
align = 'right';
} else if (offset === 0) {
Expand Down Expand Up @@ -334,8 +323,7 @@ export default class GeometryLabel {

private getLabelCfgs(mapppingArray: MappingDatum[]): LabelCfg[] {
const geometry = this.geometry;
const defaultLabelCfg = this.getDefaultLabelCfg();
const { type, theme, labelOption, scales, coordinate } = geometry;
const { labelOption, scales, coordinate } = geometry;
const { fields, callback, cfg } = labelOption as LabelOption;
const labelScales = fields.map((field: string) => {
return scales[field];
Expand Down Expand Up @@ -365,6 +353,18 @@ export default class GeometryLabel {
...callbackCfg,
};

if (isFunction(labelCfg.position)) {
labelCfg.position = labelCfg.position(origin, mappingData, index);
}

const offset = this.getLabelOffset(labelCfg.offset || 0);
// defaultCfg 需要判断 innerLabels & labels
const defaultLabelCfg = this.getDefaultLabelCfg(offset, labelCfg.position);
// labelCfg priority: defaultCfg < cfg < callbackCfg
labelCfg = deepMix({}, defaultLabelCfg, labelCfg);
// 获取最终的 offset
labelCfg.offset = this.getLabelOffset(labelCfg.offset || 0);

const content = labelCfg.content;
if (isFunction(content)) {
labelCfg.content = content(origin, mappingData, index);
Expand All @@ -373,12 +373,6 @@ export default class GeometryLabel {
labelCfg.content = originText[0];
}

if (isFunction(labelCfg.position)) {
labelCfg.position = labelCfg.position(origin, mappingData, index);
}

labelCfg = this.getThemedLabelCfg(labelCfg);

labelCfgs.push(labelCfg);
});

Expand Down Expand Up @@ -406,10 +400,14 @@ export default class GeometryLabel {
return labelTexts;
}

private getOffsetVector(offset = 0) {
private getOffsetVector(offset: number | string = 0) {
const coordinate = this.getCoordinate();
let actualOffset = 0;
if (isNumber(offset)) {
actualOffset = offset;
}
// 如果 x,y 翻转,则偏移 x,否则偏移 y
return coordinate.isTransposed ? coordinate.applyMatrix(offset, 0) : coordinate.applyMatrix(0, offset);
return coordinate.isTransposed ? coordinate.applyMatrix(actualOffset, 0) : coordinate.applyMatrix(0, actualOffset);
}

private getGeometryShapes() {
Expand Down
Loading

0 comments on commit 49051d4

Please sign in to comment.