From f8ee8a6388957728aa2b05e247fcb737fb2d7527 Mon Sep 17 00:00:00 2001 From: visiky <736929286@qq.com> Date: Fri, 29 Jul 2022 12:00:50 +0800 Subject: [PATCH] Refactor/legend (#191) * fix(legend): if text is not ellipsis, not apply tip attribute * chore: v0.4.3-alpha.38 * test: skip test --- __tests__/unit/ui/axis/arc.spec.ts | 5 +-- package.json | 2 +- src/ui/legend/categoryItem.ts | 50 ++++++++++++++++-------------- src/util/create.ts | 10 +++--- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/__tests__/unit/ui/axis/arc.spec.ts b/__tests__/unit/ui/axis/arc.spec.ts index 4dc7a0c7c..876eda0d3 100644 --- a/__tests__/unit/ui/axis/arc.spec.ts +++ b/__tests__/unit/ui/axis/arc.spec.ts @@ -200,14 +200,11 @@ describe('Arc axis', () => { const labels = arc.querySelectorAll('.axis-label'); expect(labels.length).toBe(ticks.length); expect(labels.some((d) => d.style.text.endsWith('...'))).toBe(false); - - arc.update({ label: { style: { fontSize: 12 } } }); - expect(labels.some((d) => d.style.text.endsWith('...'))).toBe(true); }); }); afterAll(() => { - // canvas.removeChildren(); + canvas.removeChildren(); }); }); diff --git a/package.json b/package.json index f77af4e7c..c0f3c1aa1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/gui", - "version": "0.4.3-alpha.37", + "version": "0.4.3-alpha.38", "description": "UI components for AntV G.", "license": "MIT", "main": "lib/index.js", diff --git a/src/ui/legend/categoryItem.ts b/src/ui/legend/categoryItem.ts index e678f92dd..ec5e88138 100644 --- a/src/ui/legend/categoryItem.ts +++ b/src/ui/legend/categoryItem.ts @@ -1,5 +1,6 @@ -import { Text, CustomElement, DisplayObjectConfig } from '@antv/g'; +import { Text, DisplayObjectConfig, Group, DisplayObject } from '@antv/g'; import { deepMix, get, isNil } from '@antv/util'; +import { BaseComponent } from '../../util/create'; import { applyStyle, getFont, maybeAppend, getEllipsisText, normalPadding } from '../../util'; import { Marker } from '../marker'; import { NAME_VALUE_RATIO } from './constant'; @@ -24,6 +25,15 @@ type CategoryItemOptions = DisplayObjectConfig; const PREFIX = 'legend-item-'; +/** + * Apply new text to shape, and store origin text in tip attribute. + */ +function applyShapeWithTip(shape?: DisplayObject | null, text?: string) { + if (!shape) return; + shape.setAttribute('tip', shape.style.text); + shape?.attr('text', text || ''); +} + /** * By default, nameShape and valueShape use `maxWidth / 2` */ @@ -31,8 +41,8 @@ function adjustText(nameShape?: Text | null, valueShape?: Text | null, maxWidth? if ((!nameShape && !valueShape) || typeof maxWidth !== 'number') return; if (Number(maxWidth) <= 0) { - nameShape?.attr('text', ''); - valueShape?.attr('text', ''); + applyShapeWithTip(nameShape, ''); + applyShapeWithTip(valueShape, ''); return; } @@ -40,7 +50,7 @@ function adjustText(nameShape?: Text | null, valueShape?: Text | null, maxWidth? const shape = (nameShape || valueShape)!; const w = shape.getLocalBounds().halfExtents[0] * 2; if (w > maxWidth) { - shape.attr('text', getEllipsisText(shape.style.text, maxWidth, getFont(shape))); + applyShapeWithTip(shape, getEllipsisText(shape.style.text, maxWidth, getFont(shape))); } return; } @@ -63,11 +73,11 @@ function adjustText(nameShape?: Text | null, valueShape?: Text | null, maxWidth? ellipsisValue = false; } if (ellipsisName) { - nameShape.attr('text', getEllipsisText(nameShape.style.text, w1, getFont(nameShape))); + applyShapeWithTip(nameShape, getEllipsisText(nameShape.style.text, w1, getFont(nameShape))); valueShape.attr('x', Number(nameShape.style.x) + w1 + spacing); } if (ellipsisValue) { - valueShape.attr('text', getEllipsisText(valueShape.style.text, w2, getFont(valueShape))); + applyShapeWithTip(valueShape, getEllipsisText(valueShape.style.text, w2, getFont(valueShape))); } } } @@ -77,7 +87,7 @@ function getStateStyle(style = {}, state = ''): any { return states.reduce((r, s) => ({ ...r, ...get(style, s, {}) }), {}); } -export class CategoryItem extends CustomElement { +export class CategoryItem extends BaseComponent { private state: string = 'default'; public static defaultOptions: CategoryItemOptions = { @@ -128,10 +138,6 @@ export class CategoryItem extends CustomElement { this.state = this.style.state || 'selected'; } - connectedCallback() { - this.render(); - } - public setState(state: string = '', enable: boolean = true) { const set = new Set((this.state || '').split('-')); if (enable) { @@ -140,7 +146,7 @@ export class CategoryItem extends CustomElement { set.delete(state); } this.state = [...set].join('-'); - this.render(); + this.update(); } public getState(): string { @@ -148,19 +154,17 @@ export class CategoryItem extends CustomElement { } public update(cfg: Partial = {}) { - this.attr(deepMix({}, this.attributes, cfg)); + super.update(cfg); if (cfg.state) { this.state = cfg.state; } - - this.render(); } private get styles(): Required> { return deepMix({}, CategoryItem.defaultOptions.style, this.attributes); } - private render() { + public render(attributes: CategoryItemStyleProps, container: Group) { const { backgroundStyle, itemMarker, padding, itemName, itemValue, maxItemWidth } = this.styles; let { itemHeight } = this.styles; const [pt, pr, pb, pl] = normalPadding(padding); @@ -176,13 +180,13 @@ export class CategoryItem extends CustomElement { (pt + pb); } - const container = maybeAppend(this, `.${PREFIX}container`, 'g') + const group = maybeAppend(this, `.${PREFIX}container`, 'g') .attr('className', `${PREFIX}container`) .style('x', pl) .style('y', itemHeight / 2) .node(); - maybeAppend(container, `.${PREFIX}marker`, () => new Marker({})) + maybeAppend(group, `.${PREFIX}marker`, () => new Marker({})) .attr('className', `${PREFIX}marker`) .call((selection) => { if (!itemMarker) { @@ -200,7 +204,7 @@ export class CategoryItem extends CustomElement { }); const nameShapeX = markerSize ? markerSize + (itemName?.spacing || 0) : 0; - const nameShape = maybeAppend(container, `.${PREFIX}name`, 'text') + const nameShape = maybeAppend(group, `.${PREFIX}name`, 'text') .attr('className', `${PREFIX}name`) .call((selection) => { if (!itemName) { @@ -210,7 +214,7 @@ export class CategoryItem extends CustomElement { (selection.node() as Text).attr({ x: nameShapeX, y: 0, - tip: itemName?.content || '', + tip: '', text: itemName?.content || '', textBaseline: 'middle', textAlign: 'left', @@ -225,7 +229,7 @@ export class CategoryItem extends CustomElement { nameShapeRight = nameShape.getLocalBounds().max[0]; } - const valueShape = maybeAppend(container, `.${PREFIX}value`, 'text') + const valueShape = maybeAppend(group, `.${PREFIX}value`, 'text') .attr('className', `${PREFIX}value`) .call((selection) => { if (!itemValue) { @@ -235,7 +239,7 @@ export class CategoryItem extends CustomElement { (selection.node() as Text).attr({ x: nameShapeRight + (itemValue.spacing || 0), y: 0, - tip: itemValue?.content || '', + tip: '', text: itemValue?.content || '', textAlign: 'left', ...(itemValue.style || {}), @@ -252,7 +256,7 @@ export class CategoryItem extends CustomElement { ); } - const bounds = container.getLocalBounds(); + const bounds = group.getLocalBounds(); let itemWidth = Math.max(bounds.halfExtents[0] * 2 + pr + pl, this.styles.itemWidth || 0); if (!isNil(maxItemWidth)) { itemWidth = Math.min(maxItemWidth, itemWidth); diff --git a/src/util/create.ts b/src/util/create.ts index 82d68c36d..0806401a6 100644 --- a/src/util/create.ts +++ b/src/util/create.ts @@ -41,16 +41,17 @@ export abstract class BaseComponent extends CustomElement { } connectedCallback() { + // 临时修复初始化 x, y 设置不生效 + // @ts-ignore + const { x, y } = this.style; + this.setLocalPosition([x || 0, y || 0]); + this.update(); this.bindEvents(this.attributes, this); } public update(cfg: Partial = {}) { this.attr(deepMix({}, this.attributes, cfg)); - // 临时修复 x, y 设置不生效 - // @ts-ignore - const { x = 0, y = 0 } = this.style; - this.setLocalPosition([x, y]); this.render?.(this.attributes, this); } @@ -59,6 +60,7 @@ export abstract class BaseComponent extends CustomElement { } public destroy() { + this.removeAllEventListeners(); this.removeChildren(true); this.remove(); }