feature:添加泄漏区功能部分
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
import { Vector } from "./vector";
|
||||
|
||||
|
||||
|
||||
// 包围盒类型
|
||||
export type BoundingRect = {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
|
||||
// 包围盒操作
|
||||
export const Bound = {
|
||||
|
||||
/**
|
||||
* 从点集生成包围盒
|
||||
* @param points
|
||||
*/
|
||||
fromPoints(points: Array<[number, number]>): BoundingRect {
|
||||
let maxX = -Infinity,
|
||||
minX = Infinity,
|
||||
maxY = -Infinity,
|
||||
minY = Infinity;
|
||||
|
||||
points.map(item => {
|
||||
if(item[0] > maxX) maxX = item[0];
|
||||
if(item[0] < minX) minX = item[0];
|
||||
if(item[1] > maxY) maxY = item[1];
|
||||
if(item[1] < minY) minY = item[1];
|
||||
});
|
||||
|
||||
return {
|
||||
x: minX,
|
||||
y: minY,
|
||||
width: maxX - minX,
|
||||
height: maxY - minY
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 由包围盒转化为四个顶点(顺时针)
|
||||
* @param bound
|
||||
*/
|
||||
toPoints(bound: BoundingRect): Array<[number, number]> {
|
||||
return [
|
||||
[bound.x, bound.y],
|
||||
[bound.x + bound.width, bound.y],
|
||||
[bound.x + bound.width, bound.y + bound.height],
|
||||
[bound.x, bound.y + bound.height]
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* 求包围盒并集
|
||||
* @param arg
|
||||
*/
|
||||
union(...arg: BoundingRect[]): BoundingRect {
|
||||
return arg.length > 1?
|
||||
arg.reduce((total, cur) => {
|
||||
let minX = total.x < cur.x? total.x: cur.x,
|
||||
maxX = total.x + total.width < cur.x + cur.width? cur.x + cur.width: total.x + total.width,
|
||||
minY = total.y < cur.y? total.y: cur.y,
|
||||
maxY = total.y + total.height < cur.y + cur.height? cur.y + cur.height: total.y + total.height;
|
||||
|
||||
return {
|
||||
x: minX,
|
||||
y: minY,
|
||||
width: maxX - minX,
|
||||
height: maxY - minY
|
||||
};
|
||||
}): arg[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* 包围盒求交集
|
||||
* @param b1
|
||||
* @param b2
|
||||
*/
|
||||
intersect(b1: BoundingRect, b2: BoundingRect): BoundingRect {
|
||||
let x, y,
|
||||
maxX, maxY,
|
||||
overlapsX,
|
||||
overlapsY;
|
||||
|
||||
if(b1.x < b2.x + b2.width && b1.x + b1.width > b2.x) {
|
||||
x = b1.x < b2.x? b2.x: b1.x;
|
||||
maxX = b1.x + b1.width < b2.x + b2.width? b1.x + b1.width: b2.x + b2.width;
|
||||
overlapsX = maxX - x;
|
||||
}
|
||||
|
||||
if(b1.y < b2.y + b2.height && b1.y + b1.height > b2.y) {
|
||||
y = b1.y < b2.y? b2.y: b1.y;
|
||||
maxY = b1.y + b1.height < b2.y + b2.height? b1.y + b1.height: b2.y + b2.height;
|
||||
overlapsY = maxY - y;
|
||||
}
|
||||
|
||||
if(!overlapsX || !overlapsY) return null;
|
||||
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
width: overlapsX,
|
||||
height: overlapsY
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 求包围盒旋转后新形成的包围盒
|
||||
* @param bound
|
||||
* @param rot
|
||||
*/
|
||||
rotation(bound: BoundingRect, rot: number): BoundingRect {
|
||||
let cx = bound.x + bound.width / 2,
|
||||
cy = bound.y + bound.height / 2;
|
||||
|
||||
return Bound.fromPoints(Bound.toPoints(bound).map(item => Vector.rotation(rot, item, [cx, cy])));
|
||||
},
|
||||
|
||||
/**
|
||||
* 判断两个包围盒是否相交
|
||||
* @param b1
|
||||
* @param b2
|
||||
*/
|
||||
isOverlap(b1: BoundingRect, b2: BoundingRect): boolean {
|
||||
let maxX1 = b1.x + b1.width,
|
||||
maxY1 = b1.y + b1.height,
|
||||
maxX2 = b2.x + b2.width,
|
||||
maxY2 = b2.y + b2.height;
|
||||
|
||||
if (b1.x < maxX2 && b2.x < maxX1 && b1.y < maxY2 && b2.y < maxY1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
import { Util } from "./util";
|
||||
import { BoundingRect, Bound } from "./boundingRect";
|
||||
import { Vector } from "./vector";
|
||||
import { Element } from "../Model/modelData";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* element组
|
||||
*/
|
||||
export class Group {
|
||||
id: string;
|
||||
private elements: Array<Element | Group> = [];
|
||||
|
||||
constructor(...arg: Array<Element | Group>) {
|
||||
this.id = Util.generateId();
|
||||
|
||||
if(arg) {
|
||||
this.add(...arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加element
|
||||
* @param arg
|
||||
*/
|
||||
add(...arg: Array<Element | Group>) {
|
||||
arg.map(ele => {
|
||||
this.elements.push(ele);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除element
|
||||
* @param element
|
||||
*/
|
||||
remove(element: Element | Group) {
|
||||
Util.removeFromList(this.elements, item => item.id === element.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取group的包围盒
|
||||
*/
|
||||
getBound(): BoundingRect {
|
||||
return Bound.union(...this.elements.map(item => item.getBound()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 位移group
|
||||
* @param dx
|
||||
* @param dy
|
||||
*/
|
||||
translate(dx: number, dy: number) {
|
||||
this.elements.map(item => {
|
||||
if(item instanceof Group) {
|
||||
item.translate(dx, dy);
|
||||
}
|
||||
else {
|
||||
item.set('x', item.get('x') + dx);
|
||||
item.set('y', item.get('y') + dy);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转group
|
||||
* @param rotation
|
||||
* @param center
|
||||
*/
|
||||
rotate(rotation: number, center?: [number, number]) {
|
||||
// if(rotation === 0) return;
|
||||
|
||||
// let {x, y, width, height} = this.getBound(),
|
||||
// cx = x + width / 2,
|
||||
// cy = y + height / 2;
|
||||
|
||||
// if(center) {
|
||||
// cx = center[0];
|
||||
// cy = center[1];
|
||||
// }
|
||||
|
||||
// this.elements.map(item => {
|
||||
// if(item instanceof Group) {
|
||||
// item.rotate(rotation, [cx, cy]);
|
||||
// }
|
||||
// else {
|
||||
// let d = Vector.rotation(rotation, [item.x, item.y], [cx, cy]);
|
||||
// item.x = d[0];
|
||||
// item.y = d[1];
|
||||
// item.set('rotation', rotation);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空group
|
||||
*/
|
||||
clear() {
|
||||
this.elements.length = 0;
|
||||
}
|
||||
}
|
||||
+22
-11
@@ -1,4 +1,5 @@
|
||||
import { ConstructedData } from "../Model/modelConstructor";
|
||||
import { ConstructList } from "../Model/modelConstructor";
|
||||
import { G6EdgeModel, G6NodeModel, Link, Model } from "../Model/modelData";
|
||||
import { SV } from "../StructV";
|
||||
import { G6Data } from "../View/renderer";
|
||||
|
||||
@@ -8,7 +9,6 @@ import { G6Data } from "../View/renderer";
|
||||
*/
|
||||
export const Util = {
|
||||
|
||||
|
||||
/**
|
||||
* 生成唯一id
|
||||
*/
|
||||
@@ -78,28 +78,39 @@ export const Util = {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param constructedDataType
|
||||
* @param constructListType
|
||||
* @returns
|
||||
*/
|
||||
converterList(constructedDataType: ConstructedData[keyof ConstructedData]) {
|
||||
return [].concat(...Object.keys(constructedDataType).map(item => constructedDataType[item]));
|
||||
converterList(modelContainer: { [key: string]: ConstructList[keyof ConstructList]}) {
|
||||
return [].concat(...Object.keys(modelContainer).map(item => modelContainer[item]));
|
||||
},
|
||||
|
||||
/**
|
||||
* G6 data 转换器
|
||||
* @param constructedData
|
||||
* @param constructList
|
||||
* @returns
|
||||
*/
|
||||
convertG6Data(constructedData: ConstructedData): G6Data {
|
||||
let nodes = [...Util.converterList(constructedData.element), ...Util.converterList(constructedData.pointer)],
|
||||
edges = Util.converterList(constructedData.link);
|
||||
convertG6Data(constructList: ConstructList): G6Data {
|
||||
let nodes = [...constructList.element, ...constructList.pointer],
|
||||
edges = constructList.link;
|
||||
|
||||
return {
|
||||
nodes: nodes.map(item => item.cloneProps()),
|
||||
edges: edges.map(item => item.cloneProps())
|
||||
nodes: nodes.map(item => item.cloneProps()) as G6NodeModel[],
|
||||
edges: edges.map(item => item.cloneProps()) as G6EdgeModel[]
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 将 modelList 转换到 G6Data
|
||||
* @param modelList
|
||||
*/
|
||||
convertModelList2G6Data(modelList: Model[]): G6Data {
|
||||
return {
|
||||
nodes: <G6NodeModel[]>(modelList.filter(item => !(item instanceof Link)).map(item => item.cloneProps())),
|
||||
edges: <G6EdgeModel[]>(modelList.filter(item => item instanceof Link).map(item => item.cloneProps()))
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 计算旋转矩阵
|
||||
* @param matrix
|
||||
|
||||
Reference in New Issue
Block a user