UNPKG

@antv/g2

Version:

the Grammar of Graphics in Javascript

86 lines (81 loc) 2.63 kB
import { get, each } from '@antv/util'; import { BBox, IGroup, IShape } from '../../../dependents'; import { intersect } from '../../../util/collision-detect'; import { LabelItem } from '../interface'; import { getLabelBackgroundInfo } from '../util'; import { createWorker } from '../util/createWorker'; import { code as layoutCode } from './worker/hide-overlap'; type Item = { x: number; y: number; width: number; height: number; rotation?: number; visible?: boolean; }; const layout = (items: Item[]): Item[] => { const boxes = items.slice(); for (let i = 0; i < boxes.length; i++) { const box1 = boxes[i]; if (box1.visible) { for (let j = i + 1; j < boxes.length; j++) { const box2 = boxes[j]; if (box1 !== box2 && box2.visible) { if (intersect(box1, box2)) { box2.visible = false; } } } } } return boxes; } const cache: Map<string, any> = new Map(); const worker = createWorker(layoutCode); /** * label 防遮挡布局:在不改变 label 位置的情况下对相互重叠的 label 进行隐藏(非移除) * 不同于 'overlap' 类型的布局,该布局不会对 label 的位置进行偏移调整。 * @param labels 参与布局调整的 label 数组集合 */ export function hideOverlap(labelItems: LabelItem[], labels: IGroup[], shapes: IShape[] | IGroup[], region: BBox) { // todo 添加 label rank return new Promise((resolve) => { const boxes = labels.map((d, idx) => ({ ...getLabelBackgroundInfo(d, labelItems[idx], get(labelItems[idx], 'background.padding')), visible: true, })); const memoKey = JSON.stringify(boxes); const cb = (items: Item[]) => { cache.set(memoKey, items); each(items, ({ visible }, idx) => { const labelShape = labels[idx]; if (visible) { labelShape?.show() } else { labelShape?.hide(); } }); return resolve(items); } if (cache.get(memoKey)) { cb(cache.get(memoKey)) } else if (worker) { // Do layout in worker. try { worker.postMessage(JSON.stringify({ type: 'hide-overlap', items: boxes })); worker.onmessage = (e) => cb(Array.isArray(e.data) ? e.data : []); worker.onmessageerror = (e) => { console.warn('[AntV G2] Web worker is not available'); // Normal layout in main thread. cb(layout(boxes)); }; } catch (e) { console.error(e); cb(layout(boxes)); } } else { // Normal layout in main thread. cb(layout(boxes)); } }); }