fix:修复释放节点的bug

This commit is contained in:
黎智洲 2021-05-26 21:50:16 +08:00
parent 2a9a108d1c
commit ad9333bd3b
13 changed files with 158 additions and 110 deletions

View File

@ -216,43 +216,59 @@
}
}
const data = {
head: [
{
"type": "QPtr",
"id": 140737338526359,
"label": "front",
"front": "node#8358681150976310000",
"external": [
"lq"
]
},
{
"type": "QPtr",
"id": 140737338526360,
"label": "rear",
"rear": "node#15844482482171916",
"external": null
}
],
node: []
{
"LinkQueue": {
"data": [
{
"type": "head",
"name": "Qptr",
"id": 6385328,
"label": "front",
"front": "node#6385360",
"external": [
"lq"
]
},
{
"type": "head",
"name": "Qptr",
"id": 6385329,
"label": "rear",
"rear": "node#6385424",
"external": null
},
{
"id": 6385360,
"data": "",
"next": "node#6385424",
"type": "node"
},
{
"id": 6385424,
"data": "F",
"next": null,
"type": "node"
},
{
"id": 6385392,
"data": "",
"next": "node#6311952",
"freed": true,
"external": [
"p"
],
"type": "node"
},
{
"id": 6311952,
"data": "1",
"next": null,
"type": "node"
}
],
"layouter": "LinkQueue"
}
}
let d = [
{ id: 10, type: 'head', name: 'QPtr', label: 'front', external: ['lq'], front: 0 },
{ id: 11, type: 'head', name: 'QPtr', label: 'rear', external: null, rear: 2 },
{ id: 0, next: 1 },
{ id: 1, next: 2 },
{ id: 2 }
];
const LQueue = function(container) {
return{
engine: new LinkQueue(container),
data: [data]
}
};

2
dist/sv.js vendored

File diff suppressed because one or more lines are too long

View File

@ -40,25 +40,15 @@ export class ModelConstructor {
Object.keys(sources).forEach(name => {
let sourceGroup = sources[name],
layouterName = sourceGroup.layouter;
if(!layouterName) {
layoutGroupTable.set(name, {
element: [],
link: [],
pointer: [],
options: null,
layouter: null,
modelList: []
});
layouterName = sourceGroup.layouter,
layouter: Layouter = layouterMap[sourceGroup.layouter];
if(!layouterName || !layouter) {
return;
}
let sourceDataString: string = JSON.stringify(sourceGroup.data),
prevString: string = this.prevSourcesStringMap[name],
layouter: Layouter = null,
options: LayoutGroupOptions = null,
elementList: Element[] = [],
pointerList: Pointer[] = [];
@ -66,13 +56,14 @@ export class ModelConstructor {
return;
}
layouter = layouterMap[sourceGroup.layouter];
options = optionsTable[layouterName];
const options: LayoutGroupOptions = optionsTable[layouterName],
elementOptions = options.element || { },
pointerOptions = options.pointer || { };
const sourceData = layouter.sourcesPreprocess? layouter.sourcesPreprocess(sourceGroup.data): sourceGroup.data;
elementList = this.constructElements(options.element, name, sourceData, layouterName);
pointerList = this.constructPointers(options.pointer, elementList);
elementList = this.constructElements(elementOptions, name, sourceData, layouterName);
pointerList = this.constructPointers(pointerOptions, elementList);
layoutGroupTable.set(name, {
element: elementList,
@ -85,7 +76,8 @@ export class ModelConstructor {
});
layoutGroupTable.forEach((layoutGroup: LayoutGroup) => {
const linkList: Link[] = this.constructLinks(layoutGroup.options.link, layoutGroup.element, layoutGroupTable);
const linkOptions = layoutGroup.options.link || { },
linkList: Link[] = this.constructLinks(linkOptions, layoutGroup.element, layoutGroupTable);
layoutGroup.link = linkList;
layoutGroup.modelList.push(...linkList);

View File

@ -201,7 +201,7 @@ export class Element extends Model {
rotation: option.rotation || 0,
type: option.type,
size: option.size,
anchorPoints: option.anchorPoint,
anchorPoints: option.anchorPoints,
label: option.label,
style: Util.objectClone<Style>(option.style),
labelCfg: Util.objectClone<ElementLabelOption>(option.labelOptions),
@ -279,7 +279,7 @@ export class Pointer extends Model {
rotation: 0,
type: option.type || 'external-pointer',
size: option.size,
anchorPoints: option.anchorPoint,
anchorPoints: option.anchorPoints,
label: typeof this.label === 'string'? this.label: this.label.join(', '),
style: Util.objectClone<Style>(option.style),
labelCfg: Util.objectClone<ElementLabelOption>(option.labelOptions),

View File

@ -60,7 +60,7 @@ export default G6.registerNode('binary-tree-node', {
return [
[0.5, 0],
[0.125, 0.5],
[0.875, 0.5],
[0.875, 0.5]
];
},
});

View File

@ -8,7 +8,8 @@ export default G6.registerNode('external-pointer', {
const keyShape = group.addShape('path', {
attrs: {
path: this.getPath(cfg),
fill: cfg.style.fill
fill: cfg.style.fill,
matrix: cfg.style.matrix
},
name: 'pointer-path'
});

View File

@ -7,7 +7,7 @@ export default G6.registerNode('link-list-node', {
const width = cfg.size[0],
height = cfg.size[1];
const wrapperRect = group.addShape('rect', {
attrs: {
x: width / 2,
@ -57,12 +57,12 @@ export default G6.registerNode('link-list-node', {
getAnchorPoints() {
return [
[0, 0.5],
[5 / 6, 0.5],
[5 / 6, 0],
[5 / 6, 1],
[0.5, 0],
[0.5, 1]
[5 / 6, 0],
[5 / 6, 0.5],
[5 / 6, 1],
[0.5, 1],
[0, 0.5]
];
}
});

View File

@ -8,39 +8,54 @@ import binaryTreeNode from "./RegisteredShape/binaryTreeNode";
import twoCellNode from "./RegisteredShape/twoCellNode";
import { Vector } from "./Common/vector";
import indexedNode from "./RegisteredShape/indexedNode";
import { EngineOptions, Layouter } from "./options";
export interface StructV {
(DOMContainer: HTMLElement, engineOptions: EngineOptions): Engine;
Group: typeof Group;
Bound: typeof Bound;
Vector: typeof Vector,
Mat3: any;
G6: any;
registeredShape: any[];
registeredLayouter: { [key: string]: Layouter },
export const SV = {
Engine: Engine,
Group: Group,
Bound: Bound,
Vector: Vector,
Mat3: G6.Util.mat3,
G6,
registeredShape: [
externalPointer,
linkListNode,
binaryTreeNode,
twoCellNode,
indexedNode
],
registeredLayouter: { },
registerShape: G6.registerNode,
registerShape: Function,
/**
*
* @param name
* @param layouter
*/
registerLayouter(name: string, layouter) {
SV.registeredLayouter[name] = layouter;
}
registerLayouter(name: string, layouter);
}
export const SV: StructV = function(DOMContainer: HTMLElement, engineOptions: EngineOptions = { }) {
return new Engine(DOMContainer, engineOptions);
}
SV.Group = Group;
SV.Bound = Bound;
SV.Vector = Vector;
SV.Mat3 = G6.Util.mat3;
SV.G6 = G6;
SV.registeredLayouter = {};
SV.registeredShape = [
externalPointer,
linkListNode,
binaryTreeNode,
twoCellNode,
indexedNode
];
SV.registerShape = G6.registerNode;
SV.registerLayouter = function(name: string, layouter) {
SV.registeredLayouter[name] = layouter;
};

View File

@ -102,8 +102,13 @@ import { Container } from "./container";
dragStartY = null;
g6Instance.on('node:dragstart', ev => {
const model = ev.item.getModel(),
dragNode = this.engine.optionsTable[model.SVLayouter].behavior.dragNode;
const model = ev.item.getModel();
if(model.SVModelType === 'pointer') {
return;
}
const dragNode = this.engine.optionsTable[model.SVLayouter].behavior.dragNode;
if(dragNode === false) {
return;

View File

@ -1,5 +1,6 @@
import { Bound, BoundingRect } from '../Common/boundingRect';
import { Group } from '../Common/group';
import { Vector } from '../Common/vector';
import { Engine } from '../engine';
import { LayoutGroupTable } from '../Model/modelConstructor';
import { Element, Model, Pointer } from '../Model/modelData';
@ -41,12 +42,24 @@ export class Layouter {
anchor = options.anchor || 0;
let target = item.target,
targetBound: BoundingRect = item.target.getBound(),
anchorPosition = item.target.G6Item.getAnchorPoints()[anchor];
targetBound: BoundingRect = target.getBound(),
anchorPosition = item.target.G6Item.getAnchorPoints()[anchor],
center: [number, number] = [targetBound.x + targetBound.width / 2, targetBound.y + targetBound.height / 2],
pointerPosition: [number, number];
anchorPosition = [anchorPosition.x, anchorPosition.y];
let anchorVector = Vector.subtract(anchorPosition, center),
angle = anchorVector[0] === 0? 0: (Math.PI / 2 - Math.atan(anchorVector[1] / anchorVector[0])),
len = Vector.length(anchorVector) + offset;
anchorVector = Vector.normalize(anchorVector);
pointerPosition = Vector.location(center, anchorVector, len);
item.set({
x: targetBound.x + targetBound.width / 2,
y: targetBound.y - offset
x: pointerPosition[0],
y: pointerPosition[1],
rotation: angle
});
});
}
@ -56,7 +69,7 @@ export class Layouter {
* @param container
* @param models
*/
private fitCenter(container: Container, group: Group) {
private fitCenter(container: Container, group: Group) {
let width = container.getG6Instance().getWidth(),
height = container.getG6Instance().getHeight(),
viewBound: BoundingRect = group.getBound(),
@ -151,7 +164,7 @@ export class Layouter {
* @param container
* @param layoutGroupTable
*/
public layoutAll(container: Container, layoutGroupTable: LayoutGroupTable) {
public layoutAll(container: Container, layoutGroupTable: LayoutGroupTable) {
layoutGroupTable.forEach(item => {
item.modelList.forEach(model => {
model.G6Item = model.shadowG6Item;

View File

@ -72,24 +72,30 @@ export class ViewManager {
*/
private getFreedConstructList(layoutGroupTable: LayoutGroupTable): Model[] {
let freedList: Model[] = [],
freedGroup = null,
freedGroupName = null;
freedGroup: LayoutGroup = null,
freedGroupName: string = null,
removeModels: Model[] = [];
for(let group in layoutGroupTable) {
let freedElements: Model[] = layoutGroupTable[group].element.filter(item => item.freed);
layoutGroupTable.forEach((group, key) => {
let freedElements: Model[] = group.element.filter(item => item.freed);
if(freedElements.length) {
freedGroupName = group;
break;
freedGroupName = key;
freedList = freedElements;
}
}
});
freedGroup = layoutGroupTable[freedGroupName];
freedGroup = layoutGroupTable.get(freedGroupName);
freedList.forEach(fItem => {
freedGroup.element.splice(freedGroup.element.findIndex(item => item.id === fItem.id), 1);
freedGroup.link.splice(freedGroup.link.findIndex(item => item.element.id === fItem.id || item.target.id === fItem.id));
freedGroup.pointer.splice(freedGroup.pointer.findIndex(item => item.target.id === fItem.id));
removeModels.push(...freedGroup.element.splice(freedGroup.element.findIndex(item => item.id === fItem.id), 1));
removeModels.push(...freedGroup.link.splice(freedGroup.link.findIndex(item => item.element.id === fItem.id || item.target.id === fItem.id)));
removeModels.push(...freedGroup.pointer.splice(freedGroup.pointer.findIndex(item => item.target.id === fItem.id)));
});
removeModels.map(model => {
const index = freedGroup.modelList.findIndex(item => item.id === model.id);
freedGroup.modelList.splice(index, 1);
});
return freedList;

View File

@ -18,7 +18,7 @@ export class Engine {
public optionsTable: { [key: string]: LayoutGroupOptions };
constructor(DOMContainer: HTMLElement, engineOptions: EngineOptions = { }) {
constructor(DOMContainer: HTMLElement, engineOptions: EngineOptions) {
this.optionsTable = {};
this.engineOptions = Object.assign({

View File

@ -36,7 +36,7 @@ export interface ElementOption {
type: string;
size: number | [number, number];
rotation: number;
anchorPoint: [number, number];
anchorPoints: [number, number];
label: string;
labelOptions: ElementLabelOption;
style: Style;