feat: rect type combo and its behaviors (#4844)

* feat: rect combo

* feat: behaviors for rect combo

* chore: lint

* chore: update lock file up to date

* chore: refine lock file

* chore: update workflows

* feat: comboCombined layout

* chore: update layout

* chore: update lock

* chore: refine
This commit is contained in:
Yanyan Wang 2023-08-24 14:08:15 +08:00 committed by GitHub
parent c09593aa2c
commit c01a1e1aae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 2508 additions and 777 deletions

View File

@ -28,13 +28,13 @@ jobs:
# postInstall will build the product
- name: Install dependencies and Build the product
run: pnpm install
run: pnpm install --no-frozen-lockfile
- name: Run CI
run: |
cd packages/g6
npm run ci
- name: Workflow failed alert
if: ${{ failure() }}
uses: actions-cool/maintain-one-comment@main

View File

@ -45,6 +45,7 @@
"fix": "eslint ./src ./tests --fix && prettier ./src ./tests --write ",
"test": "jest",
"test:integration": "node --expose-gc --max-old-space-size=4096 --unhandled-rejections=strict node_modules/jest/bin/jest tests/integration/ --config jest.node.config.js --coverage -i --logHeapUsage --detectOpenHandles",
"test:integration_one": "node --expose-gc --max-old-space-size=4096 --unhandled-rejections=strict node_modules/jest/bin/jest tests/integration/combo-render.spec.ts --config jest.node.config.js --coverage -i --logHeapUsage --detectOpenHandles",
"size": "limit-size",
"test-live": "DEBUG_MODE=1 jest --watch ./tests/unit/item-animate-spec.ts",
"test-behavior": "DEBUG_MODE=1 jest --watch ./tests/unit/item-3d-spec.ts"
@ -72,7 +73,7 @@
"@antv/g-webgl": "^1.7.44",
"@antv/graphlib": "^2.0.2",
"@antv/gui": "^0.5.0-alpha.16",
"@antv/layout": "^1.2.4",
"@antv/layout": "^1.2.5",
"@antv/layout-gpu": "^1.1.5",
"@antv/layout-wasm": "1.3.1",
"@antv/matrix-util": "^3.0.4",
@ -120,7 +121,7 @@
"stats-js": "1.0.1",
"stats.js": "^0.17.0",
"ts-jest": "^28.0.8",
"typedoc": "^0.24.0",
"typedoc": "^0.24.8",
"typescript": "^4.9.5",
"vite": "^4.2.2",
"xmlserializer": "^0.6.1"

View File

@ -3,12 +3,13 @@ import { Group, Tuple3Number } from '@antv/g';
import { clone, throttle } from '@antv/util';
import { DisplayMapper, LodStrategyObj, State } from '../types/item';
import { ComboStyleSet } from '../types/theme';
import {
ComboModelData,
ComboUserModel,
ComboUserModelData,
} from '../types/combo';
import { ComboModelData, ComboUserModelData } from '../types/combo';
import { Point } from '../types/common';
import {
getCircleIntersectByPoint,
getNearestPoint,
getRectIntersectByPoint,
} from '../util/point';
import Node from './node';
interface IProps {
@ -39,6 +40,7 @@ interface IProps {
}
export default class Combo extends Node {
public type: 'combo';
private anchorPointsCache: Point[] | undefined;
private cacheCombinedBounds?:
| {
@ -49,7 +51,7 @@ export default class Combo extends Node {
}
| false;
private getCombinedBounds: () =>
public getCombinedBounds: () =>
| {
center: Tuple3Number;
min: Tuple3Number;
@ -58,7 +60,7 @@ export default class Combo extends Node {
}
| false;
private getChildren: () => (Combo | Node)[];
public getChildren: () => (Combo | Node)[];
constructor(props: IProps) {
super({ ...props, type: 'combo' });
@ -177,6 +179,88 @@ export default class Combo extends Node {
};
}
public getIntersectPoint(
point: Point,
innerPoint: Point,
anchorPoints: number[][],
) {
const { keyShape } = this.shapeMap;
const shapeType = keyShape.nodeName;
const { collapsed, keyShape: keyShapeStyle } = this.displayModel.data;
const { x, y, z } = innerPoint;
let intersectPoint: Point | null;
switch (shapeType) {
case 'circle':
intersectPoint = getCircleIntersectByPoint(
{
x,
y,
r: collapsed ? keyShapeStyle.r : keyShape.attributes.r,
},
point,
);
break;
default: {
const bbox =
this.renderExt.boundsCache?.keyShapeLocal ||
keyShape.getLocalBounds();
intersectPoint = getRectIntersectByPoint(
collapsed
? {
x: x - keyShapeStyle.width / 2,
y: y - keyShapeStyle.height / 2,
width: keyShapeStyle.width,
height: keyShapeStyle.height,
}
: {
x: x + bbox.min[0],
y: y + bbox.min[1],
width: bbox.max[0] - bbox.min[0],
height: bbox.max[1] - bbox.min[1],
},
point,
);
}
}
let anchorPointsPositions = this.anchorPointsCache;
if (!anchorPointsPositions) {
const keyShapeBBox =
this.renderExt.boundsCache?.keyShapeLocal ||
this.shapeMap.keyShape.getLocalBounds();
const keyShapeWidth = keyShapeBBox.max[0] - keyShapeBBox.min[0];
const keyShapeHeight = keyShapeBBox.max[1] - keyShapeBBox.min[1];
anchorPointsPositions = anchorPoints.map((pointRatio) => {
const [xRatio, yRatio] = pointRatio;
return {
x: keyShapeWidth * (xRatio - 0.5) + x,
y: keyShapeHeight * (yRatio - 0.5) + y,
};
});
this.anchorPointsCache = anchorPointsPositions;
}
let linkPoint = intersectPoint;
// If the node has anchorPoints in the data, find the nearest anchor point.
if (anchorPoints.length) {
if (!linkPoint) {
// If the linkPoint is failed to calculate.
linkPoint = point;
}
linkPoint = getNearestPoint(
anchorPointsPositions,
linkPoint,
).nearestPoint;
}
if (!linkPoint) {
// If the calculations above are all failed, return the data's position
return { x, y };
}
return linkPoint;
}
// @ts-ignore
public clone(
containerGroup: Group,
onlyKeyShape?: boolean,

View File

@ -1,6 +1,6 @@
import { Group } from '@antv/g';
import { clone, throttle } from '@antv/util';
import { EdgeDisplayModel, EdgeModel, NodeModelData } from '../types';
import { EdgeDisplayModel, EdgeModel } from '../types';
import { EdgeModelData } from '../types/edge';
import { DisplayMapper, State, LodStrategyObj } from '../types/item';
import { updateShapes } from '../util/shape';
@ -18,8 +18,8 @@ interface IProps {
stateMapper?: {
[stateName: string]: DisplayMapper;
};
sourceItem: Node;
targetItem: Node;
sourceItem: Node | Combo;
targetItem: Node | Combo;
zoom?: number;
theme: {
styles: EdgeStyleSet;
@ -36,8 +36,8 @@ export default class Edge extends Item {
public displayModel: EdgeDisplayModel;
/** Set to different value in implements */
public type: 'edge' = 'edge';
public sourceItem: Node;
public targetItem: Node;
public sourceItem: Node | Combo;
public targetItem: Node | Combo;
constructor(props: IProps) {
super(props);

View File

@ -288,8 +288,7 @@ export default abstract class Item implements IItem {
const defaultMapper = DEFAULT_MAPPER[type];
const { data: innerModelData, ...otherFields } = innerModel;
const { current = innerModelData, previous } = diffData || {};
const firstRendering = !this.shapeMap?.keyShape;
const { current = innerModelData } = diffData || {};
// === no mapper, displayModel = model ===
if (!mapper) {

View File

@ -389,19 +389,18 @@ export class ItemController {
}
});
const { dataTypeField: nodeDataTypeField } = nodeTheme;
const edgeIdsToUpdate: ID[] = [];
const comboIdsToUpdate: ID[] = [];
const updateRelates = (edgeIds) => {
comboIdsToUpdate.concat(edgeIds || edgeIdsToUpdate).forEach((id) => {
const item = itemMap.get(id) as Edge | Combo;
if (item && !item.destroyed) item.forceUpdate();
});
const edgeIdsToUpdate: Set<ID> = new Set<ID>();
const comboIdsToUpdate: Set<ID> = new Set<ID>();
const updateRelates = (edgeIds?: Set<ID>) => {
[...comboIdsToUpdate]
.concat([...(edgeIds || edgeIdsToUpdate)])
.forEach((nid) => {
const item = itemMap.get(nid) as Edge | Combo;
if (item && !item.destroyed) item.forceUpdate();
});
};
const updateRelatesThrottle = debounce(updateRelates, 16, true);
const updateRelatesThrottle = throttle(updateRelates, 16, {
leading: true,
trailing: true,
});
Object.values(nodeComboUpdate).forEach((updateObj: any) => {
const { isReplace, previous, current, id } = updateObj;
if (!graphCore.hasNode(id)) return;
@ -419,47 +418,9 @@ export class ItemController {
callback(innerModel, true);
return;
}
// update the theme if the dataType value is changed
let itemTheme;
if (
nodeDataTypeField &&
previous[nodeDataTypeField] !== current[nodeDataTypeField]
) {
itemTheme = getItemTheme(
this.nodeDataTypeSet,
nodeDataTypeField,
current[nodeDataTypeField],
nodeTheme,
);
}
const relatedEdgeInnerModels = graphCore.getRelatedEdges(id);
const nodeRelatedIdsToUpdate: ID[] = [];
relatedEdgeInnerModels.forEach((edge) => {
edgeIdsToUpdate.push(edge.id);
nodeRelatedIdsToUpdate.push(edge.id);
});
const previousParentId = item.displayModel.data.parentId;
item.onframe = () => {
updateRelates(nodeRelatedIdsToUpdate);
};
item.update(
innerModel,
{ previous, current },
isReplace,
itemTheme,
onlyMove,
animate,
// call after updating finished
(_, canceled) => {
item.onframe?.();
// @ts-ignore
item.onframe = undefined;
callback(innerModel, canceled);
},
);
const nodeRelatedIdsToUpdate: Set<ID> = new Set<ID>();
// collapse and expand
if (graphCore.hasTreeStructure('combo')) {
if (type === 'combo' && current.collapsed !== previous.collapsed) {
if (current.collapsed) {
@ -468,7 +429,7 @@ export class ItemController {
this.expandCombo(graphCore, innerModel as ComboModel);
}
}
const previousParentId = item.displayModel.data.parentId;
// update the current parent combo tree
// if the node has previous parent, related previous parent combo should be updated to
if (upsertAncestors) {
@ -487,11 +448,11 @@ export class ItemController {
begins,
(treeItem) => {
if (treeItem.data._isCombo && treeItem.id !== innerModel.id)
comboIdsToUpdate.push(treeItem.id);
comboIdsToUpdate.add(treeItem.id);
const relatedEdges = graphCore.getRelatedEdges(treeItem.id);
relatedEdges.forEach((edge) => {
edgeIdsToUpdate.push(edge.id);
nodeRelatedIdsToUpdate.push(edge.id);
edgeIdsToUpdate.add(edge.id);
nodeRelatedIdsToUpdate.add(edge.id);
});
},
);
@ -500,14 +461,71 @@ export class ItemController {
graphComboTreeDfs(this.graph, [innerModel], (child) => {
const relatedEdges = graphCore.getRelatedEdges(child.id);
relatedEdges.forEach((edge) => {
edgeIdsToUpdate.push(edge.id);
nodeRelatedIdsToUpdate.push(edge.id);
edgeIdsToUpdate.add(edge.id);
nodeRelatedIdsToUpdate.add(edge.id);
});
if (child.data._isCombo && child.id !== innerModel.id)
comboIdsToUpdate.push(child.id);
comboIdsToUpdate.add(child.id);
});
}
}
// update the theme if the dataType value is changed
let itemTheme;
if (
nodeDataTypeField &&
previous[nodeDataTypeField] !== current[nodeDataTypeField]
) {
itemTheme = getItemTheme(
this.nodeDataTypeSet,
nodeDataTypeField,
current[nodeDataTypeField],
nodeTheme,
);
}
graphCore.getRelatedEdges(id).forEach((edge) => {
edgeIdsToUpdate.add(edge.id);
nodeRelatedIdsToUpdate.add(edge.id);
});
if (!onlyMove) {
item.onframe = () => updateRelates(nodeRelatedIdsToUpdate);
}
let statesCache;
if (
innerModel.data._isCombo &&
previous.collapsed !== current.collapsed
) {
statesCache = this.graph.getItemAllStates(id);
this.graph.clearItemState(id);
}
item.update(
innerModel,
{ previous, current },
isReplace,
itemTheme,
onlyMove,
animate,
// call after updating finished
throttle(
(_, canceled) => {
item.onframe?.(true);
item.onframe = undefined;
if (statesCache) {
statesCache.forEach((state) =>
this.graph.setItemState(id, state, true),
);
}
callback(innerModel, canceled);
},
500,
{
leading: true,
trailing: true,
},
),
);
const parentItem = this.itemMap.get(current.parentId);
if (current.parentId && parentItem?.model.data.collapsed) {
this.graph.hideItem(innerModel.id);
@ -515,7 +533,6 @@ export class ItemController {
});
updateRelatesThrottle();
}
// === 6. update edges' data ===
if (groupedChanges.EdgeDataUpdated.length) {
const edgeUpdate = {};
@ -561,7 +578,6 @@ export class ItemController {
);
});
}
// === 7. update edges' source target ===
if (groupedChanges.EdgeUpdated.length) {
const edgeUpdate = {};
@ -581,12 +597,10 @@ export class ItemController {
item.updateEnd('target', this.itemMap.get(target) as Node);
});
}
// === 8. combo tree structure change, resort the shapes ===
if (groupedChanges.ComboStructureChanged.length) {
this.sortByComboTree(graphCore);
}
// === 9. tree data structure change, hide the new node and edge while one of the ancestor is collapsed ===
if (groupedChanges.TreeStructureChanged.length) {
groupedChanges.TreeStructureChanged.forEach((change) => {
@ -996,39 +1010,42 @@ export class ItemController {
comboTheme,
);
itemMap.set(
combo.id,
new Combo({
model: combo,
getCombinedBounds: () => {
// calculate the position of the combo according to its children
const childModels = graphCore.getChildren(combo.id, 'combo');
return getCombinedBoundsByData(graph, childModels);
},
getChildren: () => {
const childModels = graphCore.getChildren(combo.id, 'combo');
return childModels.map(({ id }) => itemMap.get(id)) as (
| Node
| Combo
)[];
},
renderExtensions: comboExtensions,
containerGroup: comboGroup,
mapper: this.comboMapper as DisplayMapper,
stateMapper: this.comboStateMapper as {
[stateName: string]: DisplayMapper;
},
zoom,
theme: itemTheme as {
styles: ComboStyleSet;
lodStrategy: LodStrategyObj;
},
device:
graph.rendererType === 'webgl-3d'
? (graph.canvas.context as any).deviceRendererPlugin.getDevice()
: undefined,
}),
);
const getCombinedBounds = () => {
// calculate the position of the combo according to its children
const childModels = graphCore.getChildren(combo.id, 'combo');
return getCombinedBoundsByData(graph, childModels);
};
const getChildren = () => {
const childModels = graphCore.getChildren(combo.id, 'combo');
return childModels.map(({ id }) => itemMap.get(id)) as (Node | Combo)[];
};
const comboItem = new Combo({
model: combo,
getCombinedBounds,
getChildren,
renderExtensions: comboExtensions,
containerGroup: comboGroup,
mapper: this.comboMapper as DisplayMapper,
stateMapper: this.comboStateMapper as {
[stateName: string]: DisplayMapper;
},
zoom,
theme: itemTheme as {
styles: ComboStyleSet;
lodStrategy: LodStrategyObj;
},
device:
graph.rendererType === 'webgl-3d'
? (graph.canvas.context as any).deviceRendererPlugin.getDevice()
: undefined,
});
// ------- for integration tests -------
comboItem.getCombinedBounds = getCombinedBounds;
comboItem.getChildren = getChildren;
comboItem.type = 'combo';
// ------- for integration tests end-------
itemMap.set(combo.id, comboItem);
});
}
@ -1128,6 +1145,20 @@ export class ItemController {
return item.hasState(state);
}
public getItemAllStates(id: ID): string[] {
const item = this.itemMap.get(id);
if (!item) {
console.warn(
`Fail to get item state, the item with id ${id} does not exist.`,
);
return [];
}
return item
.getStates()
.filter(({ value }) => value)
.map(({ name }) => name);
}
public getItemById(id: ID) {
return this.itemMap.get(id);
}
@ -1225,14 +1256,17 @@ export class ItemController {
});
if (isAncestorCollapsed) return;
const relatedVirtualEdgeIds: ID[] = [];
let edgesToShow: ID[] = [];
const nodesToShow: ID[] = [];
// show the succeeds
graphComboTreeDfs(this.graph, [comboModel], (child) => {
graphCore.getRelatedEdges(child.id).forEach((edge) => {
if (edge.data._virtual) relatedVirtualEdgeIds.push(edge.id);
else edgesToShow.push(edge.id);
});
if (child.id !== comboModel.id) {
if (!graphCore.getNode(child.data.parentId).data.collapsed) {
this.graph.showItem(child.id);
nodesToShow.push(child.id);
}
// re-add collapsed succeeds' virtual edges by calling collapseCombo
if (child.data._isCombo && child.data.collapsed) {
@ -1240,8 +1274,18 @@ export class ItemController {
}
}
});
edgesToShow = uniq(
edgesToShow.filter((eid) => {
const { source, target } = graphCore.getEdge(eid);
return (
(this.graph.getItemVisible(source) || nodesToShow.includes(source)) &&
(this.graph.getItemVisible(target) || nodesToShow.includes(target))
);
}),
);
// remove related virtual edges
this.graph.removeData('edge', uniq(relatedVirtualEdgeIds));
this.graph.showItem(edgesToShow.concat(nodesToShow));
}
/**

View File

@ -18,7 +18,7 @@ import {
} from '../../types';
import { GraphCore } from '../../types/data';
import { EdgeModelData } from '../../types/edge';
import { layoutOneTree } from '../../util/layout';
import { isComboLayout, layoutOneTree } from '../../util/layout';
/**
* Manages layout extensions and graph layout.
@ -61,11 +61,12 @@ export class LayoutController {
this.stopLayout();
const { graphCore, options, animate = true } = params;
const layoutNodes = graphCore
.getAllNodes()
.filter(
let layoutNodes = graphCore.getAllNodes();
if (!isComboLayout(options)) {
layoutNodes = layoutNodes.filter(
(node) => this.graph.getItemVisible(node.id) && !node.data._isCombo,
);
}
const layoutNodesIdMap = {};
layoutNodes.forEach((node) => (layoutNodesIdMap[node.id] = true));
const layoutData = {
@ -80,6 +81,15 @@ export class LayoutController {
const layoutGraphCore = new GraphLib<NodeModelData, EdgeModelData>(
layoutData,
);
if (graphCore.hasTreeStructure('combo')) {
layoutGraphCore.attachTreeStructure('combo');
layoutNodes.forEach((node) => {
const parent = graphCore.getParent(node.id, 'combo');
if (parent && layoutGraphCore.hasNode(parent.id)) {
layoutGraphCore.setParent(node.id, parent.id, 'combo');
}
});
}
this.graph.emit('startlayout');

View File

@ -1233,6 +1233,16 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
return this.itemController.getItemState(id, state);
}
/**
* Get all the state names with value true for an item.
* @param id the id for the item
* @returns {string[]} the state names with value true
* @group Item
*/
public getItemAllStates(id: ID): string[] {
return this.itemController.getItemAllStates(id);
}
/**
* Clear all the states for item(s).
* @param ids the id(s) for the item(s) to be clear
@ -1366,6 +1376,10 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
dx: number,
dy: number,
upsertAncestors?: boolean,
callback?: (
model: NodeModel | EdgeModel | ComboModel,
canceled?: boolean,
) => void,
stack?: boolean,
): ComboModel[] {
const idArr = isArray(ids) ? ids : [ids];
@ -1380,6 +1394,7 @@ export default class Graph<B extends BehaviorRegistry, T extends ThemeRegistry>
theme: specification,
upsertAncestors,
action: 'updatePosition',
callback,
});
this.emit('afteritemchange', {
type: 'combo',

View File

@ -335,6 +335,10 @@ export default class DragCombo extends Behavior {
deltaY: number,
transient: boolean,
upsertAncestors = true,
callback?: (
model: EdgeModel | NodeModel | ComboModel,
canceled?: boolean,
) => void,
) {
if (transient) {
// Move transient nodes
@ -357,6 +361,7 @@ export default class DragCombo extends Behavior {
deltaX,
deltaY,
upsertAncestors,
callback,
);
}
@ -458,30 +463,29 @@ export default class DragCombo extends Behavior {
const deltaX = pointerEvent.canvas.x - baseX + 0.01;
// @ts-ignore FIXME: Type
const deltaY = pointerEvent.canvas.y - baseY + 0.01;
this.moveCombos(deltaX, deltaY, false, true);
// }
this.moveCombos(deltaX, deltaY, false, true, () => {
// restore the hidden items after move real combos done
if (enableTransient) {
this.clearTransientItems();
}
if (enableTransient) {
this.clearTransientItems();
}
if (this.options.enableDelegate) {
this.clearDelegate();
}
if (this.options.enableDelegate) {
this.clearDelegate();
}
// Restore all hidden items.
// For all hideRelatedEdges, enableTransient and enableDelegate cases.
this.restoreHiddenItems();
// Emit event.
if (this.options.eventName) {
this.graph.emit(this.options.eventName, {
itemIds: this.originPositions.map((position) => position.id),
});
}
// Restore all hidden items.
// For all hideRelatedEdges, enableTransient and enableDelegate cases.
this.restoreHiddenItems();
// Emit event.
if (this.options.eventName) {
this.graph.emit(this.options.eventName, {
itemIds: this.originPositions.map((position) => position.id),
});
}
// Reset state.
this.originPositions = [];
// Reset state.
this.originPositions = [];
});
}
public onKeydown(event: KeyboardEvent) {

View File

@ -324,6 +324,10 @@ export default class DragNode extends Behavior {
deltaY: number,
transient: boolean,
upsertAncestors = true,
callback?: (
model: EdgeModel | NodeModel | ComboModel,
canceled?: boolean,
) => void,
) {
if (transient) {
// Move transient nodes
@ -350,7 +354,12 @@ export default class DragNode extends Behavior {
},
};
});
this.graph.updateNodePosition(positionChanges, upsertAncestors);
this.graph.updateNodePosition(
positionChanges,
upsertAncestors,
true,
callback,
);
}
}
@ -446,30 +455,30 @@ export default class DragNode extends Behavior {
const deltaX = pointerEvent.canvas.x - this.originX + 0.01;
// @ts-ignore FIXME: Type
const deltaY = pointerEvent.canvas.y - this.originY + 0.01;
this.moveNodes(deltaX, deltaY, false, true);
// }
this.moveNodes(deltaX, deltaY, false, true, () => {
// restore the hidden items after move real nodes done
if (enableTransient) {
this.clearTransientItems();
}
if (enableTransient) {
this.clearTransientItems();
}
if (this.options.enableDelegate) {
this.clearDelegate();
}
if (this.options.enableDelegate) {
this.clearDelegate();
}
// Restore all hidden items.
// For all hideRelatedEdges, enableTransient and enableDelegate cases.
this.restoreHiddenItems();
// Restore all hidden items.
// For all hideRelatedEdges, enableTransient and enableDelegate cases.
this.restoreHiddenItems();
// Emit event.
if (this.options.eventName) {
this.graph.emit(this.options.eventName, {
itemIds: this.originPositions.map((position) => position.id),
});
}
// Emit event.
if (this.options.eventName) {
this.graph.emit(this.options.eventName, {
itemIds: this.originPositions.map((position) => position.id),
});
}
// Reset state.
this.originPositions = [];
// Reset state.
this.originPositions = [];
});
}
// TODO: deal with combos
@ -494,22 +503,23 @@ export default class DragNode extends Behavior {
this.originPositions = [];
}
// TODO(FIXME): dragging nodes' keyShape accepth drop event while drag on labelShape, makes the parent unchanged
public onDropNode(event: IG6GraphEvent) {
// drop on a node A, move the dragged node to the same parent of A
const targetNodeData = this.graph.getNodeData(event.itemId);
const { parentId: newParentId } = targetNodeData.data;
this.originPositions.forEach(({ id }) => {
if (id === targetNodeData.id) return;
const model = this.graph.getNodeData(id);
if (!model) return;
const { parentId } = model.data;
// if the parents are same, do nothing
if (parentId === newParentId) return;
// // drop on a node A, move the dragged node to the same parent of A
// const targetNodeData = this.graph.getNodeData(event.itemId);
// const { parentId: newParentId } = targetNodeData.data;
// this.originPositions.forEach(({ id }) => {
// if (id === targetNodeData.id) return;
// const model = this.graph.getNodeData(id);
// if (!model) return;
// const { parentId } = model.data;
// // if the parents are same, do nothing
// if (parentId === newParentId) return;
// update data to change the structure
// if newParentId is undefined, new parent is the canvas
this.graph.updateData('node', { id, data: { parentId: newParentId } });
});
// // update data to change the structure
// // if newParentId is undefined, new parent is the canvas
// this.graph.updateData('node', { id, data: { parentId: newParentId } });
// });
this.onPointerUp(event);
}

View File

@ -31,7 +31,6 @@ import RotateCanvas3D from './behavior/rotate-canvas-3d';
import TrackCanvas3D from './behavior/track-canvas-3d';
import ZoomCanvas from './behavior/zoom-canvas';
import ZoomCanvas3D from './behavior/zoom-canvas-3d';
import { CircleCombo } from './item/combo/circle';
import CollapseExpandTree from './behavior/collapse-expand-tree';
import { CubicEdge } from './item/edge/cubic';
@ -47,6 +46,8 @@ import toolbar from './plugin/toolbar';
import Tooltip from './plugin/tooltip';
import lassoSelector from './selector/lasso';
import rectSelector from './selector/rect';
import { CircleCombo } from './item/combo/circle';
import { RectCombo } from './item/combo/rect';
const stdLib = {
transforms: {
@ -108,6 +109,7 @@ const stdLib = {
},
combos: {
'circle-combo': CircleCombo,
'rect-combo': RectCombo,
},
};

View File

@ -0,0 +1,123 @@
import { DisplayObject } from '@antv/g';
import { State } from '../../../types/item';
import {
ComboDisplayModel,
ComboModelData,
ComboShapeMap,
ComboShapeStyles,
} from '../../../types/combo';
import { BaseNode } from '../node/base';
export class RectCombo extends BaseNode {
override defaultStyles = {
keyShape: {
x: 0,
y: 0,
width: 32,
height: 32,
},
};
mergedStyles: ComboShapeStyles;
constructor(props) {
super(props);
// suggest to merge default styles like this to avoid style value missing
// this.defaultStyles = mergeStyles([this.baseDefaultStyles, this.defaultStyles]);
}
public draw(
model: ComboDisplayModel,
shapeMap: ComboShapeMap,
diffData?: { previous: ComboModelData; current: ComboModelData },
diffState?: { previous: State[]; current: State[] },
): ComboShapeMap {
const { data = {} } = model;
let shapes: ComboShapeMap = { keyShape: undefined };
// keyShape
shapes.keyShape = this.drawKeyShape(model, shapeMap, diffData);
// haloShape
if (data.haloShape && this.drawHaloShape) {
shapes.haloShape = this.drawHaloShape(model, shapeMap, diffData);
}
// labelShape
if (data.labelShape) {
shapes.labelShape = this.drawLabelShape(model, shapeMap, diffData);
}
// labelBackgroundShape
if (data.labelBackgroundShape) {
shapes.labelBackgroundShape = this.drawLabelBackgroundShape(
model,
shapeMap,
diffData,
);
}
// anchor shapes
if (data.anchorShapes) {
const anchorShapes = this.drawAnchorShapes(
model,
shapeMap,
diffData,
diffState,
);
shapes = {
...shapes,
...anchorShapes,
};
}
// iconShape
if (data.iconShape) {
shapes.iconShape = this.drawIconShape(model, shapeMap, diffData);
}
// badgeShape
if (data.badgeShapes) {
const badgeShapes = this.drawBadgeShapes(
model,
shapeMap,
diffData,
diffState,
);
shapes = {
...shapes,
...badgeShapes,
};
}
// otherShapes
if (data.otherShapes && this.drawOtherShapes) {
shapes = {
...shapes,
...this.drawOtherShapes(model, shapeMap, diffData),
};
}
return shapes;
}
public drawKeyShape(
model: ComboDisplayModel,
shapeMap: ComboShapeMap,
diffData?: { previous: ComboModelData; current: ComboModelData },
diffState?: { previous: State[]; current: State[] },
): DisplayObject {
return this.upsertShape(
'rect',
'keyShape',
this.mergedStyles.keyShape,
shapeMap,
model,
);
}
public getMergedStyles(model: ComboDisplayModel) {
const merged = super.getMergedStyles(model);
merged.keyShape.x =
(merged.keyShape.x as number) - merged.keyShape.width / 2;
merged.keyShape.y =
(merged.keyShape.y as number) - merged.keyShape.height / 2;
return merged;
}
}

View File

@ -416,14 +416,16 @@ export abstract class BaseNode {
this.mergedStyles;
if (haloShapeStyle.visible === false) return;
const { nodeName, attributes } = keyShape;
const { x, y, fill } = attributes;
return this.upsertShape(
nodeName as SHAPE_TYPE,
'haloShape',
{
...keyShapeStyle,
// actual attributes in the keyShape has higher priority than the style config props of keyShape
...attributes,
stroke: attributes.fill,
...keyShapeStyle,
x,
y,
stroke: fill,
...haloShapeStyle,
batchKey: 'halo',
},

View File

@ -31,12 +31,13 @@ export default class Minimap extends Base {
/** The viewport DOM on the minimap. */
private viewport: HTMLElement | undefined;
/** Cache the mapping of graphics of nodes/edges/combos on main graph and minimap graph. */
private itemMap: {
[id: string]: {
private itemMap: Map<
ID,
{
minimapItem: DisplayObject;
graphItem: DisplayObject;
};
} = {};
}
> = new Map();
private container: HTMLDivElement;
/** Ratio of (minimap graph size / main graph size). */
private ratio: number;
@ -351,13 +352,13 @@ export default class Minimap extends Base {
* @param group container graphics group on minimap
*/
private updateOneNodeKeyShape(nodeModel, group) {
const { itemMap = {}, graph } = this;
const { itemMap = new Map(), graph } = this;
const graphNodeGroup = graph.canvas
.getRoot()
.find((ele) => ele.id === 'node-group');
if (!graphNodeGroup) return;
let { minimapItem, graphItem } = itemMap[nodeModel.id] || {};
let { minimapItem, graphItem } = itemMap.get(nodeModel.id) || {};
if (!minimapItem || minimapItem.destroyed) {
graphItem = graphNodeGroup
.find((ele) => ele.getAttribute('data-item-id') === nodeModel.id)
@ -365,7 +366,7 @@ export default class Minimap extends Base {
minimapItem = graphItem.cloneNode();
minimapItem.id = `minimap-keyShape-${nodeModel.id}`;
group.appendChild(minimapItem);
itemMap[nodeModel.id] = { graphItem, minimapItem };
itemMap.set(nodeModel.id, { graphItem, minimapItem });
}
const bbox = graphItem.getRenderBounds();
if (!bbox) return;
@ -433,16 +434,14 @@ export default class Minimap extends Base {
}
private clearDestroyedShapes() {
const { itemMap = {} } = this;
const keys = Object.keys(itemMap);
if (!keys || keys.length === 0) return;
for (let i = keys.length - 1; i >= 0; i--) {
const { minimapItem, graphItem } = itemMap[keys[i]] || {};
const { itemMap = new Map() } = this;
itemMap.forEach((val, key) => {
const { minimapItem, graphItem } = val || {};
if (graphItem.destroyed && minimapItem) {
minimapItem.remove();
delete itemMap[keys[i]];
itemMap.delete(key);
}
}
});
}
/**
@ -451,12 +450,12 @@ export default class Minimap extends Base {
* @param group container graphics group on minimap
*/
private updateOneEdgeKeyShape(edgeModel, group) {
const { itemMap = {}, graph } = this;
const { itemMap = new Map(), graph } = this;
const graphEdgeGroup = graph.canvas
.getRoot()
.find((ele) => ele.id === 'edge-group');
if (!graphEdgeGroup) return;
let { minimapItem, graphItem } = itemMap[edgeModel.id] || {};
let { minimapItem, graphItem } = itemMap.get(edgeModel.id) || {};
if (minimapItem && !minimapItem.destroyed) {
const path = graphItem.style.path;
minimapItem.style.path = path;
@ -470,7 +469,7 @@ export default class Minimap extends Base {
}
if (!graph.getItemVisible(edgeModel.id)) minimapItem.hide();
else minimapItem.show();
itemMap[edgeModel.id] = { graphItem, minimapItem };
itemMap.set(edgeModel.id, { graphItem, minimapItem });
this.itemMap = itemMap;
}
@ -480,7 +479,7 @@ export default class Minimap extends Base {
* @param group container graphics group on minimap
*/
private updateOneNodeDelegateShape(nodeModel, group) {
const { itemMap = {}, options, graph } = this;
const { itemMap = new Map(), options, graph } = this;
const { delegateStyle } = options;
const graphNodeGroup = graph.canvas
@ -489,7 +488,7 @@ export default class Minimap extends Base {
if (!graphNodeGroup) return;
// 差量更新 minimap 上的一个节点,对应主图的 item
let { minimapItem, graphItem } = itemMap[nodeModel.id] || {};
let { minimapItem, graphItem } = itemMap.get(nodeModel.id) || {};
if (!graphItem) {
graphItem = graphNodeGroup
.find((ele) => ele.getAttribute('data-item-id') === nodeModel.id)
@ -523,7 +522,7 @@ export default class Minimap extends Base {
if (!graph.getItemVisible(nodeModel.id)) minimapItem.hide();
else minimapItem.show();
itemMap[nodeModel.id] = { graphItem, minimapItem };
itemMap.set(nodeModel.id, { graphItem, minimapItem });
this.itemMap = itemMap;
}

View File

@ -92,6 +92,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
selected: {
@ -108,6 +109,7 @@ export default {
zIndex: -1,
pointerEvents: 'none',
visible: true,
droppable: false,
},
},
active: {
@ -120,6 +122,7 @@ export default {
zIndex: -1,
pointerEvents: 'none',
visible: true,
droppable: false,
},
},
highlight: {
@ -132,6 +135,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
inactive: {
@ -146,6 +150,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
disable: {
@ -155,6 +160,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
},
@ -239,6 +245,7 @@ export default {
zIndex: -1,
pointerEvents: 'none',
visible: true,
droppable: false,
},
},
active: {
@ -251,6 +258,7 @@ export default {
zIndex: -1,
pointerEvents: 'none',
visible: true,
droppable: false,
},
},
highlight: {

View File

@ -95,6 +95,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
selected: {
@ -111,6 +112,7 @@ export default {
pointerEvents: 'none',
zIndex: -1,
visible: true,
droppable: false,
},
},
active: {
@ -123,6 +125,7 @@ export default {
pointerEvents: 'none',
zIndex: -1,
visible: true,
droppable: false,
},
},
highlight: {
@ -135,6 +138,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
inactive: {
@ -149,6 +153,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
disable: {
@ -158,6 +163,7 @@ export default {
},
haloShape: {
visible: false,
droppable: false,
},
},
},
@ -241,6 +247,7 @@ export default {
zIndex: -1,
pointerEvents: 'none',
visible: true,
droppable: false,
},
},
active: {
@ -253,6 +260,7 @@ export default {
zIndex: -1,
pointerEvents: 'none',
visible: true,
droppable: false,
},
},
highlight: {
@ -325,6 +333,7 @@ export default {
zIndex: -1,
visible: true,
stroke: 'rgba(153,173,209,1)',
droppable: false,
},
},
active: {
@ -339,6 +348,7 @@ export default {
zIndex: -1,
visible: true,
stroke: 'rgba(153,173,209,1)',
droppable: false,
},
},
highlight: {
@ -380,8 +390,8 @@ export default {
stroke: comboStroke,
// the collapsed size
r: 16,
width: 20,
height: 10,
width: 48,
height: 24,
padding: [25, 20, 15, 20],
},
iconShape: {

View File

@ -272,6 +272,10 @@ export interface IGraph<
dx: number,
dy: number,
upsertAncestors?: boolean,
callback?: (
model: NodeModel | EdgeModel | ComboModel,
canceled?: boolean,
) => void,
stack?: boolean,
) => ComboModel[];
@ -490,6 +494,13 @@ export interface IGraph<
* @group Item
*/
getItemState: (id: ID, state: string) => boolean | string;
/**
* Get all the state names with value true for an item.
* @param id the id for the item
* @returns {string[]} the state names with value true
* @group Item
*/
getItemAllStates: (id: ID) => string[];
/**
* Clear all the states for item(s).
* @param ids the id(s) for the item(s) to be clear

View File

@ -275,7 +275,6 @@ const runAnimateOnShape = (
beginStyle: ShapeStyle,
animateConfig,
) => {
if (!shape.isVisible()) return;
let animateArr;
if (!fields?.length) {
animateArr = getStyleDiff(shape.attributes, targetStyle);
@ -294,6 +293,13 @@ const runAnimateOnShape = (
});
}
if (!checkFrames(animateArr, shape)) return;
if (!shape.isVisible()) {
// Invisible, do not apply animate. Directly assign the target style instead.
Object.keys(animateArr[1]).forEach(
(field) => (shape.style[field] = animateArr[1][field]),
);
return;
}
return shape.animate(animateArr, animateConfig);
};
@ -392,9 +398,6 @@ export const animateShapes = (
export const getAnimatesExcludePosition = (animates) => {
if (!animates.update) return animates;
const isGroupId = (id) => !id || id === 'group';
// const groupUpdateAnimates = animates.update.filter(
// ({ shapeId }) => isGroupId(shapeId),
// );
const excludedAnimates = [];
animates.update.forEach((animate) => {
const { shapeId, fields } = animate;

View File

@ -1,10 +1,11 @@
import { NodeUserModel } from 'types';
import { TreeData } from '@antv/graphlib';
import { ID, TreeData } from '@antv/graphlib';
import { NodeUserModelData } from 'types/node';
import { isArray } from '@antv/util';
import { depthFirstSearch, connectedComponent } from '@antv/algorithm';
import { GraphCore, GraphData } from '../types/data';
import { IGraph } from '../types/graph';
import { NodeModel } from '../types';
/**
* Deconstruct data and distinguish nodes and combos from graphcore data.
@ -236,12 +237,19 @@ export const treeData2GraphData = (
export const graphData2TreeData = (
nodeMap: { [id: string]: any },
graphData: GraphData,
propRootIds = [],
propRootIds: ID[] = [],
) => {
const trees = [];
const connectedComponents = connectedComponent(graphData as any, false);
const graphDataWithoutCombos = {
nodes: graphData.nodes?.filter((node) => !node.data._isCombo),
edges: graphData.edges,
};
const connectedComponents = connectedComponent(
graphDataWithoutCombos as any,
false,
) as NodeModel[][];
const rootIds = [];
const componentsNodeIds = [];
const componentsNodeIds: ID[][] = [];
connectedComponents.forEach((com, i) => {
componentsNodeIds[i] = com.map((node) => node.id);
if (propRootIds.length) {

View File

@ -37,7 +37,7 @@ export const upsertTransientItem = (
onlyDrawKeyShape?: boolean,
upsertAncestors = true,
) => {
let transientItem = transientItemMap[item.model.id];
let transientItem = transientItemMap.get(item.model.id);
if (transientItem) {
return transientItem;
}
@ -104,7 +104,7 @@ export const upsertTransientItem = (
) as Combo;
transientItem.toBack();
}
transientItemMap[item.model.id] = transientItem;
transientItemMap.set(item.model.id, transientItem);
transientItem.transient = true;
if (item.type !== 'edge' && upsertAncestors) {

View File

@ -63,3 +63,9 @@ export const layoutOneTree = (
begin[isHorizontal ? 1 : 0] += range[1] + diff + treeGap;
return nodePositions;
};
export const isComboLayout = (options) => {
const { type } = options;
if (['comboCombined', 'comboForce'].includes(type)) return true;
return false;
};

View File

@ -0,0 +1,822 @@
export const data = {
nodes: [
{
id: '0',
data: {
parentId: 'a',
},
},
{
id: '1',
data: {
parentId: 'a',
},
},
{
id: '2',
data: {
parentId: 'a',
},
},
{
id: '3',
data: {
parentId: 'a',
},
},
{
id: '4',
data: {
parentId: 'a',
},
},
{
id: '5',
data: {
parentId: 'a',
},
},
{
id: '6',
data: {
parentId: 'a',
},
},
{
id: '7',
data: {
parentId: 'a',
},
},
{
id: '8',
data: {
parentId: 'a',
},
},
{
id: '9',
data: {
parentId: 'a',
},
},
{
id: '10',
data: {
parentId: 'a',
},
},
{
id: '11',
data: {
parentId: 'a',
},
},
{
id: '12',
data: {
parentId: 'a',
},
},
{
id: '13',
data: {
parentId: 'a',
},
},
{
id: '14',
data: {
parentId: 'a',
},
},
{
id: '15',
data: {
parentId: 'a',
},
},
{
id: '16',
data: {
parentId: 'b',
},
},
{
id: '17',
data: {
parentId: 'b',
},
},
{
id: '18',
data: {
parentId: 'b',
},
},
{
id: '19',
data: {
parentId: 'b',
},
},
{
id: '20',
data: {},
},
{
id: '21',
data: {},
},
{
id: '22',
data: {},
},
{
id: '23',
data: {
parentId: 'c',
},
},
{
id: '24',
data: {
parentId: 'a',
},
},
{
id: '25',
data: {},
},
{
id: '26',
data: {},
},
{
id: '27',
data: {
parentId: 'c',
},
},
{
id: '28',
data: {
parentId: 'c',
},
},
{
id: '29',
data: {
parentId: 'c',
},
},
{
id: '30',
data: {
parentId: 'c',
},
},
{
id: '31',
data: {
parentId: 'c',
},
},
{
id: '32',
data: {
parentId: 'd',
},
},
{
id: '33',
data: {
parentId: 'd',
},
},
],
edges: [
{
id: 'edge-0.01993341478870847',
source: 'a',
target: 'b',
data: {
labelShape: {
text: 'Combo A - Combo B',
stroke: '#fff',
lineWidth: 5,
fontSize: 20,
},
keyShape: {
stroke: 'red',
},
},
},
{
id: 'edge-0.5214746372435413',
source: 'a',
target: '33',
data: {
labelShape: {
text: 'Combo-Node',
stroke: '#fff',
lineWidth: 5,
fontSize: 20,
},
keyShape: {
stroke: 'blue',
},
},
},
{
id: 'edge-0.4469559127736913',
source: '0',
target: '1',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.23210761533109747',
source: '0',
target: '2',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.5824837517526993',
source: '0',
target: '3',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.5774159718550838',
source: '0',
target: '4',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.9554933245946797',
source: '0',
target: '5',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.8541173627270486',
source: '0',
target: '7',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.9436639396876105',
source: '0',
target: '8',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.18387890055282274',
source: '0',
target: '9',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.5989992953130812',
source: '0',
target: '10',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.1706485291459836',
source: '0',
target: '11',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.9210147080891349',
source: '0',
target: '13',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.3812198201194317',
source: '0',
target: '14',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.4857276631680716',
source: '0',
target: '15',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.43881862498777857',
source: '0',
target: '16',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.4261236642937114',
source: '2',
target: '3',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.7221158321999745',
source: '4',
target: '5',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.42506345785382527',
source: '4',
target: '6',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.9773963905075538',
source: '5',
target: '6',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.6201936044437448',
source: '7',
target: '13',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.00024442602366181454',
source: '8',
target: '14',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.23396189752683205',
source: '9',
target: '10',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.13004316144808747',
source: '10',
target: '22',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.48354582553982706',
source: '10',
target: '14',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.2925169544203323',
source: '10',
target: '12',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.3718095338067309',
source: '10',
target: '24',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.6797871272028819',
source: '10',
target: '21',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.43386454797593044',
source: '10',
target: '20',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.5298529000486405',
source: '11',
target: '24',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.4923557745036993',
source: '11',
target: '22',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.3912299412926239',
source: '11',
target: '14',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.7241868541038936',
source: '12',
target: '13',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.9783118420560588',
source: '16',
target: '17',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.8359508452785043',
source: '16',
target: '18',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.3260263796039027',
source: '16',
target: '21',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.7343120866226782',
source: '16',
target: '22',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.11353623383427447',
source: '17',
target: '18',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.44673858057367455',
source: '17',
target: '20',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.9074289235299271',
source: '18',
target: '19',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.08561999349929672',
source: '19',
target: '20',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.25271066887883165',
source: '19',
target: '33',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.87691685052256',
source: '19',
target: '22',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.7481576350022041',
source: '19',
target: '23',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.08690181829615584',
source: '20',
target: '21',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.09496256055594943',
source: '21',
target: '22',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.3311164801494788',
source: '22',
target: '24',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.19443708532706316',
source: '22',
target: '25',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.8189473993335785',
source: '22',
target: '26',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.14226958344009755',
source: '22',
target: '23',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.5463413587134691',
source: '22',
target: '28',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.25546228085920086',
source: '22',
target: '30',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.010206434942076958',
source: '22',
target: '31',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.8064821425589817',
source: '22',
target: '32',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.34724087456902364',
source: '22',
target: '33',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.265333871120637',
source: '23',
target: '28',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.4778573966413959',
source: '23',
target: '27',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.9426592331914649',
source: '23',
target: '29',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.36170909908551074',
source: '23',
target: '30',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.622124933887169',
source: '23',
target: '31',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.49703094218859767',
source: '23',
target: '33',
data: {
labelShape: {},
keyShape: {},
},
},
{
id: 'edge-0.6683528774440479',
source: '32',
target: '33',
data: {
labelShape: {},
keyShape: {},
},
},
],
combos: [
{
id: 'a',
data: {
label: 'Combo A',
},
},
{
id: 'b',
data: {
label: 'Combo B',
},
},
{
id: 'c',
data: {
label: 'Combo C',
},
},
{
id: 'd',
data: {
label: 'Combo D',
parentId: 'b',
},
},
],
};
export const smallData = {
nodes: [
{ id: 'node1', data: { parentId: 'combo1' } },
{ id: 'node2', data: { parentId: 'combo1' } },
{ id: 'node3', data: { parentId: 'combo2' } },
{ id: 'node4', data: { parentId: 'combo1' } },
{ id: 'node5', data: {} },
],
edges: [
{ id: 'edge1', source: 'node1', target: 'node2', data: {} },
{ id: 'edge2', source: 'node1', target: 'node3', data: {} },
{ id: 'edge3', source: 'node1', target: 'node4', data: {} },
{ id: 'edge4', source: 'node2', target: 'node3', data: {} },
{ id: 'edge5', source: 'node3', target: 'node4', data: {} },
{ id: 'edge6', source: 'node4', target: 'node5', data: {} },
],
combos: [
{ id: 'combo1', data: { parentId: 'combo2' } }, // collapsed: true
{ id: 'combo2', data: {} },
{ id: 'combo3', data: {} },
],
};

View File

@ -6,6 +6,7 @@ export default (
context: TestCaseContext,
options: { trigger?: string } = {},
) => {
// no animations for testing
const { trigger = 'click' } = options;
const graph = new G6.Graph({
...context,

View File

@ -1,7 +1,13 @@
import { Graph } from '../../../src/index';
import { TestCaseContext } from '../interface';
export default (context: TestCaseContext) => {
const graph = new Graph({
import G6 from '../../../src/index';
export default (
context,
options: {
disableAnimate?: boolean;
comboType?: 'circle-combo' | 'rect-combo';
} = {},
) => {
const { disableAnimate = false, comboType = 'circle-combo' } = options;
const graph = new G6.Graph({
...context,
layout: {
type: 'grid',
@ -14,19 +20,22 @@ export default (context: TestCaseContext) => {
formatter: (model) => model.id,
},
},
animates: {
update: [
{
fields: ['opacity'],
shapeId: 'haloShape',
animates: disableAnimate
? {}
: {
update: [
{
fields: ['opacity'],
shapeId: 'haloShape',
},
],
},
],
},
},
combo: (model) => {
return {
id: model.id,
data: {
type: comboType,
...model.data,
keyShape: {
padding: [10, 20, 30, 40],
@ -36,39 +45,38 @@ export default (context: TestCaseContext) => {
text: model.id,
},
animates: {
buildIn: [
{
fields: ['opacity'],
duration: 500,
delay: 500 + Math.random() * 500,
animates: disableAnimate
? {}
: {
buildIn: [
{
fields: ['opacity'],
duration: 500,
delay: 500 + Math.random() * 500,
},
],
buildOut: [
{
fields: ['opacity'],
duration: 200,
},
],
update: [
{
fields: ['lineWidth', 'r'],
shapeId: 'keyShape',
},
{
fields: ['opacity'],
shapeId: 'haloShape',
},
],
},
],
buildOut: [
{
fields: ['opacity'],
duration: 200,
},
],
update: [
{
fields: ['lineWidth', 'r'],
shapeId: 'keyShape',
},
{
fields: ['opacity'],
shapeId: 'haloShape',
},
],
},
},
};
},
data: {
nodes: [
// { id: 'node1', data: {} },
// { id: 'node2', data: {} },
// { id: 'node3', data: {} },
{ id: 'node1', data: { parentId: 'combo1' } },
{ id: 'node2', data: { parentId: 'combo1' } },
{ id: 'node3', data: { parentId: 'combo2' } },
@ -82,7 +90,6 @@ export default (context: TestCaseContext) => {
{ id: 'edge4', source: 'node2', target: 'node3', data: {} },
{ id: 'edge5', source: 'node3', target: 'node4', data: {} },
{ id: 'edge6', source: 'node4', target: 'node5', data: {} },
// { id: 'edge7', source: 'node5', target: 'combo1', data: {} },
],
combos: [
{ id: 'combo1', data: { parentId: 'combo2' } }, // collapsed: true
@ -93,7 +100,12 @@ export default (context: TestCaseContext) => {
modes: {
default: [
'collapse-expand-combo',
'drag-node',
// 'drag-node',
{
type: 'drag-node',
enableTransient: false,
updateComboStructure: false,
},
'drag-canvas',
{
type: 'click-select',
@ -103,59 +115,13 @@ export default (context: TestCaseContext) => {
type: 'hover-activate',
itemTypes: ['node', 'edge', 'combo'],
},
'drag-combo',
{
type: 'drag-combo',
enableTransient: true,
updateComboStructure: true,
},
],
},
});
graph.on('canvas:click', (e) => {
console.log('graph', graph);
/** modify node's parent to another combo */
// graph.updateData('node', {
// id: 'node1',
// data: {
// parentId: 'combo2',
// },
// });
/** invalid modification (to its succeeds) */
// graph.updateData('combo', {
// id: 'combo2',
// data: {
// parentId: 'combo1',
// },
// });
/** add combo */
// graph.addCombo(
// {
// id: 'newcombo',
// data: {
// parentId: 'combo2',
// },
// },
// ['node1', 'combo1', 'node4'],
// );
/** collapse combo */
// if (!graph.getComboData('combo1')?.data.collapsed) {
// graph.collapseCombo(['combo1']);
// setTimeout(() => {
// graph.collapseCombo(['combo2']);
// }, 1000);
// } else {
// graph.expandCombo(['combo2']);
// setTimeout(() => {
// graph.expandCombo(['combo1']);
// }, 1000);
// }
/** remove combo = uncombo */
// graph.removeData('combo', 'combo1');
/** move an empty combo */
// graph.updateData('combo', {
// id: 'combo3',
// data: {
// x: 100,
// y: 200,
// },
// });
// graph.moveCombo('combo3', 100, 200);
});
return graph;
};

View File

@ -0,0 +1,109 @@
import G6, { stdLib } from '../../../src/index';
import { container, height, width } from '../../datasets/const';
import {
data as comboData,
smallData as smallComboData,
} from '../../datasets/combo-data';
export default () => {
const graph = new G6.Graph({
container,
width,
height,
type: 'graph',
layout: {
type: 'comboCombined',
// innerLayout: new stdLib.layouts['force']({ minMovement: 1 }),
innerLayout: new stdLib.layouts['concentric'](),
},
node: {
labelShape: {
position: 'center',
text: {
fields: ['id'],
formatter: (model) => model.id,
},
},
animates: {
update: [
{
fields: ['opacity'],
shapeId: 'haloShape',
},
],
},
},
combo: (model) => {
return {
id: model.id,
data: {
...model.data,
type: 'circle-combo',
keyShape: {
padding: [10, 20, 30, 40],
width: 50,
height: 20,
},
labelShape: {
text: model.id,
},
animates: {
buildIn: [
{
fields: ['opacity'],
duration: 500,
delay: 500 + Math.random() * 500,
},
],
buildOut: [
{
fields: ['opacity'],
duration: 200,
},
],
update: [
{
// when rect combo collapased, rect's width/height/x/y are all changed,
// which is different from circle that the x/y of circle does not change.
fields: ['lineWidth', 'width', 'height', 'x', 'y'],
shapeId: 'keyShape',
},
{
fields: ['opacity'],
shapeId: 'haloShape',
},
],
},
},
};
},
data: comboData,
modes: {
default: [
'collapse-expand-combo',
'drag-canvas',
'zoom-canvas',
{
type: 'click-select',
itemTypes: ['node', 'edge', 'combo'],
},
{
type: 'hover-activate',
itemTypes: ['node', 'edge', 'combo'],
},
{
type: 'drag-combo',
enableTransient: true,
updateComboStructure: true,
},
{
type: 'drag-node',
enableTransient: true,
updateComboStructure: true,
},
],
},
});
return graph;
};

View File

@ -79,7 +79,6 @@ export default (context: TestCaseContext) => {
graph = new Graph({
...context,
type: 'graph',
data,
modes: {
default: ['click-select', 'drag-node'],

View File

@ -79,7 +79,6 @@ export default (context: TestCaseContext) => {
graph = new Graph({
...context,
type: 'graph',
data,
modes: {
default: ['click-select', 'drag-node', 'zoom-canvas', 'drag-canvas'],

View File

@ -4,6 +4,7 @@ import behaviors_brush_select from './behaviors/brush-select';
import behaviors_click_select from './behaviors/click-select';
import behaviors_collapse_expand_tree from './behaviors/collapse-expand-tree';
import comboBasic from './combo/combo-basic';
import comboRect from './combo/combo-rect';
import bugReproduce from './demo/bugReproduce';
import demo from './demo/demo';
import demoFor4 from './demo/demoFor4';
@ -35,11 +36,11 @@ import fisheye from './plugins/fisheye';
import hexagon from './demo/hexagon';
import triangle from './demo/triangle';
import toolbar from './plugins/toolbar';
import ellipse from './demo/ellipse';
import treeGraph from './tree/treeGraph';
import user_defined_canvas from './user-defined-canvas/circular';
import visual from './visual/visual';
export {
animations_node_build_in,
behaviors_activateRelations,
@ -47,13 +48,19 @@ export {
behaviors_click_select,
behaviors_collapse_expand_tree,
bugReproduce,
rect,
ellipse,
hexagon,
triangle,
comboBasic,
comboRect,
cubic_edge,
cubic_horizon_edge,
cubic_vertical_edge,
line_edge,
quadratic,
demo,
demoFor4,
ellipse,
fisheye,
layouts_circular,
layouts_custom,
@ -68,18 +75,13 @@ export {
layouts_fruchterman_wasm,
layouts_grid,
donut_node,
line_edge,
menu,
performance,
performance_layout,
performance_layout_3d,
quadratic,
rect,
toolbar,
tooltip,
hexagon,
treeGraph,
triangle,
user_defined_canvas,
visual,
treeGraph,
};

View File

@ -0,0 +1,114 @@
import comboBasic from '../demo/combo/combo-basic';
import './utils/useSnapshotMatchers';
import { createContext, sleep } from './utils';
describe('combo circle', () => {
// TODO(FIXME): 本地能通过,线上不通过
xit('circle combo should be rendered correctly with Canvas2D', (done) => {
const dir = `${__dirname}/snapshots/canvas`;
const { backgroundCanvas, canvas, transientCanvas, container } =
createContext('canvas', 500, 500);
const graph = comboBasic(
{
container,
backgroundCanvas,
canvas,
transientCanvas,
width: 500,
height: 500,
},
{
disableAnimate: true,
},
);
graph.on('afterlayout', async () => {
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-circle');
//seleted state
graph.setItemState('combo1', 'selected', true);
sleep(200);
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-circle-selected');
graph.collapseCombo('combo1');
sleep(200);
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-circle-collapsed');
graph.expandCombo('combo1');
sleep(200);
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-circle-expand');
graph.destroy();
done();
});
});
xit('rect combo should be rendered correctly with Canvas2D', (done) => {
const dir = `${__dirname}/snapshots/canvas`;
const { backgroundCanvas, canvas, transientCanvas, container } =
createContext('canvas', 500, 500);
const graph = comboBasic(
{
container,
backgroundCanvas,
canvas,
transientCanvas,
width: 500,
height: 500,
},
{
disableAnimate: true,
comboType: 'rect-combo',
},
);
graph.on('afterlayout', async () => {
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-rect');
//seleted state
graph.setItemState('combo1', 'selected', true);
sleep(200);
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-rect-selected');
graph.collapseCombo('combo1');
sleep(200);
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-rect-collapsed');
graph.expandCombo('combo1');
sleep(200);
await expect(canvas).toMatchCanvasSnapshot(dir, 'combo-rect-expand');
graph.destroy();
done();
});
});
xit('circle combo should be rendered correctly with SVG', (done) => {
const dir = `${__dirname}/snapshots/svg`;
const { backgroundCanvas, canvas, transientCanvas, container } =
createContext('svg', 500, 500);
const graph = comboBasic(
{
container,
backgroundCanvas,
canvas,
transientCanvas,
width: 500,
height: 500,
},
{
disableAnimate: true,
},
);
graph.on('afterlayout', async () => {
await expect(canvas).toMatchSVGSnapshot(dir, 'combo-circle');
//seleted state
graph.setItemState('combo1', 'selected', true);
sleep(200);
await expect(canvas).toMatchSVGSnapshot(dir, 'combo-circle-selected');
graph.collapseCombo('combo1');
sleep(200);
await expect(canvas).toMatchSVGSnapshot(dir, 'combo-circle-collapsed');
graph.expandCombo('combo1');
sleep(200);
await expect(canvas).toMatchSVGSnapshot(dir, 'combo-circle-expand');
graph.destroy();
done();
});
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -81,7 +81,7 @@ describe('data', () => {
JSON.stringify(edge2InnerData),
);
expect(
graph.itemController.itemMap['edge2'].shapeMap['keyShape'].attributes
graph.itemController.itemMap.get('edge2').shapeMap['keyShape'].attributes
.lineWidth,
).toBe(edge2UpdateUserData.data.keyShape.lineWidth);
@ -93,13 +93,15 @@ describe('data', () => {
graph.updateData('edge', edge1UpdateUserData);
const newSourceData = graph.getNodeData('node3');
expect(
graph.itemController.itemMap['edge1'].shapeMap['keyShape'].attributes.x1,
graph.itemController.itemMap.get('edge1').shapeMap['keyShape'].attributes
.x1,
).toBe(newSourceData.data.x);
expect(
graph.itemController.itemMap['edge1'].shapeMap['keyShape'].attributes.y1,
graph.itemController.itemMap.get('edge1').shapeMap['keyShape'].attributes
.y1,
).toBe(newSourceData.data.y);
expect(graph.itemController.itemMap['edge1'].sourceItem).toBe(
graph.itemController.itemMap['node3'],
expect(graph.itemController.itemMap.get('edge1').sourceItem).toBe(
graph.itemController.itemMap.get('node3'),
);
// === update edge source, target, and data in the same time ===
@ -116,7 +118,7 @@ describe('data', () => {
graph.updateData('edge', edge1UpdateUserData2);
const sourceData = graph.getNodeData('node1');
const targetData = graph.getNodeData('node4');
const edgeItem = graph.itemController.itemMap['edge1'];
const edgeItem = graph.itemController.itemMap.get('edge1');
expect(edgeItem.shapeMap['keyShape'].attributes.x1).toBe(sourceData.data.x);
expect(edgeItem.shapeMap['keyShape'].attributes.y1).toBe(sourceData.data.y);
expect(edgeItem.shapeMap['keyShape'].attributes.x2).toBe(targetData.data.x);
@ -145,8 +147,8 @@ describe('data', () => {
},
},
]);
const node1Item = graph.itemController.itemMap['node1'];
const node2Item = graph.itemController.itemMap['node2'];
const node1Item = graph.itemController.itemMap.get('node1');
const node2Item = graph.itemController.itemMap.get('node2');
expect(node1Item.shapeMap['keyShape'].attributes.fill).toBe('#0f0');
expect(node2Item.shapeMap['keyShape'].attributes.lineWidth).toBe(2);
expect(node2Item.shapeMap['keyShape'].attributes.stroke).toBe('#0f0');
@ -171,10 +173,12 @@ describe('data', () => {
},
},
]);
const edge1Item = graph.itemController.itemMap['edge1'];
const edge2Item = graph.itemController.itemMap['edge2'];
const edge1Item = graph.itemController.itemMap.get('edge1');
const edge2Item = graph.itemController.itemMap.get('edge2');
expect(edge1Item.shapeMap['keyShape'].attributes.stroke).toBe('#0f0');
expect(edge1Item.sourceItem).toBe(graph.itemController.itemMap['node2']);
expect(edge1Item.sourceItem).toBe(
graph.itemController.itemMap.get('node2'),
);
expect(
JSON.stringify(edge2Item.shapeMap['keyShape'].attributes.lineDash),
).toBe('[5,5]');

View File

@ -111,11 +111,11 @@ describe('drag-node', () => {
expect(graph.getItemVisible('edge2')).toBe(false);
// @ts-ignore
expect(
graph.itemController.transientItemMap['node1'].model.data.x,
graph.itemController.transientItemMap.get('node1').model.data.x,
).toEqual(250);
// @ts-ignore
expect(
graph.itemController.transientItemMap['node1'].model.data.y,
graph.itemController.transientItemMap.get('node1').model.data.y,
).toEqual(350);
// Should update position when drag ends.

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ describe('node item', () => {
});
graph.on('afterrender', () => {
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem).not.toBe(undefined);
expect(nodeItem.shapeMap.labelShape).toBe(undefined);
done();
@ -43,7 +43,7 @@ describe('node item', () => {
labelBackgroundShape: {},
},
});
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem.shapeMap.labelShape).not.toBe(undefined);
expect(nodeItem.shapeMap.labelShape.attributes.text).toBe('node-label');
expect(nodeItem.shapeMap.labelShape.attributes.fill).toBe('#000');
@ -85,7 +85,7 @@ describe('node item', () => {
},
},
});
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem.shapeMap.iconShape).not.toBe(undefined);
expect(nodeItem.shapeMap.iconShape.attributes.width).toBe(16);
expect(nodeItem.shapeMap.iconShape.nodeName).toBe('image');
@ -148,9 +148,9 @@ describe('node mapper', () => {
} as any);
graph.read(clone(data));
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe('#0f0');
let node2 = graph.itemController.itemMap['node2'];
let node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#f00');
// update user data
@ -160,7 +160,7 @@ describe('node mapper', () => {
buStatus: true,
},
});
node2 = graph.itemController.itemMap['node2'];
node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#0f0');
graph.destroy();
@ -191,11 +191,11 @@ describe('node mapper', () => {
} as any);
graph.read(clone(data));
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe('#0f0');
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(5);
expect(node1.shapeMap.keyShape.attributes.stroke).toBe('#fff');
let node2 = graph.itemController.itemMap['node2'];
let node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#f00');
expect(node2.shapeMap.keyShape.attributes.lineWidth).toBe(5);
expect(node2.shapeMap.keyShape.attributes.stroke).toBe('#000');
@ -208,7 +208,7 @@ describe('node mapper', () => {
},
type,
});
node2 = graph.itemController.itemMap['node2'];
node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#0f0');
expect(node2.shapeMap.keyShape.attributes.stroke).toBe('#fff');
@ -277,42 +277,51 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node1');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple nodes state
graph.setItemState(['node1', 'node2'], 'selected', true);
expect(graph.findIdByState('node', 'selected').length).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node2');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
graph.setItemState(['node1', 'node2'], 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple states
@ -321,28 +330,34 @@ describe('state', () => {
expect(graph.findIdByState('node', 'highlight').length).toBe(2);
// should be merged styles from selected and highlight
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -350,13 +365,15 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(graph.findIdByState('node', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(16);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();

View File

@ -176,9 +176,9 @@ describe('node show up animations', () => {
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
const node1KeyShapeBBox = graph.getRenderBBox('node1');
const node2 = graph.itemController.itemMap['node2'];
const node2 = graph.itemController.itemMap.get('node2');
const node2KeyShapeBBox = graph.getRenderBBox('node2');
expect(node1.shapeMap.keyShape.attributes.opacity).toBe(0);
expect(node1KeyShapeBBox.max[0] - node1KeyShapeBBox.min[0]).toBe(0);
@ -233,7 +233,7 @@ describe('node show up animations', () => {
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.opacity).toBe(0);
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(1);
setTimeout(() => {
@ -287,7 +287,7 @@ describe('edge show up animations', () => {
});
graph.on('afterrender', () => {
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.opacity).toBe(0);
expect(edge1.shapeMap.keyShape.attributes.lineWidth).toBe(1);
setTimeout(() => {
@ -334,7 +334,7 @@ describe('edge show up animations', () => {
});
graph.on('afterrender', () => {
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.opacity).toBe(0);
expect(edge1.shapeMap.keyShape.attributes.lineWidth).toBe(1);
setTimeout(() => {
@ -405,7 +405,7 @@ describe('node update animations', () => {
},
},
});
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(1);
expect(node1.group.attributes.x).toBe(100);
expect(node1.group.attributes.y).toBe(200);
@ -467,7 +467,7 @@ describe('node update animations', () => {
},
},
});
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(1);
expect(node1.group.attributes.x).toBe(100);
expect(node1.group.attributes.y).toBe(200);
@ -533,7 +533,7 @@ describe('node update animations', () => {
graph.on('afterrender', () => {
setTimeout(() => {
graph.setItemState('node1', 'selected', true);
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe(
'rgb(239, 244, 255)',
);
@ -595,7 +595,7 @@ describe('node update animations', () => {
graph.on('afterrender', () => {
setTimeout(() => {
graph.setItemState('node1', 'selected', true);
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(1);
expect(node1.shapeMap.keyShape.attributes.fill).toBe(
'rgb(239, 244, 255)',
@ -664,7 +664,7 @@ describe('edge update animations', () => {
},
},
});
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.stroke).toBe('#000');
expect(edge1.shapeMap.keyShape.attributes.lineWidth).toBe(2);
setTimeout(() => {
@ -716,7 +716,7 @@ describe('edge update animations', () => {
},
},
});
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.stroke).toBe('#000');
expect(edge1.shapeMap.keyShape.attributes.lineWidth).toBe(2);
setTimeout(() => {
@ -777,7 +777,7 @@ describe('edge update animations', () => {
graph.on('afterrender', () => {
setTimeout(() => {
graph.setItemState('edge1', 'selected', true);
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.stroke).toBe('#000');
expect(edge1.shapeMap.keyShape.attributes.lineWidth).toBe(2);
setTimeout(() => {
@ -830,7 +830,7 @@ describe('edge update animations', () => {
graph.on('afterrender', () => {
setTimeout(() => {
graph.setItemState('edge1', 'selected', true);
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.stroke).toBe('#000');
expect(edge1.shapeMap.keyShape.attributes.lineWidth).toBe(2);
setTimeout(() => {
@ -888,7 +888,7 @@ describe('node show up animations', () => {
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.opacity).toBe(0);
expect(node1.shapeMap.keyShape.attributes.fill).toBe(
'rgb(239, 244, 255)',
@ -944,7 +944,7 @@ describe('node show up animations', () => {
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe(
'rgb(239, 244, 255)',
);
@ -1014,7 +1014,7 @@ describe('edge show up animations', () => {
});
graph.on('afterrender', () => {
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.opacity).toBe(0);
expect(edge1.shapeMap.keyShape.attributes.stroke).toBe('#000');
setTimeout(() => {
@ -1059,7 +1059,7 @@ describe('edge show up animations', () => {
});
graph.on('afterrender', () => {
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.keyShape.attributes.stroke).toBe('#000');
graph.updateData('edge', {
id: 'edge1',
@ -1129,7 +1129,7 @@ describe('custom node animations', () => {
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.extraShape.attributes.opacity).toBe(0);
setTimeout(() => {
expect(node1.shapeMap.keyShape.attributes.opacity > 0).toBe(true);
@ -1174,7 +1174,7 @@ describe('custom node animations', () => {
});
graph.on('afterrender', () => {
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.runningCircle.attributes.offsetDistance).toBe(0);
setTimeout(() => {
const currentOffsetDistance =
@ -1232,7 +1232,7 @@ describe('node update position with edges', () => {
const oriData = clone(data);
graph.on('afterrender', () => {
const edge = graph.itemController.itemMap['edge1'];
const edge = graph.itemController.itemMap.get('edge1');
let { keyShape: edgeKeyShape } = edge.shapeMap;
expect(edgeKeyShape.attributes.x1).toBe(oriData.nodes[0].data.x);
expect(edgeKeyShape.attributes.y1).toBe(oriData.nodes[0].data.y);
@ -1253,9 +1253,9 @@ describe('node update position with edges', () => {
},
});
setTimeout(() => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.model.data.x).not.toBe(oriData.nodes[0].data.x);
const node2 = graph.itemController.itemMap['node2'];
const node2 = graph.itemController.itemMap.get('node2');
expect(node2.model.data.x).not.toBe(oriData.nodes[1].data.x);
edgeKeyShape = edge.shapeMap.keyShape;
expect(edgeKeyShape.attributes.x1).not.toBe(oriData.nodes[0].data.x);

View File

@ -37,7 +37,7 @@ describe('node item', () => {
});
graph.on('afterrender', () => {
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem).not.toBe(undefined);
expect(nodeItem.shapeMap.labelShape).toBe(undefined);
done();
@ -54,7 +54,7 @@ describe('node item', () => {
labelBackgroundShape: {},
},
});
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem.shapeMap.labelShape).not.toBe(undefined);
expect(nodeItem.shapeMap.labelShape.attributes.text).toBe('node-label');
expect(nodeItem.shapeMap.labelShape.attributes.fill).toBe('#000');
@ -96,7 +96,7 @@ describe('node item', () => {
},
},
});
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem.shapeMap.iconShape).not.toBe(undefined);
expect(nodeItem.shapeMap.iconShape.attributes.width).toBe(16);
expect(nodeItem.shapeMap.iconShape.nodeName).toBe('image');
@ -157,9 +157,9 @@ describe('node mapper', () => {
} as any);
graph.read(clone(data));
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe('#0f0');
let node2 = graph.itemController.itemMap['node2'];
let node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#f00');
// update user data
@ -169,7 +169,7 @@ describe('node mapper', () => {
buStatus: true,
},
});
node2 = graph.itemController.itemMap['node2'];
node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#0f0');
graph.destroy();
@ -200,11 +200,11 @@ describe('node mapper', () => {
} as any);
graph.read(clone(data));
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe('#0f0');
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(5);
expect(node1.shapeMap.keyShape.attributes.stroke).toBe('#fff');
let node2 = graph.itemController.itemMap['node2'];
let node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#f00');
expect(node2.shapeMap.keyShape.attributes.lineWidth).toBe(5);
expect(node2.shapeMap.keyShape.attributes.stroke).toBe('#000');
@ -216,7 +216,7 @@ describe('node mapper', () => {
buStatus: true,
},
});
node2 = graph.itemController.itemMap['node2'];
node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#0f0');
expect(node2.shapeMap.keyShape.attributes.stroke).toBe('#fff');
@ -360,19 +360,19 @@ describe('register node', () => {
},
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.extraShape).not.toBe(undefined);
expect(node1.shapeMap.keyShape.style.r).toBe(25);
const node2 = graph.itemController.itemMap['node2'];
const node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.extraShape).toBe(undefined);
const node3 = graph.itemController.itemMap['node3'];
const node3 = graph.itemController.itemMap.get('node3');
// labelShape is assigned with undefined in node3's data, shapes defined in drawLabelShape will be undefined
expect(node3.shapeMap.extraShape).not.toBe(undefined);
expect(node3.shapeMap.keyShape.style.r).toBe(25);
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
expect(edge1.shapeMap.buShape).not.toBe(undefined);
const edge2 = graph.itemController.itemMap['edge2'];
const edge2 = graph.itemController.itemMap.get('edge2');
expect(edge2.shapeMap.buShape).toBe(undefined);
// update node type
@ -495,14 +495,14 @@ describe('register node', () => {
},
});
graph.on('afterrender', (e) => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.testShape).not.toBe(undefined);
expect(node1.shapeMap.keyShape.nodeName).toBe('rect');
const node3 = graph.itemController.itemMap['node3'];
const node3 = graph.itemController.itemMap.get('node3');
expect(node3.shapeMap.testShape).not.toBe(undefined);
expect(node3.shapeMap.keyShape.nodeName).toBe('rect');
let node2 = graph.itemController.itemMap['node2'];
let node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.testShape).toBe(undefined);
expect(node2.shapeMap.keyShape.nodeName).toBe('circle');
@ -513,7 +513,7 @@ describe('register node', () => {
type: 'custom-node1',
},
});
node2 = graph.itemController.itemMap['node2'];
node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.testShape).not.toBe(undefined);
expect(node2.shapeMap.keyShape.nodeName).toBe('rect');
@ -581,42 +581,51 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node1');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple nodes state
graph.setItemState(['node1', 'node2'], 'selected', true);
expect(graph.findIdByState('node', 'selected').length).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node2');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
graph.setItemState(['node1', 'node2'], 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple states
@ -625,28 +634,34 @@ describe('state', () => {
expect(graph.findIdByState('node', 'highlight').length).toBe(2);
// should be merged styles from selected and highlight
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -654,13 +669,15 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(graph.findIdByState('node', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(16);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();
@ -732,42 +749,51 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node1');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple nodes state
graph.setItemState(['node1', 'node2'], 'selected', true);
expect(graph.findIdByState('node', 'selected').length).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node2');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
graph.setItemState(['node1', 'node2'], 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple states
@ -776,28 +802,34 @@ describe('state', () => {
expect(graph.findIdByState('node', 'highlight').length).toBe(2);
// should be merged styles from selected and highlight
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -805,13 +837,15 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(graph.findIdByState('node', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(16);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();
@ -971,7 +1005,7 @@ describe('state', () => {
},
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.extraShape).not.toBe(undefined);
graph.setItemState('node1', 'selected', true);
expect(node1.shapeMap.labelShape.style.fill).toBe('#fff');
@ -979,7 +1013,7 @@ describe('state', () => {
expect(node1.shapeMap.keyShape.style.stroke).toBe('#fff');
expect(node1.shapeMap.keyShape.style.lineWidth).toBe(2);
const node2 = graph.itemController.itemMap['node2'];
const node2 = graph.itemController.itemMap.get('node2');
graph.setItemState('node2', 'selected', true);
expect(node2.shapeMap.extraShape).toBe(undefined);
expect(node2.shapeMap.keyShape.style.fill).toBe('#00f');

View File

@ -168,7 +168,7 @@ describe('plugin', () => {
);
expect(node1Delegate.nodeName).toBe('circle');
const node1KeyShape =
graph.itemController.itemMap['node1'].shapeMap['keyShape'];
graph.itemController.itemMap.get('node1').shapeMap['keyShape'];
expect(node1Delegate.style.fill).toBe(node1KeyShape.style.fill);
const node2Delegate = minimapRootGroup.find(
@ -176,7 +176,7 @@ describe('plugin', () => {
);
expect(node2Delegate.nodeName).toBe('circle');
const node2KeyShape =
graph.itemController.itemMap['node2'].shapeMap['keyShape'];
graph.itemController.itemMap.get('node2').shapeMap['keyShape'];
expect(node2Delegate.style.fill).toBe(node2KeyShape.style.fill);
graph.destroy();

View File

@ -101,7 +101,7 @@ describe('edge item', () => {
});
graph.on('afterrender', () => {
const edgeItem = graph.itemController.itemMap['edge1'];
const edgeItem = graph.itemController.itemMap.get('edge1');
expect(edgeItem).not.toBe(undefined);
expect(edgeItem.shapeMap.labelShape.attributes.text).toBe('label');
expect(edgeItem.shapeMap.labelShape.attributes.fill).toBe('blue');
@ -131,7 +131,7 @@ describe('edge item', () => {
},
},
});
const edgeItem = graph.itemController.itemMap['edge1'];
const edgeItem = graph.itemController.itemMap.get('edge1');
expect(edgeItem.shapeMap.labelShape).not.toBe(undefined);
expect(edgeItem.shapeMap.labelShape.attributes.text).toBe('edge-label');
const fill = edgeItem.shapeMap.labelShape.attributes.fill;
@ -197,7 +197,7 @@ describe('edge item', () => {
},
},
});
const edgeItem = graph.itemController.itemMap['edge1'];
const edgeItem = graph.itemController.itemMap.get('edge1');
let { labelShape, iconShape, labelBackgroundShape } = edgeItem.shapeMap;
expect(iconShape.attributes.x + iconShape.attributes.width + 6).toBe(
labelBackgroundShape.getGeometryBounds().min[0] +
@ -332,42 +332,51 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'selected').length).toBe(1);
expect(graph.findIdByState('edge', 'selected')[0]).toBe('edge1');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'selected', false);
expect(graph.findIdByState('edge', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
// set multiple edges state
graph.setItemState(['edge1', 'edge2'], 'selected', true);
expect(graph.findIdByState('edge', 'selected').length).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'selected', false);
expect(graph.findIdByState('edge', 'selected').length).toBe(1);
expect(graph.findIdByState('edge', 'selected')[0]).toBe('edge2');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge1', 'edge2'], 'selected', false);
expect(graph.findIdByState('edge', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge2', 'edge1'], ['selected', 'highlight'], true);
@ -375,22 +384,28 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'highlight').length).toBe(2);
// should be merged styles from selected and highlight
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -398,10 +413,12 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'selected').length).toBe(0);
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();
@ -465,42 +482,51 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'active').length).toBe(1);
expect(graph.findIdByState('edge', 'active')[0]).toBe('edge1');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'active', false);
expect(graph.findIdByState('edge', 'active').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
// set multiple edges state
graph.setItemState(['edge1', 'edge2'], 'active', true);
expect(graph.findIdByState('edge', 'active').length).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'active', false);
expect(graph.findIdByState('edge', 'active').length).toBe(1);
expect(graph.findIdByState('edge', 'active')[0]).toBe('edge2');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge1', 'edge2'], 'active', false);
expect(graph.findIdByState('edge', 'active').length).toBe(0);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge2', 'edge1'], ['active', 'highlight'], true);
@ -508,22 +534,28 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'highlight').length).toBe(2);
// should be merged styles from active and highlight
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -531,10 +563,12 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'active').length).toBe(0);
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();
@ -598,42 +632,51 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'highlight').length).toBe(1);
expect(graph.findIdByState('edge', 'highlight')[0]).toBe('edge1');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
graph.setItemState('edge1', 'highlight', false);
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
// set multiple edges state
graph.setItemState(['edge1', 'edge2'], 'highlight', true);
expect(graph.findIdByState('edge', 'highlight').length).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
graph.setItemState('edge1', 'highlight', false);
expect(graph.findIdByState('edge', 'highlight').length).toBe(1);
expect(graph.findIdByState('edge', 'highlight')[0]).toBe('edge2');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge1', 'edge2'], 'highlight', false);
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge2', 'edge1'], ['highlight', 'highlight'], true);
@ -641,22 +684,28 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'highlight').length).toBe(2);
// should be merged styles from highlight and highlight
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -664,10 +713,12 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();
@ -731,42 +782,51 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'inactive').length).toBe(1);
expect(graph.findIdByState('edge', 'inactive')[0]).toBe('edge1');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'inactive', false);
expect(graph.findIdByState('edge', 'inactive').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
// set multiple edges state
graph.setItemState(['edge1', 'edge2'], 'inactive', true);
expect(graph.findIdByState('edge', 'inactive').length).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'inactive', false);
expect(graph.findIdByState('edge', 'inactive').length).toBe(1);
expect(graph.findIdByState('edge', 'inactive')[0]).toBe('edge2');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge1', 'edge2'], 'inactive', false);
expect(graph.findIdByState('edge', 'inactive').length).toBe(0);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge2', 'edge1'], ['inactive', 'highlight'], true);
@ -774,22 +834,28 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'highlight').length).toBe(2);
// should be merged styles from inactive and highlight
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -797,10 +863,12 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'inactive').length).toBe(0);
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();
@ -864,42 +932,51 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'disable').length).toBe(1);
expect(graph.findIdByState('edge', 'disable')[0]).toBe('edge1');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'disable', false);
expect(graph.findIdByState('edge', 'disable').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
// set multiple edges state
graph.setItemState(['edge1', 'edge2'], 'disable', true);
expect(graph.findIdByState('edge', 'disable').length).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('edge1', 'disable', false);
expect(graph.findIdByState('edge', 'disable').length).toBe(1);
expect(graph.findIdByState('edge', 'disable')[0]).toBe('edge2');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge1', 'edge2'], 'disable', false);
expect(graph.findIdByState('edge', 'disable').length).toBe(0);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
graph.setItemState(['edge2', 'edge1'], ['disable', 'highlight'], true);
@ -907,22 +984,28 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'highlight').length).toBe(2);
// should be merged styles from disable and highlight
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['edge2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -930,10 +1013,12 @@ describe('state', () => {
expect(graph.findIdByState('edge', 'disable').length).toBe(0);
expect(graph.findIdByState('edge', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.lineWidth,
).toBe(1);
expect(
graph.itemController.itemMap['edge1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('edge1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();

View File

@ -2115,9 +2115,9 @@ describe('graph show up animations', () => {
// graph.showItem('node1');
// });
graph.on('afterrender', () => {
// const node1 = graph.itemController.itemMap['node1'];
// const node1 = graph.itemController.itemMap.get('node1');
// const node1KeyShapeBBox = graph.getRenderBBox('node1');
// const node2 = graph.itemController.itemMap['node2'];
// const node2 = graph.itemController.itemMap.get('node2');
// const node2KeyShapeBBox = graph.getRenderBBox('node2');
// expect(node1.shapeMap.keyShape.attributes.opacity).toBe(0);
// expect(node1KeyShapeBBox.max[0] - node1KeyShapeBBox.min[0]).toBe(0);
@ -2172,7 +2172,7 @@ describe('graph show up animations', () => {
});
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.opacity).toBe(0);
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(1);
setTimeout(() => {

View File

@ -125,7 +125,7 @@ describe('theme', () => {
},
});
graph.on('afterlayout', () => {
const node = graph.itemController.itemMap['node1'];
const node = graph.itemController.itemMap.get('node1');
const { keyShape: nodeKeyShape, labelShape: nodeLabelShape } =
node.shapeMap;
expect(node.shapeMap.haloShape).toBe(undefined);
@ -135,7 +135,7 @@ describe('theme', () => {
expect(nodeLabelShape.style.fontWeight).toBe(
LightTheme.node.styles[0].default.labelShape.fontWeight,
);
const edge = graph.itemController.itemMap['edge1'];
const edge = graph.itemController.itemMap.get('edge1');
const { keyShape: edgeKeyShape, labelShape: edgeLabelShape } =
edge.shapeMap;
expect(edge.shapeMap.haloShape).toBe(undefined);
@ -181,7 +181,7 @@ describe('theme', () => {
LightTheme.edge.styles[0].default.labelShape.fill,
);
const node4 = graph.itemController.itemMap['node4'];
const node4 = graph.itemController.itemMap.get('node4');
expect(node4.shapeMap.anchorShape0).not.toBe(undefined);
expect(node4.shapeMap.anchorShape1).not.toBe(undefined);
expect(node4.shapeMap.anchorShape2).not.toBe(undefined);
@ -287,23 +287,23 @@ describe('theme', () => {
.backgroundColor,
).toBe('rgb(255, 255, 255)'); // = rgb format of LightTheme.canvas.backgroundColor
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
const { keyShape: nodeKeyShape1, labelShape: nodeLabelShape1 } =
node1.shapeMap;
expect(nodeKeyShape1.style.fill).toBe('#f00');
expect(nodeLabelShape1.style.fill).toBe('#f00');
const node2 = graph.itemController.itemMap['node2'];
const node2 = graph.itemController.itemMap.get('node2');
const { keyShape: nodeKeyShape2, labelShape: nodeLabelShape2 } =
node2.shapeMap;
expect(nodeKeyShape2.style.fill).toBe('#0f0');
expect(nodeLabelShape2.style.fill).toBe('#0f0');
const node3 = graph.itemController.itemMap['node3'];
const node3 = graph.itemController.itemMap.get('node3');
const { keyShape: nodeKeyShape3, labelShape: nodeLabelShape3 } =
node3.shapeMap;
expect(nodeKeyShape3.style.fill).toBe('#00f');
expect(nodeLabelShape3.style.fill).toBe('#00f');
// node4 has no mapped palette, buitin theme take effects
const node4 = graph.itemController.itemMap['node4'];
const node4 = graph.itemController.itemMap.get('node4');
const { keyShape: nodeKeyShape4, labelShape: nodeLabelShape4 } =
node4.shapeMap;
expect(nodeKeyShape4.style.fill).toBe(
@ -314,18 +314,18 @@ describe('theme', () => {
);
// edges
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
const { keyShape: edgeKeyShape1, labelShape: edgeLabelShape1 } =
edge1.shapeMap;
expect(edgeKeyShape1.style.stroke).toBe('#f00');
expect(edgeLabelShape1.style.fill).toBe('#f00');
const edge2 = graph.itemController.itemMap['edge2'];
const edge2 = graph.itemController.itemMap.get('edge2');
const { keyShape: edgeKeyShape2, labelShape: edgeLabelShape2 } =
edge2.shapeMap;
expect(edgeKeyShape2.style.stroke).toBe('#0f0');
expect(edgeLabelShape2.style.fill).toBe('#0f0');
// edge3 has no mapped palette, buitin theme take effects
const edge3 = graph.itemController.itemMap['edge3'];
const edge3 = graph.itemController.itemMap.get('edge3');
const { keyShape: edgeKeyShape4, labelShape: edgeLabelShape4 } =
edge3.shapeMap;
expect(edgeKeyShape4.style.stroke).toBe(
@ -498,23 +498,23 @@ describe('theme', () => {
},
});
graph.on('afterlayout', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
const { keyShape: nodeKeyShape1, labelShape: nodeLabelShape1 } =
node1.shapeMap;
expect(nodeKeyShape1.style.fill).toBe('#f00');
expect(nodeLabelShape1.style.fill).toBe('#f00');
const node2 = graph.itemController.itemMap['node2'];
const node2 = graph.itemController.itemMap.get('node2');
const { keyShape: nodeKeyShape2, labelShape: nodeLabelShape2 } =
node2.shapeMap;
expect(nodeKeyShape2.style.fill).toBe('#0f0');
expect(nodeLabelShape2.style.fill).toBe('#0f0');
const node3 = graph.itemController.itemMap['node3'];
const node3 = graph.itemController.itemMap.get('node3');
const { keyShape: nodeKeyShape3, labelShape: nodeLabelShape3 } =
node3.shapeMap;
expect(nodeKeyShape3.style.fill).toBe('#00f');
expect(nodeLabelShape3.style.fill).toBe('#00f');
// node4 has no mapped palette, buitin theme take effects
const node4 = graph.itemController.itemMap['node4'];
const node4 = graph.itemController.itemMap.get('node4');
const { keyShape: nodeKeyShape4, labelShape: nodeLabelShape4 } =
node4.shapeMap;
// different from map, undefined data type value will be regarded as a value to find corresponding color in palette. That is because g6 doesn't know if the value undefined is the real value or not
@ -522,18 +522,18 @@ describe('theme', () => {
expect(nodeLabelShape4.style.fill).toBe('#f00');
// edges
const edge1 = graph.itemController.itemMap['edge1'];
const edge1 = graph.itemController.itemMap.get('edge1');
const { keyShape: edgeKeyShape1, labelShape: edgeLabelShape1 } =
edge1.shapeMap;
expect(edgeKeyShape1.style.stroke).toBe('#f00');
expect(edgeLabelShape1.style.fill).toBe('#f00');
const edge2 = graph.itemController.itemMap['edge2'];
const edge2 = graph.itemController.itemMap.get('edge2');
const { keyShape: edgeKeyShape2, labelShape: edgeLabelShape2 } =
edge2.shapeMap;
expect(edgeKeyShape2.style.stroke).toBe('#0f0');
expect(edgeLabelShape2.style.fill).toBe('#0f0');
// edge3 has no mapped palette, buitin theme take effects
const edge3 = graph.itemController.itemMap['edge3'];
const edge3 = graph.itemController.itemMap.get('edge3');
const { keyShape: edgeKeyShape3 } = edge3.shapeMap;
expect(edgeKeyShape3.style.stroke).toBe('#f00');
@ -735,7 +735,7 @@ describe('theme', () => {
});
graph.on('afterlayout', () => {
// custom node's and edge's keyShape follow the light theme
const node = graph.itemController.itemMap['node1'];
const node = graph.itemController.itemMap.get('node1');
const { keyShape: nodeKeyShape, labelShape: nodeLabelShape } =
node.shapeMap;
expect(nodeKeyShape.style.fill).toBe(
@ -744,7 +744,7 @@ describe('theme', () => {
expect(nodeLabelShape.style.fontWeight).toBe(
LightTheme.node.styles[0].default.labelShape.fontWeight,
);
const edge = graph.itemController.itemMap['edge1'];
const edge = graph.itemController.itemMap.get('edge1');
const { keyShape: edgeKeyShape, labelShape: edgeLabelShape } =
edge.shapeMap;
expect(edgeKeyShape.style.stroke).toBe(

View File

@ -64,20 +64,20 @@ describe('theme', () => {
},
});
graph.on('afterlayout', () => {
let node = graph.itemController.itemMap['node1'];
let node = graph.itemController.itemMap.get('node1');
let nodeKeyShape = node.shapeMap.keyShape;
let { fill: keyShapeFill, stroke: keyShapeStroke } = nodeKeyShape.style;
expect(keyShapeFill).toBe('rgb(255, 230, 230)');
expect(keyShapeStroke).toBe('#f00');
node = graph.itemController.itemMap['node2'];
node = graph.itemController.itemMap.get('node2');
nodeKeyShape = node.shapeMap.keyShape;
keyShapeFill = nodeKeyShape.style.fill;
keyShapeStroke = nodeKeyShape.style.stroke;
expect(keyShapeFill).toBe('rgb(230, 255, 230)');
expect(keyShapeStroke).toBe('#0f0');
node = graph.itemController.itemMap['node3'];
node = graph.itemController.itemMap.get('node3');
nodeKeyShape = node.shapeMap.keyShape;
keyShapeFill = nodeKeyShape.style.fill;
keyShapeStroke = nodeKeyShape.style.stroke;
@ -95,7 +95,7 @@ describe('theme', () => {
expect(keyShapeLineWidth).toBe(4);
expect(keyShapeShadowColor).toBe('#00f');
let edge = graph.itemController.itemMap['edge1'];
let edge = graph.itemController.itemMap.get('edge1');
let edgeKeyShape = edge.shapeMap.keyShape;
let { stroke: edgeKeyShapeStroke } = edgeKeyShape.style;
expect(edgeKeyShapeStroke).toBe('rgb(255, 153, 153)');
@ -106,7 +106,7 @@ describe('theme', () => {
expect(edgeKeyShape.style.lineWidth).toBe(2);
// edge without dataType, follow the first pallete
edge = graph.itemController.itemMap['edge3'];
edge = graph.itemController.itemMap.get('edge3');
edgeKeyShape = edge.shapeMap.keyShape;
edgeKeyShapeStroke = edgeKeyShape.style.stroke;
expect(edgeKeyShapeStroke).toBe('rgb(255, 153, 153)');
@ -169,20 +169,20 @@ describe('theme', () => {
},
});
graph.on('afterlayout', () => {
let node = graph.itemController.itemMap['node1'];
let node = graph.itemController.itemMap.get('node1');
let nodeKeyShape = node.shapeMap.keyShape;
let { fill: keyShapeFill, stroke: keyShapeStroke } = nodeKeyShape.style;
expect(keyShapeFill).toBe('rgb(255, 230, 230)');
expect(keyShapeStroke).toBe('#f00');
node = graph.itemController.itemMap['node2'];
node = graph.itemController.itemMap.get('node2');
nodeKeyShape = node.shapeMap.keyShape;
keyShapeFill = nodeKeyShape.style.fill;
keyShapeStroke = nodeKeyShape.style.stroke;
expect(keyShapeFill).toBe('rgb(230, 255, 230)');
expect(keyShapeStroke).toBe('#0f0');
node = graph.itemController.itemMap['node3'];
node = graph.itemController.itemMap.get('node3');
nodeKeyShape = node.shapeMap.keyShape;
keyShapeFill = nodeKeyShape.style.fill;
keyShapeStroke = nodeKeyShape.style.stroke;
@ -201,7 +201,7 @@ describe('theme', () => {
expect(keyShapeShadowColor).toBe('#00f');
// node without dataType, follow the default(light) pallete
node = graph.itemController.itemMap['node4'];
node = graph.itemController.itemMap.get('node4');
const { keyShape } = node.shapeMap;
keyShapeStroke = keyShape.style.stroke;
expect(keyShapeStroke).toBe(
@ -217,7 +217,7 @@ describe('theme', () => {
LightTheme.node.styles[0].selected.keyShape.lineWidth,
);
let edge = graph.itemController.itemMap['edge1'];
let edge = graph.itemController.itemMap.get('edge1');
let { keyShape: edgeKeyShape } = edge.shapeMap;
let { stroke: edgeKeyShapeStroke } = edgeKeyShape.style;
expect(edgeKeyShapeStroke).toBe('rgb(255, 153, 153)');
@ -228,7 +228,7 @@ describe('theme', () => {
expect(edgeKeyShape.style.lineWidth).toBe(2);
// edge without dataType, follow the default(light) pallete
edge = graph.itemController.itemMap['edge3'];
edge = graph.itemController.itemMap.get('edge3');
edgeKeyShape = edge.shapeMap.keyShape;
edgeKeyShapeStroke = edgeKeyShape.style.stroke;
expect(edgeKeyShapeStroke).toBe(
@ -290,20 +290,20 @@ describe('theme', () => {
},
});
graph.on('afterlayout', () => {
let node = graph.itemController.itemMap['node1'];
let node = graph.itemController.itemMap.get('node1');
let nodeKeyShape = node.shapeMap.keyShape;
let { fill: keyShapeFill, stroke: keyShapeStroke } = nodeKeyShape.style;
expect(keyShapeFill).toBe('rgb(146, 95, 95)');
expect(keyShapeStroke).toBe('rgb(228, 24, 24)');
node = graph.itemController.itemMap['node2'];
node = graph.itemController.itemMap.get('node2');
nodeKeyShape = node.shapeMap.keyShape;
keyShapeFill = nodeKeyShape.style.fill;
keyShapeStroke = nodeKeyShape.style.stroke;
expect(keyShapeFill).toBe('rgb(95, 146, 95)');
expect(keyShapeStroke).toBe('rgb(24, 228, 24)');
node = graph.itemController.itemMap['node3'];
node = graph.itemController.itemMap.get('node3');
nodeKeyShape = node.shapeMap.keyShape;
keyShapeFill = nodeKeyShape.style.fill;
keyShapeStroke = nodeKeyShape.style.stroke;
@ -321,7 +321,7 @@ describe('theme', () => {
expect(keyShapeLineWidth).toBe(4);
expect(keyShapeShadowColor).toBe('#00f');
let edge = graph.itemController.itemMap['edge1'];
let edge = graph.itemController.itemMap.get('edge1');
let { keyShape: edgeKeyShape } = edge.shapeMap;
let { stroke: edgeKeyShapeStroke } = edgeKeyShape.style;
expect(edgeKeyShapeStroke).toBe('rgb(228, 24, 24)');
@ -332,7 +332,7 @@ describe('theme', () => {
expect(edgeKeyShape.style.lineWidth).toBe(2);
// edge without dataType, follow the first pallete
edge = graph.itemController.itemMap['edge3'];
edge = graph.itemController.itemMap.get('edge3');
edgeKeyShape = edge.shapeMap.keyShape;
edgeKeyShapeStroke = edgeKeyShape.style.stroke;
expect(edgeKeyShapeStroke).toBe('rgb(228, 24, 24)');

View File

@ -24,7 +24,7 @@ describe('node item', () => {
});
graph.on('afterrender', () => {
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem).not.toBe(undefined);
expect(nodeItem.shapeMap.labelShape).toBe(undefined);
done();
@ -41,7 +41,7 @@ describe('node item', () => {
labelBackgroundShape: {},
},
});
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem.shapeMap.labelShape).not.toBe(undefined);
expect(nodeItem.shapeMap.labelShape.attributes.text).toBe('node-label');
expect(nodeItem.shapeMap.labelShape.attributes.fill).toBe('#000');
@ -83,7 +83,7 @@ describe('node item', () => {
},
},
});
const nodeItem = graph.itemController.itemMap['node1'];
const nodeItem = graph.itemController.itemMap.get('node1');
expect(nodeItem.shapeMap.iconShape).not.toBe(undefined);
expect(nodeItem.shapeMap.iconShape.attributes.width).toBe(16);
expect(nodeItem.shapeMap.iconShape.nodeName).toBe('image');
@ -145,9 +145,9 @@ describe('node mapper', () => {
} as any);
graph.read(clone(data));
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe('#0f0');
let node2 = graph.itemController.itemMap['node2'];
let node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#f00');
// update user data
@ -157,7 +157,7 @@ describe('node mapper', () => {
buStatus: true,
},
});
node2 = graph.itemController.itemMap['node2'];
node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#0f0');
graph.destroy();
@ -188,11 +188,11 @@ describe('node mapper', () => {
} as any);
graph.read(clone(data));
graph.on('afterrender', () => {
const node1 = graph.itemController.itemMap['node1'];
const node1 = graph.itemController.itemMap.get('node1');
expect(node1.shapeMap.keyShape.attributes.fill).toBe('#0f0');
expect(node1.shapeMap.keyShape.attributes.lineWidth).toBe(5);
expect(node1.shapeMap.keyShape.attributes.stroke).toBe('#fff');
let node2 = graph.itemController.itemMap['node2'];
let node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#f00');
expect(node2.shapeMap.keyShape.attributes.lineWidth).toBe(5);
expect(node2.shapeMap.keyShape.attributes.stroke).toBe('#000');
@ -204,7 +204,7 @@ describe('node mapper', () => {
buStatus: true,
},
});
node2 = graph.itemController.itemMap['node2'];
node2 = graph.itemController.itemMap.get('node2');
expect(node2.shapeMap.keyShape.attributes.fill).toBe('#0f0');
expect(node2.shapeMap.keyShape.attributes.stroke).toBe('#fff');
@ -273,42 +273,51 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node1');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple nodes state
graph.setItemState(['node1', 'node2'], 'selected', true);
expect(graph.findIdByState('node', 'selected').length).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(2);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#0f0');
graph.setItemState('node1', 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(1);
expect(graph.findIdByState('node', 'selected')[0]).toBe('node2');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
graph.setItemState(['node1', 'node2'], 'selected', false);
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
// set multiple states
@ -317,28 +326,34 @@ describe('state', () => {
expect(graph.findIdByState('node', 'highlight').length).toBe(2);
// should be merged styles from selected and highlight
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.lineWidth,
).toBe(3);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.stroke,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.stroke,
).toBe('#00f');
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style.r,
).toBe(30);
expect(
graph.itemController.itemMap['node2'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node2').shapeMap.keyShape.style
.opacity,
).toBe(0.5);
// clear states
@ -346,13 +361,15 @@ describe('state', () => {
expect(graph.findIdByState('node', 'selected').length).toBe(0);
expect(graph.findIdByState('node', 'highlight').length).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.r,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style.r,
).toBe(16);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.lineWidth,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.lineWidth,
).toBe(0);
expect(
graph.itemController.itemMap['node1'].shapeMap.keyShape.style.opacity,
graph.itemController.itemMap.get('node1').shapeMap.keyShape.style
.opacity,
).toBe(1);
graph.destroy();

View File

@ -1,5 +1,9 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
overrides:
prettier: ^2.8.8
@ -30,7 +34,7 @@ importers:
version: 0.17.0
vite:
specifier: ^4.2.1
version: 4.2.2(@types/node@13.11.1)(less@3.13.1)(stylus@0.54.8)
version: 4.2.2(@types/node@20.4.7)
packages/g6:
dependencies:
@ -77,8 +81,8 @@ importers:
specifier: latest
version: 0.6.11
'@antv/layout':
specifier: ^1.2.4
version: 1.2.4(workerize-loader@2.0.2)
specifier: ^1.2.5
version: 1.2.5(workerize-loader@2.0.2)
'@antv/layout-gpu':
specifier: ^1.1.5
version: 1.1.5(workerize-loader@2.0.2)
@ -105,7 +109,7 @@ importers:
version: 2.5.0
typedoc-plugin-markdown:
specifier: ^3.14.0
version: 3.14.0(typedoc@0.24.0)
version: 3.14.0(typedoc@0.24.8)
typescript:
specifier: ^5.1.6
version: 5.1.6
@ -216,8 +220,8 @@ importers:
specifier: ^28.0.8
version: 28.0.8(@babel/core@7.22.10)(jest@28.1.3)(typescript@5.1.6)
typedoc:
specifier: ^0.24.0
version: 0.24.0(typescript@5.1.6)
specifier: ^0.24.8
version: 0.24.8(typescript@5.1.6)
vite:
specifier: ^4.2.2
version: 4.2.2(@types/node@13.11.1)(less@3.13.1)(stylus@0.54.8)
@ -1163,6 +1167,23 @@ packages:
- workerize-loader
dev: false
/@antv/layout@1.2.5(workerize-loader@2.0.2):
resolution: {integrity: sha512-2vYULfYBKZO6Sv+qQWr9MsYPMJYJUWGj54VdrfgPzldz2VjPNqCmMC0+3IobFxGIlgdmgEe5VAuSIJmQvvuRvQ==}
dependencies:
'@antv/event-emitter': 0.1.3
'@antv/graphlib': 2.0.2
'@antv/util': 3.3.4
'@naoak/workerize-transferable': 0.1.0(workerize-loader@2.0.2)
comlink: 4.4.1
d3-force: 3.0.0
d3-octree: 1.0.2
d3-quadtree: 3.0.1
ml-matrix: 6.10.4
tslib: 2.6.2
transitivePeerDependencies:
- workerize-loader
dev: false
/@antv/matrix-util@3.0.4:
resolution: {integrity: sha512-BAPyu6dUliHcQ7fm9hZSGKqkwcjEDVLVAstlHULLvcMZvANHeLXgHEgV7JqcAV/GIhIz8aZChIlzM1ZboiXpYQ==}
dependencies:
@ -11114,7 +11135,7 @@ packages:
dependencies:
'@babel/core': 7.21.0
postcss: 8.4.28
postcss-syntax: 0.36.2(postcss-html@0.36.0)(postcss-jsx@0.36.4)(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39)
postcss-syntax: 0.36.2(postcss@8.4.28)
transitivePeerDependencies:
- supports-color
dev: false
@ -13030,7 +13051,7 @@ packages:
esbuild: 0.17.19
regenerate: 1.4.2
regenerate-unicode-properties: 10.1.0
spdy: 4.0.2(supports-color@6.1.0)
spdy: 4.0.2
transitivePeerDependencies:
- supports-color
dev: false
@ -13046,7 +13067,7 @@ packages:
less: 4.1.3
postcss-preset-env: 7.5.0(postcss@8.4.28)
rollup-plugin-visualizer: 5.9.0(rollup@2.33.3)
vite: 4.3.1(@types/node@20.4.7)(less@4.1.3)(sass@1.66.1)(stylus@0.54.8)
vite: 4.3.1(@types/node@20.4.7)(less@3.13.1)(stylus@0.54.8)
transitivePeerDependencies:
- '@types/node'
- postcss
@ -13348,7 +13369,7 @@ packages:
eslint-plugin-react: 7.32.2(eslint@7.22.0)
eslint-plugin-react-hooks: 4.6.0(eslint@7.22.0)
postcss: 8.4.28
postcss-syntax: 0.36.2(postcss-html@0.36.0)(postcss-jsx@0.36.4)(postcss-less@3.1.4)(postcss-markdown@0.36.0)(postcss-scss@2.1.1)(postcss@7.0.39)
postcss-syntax: 0.36.2(postcss@8.4.28)
stylelint-config-standard: 25.0.0(stylelint@14.16.1)
transitivePeerDependencies:
- eslint
@ -13522,7 +13543,7 @@ packages:
'@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.10)
'@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.10)
react-refresh: 0.14.0
vite: 4.3.1(@types/node@20.4.7)(less@4.1.3)(sass@1.66.1)(stylus@0.54.8)
vite: 4.3.1(@types/node@20.4.7)(less@3.13.1)(stylus@0.54.8)
transitivePeerDependencies:
- supports-color
dev: false
@ -29059,18 +29080,11 @@ packages:
brace-expansion: 2.0.1
dev: false
/minimatch@7.4.6:
resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==}
engines: {node: '>=10'}
dependencies:
brace-expansion: 2.0.1
/minimatch@9.0.3:
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
brace-expansion: 2.0.1
dev: true
/minimist-options@3.0.2:
resolution: {integrity: sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==}
@ -32084,6 +32098,30 @@ packages:
postcss-markdown: 0.36.0(postcss-syntax@0.36.2)(postcss@7.0.39)
postcss-scss: 2.1.1
/postcss-syntax@0.36.2(postcss@8.4.28):
resolution: {integrity: sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==}
peerDependencies:
postcss: '>=5.0.0'
postcss-html: '*'
postcss-jsx: '*'
postcss-less: '*'
postcss-markdown: '*'
postcss-scss: '*'
peerDependenciesMeta:
postcss-html:
optional: true
postcss-jsx:
optional: true
postcss-less:
optional: true
postcss-markdown:
optional: true
postcss-scss:
optional: true
dependencies:
postcss: 8.4.28
dev: false
/postcss-unique-selectors@4.0.1:
resolution: {integrity: sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==}
engines: {node: '>=6.9.0'}
@ -37188,6 +37226,19 @@ packages:
/spdx-license-ids@3.0.13:
resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==}
/spdy-transport@3.0.0:
resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==}
dependencies:
debug: 4.3.4(supports-color@5.5.0)
detect-node: 2.1.0
hpack.js: 2.1.6
obuf: 1.1.2
readable-stream: 3.6.2
wbuf: 1.7.3
transitivePeerDependencies:
- supports-color
dev: false
/spdy-transport@3.0.0(supports-color@6.1.0):
resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==}
dependencies:
@ -37200,6 +37251,19 @@ packages:
transitivePeerDependencies:
- supports-color
/spdy@4.0.2:
resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==}
engines: {node: '>=6.0.0'}
dependencies:
debug: 4.3.4(supports-color@5.5.0)
handle-thing: 2.0.1
http-deceiver: 1.2.7
select-hose: 2.0.0
spdy-transport: 3.0.0
transitivePeerDependencies:
- supports-color
dev: false
/spdy@4.0.2(supports-color@6.1.0):
resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==}
engines: {node: '>=6.0.0'}
@ -39249,13 +39313,13 @@ packages:
typedoc: 0.17.6(typescript@4.6.3)
dev: false
/typedoc-plugin-markdown@3.14.0(typedoc@0.24.0):
/typedoc-plugin-markdown@3.14.0(typedoc@0.24.8):
resolution: {integrity: sha512-UyQLkLRkfTFhLdhSf3RRpA3nNInGn+k6sll2vRXjflaMNwQAAiB61SYbisNZTg16t4K1dt1bPQMMGLrxS0GZ0Q==}
peerDependencies:
typedoc: '>=0.23.0'
dependencies:
handlebars: 4.7.8
typedoc: 0.24.0(typescript@5.1.6)
typedoc: 0.24.8(typescript@5.1.6)
dev: false
/typedoc@0.17.6(typescript@4.6.3):
@ -39278,16 +39342,16 @@ packages:
typescript: 4.6.3
dev: false
/typedoc@0.24.0(typescript@5.1.6):
resolution: {integrity: sha512-yNbhPdDCb67r+v+SRcyXDp5JTImMqHHOFQDI7zciT7rXJnJt5UD9wz1Z4WllCVm5Ey92j2bOML0hnaiK1Pk2JA==}
/typedoc@0.24.8(typescript@5.1.6):
resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==}
engines: {node: '>= 14.14'}
hasBin: true
peerDependencies:
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x
dependencies:
lunr: 2.3.9
marked: 4.3.0
minimatch: 7.4.6
minimatch: 9.0.3
shiki: 0.14.3
typescript: 5.1.6
@ -40286,7 +40350,41 @@ packages:
fsevents: 2.3.3
dev: true
/vite@4.3.1(@types/node@20.4.7)(less@4.1.3)(sass@1.66.1)(stylus@0.54.8):
/vite@4.2.2(@types/node@20.4.7):
resolution: {integrity: sha512-PcNtT5HeDxb3QaSqFYkEum8f5sCVe0R3WK20qxgIvNBZPXU/Obxs/+ubBMeE7nLWeCo2LDzv+8hRYSlcaSehig==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
'@types/node': '>= 14'
less: '*'
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
dependencies:
'@types/node': 20.4.7
esbuild: 0.17.19
postcss: 8.4.28
resolve: 1.22.4
rollup: 3.28.1
optionalDependencies:
fsevents: 2.3.3
dev: true
/vite@4.3.1(@types/node@20.4.7)(less@3.13.1)(stylus@0.54.8):
resolution: {integrity: sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
@ -40313,10 +40411,9 @@ packages:
dependencies:
'@types/node': 20.4.7
esbuild: 0.17.19
less: 4.1.3
less: 3.13.1
postcss: 8.4.28
rollup: 3.28.1
sass: 1.66.1
stylus: 0.54.8
optionalDependencies:
fsevents: 2.3.3