fix: 修复泄漏区布局问题

This commit is contained in:
黎智洲 2022-02-25 18:30:41 +08:00
parent 7bba64cc9e
commit dd219ce946
7 changed files with 293 additions and 285 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules node_modules
test test
dist

View File

@ -129,7 +129,6 @@ SV.registerLayout('BinaryTree', {
*/ */
layout(elements, layoutOptions) { layout(elements, layoutOptions) {
let root = elements[0]; let root = elements[0];
let visited = new Group();
this.layoutItem(root, null, -1, layoutOptions); this.layoutItem(root, null, -1, layoutOptions);
} }
}); });

6
dist/sv.js vendored

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,6 @@ import { SVAddressLabel, SVFreedLabel, SVIndexLabel, SVMarker } from '../Model/S
import { AddressLabelOption, IndexLabelOption, LayoutOptions, MarkerOption, ViewOptions } from '../options'; import { AddressLabelOption, IndexLabelOption, LayoutOptions, MarkerOption, ViewOptions } from '../options';
import { ViewContainer } from './viewContainer'; import { ViewContainer } from './viewContainer';
export class LayoutProvider { export class LayoutProvider {
private engine: Engine; private engine: Engine;
private viewOptions: ViewOptions; private viewOptions: ViewOptions;
@ -22,7 +21,6 @@ export class LayoutProvider {
this.viewContainer = viewContainer; this.viewContainer = viewContainer;
} }
/** /**
* *
* @param layoutGroupTable * @param layoutGroupTable
@ -70,19 +68,22 @@ export class LayoutProvider {
let target = item.target, let target = item.target,
targetBound: BoundingRect = target.getBound(), targetBound: BoundingRect = target.getBound(),
g6AnchorPosition = item.target.shadowG6Item.getAnchorPoints()[anchor] as IPoint, g6AnchorPosition = item.target.shadowG6Item.getAnchorPoints()[anchor] as IPoint,
center: [number, number] = [targetBound.x + targetBound.width / 2, targetBound.y + targetBound.height / 2], center: [number, number] = [
targetBound.x + targetBound.width / 2,
targetBound.y + targetBound.height / 2,
],
markerPosition: [number, number], markerPosition: [number, number],
markerEndPosition: [number, number]; markerEndPosition: [number, number];
let anchorPosition: [number, number] = [g6AnchorPosition.x, g6AnchorPosition.y]; let anchorPosition: [number, number] = [g6AnchorPosition.x, g6AnchorPosition.y];
let anchorVector = Vector.subtract(anchorPosition, center), let anchorVector = Vector.subtract(anchorPosition, center),
angle = 0, len = Vector.length(anchorVector) + offset; angle = 0,
len = Vector.length(anchorVector) + offset;
if (anchorVector[0] === 0) { if (anchorVector[0] === 0) {
angle = anchorVector[1] > 0 ? -Math.PI : 0; angle = anchorVector[1] > 0 ? -Math.PI : 0;
} } else {
else {
angle = Math.sign(anchorVector[0]) * (Math.PI / 2 - Math.atan(anchorVector[1] / anchorVector[0])); angle = Math.sign(anchorVector[0]) * (Math.PI / 2 - Math.atan(anchorVector[1] / anchorVector[0]));
} }
@ -98,7 +99,7 @@ export class LayoutProvider {
x: markerPosition[0], x: markerPosition[0],
y: markerPosition[1], y: markerPosition[1],
rotation: angle, rotation: angle,
markerEndPosition markerEndPosition,
}); });
}); });
} }
@ -114,7 +115,7 @@ export class LayoutProvider {
item.set({ item.set({
x: freedNodeBound.x + freedNodeBound.width / 2, x: freedNodeBound.x + freedNodeBound.width / 2,
y: freedNodeBound.y + freedNodeBound.height * 1.5, y: freedNodeBound.y + freedNodeBound.height * 1.5,
size: [freedNodeBound.width, 0] size: [freedNodeBound.width, 0],
}); });
}); });
} }
@ -125,31 +126,37 @@ export class LayoutProvider {
* @param indexLabelOptions * @param indexLabelOptions
*/ */
private layoutIndexLabel(indexLabels: SVIndexLabel[], indexLabelOptions: { [key: string]: IndexLabelOption }) { private layoutIndexLabel(indexLabels: SVIndexLabel[], indexLabelOptions: { [key: string]: IndexLabelOption }) {
const indexLabelPositionMap: { [key: string]: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => { x: number, y: number } } = { const indexLabelPositionMap: {
[key: string]: (
nodeBound: BoundingRect,
labelBound: BoundingRect,
offset: number
) => { x: number; y: number };
} = {
top: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => { top: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => {
return { return {
x: nodeBound.x + nodeBound.width / 2, x: nodeBound.x + nodeBound.width / 2,
y: nodeBound.y - offset y: nodeBound.y - offset,
}; };
}, },
right: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => { right: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => {
return { return {
x: nodeBound.x + nodeBound.width + offset, x: nodeBound.x + nodeBound.width + offset,
y: nodeBound.y + nodeBound.height / 2 y: nodeBound.y + nodeBound.height / 2,
}; };
}, },
bottom: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => { bottom: (nodeBound: BoundingRect, labelBound: BoundingRect, offset: number) => {
return { return {
x: nodeBound.x + nodeBound.width / 2, x: nodeBound.x + nodeBound.width / 2,
y: nodeBound.y + nodeBound.height + offset y: nodeBound.y + nodeBound.height + offset,
}; };
}, },
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 - offset,
y: nodeBound.y + nodeBound.height / 2 y: nodeBound.y + nodeBound.height / 2,
}; };
} },
}; };
indexLabels.forEach(item => { indexLabels.forEach(item => {
@ -176,12 +183,11 @@ export class LayoutProvider {
item.set({ item.set({
x: nodeBound.x + nodeBound.width / 2, x: nodeBound.x + nodeBound.width / 2,
y: nodeBound.y - offset y: nodeBound.y - offset,
}); });
}); });
} }
/** /**
* model进行布局 * model进行布局
* @param layoutGroupTable * @param layoutGroupTable
@ -235,13 +241,13 @@ export class LayoutProvider {
leakModels.forEach(item => { leakModels.forEach(item => {
item.set({ item.set({
x: item.layoutX, x: item.layoutX,
y: item.layoutY y: item.layoutY,
}); });
}); });
const globalLeakGroupBound: BoundingRect = accumulateLeakModels.length ? const globalLeakGroupBound: BoundingRect = accumulateLeakModels.length
Bound.union(...accumulateLeakModels.map(item => item.getBound())) : ? Bound.union(...accumulateLeakModels.map(item => item.getBound()))
{ x: 0, y: leakAreaY, width: 0, height: 0 }; : { x: 0, y: leakAreaY, width: 0, height: 0 };
const layoutGroups = Util.groupBy(leakModels, 'group'); const layoutGroups = Util.groupBy(leakModels, 'group');
Object.keys(layoutGroups).forEach(key => { Object.keys(layoutGroups).forEach(key => {
@ -280,8 +286,7 @@ export class LayoutProvider {
if (prevBound) { if (prevBound) {
dx = prevBound.x + prevBound.width - bound.x; dx = prevBound.x + prevBound.width - bound.x;
} } else {
else {
dx = bound.x; dx = bound.x;
} }
@ -295,7 +300,6 @@ export class LayoutProvider {
return wrapperGroup; return wrapperGroup;
} }
/** /**
* *
* @param models * @param models
@ -304,24 +308,27 @@ export class LayoutProvider {
private fitCenter(group: Group) { private fitCenter(group: Group) {
let width = this.viewContainer.getG6Instance().getWidth(), let width = this.viewContainer.getG6Instance().getWidth(),
height = this.viewContainer.getG6Instance().getHeight(), height = this.viewContainer.getG6Instance().getHeight(),
viewBound: BoundingRect = group.getBound(),
leakAreaHeight = this.engine.viewOptions.leakAreaHeight; leakAreaHeight = this.engine.viewOptions.leakAreaHeight;
if (this.viewContainer.hasLeak) { const centerX = width / 2,
height = height - leakAreaHeight; centerY = height / 2,
} boundCenterX = viewBound.x + viewBound.width / 2;
const viewBound: BoundingRect = group.getBound(), let dx = centerX - boundCenterX,
centerX = width / 2, centerY = height / 2, dy = 0;
boundCenterX = viewBound.x + viewBound.width / 2,
boundCenterY = viewBound.y + viewBound.height / 2, if (this.viewContainer.hasLeak) {
dx = centerX - boundCenterX, const boundBottomY = viewBound.y + viewBound.height;
dy = height - leakAreaHeight - 100 - boundBottomY;
} else {
const boundCenterY = viewBound.y + viewBound.height / 2;
dy = centerY - boundCenterY; dy = centerY - boundCenterY;
}
group.translate(dx, dy); group.translate(dx, dy);
} }
/** /**
* *
* @param layoutGroupTable * @param layoutGroupTable

View File

@ -140,7 +140,7 @@ export class ViewContainer {
* @param models * @param models
* @param layoutFn * @param layoutFn
*/ */
render(layoutGroupTable: LayoutGroupTable) { render(layoutGroupTable: LayoutGroupTable, a: boolean) {
const modelList = Util.convertGroupTable2ModelList(layoutGroupTable), const modelList = Util.convertGroupTable2ModelList(layoutGroupTable),
diffResult = this.reconcile.diff(this.layoutGroupTable, this.prevModelList, modelList, this.accumulateLeakModels), diffResult = this.reconcile.diff(this.layoutGroupTable, this.prevModelList, modelList, this.accumulateLeakModels),
renderModelList = [ renderModelList = [

View File

@ -67,7 +67,7 @@ export class Engine {
const layoutGroupTable = this.modelConstructor.construct(source); const layoutGroupTable = this.modelConstructor.construct(source);
// 2 渲染使用g6进行渲染 // 2 渲染使用g6进行渲染
this.viewContainer.render(layoutGroupTable); this.viewContainer.render(layoutGroupTable, source.enterFunction as boolean);
} }

View File

@ -16,6 +16,7 @@ export interface SourceNode {
export type Sources = { export type Sources = {
enterFunction: any;
[key: string]: { [key: string]: {
data: SourceNode[]; data: SourceNode[];
layouter: string; layouter: string;