refactor(elements): adjust the computation logic of combo (#6275)

* feat(util): add hasPosition util

* refactor(elements): adjust the computation logic of combo

* test: add test case

---------

Co-authored-by: antv <antv@antfin.com>
This commit is contained in:
Aaron 2024-09-05 11:17:16 +08:00 committed by GitHub
parent 5203d148aa
commit fb1626d15f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 128 additions and 3 deletions

View File

@ -0,0 +1,66 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" style="background: transparent; position: absolute; outline: none;" color-interpolation-filters="sRGB" tabindex="1">
<defs/>
<g >
<g fill="none">
<g fill="none" class="elements">
<g fill="none" x="50" y="100" transform="matrix(1,0,0,1,50,100)">
<g>
<circle fill="rgba(153,173,209,1)" class="key" stroke-dasharray="0,0" stroke-width="1" stroke="rgba(153,173,209,1)" r="26"/>
</g>
<g fill="none" class="label" transform="matrix(1,0,0,1,0,26)">
<g>
<text fill="rgba(0,0,0,1)" dominant-baseline="central" paint-order="stroke" dx="0.5" dy="11.5px" class="text" font-size="12" font-family="system-ui, sans-serif" text-anchor="middle" font-weight="400">
combo-1
</text>
</g>
</g>
<g fill="none" class="collapsed-marker" x="0" y="0">
<g>
<text fill="rgba(255,255,255,1)" dominant-baseline="central" paint-order="stroke" dx="0.5" class="icon" text-anchor="middle" font-size="12">
1
</text>
</g>
</g>
</g>
<g fill="none" x="100" y="100" transform="matrix(1,0,0,1,100,100)">
<g>
<circle fill="rgba(153,173,209,1)" class="key" stroke-dasharray="0,0" stroke-width="1" stroke="rgba(153,173,209,1)" r="26"/>
</g>
<g fill="none" class="label" transform="matrix(1,0,0,1,0,26)">
<g>
<text fill="rgba(0,0,0,1)" dominant-baseline="central" paint-order="stroke" dx="0.5" dy="11.5px" class="text" font-size="12" font-family="system-ui, sans-serif" text-anchor="middle" font-weight="400">
combo-2
</text>
</g>
</g>
<g fill="none" class="collapsed-marker" x="0" y="0">
<g>
<text fill="rgba(255,255,255,1)" dominant-baseline="central" paint-order="stroke" dx="0.5" class="icon" text-anchor="middle" font-size="12">
1
</text>
</g>
</g>
</g>
<g fill="none" x="0" y="0">
<g>
<circle fill="rgba(153,173,209,1)" class="key" stroke-dasharray="0,0" stroke-width="1" stroke="rgba(153,173,209,1)" r="26"/>
</g>
<g fill="none" class="label" transform="matrix(1,0,0,1,0,26)">
<g>
<text fill="rgba(0,0,0,1)" dominant-baseline="central" paint-order="stroke" dx="0.5" dy="11.5px" class="text" font-size="12" font-family="system-ui, sans-serif" text-anchor="middle" font-weight="400">
combo-3
</text>
</g>
</g>
<g fill="none" class="collapsed-marker" x="0" y="0">
<g>
<text fill="rgba(255,255,255,1)" dominant-baseline="central" paint-order="stroke" dx="0.5" class="icon" text-anchor="middle" font-size="12">
1
</text>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -149,3 +149,36 @@ describe('combo drag zIndex', () => {
await expect(graph).toMatchSnapshot(__filename, 'combo-zIndex');
});
});
describe('combo with position', () => {
it('combo with position', async () => {
const graph = createGraph({
data: {
nodes: [
{ id: 'node-1', combo: 'combo-1', style: { x: 50, y: 100 } },
{ id: 'node-2', combo: 'combo-2' },
{ id: 'node-3', combo: 'combo-3' },
],
combos: [
{ id: 'combo-1', style: { x: 0, y: 0, collapsed: true } },
{ id: 'combo-2', style: { x: 100, y: 100, collapsed: true } },
{ id: 'combo-3', style: { collapsed: true } },
],
},
node: {
style: {
labelText: (d) => d.id,
},
},
combo: {
style: {
labelText: (d) => d.id,
},
},
});
await graph.draw();
await expect(graph).toMatchSnapshot(__filename, 'combo-with-position');
});
});

View File

@ -1,4 +1,10 @@
import { getXYByAnchor, getXYByPlacement, getXYByRelativePlacement, positionOf } from '@/src/utils/position';
import {
getXYByAnchor,
getXYByPlacement,
getXYByRelativePlacement,
hasPosition,
positionOf,
} from '@/src/utils/position';
import { AABB } from '@antv/g';
describe('position', () => {
@ -36,4 +42,12 @@ describe('position', () => {
expect(positionOf({ id: 'node', style: { x: 10, y: 20 } })).toEqual([10, 20, 0]);
expect(positionOf({ id: 'node', style: { x: 10, y: 20, z: 30 } })).toEqual([10, 20, 30]);
});
it('hasPosition', () => {
expect(hasPosition({ id: 'node' })).toBeFalsy();
expect(hasPosition({ id: 'node', style: { x: 10 } })).toBeTruthy();
expect(hasPosition({ id: 'node', style: { y: 20 } })).toBeTruthy();
expect(hasPosition({ id: 'node', style: { z: 30 } })).toBeTruthy();
expect(hasPosition({ id: 'node', style: { x: 10, y: 20, z: 30 } })).toBeTruthy();
});
});

View File

@ -15,7 +15,7 @@ import type {
import { getBBoxHeight, getBBoxWidth, getCombinedBBox, getExpandedBBox } from '../../utils/bbox';
import { idOf } from '../../utils/id';
import { parsePadding } from '../../utils/padding';
import { getXYByPlacement, positionOf } from '../../utils/position';
import { getXYByPlacement, hasPosition, positionOf } from '../../utils/position';
import { subStyleProps } from '../../utils/prefix';
import { parseSize } from '../../utils/size';
import { mergeOptions } from '../../utils/style';
@ -210,7 +210,7 @@ export abstract class BaseCombo<S extends BaseComboStyleProps = BaseComboStylePr
const { model } = context!;
const descendants = model.getDescendantsData(this.id).filter((datum) => !model.isCombo(idOf(datum)));
if (descendants.length > 0) {
if (descendants.length > 0 && descendants.some(hasPosition)) {
// combo 被收起,返回平均中心位置 / combo is collapsed, return the average center position
const totalPosition = descendants.reduce((acc, datum) => add(acc, positionOf(datum)), [0, 0, 0] as Point);
return divide(totalPosition, descendants.length);

View File

@ -15,6 +15,18 @@ export function positionOf(datum: NodeLikeData): Point {
return [+x, +y, +z];
}
/**
* <zh/>
*
* <en/> Check if the data has a position coordinate
* @param datum - <zh/> / combo | <en/> data of node/combo
* @returns - <zh/> | <en/> Whether there is a position coordinate
*/
export function hasPosition(datum: NodeLikeData): boolean {
const { x, y, z } = datum.style || {};
return x !== undefined || y !== undefined || z !== undefined;
}
/**
* <zh/>
*