Skip to content

Commit

Permalink
refactor: 重构 Label 相关模块,将饼图 label 的布局调整到 LabelLayout 中
Browse files Browse the repository at this point in the history
  • Loading branch information
simaQ committed Mar 20, 2020
1 parent 4537b96 commit 402d6c5
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 280 deletions.
100 changes: 68 additions & 32 deletions src/component/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,28 @@ export default class Labels {
this.shapesMap = {};
const container = this.container;
const offscreenGroup = this.createOffscreenGroup(); // 创建虚拟分组
// 在虚拟 group 中创建 shapes
// step 1: 在虚拟 group 中创建 shapes
for (const item of items) {
if (item) {
this.renderLabel(item, offscreenGroup);
}
}
this.adjustLabels(shapes); // 调整 labels

// step 2: 根据布局,调整 labels
this.doLayout(items, shapes);

// step 3: 绘制 labelLine
this.renderLabelLine(items);

// step 4: 根据用户设置的偏移量调整 label
this.adjustLabel(items);

// 进行添加、更新、销毁操作
const lastShapesMap = this.lastShapesMap;
const shapesMap = this.shapesMap;
each(shapesMap, (shape, id) => {
if (shape.destroyed) {
// label 在布局调整环节被删除了(adjustLabels
// label 在布局调整环节被删除了(doLayout
delete shapesMap[id];
} else {
if (lastShapesMap[id]) {
Expand Down Expand Up @@ -180,6 +188,7 @@ export default class Labels {

translate(content, x, y); // 将 label 平移至 x, y 指定的位置
labelShape = content;
content.set('_name', 'labelContent');
labelGroup.add(content);
} else {
labelShape = labelGroup.addShape('text', {
Expand All @@ -192,18 +201,18 @@ export default class Labels {
...cfg.style,
},
...shapeAppendCfg,
_name: 'labelContent',
});
}

if (cfg.rotate) {
rotate(labelShape, cfg.rotate);
}
this.drawLabelLine(cfg, labelGroup);
this.shapesMap[id] = labelGroup;
}

// 根据type对label布局
private adjustLabels(shapes) {
private doLayout(items: LabelItem[], shapes: Record<string, IShape | IGroup>) {
if (this.layout) {
const layouts = isArray(this.layout) ? this.layout : [this.layout];
each(layouts, (layout: GeometryLabelLayoutCfg) => {
Expand All @@ -216,38 +225,47 @@ export default class Labels {
geometryShapes.push(shapes[id]);
});

layoutFn(labelShapes, geometryShapes, this.region, layout.cfg);
layoutFn(items, labelShapes, geometryShapes, this.region, layout.cfg);
}
});
}
}

private drawLabelLine(labelCfg: LabelItem, container: IGroup) {
if (!labelCfg.labelLine) {
// labelLine: null | false,关闭 label 对应的 labelLine
return;
}
const labelLineCfg = get(labelCfg, 'labelLine', {});
let path = labelLineCfg.path;
if (!path) {
const start = labelCfg.start;
path = [
['M', start.x, start.y],
['L', labelCfg.x, labelCfg.y],
];
}
container.addShape('path', {
capture: false, // labelLine 默认不参与事件捕获
attrs: {
path,
stroke: labelCfg.color ? labelCfg.color : get(labelCfg, ['style', 'fill'], '#000'),
fill: null,
...labelLineCfg.style,
},
id: labelCfg.id,
origin: labelCfg.mappingData,
data: labelCfg.data,
coordinate: labelCfg.coordinate,
private renderLabelLine(labelItems: LabelItem[]) {
each(labelItems, (labelItem) => {
if (!labelItem) {
return;
}
if (!labelItem.labelLine) {
// labelLine: null | false,关闭 label 对应的 labelLine
return;
}
const labelLineCfg = get(labelItem, 'labelLine', {});
const id = labelItem.id;
let path = labelLineCfg.path;
if (!path) {
const start = labelItem.start;
path = [
['M', start.x, start.y],
['L', labelItem.x, labelItem.y],
];
}
const labelGroup = this.shapesMap[id];
if (!labelGroup.destroyed) {
labelGroup.addShape('path', {
capture: false, // labelLine 默认不参与事件捕获
attrs: {
path,
stroke: labelItem.color ? labelItem.color : get(labelItem, ['style', 'fill'], '#000'),
fill: null,
...labelLineCfg.style,
},
id,
origin: labelItem.mappingData,
data: labelItem.data,
coordinate: labelItem.coordinate,
});
}
});
}

Expand All @@ -257,4 +275,22 @@ export default class Labels {
const newGroup = new GroupClass({});
return newGroup;
}

private adjustLabel(items: LabelItem[]) {
each(items, (item) => {
if (item) {
const id = item.id;
const labelGroup = this.shapesMap[id];
if (!labelGroup.destroyed) {
const labelShape = labelGroup.find(ele => ele.get('_name') === 'labelContent');
if (item.offsetX) {
labelShape.attr('x', labelShape.attr('x') + item.offsetX);
}
if (item.offsetY) {
labelShape.attr('y', labelShape.attr('y') + item.offsetY);
}
}
}
});
}
}
78 changes: 12 additions & 66 deletions src/geometry/label/base.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { deepMix, each, get, isArray, isFunction, isNil, isNumber, isUndefined } from '@antv/util';

import { FIELD_ORIGIN } from '../../constant';
import { Coordinate, Scale } from '../../dependents';
import { Datum, LabelOption, LooseObject, MappingDatum, Point } from '../../interface';
import { Scale } from '../../dependents';
import { Datum, LabelOption, MappingDatum, Point } from '../../interface';
import { LabelCfg, LabelItem, LabelPointCfg, TextAlign } from './interface';

import { getDefaultAnimateCfg } from '../../animate';
Expand All @@ -29,16 +29,15 @@ export default class GeometryLabel {
/** geometry 实例 */
public readonly geometry: Geometry;
public labelsRenderer: Labels;
/** 默认的布局 */
public defaultLayout: string;

constructor(geometry: Geometry) {
this.geometry = geometry;
}

public render(mapppingArray: MappingDatum[], isUpdate: boolean) {
let labelItems = this.getItems(mapppingArray);
labelItems = this.adjustItems(labelItems);

this.drawLines(labelItems);
const labelItems = this.getItems(mapppingArray);

const labelsRenderer = this.getLabelsRenderer();
const shapes = this.getGeometryShapes();
Expand Down Expand Up @@ -66,18 +65,6 @@ export default class GeometryLabel {
return this.geometry.coordinate;
}

/**
* 根据当前 shape 对应的映射数据获取对应的 label 配置信息。
* @param mapppingArray 映射后的绘制数据
* @returns
*/
public getLabelItems(mapppingArray: MappingDatum[]) {
const items = this.adjustItems(this.getItems(mapppingArray));
this.drawLines(items);

return items;
}

/**
* 获取 label 的默认配置
*/
Expand All @@ -99,53 +86,6 @@ export default class GeometryLabel {
position: string
) {}

/**
* 生成文本线配置
* @param item
*/
protected lineToLabel(item: LabelItem) {}

/**
* 根据用户设置的 offsetX 和 offsetY 调整 label 的 x 和 y 坐标
* @param items
* @returns
*/
protected adjustItems(items: LabelItem[]) {
each(items, (item) => {
if (!item) {
return;
}
if (item.offsetX) {
item.x += item.offsetX;
}
if (item.offsetY) {
item.y += item.offsetY;
}
});
return items;
}

/**
* 绘制 label 文本连接线
* @param items
*/
protected drawLines(items: LabelItem[]) {
each(items, (item) => {
if (!item) {
return;
}

if (item.offset <= 0) {
// 内部文本不绘制 labelLine
item.labelLine = null;
}

if (item.labelLine) {
this.lineToLabel(item);
}
});
}

/**
* 获取文本默认偏移量
* @param offset
Expand Down Expand Up @@ -331,7 +271,9 @@ export default class GeometryLabel {
if (!labelsRenderer) {
labelsRenderer = new Labels({
container: labelsContainer,
layout: get(labelOption, ['cfg', 'layout']),
layout: get(labelOption, ['cfg', 'layout'], {
type: this.defaultLayout,
}),
});
this.labelsRenderer = labelsRenderer;
}
Expand Down Expand Up @@ -370,6 +312,10 @@ export default class GeometryLabel {
item.textAlign = this.getLabelAlign(item, subIndex, total);
}

if (item.offset <= 0) {
item.labelLine = null;
}

items.push(item);
});
});
Expand Down
4 changes: 3 additions & 1 deletion src/geometry/label/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { BBox, IGroup, IShape } from '../../dependents';
import { LooseObject } from '../../interface';
import { GeometryLabelConstructor } from './base';
import { LabelItem } from './interface';

/**
* label 布局函数定义
* @param items 存储每个 label 的详细信息
* @param labels 所有的 labels 图形实例
* @param shapes 所有 label 对应的图形元素实例
* @param region 画布区域
* @param cfg 用于存储各个布局函数开放给用户的配置数据
*/
type GeometryLabelsLayoutFn = (labels: IGroup[], shapes: IShape[] | IGroup[], region: BBox, cfg?: LooseObject) => void;
type GeometryLabelsLayoutFn = (items: LabelItem[], labels: IGroup[], shapes: IShape[] | IGroup[], region: BBox, cfg?: LooseObject) => void;

const GEOMETRY_LABELS_MAP: Record<string, GeometryLabelConstructor> = {};
const GEOMETRY_LABELS_LAYOUT_MAP: Record<string, GeometryLabelsLayoutFn> = {};
Expand Down
Loading

0 comments on commit 402d6c5

Please sign in to comment.