From 1f2d6d24449007eb2d2bfc05263d871bdd61ebb0 Mon Sep 17 00:00:00 2001 From: maxim Date: Thu, 5 May 2022 11:50:27 +0100 Subject: [PATCH] label positioning on loop edges and tests for that --- .../src/utils/__tests__/processEdges.test.ts | 91 +++++++++++++++++++ packages/graphin/src/utils/processEdges.ts | 59 +++++++----- 2 files changed, 128 insertions(+), 22 deletions(-) create mode 100644 packages/graphin/src/utils/__tests__/processEdges.test.ts diff --git a/packages/graphin/src/utils/__tests__/processEdges.test.ts b/packages/graphin/src/utils/__tests__/processEdges.test.ts new file mode 100644 index 000000000..5fb8d7186 --- /dev/null +++ b/packages/graphin/src/utils/__tests__/processEdges.test.ts @@ -0,0 +1,91 @@ +import { IUserEdge } from '../../index'; +import processEdges from '../processEdges'; + +describe('processEdges', () => { + describe('Should process edges as loops', () => { + let edges: IUserEdge[]; + + beforeEach(() => { + edges = [ + { + source: '23a07720-b446-11e9-8592-cdfa43d74b9b', + target: '23a07720-b446-11e9-8592-cdfa43d74b9b', + data: {}, + style: { + label: { + value: 'a', + }, + }, + }, + { + source: '23a07720-b446-11e9-8592-cdfa43d74b9b', + target: '23a07720-b446-11e9-8592-cdfa43d74b9b', + data: {}, + style: { + label: { + value: 'b', + }, + }, + }, + { + source: '23a07720-b446-11e9-8592-cdfa43d74b9b', + target: '23a07720-b446-11e9-8592-cdfa43d74b9b', + data: {}, + style: { + label: { + value: 'c', + }, + }, + }, + ]; + }); + + it('With default values', () => { + const newEdges = processEdges(edges); + + expect(newEdges[0].style?.label?.offset).toEqual([0, -30]); + expect(newEdges[0].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[0].style?.keyshape?.loop?.distance).toEqual(0); + + expect(newEdges[1].style?.label?.offset).toEqual([0, -50]); + expect(newEdges[1].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[1].style?.keyshape?.loop?.distance).toEqual(10); + + expect(newEdges[2].style?.label?.offset).toEqual([0, -70]); + expect(newEdges[2].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[2].style?.keyshape?.loop?.distance).toEqual(20); + }); + + it('With custom loop definition', () => { + const newEdges = processEdges(edges, { loop: 20 }); + + expect(newEdges[0].style?.label?.offset).toEqual([0, -30]); + expect(newEdges[0].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[0].style?.keyshape?.loop?.distance).toEqual(0); + + expect(newEdges[1].style?.label?.offset).toEqual([0, -70]); + expect(newEdges[1].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[1].style?.keyshape?.loop?.distance).toEqual(20); + + expect(newEdges[2].style?.label?.offset).toEqual([0, -110]); + expect(newEdges[2].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[2].style?.keyshape?.loop?.distance).toEqual(40); + }); + + it('With custom loop label position', () => { + const newEdges = processEdges(edges, { loopLabelPosition: 0.5 }); + + expect(newEdges[0].style?.label?.offset).toEqual([0, -15]); + expect(newEdges[0].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[0].style?.keyshape?.loop?.distance).toEqual(0); + + expect(newEdges[1].style?.label?.offset).toEqual([0, -35]); + expect(newEdges[1].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[1].style?.keyshape?.loop?.distance).toEqual(10); + + expect(newEdges[2].style?.label?.offset).toEqual([0, -55]); + expect(newEdges[2].style?.keyshape?.type).toEqual('loop'); + expect(newEdges[2].style?.keyshape?.loop?.distance).toEqual(20); + }); + }); +}); diff --git a/packages/graphin/src/utils/processEdges.ts b/packages/graphin/src/utils/processEdges.ts index f8439fdc7..7449f1281 100644 --- a/packages/graphin/src/utils/processEdges.ts +++ b/packages/graphin/src/utils/processEdges.ts @@ -1,4 +1,5 @@ -import { IUserEdge } from '../index'; +import { IUserEdge, EdgeStyle } from '../index'; +import { deepMix } from '@antv/util'; function isEven(number: number) { return number % 2 === 0; @@ -8,6 +9,10 @@ function isOdd(number: number) { return !isEven(number); } +const POLY_DEFAULT = 30; +const LOOP_DEFAULT = 10; +const LOOP_LABEL_POSITION_DEFAULT = 1; + /** * * @param edges 边的集合 @@ -16,16 +21,20 @@ function isOdd(number: number) { const processEdges = ( edges: IUserEdge[], { - poly = 30, - loop = 10, + poly = POLY_DEFAULT, + loop = LOOP_DEFAULT, + loopLabelPosition = LOOP_LABEL_POSITION_DEFAULT, }: { /** poly distance */ - poly: number; + poly?: number; /** loop distance */ - loop: number; + loop?: number; + /** loop label position based on loop edge */ + loopLabelPosition?: number; } = { - poly: 30, - loop: 10, + poly: POLY_DEFAULT, + loop: LOOP_DEFAULT, + loopLabelPosition: LOOP_LABEL_POSITION_DEFAULT, }, ) => { const edgesMap: { [edgeId: string]: IUserEdge[] } = {}; @@ -77,30 +86,36 @@ const processEdges = ( delete edge.revert; } - let keyshapeStyle = { - type: 'poly', - poly: { - distance: resultDistance, - }, - }; - + let keyshapeStyle: EdgeStyle['keyshape']; if (isLoop) { + const distance = index * loop; + keyshapeStyle = { type: 'loop', - // @ts-ignore loop: { - distance: index * loop, + distance, + }, + }; + + if (edge.style?.label) { + const offsetX = 0; + const offsetY = -(POLY_DEFAULT * loopLabelPosition + distance * 2); + edge.style.label.offset = [offsetX, offsetY]; + } + } else { + keyshapeStyle = { + type: 'poly', + poly: { + distance: resultDistance, }, }; } - edge.style = { - ...edge.style, - keyshape: { - ...edge.style?.keyshape, - ...keyshapeStyle, + deepMix(edge, { + style: { + keyshape: keyshapeStyle, }, - }; + }); edge.isMultiple = true; newEdges.push(edge); });