fix: 增加哈希表

This commit is contained in:
陈荣燊 2022-03-27 09:22:17 +08:00
commit 5b19b89445
22 changed files with 6055 additions and 2565 deletions

View File

@ -13,7 +13,7 @@ SV.registerLayout('ChainHashTable', {
element: { element: {
head: { head: {
type: 'two-cell-node', type: 'two-cell-node',
label: '[id]', label: '[data]',
size: [70, 40], size: [70, 40],
style: { style: {
stroke: '#333', stroke: '#333',
@ -22,7 +22,7 @@ SV.registerLayout('ChainHashTable', {
}, },
node: { node: {
type: 'link-list-node', type: 'link-list-node',
label: '[id]', label: '[data]',
size: [60, 30], size: [60, 30],
style: { style: {
stroke: '#333', stroke: '#333',
@ -64,9 +64,10 @@ SV.registerLayout('ChainHashTable', {
} }
} }
}, },
pointer: { marker: {
external: { external: {
anchor: 3, type: 'pointer',
anchor: 1,
offset: 8, offset: 8,
style: { style: {
fill: '#f08a5d' fill: '#f08a5d'

View File

@ -72,6 +72,20 @@ SV.registerLayout('LinkQueue', {
fill: '#333' fill: '#333'
} }
} }
},
loopNext: {
type: 'quadratic',
curveOffset: -100,
sourceAnchor: 2,
targetAnchor: 7,
style: {
stroke: '#333',
endArrow: 'default',
startArrow: {
path: G6.Arrow.circle(2, -1),
fill: '#333'
}
}
} }
}, },
marker: { marker: {
@ -85,7 +99,7 @@ SV.registerLayout('LinkQueue', {
}, },
layout: { layout: {
xInterval: 50, xInterval: 50,
yInterval: 50 yInterval: 58
}, },
behavior: { behavior: {
dragNode: ['node'] dragNode: ['node']

View File

@ -44,6 +44,20 @@
fill: '#333' fill: '#333'
} }
} }
},
loopNext: {
type: 'quadratic',
curveOffset: -100,
sourceAnchor: 2,
targetAnchor: 7,
style: {
stroke: '#333',
endArrow: 'default',
startArrow: {
path: G6.Arrow.circle(2, -1),
fill: '#333'
}
}
} }
}, },
marker: { marker: {

View File

@ -1,14 +1,25 @@
SV.registerLayout('PCTree', { SV.registerLayout('PCTree', {
sourcesPreprocess(sources) { sourcesPreprocess(sources) {
for(let i = 0; i < sources.length; i++){ let headNodes = sources.filter(item => item.type === 'PCTreeHead');
if(sources[i].root){
sources[i].rootLabel = ['data', 'parent', 'firstChild']; for(let i = 0; i < headNodes.length; i++){
let dataNode = {
type: 'PCTreePreHead',
id: headNodes[i].id + '_0',
data: headNodes[i].preData,
indexLeft: headNodes[i].index,
root: headNodes[i].root
} }
if(dataNode.root){
dataNode.indexTop = 'data';
headNodes[i].indexTop = ' parent firstChild'
}
sources.push(dataNode)
} }
return sources; return sources;
@ -17,10 +28,23 @@ SV.registerLayout('PCTree', {
defineOptions() { defineOptions() {
return { return {
node: { node: {
PCTreePreHead: {
type: 'rect',
label: '[data]',
size: [60, 34],
labelOptions: {
style: { fontSize: 16 }
},
style: {
stroke: '#333',
fill: '#95e1d3',
offset: 25
}
},
PCTreeHead: { PCTreeHead: {
type: 'three-cell', type: 'two-cell-node',
label: ['[data]','[parent]'], label: '[data]',
size: [210, 33], size: [120, 34],
style: { style: {
stroke: '#333', stroke: '#333',
fill: '#95e1d3' fill: '#95e1d3'
@ -36,6 +60,10 @@ SV.registerLayout('PCTree', {
} }
} }
}, },
indexLabel: {
indexTop: { position: 'top' },
indexLeft: { position: 'left' }
},
link: { link: {
headNext: { headNext: {
sourceAnchor: 1, sourceAnchor: 1,
@ -68,8 +96,19 @@ SV.registerLayout('PCTree', {
} }
} }
}, },
marker: {
external: {
type: 'pointer',
anchor: 0,
offset: 8,
style: {
fill: '#f08a5d'
}
}
},
layout: { layout: {
xInterval: 50 xInterval: 50,
yInterval: 86
}, },
behavior: { behavior: {
dragNode: ['PCTreeNode'] dragNode: ['PCTreeNode']
@ -77,50 +116,80 @@ SV.registerLayout('PCTree', {
}; };
}, },
//判断node节点是否之前布局过
isUnique(value, allNodeIdValue){
let re = new RegExp("" + value);
return !re.test(allNodeIdValue);
},
/** /**
* 对子树进行递归布局 * 对子树进行递归布局
* @param node * @param node
* @param parent * @param parent
*/ */
layoutItem(node, prev, layoutOptions) { layoutItem(node, prev, layoutOptions, allNodeId) {
if(!node) { if(!node) {
return null; return null;
} }
let width = node.get('size')[0],
idValue = node.id.split('(')[1].slice(0, -1);
let width = node.get('size')[0]; //有y型链表的情况不用再布局
if(this.isUnique(idValue, allNodeId.value)){
if(prev) { if(prev) {
node.set('y', prev.get('y')); node.set('y', prev.get('y'));
node.set('x', prev.get('x') + layoutOptions.xInterval + width); node.set('x', prev.get('x') + layoutOptions.xInterval + width);
} }
allNodeId.value += idValue;
if(node.next) { if(node.next) {
this.layoutItem(node.next, node, layoutOptions); this.layoutItem(node.next, node, layoutOptions, allNodeId);
}
} }
}, },
layout(elements, layoutOptions) { layout(elements, layoutOptions) {
let headNode = elements.filter(item => item.type === 'PCTreeHead'), let headNode = elements.filter(item => item.type === 'PCTreeHead'),
i; preHeadNode = elements.filter(item => item.type === 'PCTreePreHead'),
roots = elements.filter(item => item.type === 'PCTreeNode' && item.root),
height = headNode[0].get('size')[1],
width = headNode[0].get('size')[0],
i,
allNodeId = { value: ''}; //引用类型用于传参
for(i = 0; i < headNode.length; i++) { for(i = 0; i < headNode.length; i++) {
let node = headNode[i], let node = headNode[i],
height = node.get('size')[1], preNode = preHeadNode[i];
width = node.get('size')[0];
node.set({ node.set({
x: 0, x: 0,
y: i * height y: i * height
}); });
preNode.set({
x: width / 4,
y: (i + 1) * height
})
if(node.headNext) { if(node.headNext) {
let y = node.get('y') + height - node.headNext.get('size')[1], let y = node.get('y') + height - node.headNext.get('size')[1],
x = width + layoutOptions.xInterval * 3; x = width + layoutOptions.xInterval * 2;
node.headNext.set({ x, y }); node.headNext.set({ x, y });
this.layoutItem(node.headNext, null, layoutOptions); this.layoutItem(node.headNext, null, layoutOptions, allNodeId);
} }
} }
for(i = 0; i < roots.length; i++) {
let nodeWidth = roots[0].get('size')[0],
nodeInternalSum = i * (nodeWidth + layoutOptions.xInterval);
roots[i].set({
x: headNode[0].get('x') + width + layoutOptions.xInterval * 2 + nodeInternalSum,
y: headNode[0].get('y') - layoutOptions.yInterval
})
}
} }
}); });

View File

@ -35,8 +35,12 @@ SV.registerLayout('PTree', {
data: sources[i].parent data: sources[i].parent
}); });
} }
if(sources[0]){
sources[0].indexLeft = 'data'; sources[0].indexLeft = 'data';
}
if(parentNodes[0]){
parentNodes[0].indexLeft = 'parent'; parentNodes[0].indexLeft = 'parent';
}
sources.push(...parentNodes); sources.push(...parentNodes);
@ -70,14 +74,17 @@ SV.registerLayout('PTree', {
layout(elements) { layout(elements) {
let nodeLength = elements.length, let nodeLength = elements.length;
halfLength = nodeLength / 2,
if(nodeLength == 0) return;
let halfLength = nodeLength / 2,
size = elements[0].get('size')[0], size = elements[0].get('size')[0],
i; i;
for (i = 0; i < nodeLength; i++) { for (i = 0; i < nodeLength; i++) {
let x = (i % halfLength) * size; let x = (i % halfLength) * size,
y = Math.floor(i / halfLength) * size; y = Math.floor(i / halfLength) * size;
elements[i].set({ x, y }); elements[i].set({ x, y });

View File

@ -36,6 +36,21 @@ SV.registerLayout('TriTree', {
} }
} }
}, },
parent: {
type: 'line',
sourceAnchor: 4,
targetAnchor: 6,
style: {
stroke: '#999',
lineAppendWidth: 10,
lineWidth: 1.6,
endArrow: 'default',
startArrow: {
path: G6.Arrow.circle(2, -1),
fill: '#999'
}
}
},
r_parent: { r_parent: {
type: 'quadratic', type: 'quadratic',
sourceAnchor: 4, sourceAnchor: 4,

View File

@ -8,10 +8,10 @@ const SOURCES_DATA = [{
"0x0" "0x0"
], ],
"child": [ "child": [
"0xb07ee0", "0xfd9ee0",
"0xb07f10" "0xfd9f10"
], ],
"id": "0xb07eb0", "id": "0xfd9eb0",
"name": "T", "name": "T",
"data": "A", "data": "A",
"root": true, "root": true,
@ -22,12 +22,12 @@ const SOURCES_DATA = [{
"0x0", "0x0",
"0x0" "0x0"
], ],
"id": "0xb07ee0", "id": "0xfd9ee0",
"name": "T->lchild", "name": "T->lchild",
"data": "B", "data": "B",
"type": "default", "type": "default",
"l_parent": [ "l_parent": [
"0x0" "0xfd9eb0"
], ],
"external": [ "external": [
"T1" "T1"
@ -38,12 +38,12 @@ const SOURCES_DATA = [{
"0x0", "0x0",
"0x0" "0x0"
], ],
"id": "0xb07f10", "id": "0xfd9f10",
"name": "T->rchild", "name": "T->rchild",
"data": "C", "data": "C",
"type": "default", "type": "default",
"r_parent": [ "r_parent": [
"0x0" "0xfd9eb0"
], ],
"external": [ "external": [
"T2" "T2"
@ -52,6 +52,144 @@ const SOURCES_DATA = [{
], ],
"layouter": "TriTree" "layouter": "TriTree"
}, },
"TriTree3": {
"data": [{
"external": [
"T3"
],
"parent": [
"0x0"
],
"child": [
"0x0",
"0x0"
],
"id": "0xfd9f40",
"name": "T3",
"data": "D",
"root": true,
"type": "default"
}],
"layouter": "TriTree"
},
"TriTree4": {
"data": [{
"external": [
"T4"
],
"parent": [
"0x0"
],
"child": [
"0x0",
"0x0"
],
"id": "0xfd9f70",
"name": "T4",
"data": "E",
"root": true,
"type": "default"
}],
"layouter": "TriTree"
},
"handleUpdate": {
"isEnterFunction": true,
"isFirstDebug": true
}
}, {
"TriTree0": {
"data": [{
"external": [
"T"
],
"parent": [
"0x0"
],
"child": [
"0xfd9ee0",
"0xfd9f10"
],
"id": "0xfd9eb0",
"name": "T",
"data": "A",
"root": true,
"type": "default"
},
{
"child": [
"0x0",
"0x0"
],
"id": "0xfd9ee0",
"name": "T->lchild",
"data": "B",
"type": "default",
"l_parent": [
"0xfd9eb0"
],
"external": [
"T1"
]
},
{
"child": [
"0x0",
"0x0"
],
"id": "0xfd9f10",
"name": "T->rchild",
"data": "C",
"type": "default",
"r_parent": [
"0xfd9eb0"
],
"external": [
"T2"
]
}
],
"layouter": "TriTree"
},
"TriTree3": {
"data": [{
"external": [
"T3"
],
"parent": [
"0x0"
],
"child": [
"0x0",
"0x0"
],
"id": "0xfd9f40",
"name": "T3",
"data": "D",
"root": true,
"type": "default"
}],
"layouter": "TriTree"
},
"TriTree4": {
"data": [{
"external": [
"T4"
],
"parent": [
"0xfd9f40"
],
"child": [
"0x0",
"0x0"
],
"id": "0xfd9f70",
"name": "T4",
"data": "E",
"root": true,
"type": "default"
}],
"layouter": "TriTree"
},
"handleUpdate": { "handleUpdate": {
"isEnterFunction": false, "isEnterFunction": false,
"isFirstDebug": false "isFirstDebug": false
@ -66,10 +204,10 @@ const SOURCES_DATA = [{
"0x0" "0x0"
], ],
"child": [ "child": [
"0xb07ee0", "0xfd9ee0",
"0xb07f10" "0xfd9f10"
], ],
"id": "0xb07eb0", "id": "0xfd9eb0",
"name": "T", "name": "T",
"data": "A", "data": "A",
"root": true, "root": true,
@ -80,12 +218,12 @@ const SOURCES_DATA = [{
"0x0", "0x0",
"0x0" "0x0"
], ],
"id": "0xb07ee0", "id": "0xfd9ee0",
"name": "T->lchild", "name": "T->lchild",
"data": "B", "data": "B",
"type": "default", "type": "default",
"l_parent": [ "l_parent": [
"0xb07eb0" "0xfd9eb0"
], ],
"external": [ "external": [
"T1" "T1"
@ -96,12 +234,12 @@ const SOURCES_DATA = [{
"0x0", "0x0",
"0x0" "0x0"
], ],
"id": "0xb07f10", "id": "0xfd9f10",
"name": "T->rchild", "name": "T->rchild",
"data": "C", "data": "C",
"type": "default", "type": "default",
"r_parent": [ "r_parent": [
"0x0" "0xfd9eb0"
], ],
"external": [ "external": [
"T2" "T2"
@ -110,26 +248,21 @@ const SOURCES_DATA = [{
], ],
"layouter": "TriTree" "layouter": "TriTree"
}, },
"handleUpdate": { "TriTree3": {
"isEnterFunction": false,
"isFirstDebug": false
}
}, {
"TriTree0": {
"data": [{ "data": [{
"external": [ "external": [
"T" "T3"
], ],
"parent": [ "parent": [
"0x0" "0x0"
], ],
"child": [ "child": [
"0xb07ee0", "0xfd9f70",
"0xb07f10" "0x0"
], ],
"id": "0xb07eb0", "id": "0xfd9f40",
"name": "T", "name": "T3",
"data": "A", "data": "D",
"root": true, "root": true,
"type": "default" "type": "default"
}, },
@ -138,31 +271,15 @@ const SOURCES_DATA = [{
"0x0", "0x0",
"0x0" "0x0"
], ],
"id": "0xb07ee0", "id": "0xfd9f70",
"name": "T->lchild", "name": "T3->lchild",
"data": "B", "data": "E",
"type": "default", "type": "default",
"l_parent": [ "l_parent": [
"0xb07eb0" "0xfd9f40"
], ],
"external": [ "external": [
"T1" "T4"
]
},
{
"child": [
"0x0",
"0x0"
],
"id": "0xb07f10",
"name": "T->rchild",
"data": "C",
"type": "default",
"r_parent": [
"0xb07eb0"
],
"external": [
"T2"
] ]
} }
], ],

4080
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,20 @@
{ {
"devDependencies": {
"merge": "^2.1.1",
"ts-loader": "^5.2.1",
"typescript": "^3.2.2",
"webpack": "^4.46.0",
"webpack-cli": "^3.2.3"
},
"scripts": { "scripts": {
"build": "webpack --config webpack.config.product.js", "build": "webpack --config webpack.config.product.js",
"dep": "webpack --config webpack.config.product.js && node copyDist2Anyview.js", "dep": "webpack --config webpack.config.product.js && node copyDist2Anyview.js",
"dev": "webpack --w --config webpack.config.develop.js", "dev": "webpack --watch --config webpack.config.develop.js",
"copy": "node copyDist2Anyview.js" "copy": "node copyDist2Anyview.js"
}, },
"devDependencies": {
"acorn": "^8.7.0",
"merge": "^2.1.1",
"ts-loader": "^9.2.8",
"typescript": "^4.6.2",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2"
},
"dependencies": { "dependencies": {
"@antv/g6": "^4.6.1", "@antv/g6": "^4.6.4",
"merge": "^2.1.1" "merge": "^2.1.1"
} }
} }

View File

@ -1,10 +1,9 @@
import { Graph, INode } from "@antv/g6"; import { G6Event, Graph, INode } from '@antv/g6';
import { EventBus } from "../Common/eventBus"; import { EventBus } from '../Common/eventBus';
import { LayoutGroupTable } from "../Model/modelConstructor"; import { LayoutGroupTable } from '../Model/modelConstructor';
import { SVModel } from "../Model/SVModel"; import { SVModel } from '../Model/SVModel';
import { SVNode } from "../Model/SVNode"; import { SVNode } from '../Model/SVNode';
import { ViewContainer } from "../View/viewContainer"; import { ViewContainer } from '../View/viewContainer';
/** /**
* *
@ -23,8 +22,7 @@ const checkNodeDragAlone = function (node: SVNode, dragNodeOption: boolean | str
} }
return false; return false;
} };
/** /**
* *
@ -32,7 +30,11 @@ const checkNodeDragAlone = function (node: SVNode, dragNodeOption: boolean | str
* 2. dragNodeOption type时 * 2. dragNodeOption type时
* 3. dragNodeOption false type的节点 * 3. dragNodeOption false type的节点
*/ */
export const DetermineNodeDrag = function (layoutGroupTable: LayoutGroupTable, node: SVNode, brushSelectedModels: SVModel[]) { export const DetermineNodeDrag = function (
layoutGroupTable: LayoutGroupTable,
node: SVNode,
brushSelectedModels: SVModel[]
) {
const layoutGroup = layoutGroupTable.get(node.group), const layoutGroup = layoutGroupTable.get(node.group),
dragNodeOption = layoutGroup.options.behavior?.dragNode, dragNodeOption = layoutGroup.options.behavior?.dragNode,
canNodeDragAlone = checkNodeDragAlone(node, dragNodeOption); canNodeDragAlone = checkNodeDragAlone(node, dragNodeOption);
@ -45,14 +47,13 @@ export const DetermineNodeDrag = function (layoutGroupTable: LayoutGroupTable, n
nodeModelType = node.getModelType(), nodeModelType = node.getModelType(),
modelList = (<SVModel[]>layoutGroup[nodeModelType]).filter(item => item.sourceType === nodeSourceType), modelList = (<SVModel[]>layoutGroup[nodeModelType]).filter(item => item.sourceType === nodeSourceType),
brushSelectedSameTypeModels = brushSelectedModels.filter(item => { brushSelectedSameTypeModels = brushSelectedModels.filter(item => {
return item.group === node.group && return (
item.getModelType() === nodeModelType && item.group === node.group && item.getModelType() === nodeModelType && item.sourceType === nodeSourceType
item.sourceType === nodeSourceType );
}); });
return modelList.length === brushSelectedSameTypeModels.length; return modelList.length === brushSelectedSameTypeModels.length;
} };
/** /**
* appendage * appendage
@ -97,14 +98,14 @@ export function SolveNodeAppendagesDrag(viewContainer: ViewContainer) {
node.setSelectedState(false); node.setSelectedState(false);
node.set({ node.set({
x: node.G6Item.getModel().x, x: node.G6Item.getModel().x,
y: node.G6Item.getModel().y y: node.G6Item.getModel().y,
}); });
node.getAppendagesList().forEach(item => { node.getAppendagesList().forEach(item => {
item.setSelectedState(false); item.setSelectedState(false);
item.set({ item.set({
x: item.G6Item.getModel().x, x: item.G6Item.getModel().x,
y: item.G6Item.getModel().y y: item.G6Item.getModel().y,
}); });
}); });
} }
@ -112,14 +113,14 @@ export function SolveNodeAppendagesDrag(viewContainer: ViewContainer) {
viewContainer.brushSelectedModels.forEach(item => { viewContainer.brushSelectedModels.forEach(item => {
item.set({ item.set({
x: item.G6Item.getModel().x, x: item.G6Item.getModel().x,
y: item.G6Item.getModel().y y: item.G6Item.getModel().y,
}); });
if(item instanceof SVNode) { if (item instanceof SVNode) {
item.getAppendagesList().forEach(appendage => { item.getAppendagesList().forEach(appendage => {
appendage.set({ appendage.set({
x: appendage.G6Item.getModel().x, x: appendage.G6Item.getModel().x,
y: appendage.G6Item.getModel().y y: appendage.G6Item.getModel().y,
}); });
}); });
} }
@ -127,7 +128,6 @@ export function SolveNodeAppendagesDrag(viewContainer: ViewContainer) {
}); });
} }
/** /**
* *
* @param viewContainer * @param viewContainer
@ -136,8 +136,8 @@ export function SolveBrushSelectDrag(viewContainer: ViewContainer) {
const g6Instance: Graph = viewContainer.getG6Instance(); const g6Instance: Graph = viewContainer.getG6Instance();
// 当框选完成后,监听被框选节点的数量变化事件,将被框选的节点添加到 brushSelectedModels 数组里面 // 当框选完成后,监听被框选节点的数量变化事件,将被框选的节点添加到 brushSelectedModels 数组里面
g6Instance.on('nodeselectchange', event => { g6Instance.on('nodeselectchange' as G6Event, event => {
const selectedItems = event.selectedItems as { nodes: INode[]; }, const selectedItems = event.selectedItems as { nodes: INode[] },
tmpSelectedModelList = []; tmpSelectedModelList = [];
// 如果是点击选中,不理会 // 如果是点击选中,不理会
@ -159,54 +159,44 @@ export function SolveBrushSelectDrag(viewContainer: ViewContainer) {
if (DetermineNodeDrag(viewContainer.getLayoutGroupTable(), node, tmpSelectedModelList)) { if (DetermineNodeDrag(viewContainer.getLayoutGroupTable(), node, tmpSelectedModelList)) {
viewContainer.brushSelectedModels.push(node); viewContainer.brushSelectedModels.push(node);
} } else {
else {
node.setSelectedState(false); node.setSelectedState(false);
} }
}); });
}); });
} }
/** /**
* *
* @param g6Instance * @param g6Instance
* @param hasLeak * @param hasLeak
*/ */
export function SolveDragCanvasWithLeak(viewContainer: ViewContainer) { export function SolveDragCanvasWithLeak(viewContainer: ViewContainer) {
let g6Instance = viewContainer.getG6Instance(), let g6Instance = viewContainer.getG6Instance();
prevDy = 0;
g6Instance.on('viewportchange', event => { g6Instance.on('viewportchange', event => {
if (event.action !== 'translate') { if (event.action !== 'translate') {
return false; return false;
} }
let translateX = event.matrix[7], let translateY = event.matrix[7],
dy = translateX - prevDy; dy = translateY - viewContainer.lastLeakAreaTranslateY;
prevDy = translateX; viewContainer.lastLeakAreaTranslateY = translateY;
viewContainer.leakAreaY = viewContainer.leakAreaY + dy; viewContainer.leakAreaY = viewContainer.leakAreaY + dy;
if (viewContainer.hasLeak) { if (viewContainer.hasLeak) {
EventBus.emit('onLeakAreaUpdate', { EventBus.emit('onLeakAreaUpdate', {
leakAreaY: viewContainer.leakAreaY, leakAreaY: viewContainer.leakAreaY,
hasLeak: viewContainer.hasLeak hasLeak: viewContainer.hasLeak,
}); });
} }
}); });
} }
/** /**
* *
* @param g6Instance * @param g6Instance
* @param generalModelsGroup * @param generalModelsGroup
*/ */
export function SolveZoomCanvasWithLeak(viewContainer: ViewContainer) { export function SolveZoomCanvasWithLeak(viewContainer: ViewContainer) {}
}

View File

@ -53,8 +53,13 @@ export function InitG6Behaviors(engine: Engine, viewContainer: ViewContainer): M
}; };
const selectNodeFilter = event => { const selectNodeFilter = event => {
let g6Item = event.item, let g6Item = event.item;
node: SVNode = g6Item.SVModel;
if(g6Item === null) {
return false
}
let node: SVNode = g6Item.SVModel;
if (g6Item === null || node.isNode() === false) { if (g6Item === null || node.isNode() === false) {
return false; return false;

View File

@ -444,14 +444,25 @@ export class ModelConstructor {
} }
} }
nodeList = layoutGroupTable.get(targetGroupName).node.filter(item => item.sourceType === sourceNodeType); // 为了可以连接到不同group的结点
for (let layoutGroup of layoutGroupTable.values()) {
// 若目标node不存在返回null nodeList = layoutGroup.node.filter(item => item.sourceType === sourceNodeType);
if (nodeList === undefined) { if (nodeList === undefined) {
return null; continue;
} }
targetNode = nodeList.find(item => item.sourceId === targetId); targetNode = nodeList.find(item => item.sourceId === targetId);
if (targetNode) {
break;
}
}
// nodeList = layoutGroupTable.get(targetGroupName).node.filter(item => item.sourceType === sourceNodeType);
// // 若目标node不存在返回null
// if (nodeList === undefined) {
// return null;
// }
// targetNode = nodeList.find(item => item.sourceId === targetId);
return targetNode || null; return targetNode || null;
} }

View File

@ -50,7 +50,7 @@ export default Util.registerShape(
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'label',
draggable: true, draggable: true,
}); });
} }
@ -73,7 +73,7 @@ export default Util.registerShape(
fontSize: 16, fontSize: 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null-left',
draggable: true, draggable: true,
}); });
} }
@ -90,7 +90,7 @@ export default Util.registerShape(
fontSize: 16, fontSize: 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null-right',
draggable: true, draggable: true,
}); });
} }

View File

@ -57,7 +57,7 @@ export default Util.registerShape(
fill: style.fill || '#000', fill: style.fill || '#000',
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
}, },
name: 'text', name: 'label',
draggable: true, draggable: true,
}); });
} }
@ -75,7 +75,7 @@ export default Util.registerShape(
fontSize: 16, fontSize: 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null',
draggable: true, draggable: true,
}); });
} }

View File

@ -69,7 +69,7 @@ export default registerNode('three-cell', {
fontStyle: 'italic', fontStyle: 'italic',
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'rootLabel0',
draggable: true, draggable: true,
}); });
@ -85,7 +85,7 @@ export default registerNode('three-cell', {
fontStyle: 'italic', fontStyle: 'italic',
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'rootLabel1',
draggable: true, draggable: true,
}); });
@ -101,7 +101,7 @@ export default registerNode('three-cell', {
fontStyle: 'italic', fontStyle: 'italic',
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'rootLabel2',
draggable: true, draggable: true,
}); });
} }
@ -120,7 +120,7 @@ export default registerNode('three-cell', {
fontStyle: 'italic', fontStyle: 'italic',
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'index',
draggable: true, draggable: true,
}); });
} }
@ -137,7 +137,7 @@ export default registerNode('three-cell', {
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'label1',
draggable: true, draggable: true,
}); });
@ -152,7 +152,7 @@ export default registerNode('three-cell', {
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'label2',
draggable: true, draggable: true,
}); });
} }
@ -170,7 +170,7 @@ export default registerNode('three-cell', {
fontSize: 22, fontSize: 22,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null',
draggable: true, draggable: true,
}); });
} }

View File

@ -1,8 +1,6 @@
import { Util } from '../Common/util'; import { Util } from '../Common/util';
export default Util.registerShape( export default Util.registerShape('tri-tree-node', {
'tri-tree-node',
{
draw(cfg, group) { draw(cfg, group) {
cfg.size = cfg.size; cfg.size = cfg.size;
@ -17,9 +15,9 @@ export default Util.registerShape(
height: height, height: height,
stroke: cfg.style.stroke || '#333', stroke: cfg.style.stroke || '#333',
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
fill: '#eee' fill: '#eee',
}, },
name: 'wrapper' name: 'wrapper',
}); });
group.addShape('rect', { group.addShape('rect', {
@ -30,10 +28,10 @@ export default Util.registerShape(
height: height / 4, height: height / 4,
fill: '#eee', fill: '#eee',
stroke: cfg.style.stroke || '#333', stroke: cfg.style.stroke || '#333',
cursor: cfg.style.cursor cursor: cfg.style.cursor,
}, },
name: 'top', name: 'top',
draggable: true draggable: true,
}); });
group.addShape('rect', { group.addShape('rect', {
@ -41,17 +39,16 @@ export default Util.registerShape(
x: width / 4 + width / 2, x: width / 4 + width / 2,
y: height / 2 + height / 4, y: height / 2 + height / 4,
width: width / 2, width: width / 2,
height: height / 4 * 3, height: (height / 4) * 3,
fill: cfg.color || cfg.style.fill, fill: cfg.color || cfg.style.fill,
stroke: cfg.style.stroke || '#333', stroke: cfg.style.stroke || '#333',
cursor: cfg.style.cursor cursor: cfg.style.cursor,
}, },
name: 'bottom', name: 'bottom',
draggable: true draggable: true,
}); });
const style = (cfg.labelCfg && cfg.labelCfg.style) || {}; const style = (cfg.labelCfg && cfg.labelCfg.style) || {};
if (cfg.label) { if (cfg.label) {
group.addShape('text', { group.addShape('text', {
attrs: { attrs: {
x: width, // 居中 x: width, // 居中
@ -61,34 +58,35 @@ export default Util.registerShape(
text: cfg.label, text: cfg.label,
fill: style.fill || '#000', fill: style.fill || '#000',
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
cursor: cfg.style.cursor cursor: cfg.style.cursor,
}, },
name: 'text', name: 'label',
draggable: true draggable: true,
}); });
} }
let parent = cfg.parent || cfg.l_parent || cfg.r_parent;
const isLeftEmpty = const isLeftEmpty =
!cfg.child || cfg.child[0] === undefined || cfg.child[0] === undefined || cfg.child[0] == '0x0', !cfg.child || cfg.child[0] === undefined || cfg.child[0] === undefined || cfg.child[0] == '0x0',
isRightEmpty = isRightEmpty =
!cfg.child || cfg.child[1] === undefined || cfg.child[1] === undefined || cfg.child[1] == '0x0', !cfg.child || cfg.child[1] === undefined || cfg.child[1] === undefined || cfg.child[1] == '0x0',
isparentEmpty = cfg.parent == "0x0" || cfg.l_parent == "0x0" || cfg.r_parent == "0x0"; isParentEmpty = parent[0] == '0x0';
if (isparentEmpty) { if (isParentEmpty) {
{ {
group.addShape('text', { group.addShape('text', {
attrs: { attrs: {
x: width, // 居中 x: width, // 居中
y: height / 4 * 3, y: (height / 4) * 3,
textAlign: 'center', textAlign: 'center',
textBaseline: 'middle', textBaseline: 'middle',
text: "^", text: '^',
fill: style.fill || '#000', fill: style.fill || '#000',
fontSize: style.fontSize || 14, fontSize: style.fontSize || 14,
cursor: cfg.style.cursor cursor: cfg.style.cursor,
}, },
name: 'parent', name: 'null-parent',
draggable: true draggable: true,
}); });
} }
} }
@ -106,7 +104,7 @@ export default Util.registerShape(
fontSize: 16, fontSize: 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null-left',
draggable: true, draggable: true,
}); });
} }
@ -123,12 +121,11 @@ export default Util.registerShape(
fontSize: 16, fontSize: 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null-right',
draggable: true, draggable: true,
}); });
} }
return wrapperRect; return wrapperRect;
}, },
@ -140,7 +137,7 @@ export default Util.registerShape(
[0.5, 0], [0.5, 0],
[0.5, 0.125], [0.5, 0.125],
[0.6, 1], [0.6, 1],
[0.5, 1],
]; ];
}, },
} });
);

View File

@ -52,7 +52,7 @@ export default Util.registerShape(
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'tag',
draggable: true, draggable: true,
}); });
@ -67,7 +67,7 @@ export default Util.registerShape(
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'data',
draggable: true, draggable: true,
}); });
} else { } else {
@ -82,7 +82,7 @@ export default Util.registerShape(
fontSize: style.fontSize || 16, fontSize: style.fontSize || 16,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'label',
draggable: true, draggable: true,
}); });
} }
@ -101,7 +101,7 @@ export default Util.registerShape(
fontSize: 20, fontSize: 20,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null-headNext',
draggable: true, draggable: true,
}); });
} }
@ -119,11 +119,28 @@ export default Util.registerShape(
fontSize: 20, fontSize: 20,
cursor: cfg.style.cursor, cursor: cfg.style.cursor,
}, },
name: 'text', name: 'null-start',
draggable: true, draggable: true,
}); });
} }
//pctree 数据结构中没有后续指针
if (cfg.id.includes('PCTreeHead') && !cfg.headNext) {
group.addShape('text', {
attrs: {
x: width * (5 / 4),
y: height * (8 / 7),
textAlign: 'center',
textBaseline: 'middle',
text: '^',
fill: style.fill || '#000',
fontSize: 20,
cursor: cfg.style.cursor,
},
name: 'null-headNext2',
draggable: true,
});
}
return wrapperRect; return wrapperRect;
}, },

View File

@ -155,7 +155,7 @@ export class LayoutProvider {
}, },
left: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => { left: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => {
return { return {
x: nodeBound.x - labelBound.width - offset, x: nodeBound.x - labelBound.width / 2- offset,
y: nodeBound.y + nodeBound.height / 2, y: nodeBound.y + nodeBound.height / 2,
}; };
}, },
@ -164,7 +164,8 @@ export class LayoutProvider {
indexLabels.forEach(item => { indexLabels.forEach(item => {
const options: IndexLabelOption = indexLabelOptions[item.sourceType], const options: IndexLabelOption = indexLabelOptions[item.sourceType],
nodeBound = item.target.getBound(), nodeBound = item.target.getBound(),
labelBound = item.getBound(), // labelBound = item.getBound(),
labelBound = item.shadowG6Item.getContainer().getChildren()[1].getBBox(),
offset = options.offset ?? 20, offset = options.offset ?? 20,
position = options.position ?? 'bottom'; position = options.position ?? 'bottom';

View File

@ -30,6 +30,7 @@ export class ViewContainer {
public hasLeak: boolean; public hasLeak: boolean;
public leakAreaY: number; public leakAreaY: number;
public lastLeakAreaTranslateY: number;
public brushSelectedModels: SVModel[]; // 保存框选过程中被选中的节点 public brushSelectedModels: SVModel[]; // 保存框选过程中被选中的节点
public clickSelectNode: SVNode; // 点击选中的节点 public clickSelectNode: SVNode; // 点击选中的节点
@ -49,10 +50,11 @@ export class ViewContainer {
const g6Instance = this.renderer.getG6Instance(), const g6Instance = this.renderer.getG6Instance(),
leakAreaHeight = this.engine.viewOptions.leakAreaHeight, leakAreaHeight = this.engine.viewOptions.leakAreaHeight,
height = this.getG6Instance().getHeight(), height = g6Instance.getHeight(),
{ drag, zoom } = this.engine.behaviorOptions; { drag, zoom } = this.engine.behaviorOptions;
this.leakAreaY = height - leakAreaHeight; this.leakAreaY = height - leakAreaHeight;
this.lastLeakAreaTranslateY = 0;
SolveNodeAppendagesDrag(this); SolveNodeAppendagesDrag(this);
SolveBrushSelectDrag(this); SolveBrushSelectDrag(this);
@ -68,17 +70,33 @@ export class ViewContainer {
reLayout() { reLayout() {
const g6Instance = this.getG6Instance(), const g6Instance = this.getG6Instance(),
group = g6Instance.getGroup(), group = g6Instance.getGroup(),
matrix = group.getMatrix(); matrix = group.getMatrix(),
bound = group.getCanvasBBox();
const { duration, enable, timingFunction } = this.engine.animationOptions;
if (matrix) { if (matrix) {
let dx = matrix[6], let dx = matrix[6],
dy = matrix[7]; dy = matrix[7];
g6Instance.translate(-dx, -dy); g6Instance.moveTo(bound.minX - dx, bound.minY - dy, enable, {
duration,
easing: timingFunction,
});
} }
const leakAreaHeight = this.engine.viewOptions.leakAreaHeight,
height = g6Instance.getHeight();
this.leakAreaY = height - leakAreaHeight;
this.lastLeakAreaTranslateY = 0;
this.layoutProvider.layoutAll(this.layoutGroupTable, this.accumulateLeakModels); this.layoutProvider.layoutAll(this.layoutGroupTable, this.accumulateLeakModels);
g6Instance.refresh(); g6Instance.refresh();
EventBus.emit('onLeakAreaUpdate', {
leakAreaY: this.leakAreaY,
hasLeak: this.hasLeak,
});
} }
/** /**
@ -143,8 +161,8 @@ export class ViewContainer {
private restoreHighlight(models: SVModel[]) { private restoreHighlight(models: SVModel[]) {
models.forEach(item => { models.forEach(item => {
// 不是free节点才进行还原 // 不是free节点才进行还原
if(!item.freed) { if (!item.freed) {
item.restoreHighlight() item.restoreHighlight();
} }
}); });
} }

View File

@ -6,6 +6,7 @@ import { ViewContainer } from "./View/viewContainer";
import { SVNode } from "./Model/SVNode"; import { SVNode } from "./Model/SVNode";
import { Util } from "./Common/util"; import { Util } from "./Common/util";
import { SVModel } from "./Model/SVModel"; import { SVModel } from "./Model/SVModel";
import { G6Event } from "@antv/g6";
export class Engine { export class Engine {
@ -204,7 +205,7 @@ export class Engine {
return; return;
} }
this.viewContainer.getG6Instance().on(eventName, event => { this.viewContainer.getG6Instance().on(eventName as G6Event, event => {
callback(event.item['SVModel']); callback(event.item['SVModel']);
}); });
} }

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
mode: 'production',
entry: './src/StructV.ts', entry: './src/StructV.ts',
output: { output: {
filename: './sv.js', filename: './sv.js',

3408
yarn.lock

File diff suppressed because it is too large Load Diff