fix:修复少量bug

This commit is contained in:
Phenom
2021-04-16 15:38:52 +08:00
parent 72fcf5394a
commit 0dcad0f117
18 changed files with 824 additions and 173 deletions
+2 -2
View File
@@ -96,8 +96,8 @@ export const Util = {
edges = Util.converterList(constructedData.link);
return {
nodes: nodes.map(item => item.props),
edges: edges.map(item => item.props)
nodes: nodes.map(item => item.cloneProps()),
edges: edges.map(item => item.cloneProps())
};
},
+53 -13
View File
@@ -14,9 +14,11 @@ export interface ConstructedData {
export class ModelConstructor {
private engine: Engine;
private constructedData: ConstructedData;
constructor(engine: Engine) {
this.engine = engine;
this.constructedData = null;
}
/**
@@ -28,11 +30,13 @@ export class ModelConstructor {
linkContainer = this.constructLinks(this.engine.linkOptions, elementContainer),
pointerContainer = this.constructPointers(this.engine.pointerOptions, elementContainer);
return {
this.constructedData = {
element: elementContainer,
link: linkContainer,
pointer: pointerContainer
};
return this.constructedData;
}
/**
@@ -88,12 +92,14 @@ export class ModelConstructor {
linkNames.forEach(name => {
for(let i = 0; i < elementList.length; i++) {
let element: Element = elementList[i],
sourceLinkData: sourceLinkData = element[name],
options: LinkOption = linkOptions[name],
sourceLinkData: sourceLinkData = element.sourceElement[name],
targetElement: Element | Element[] = null,
link: Link = null;
if(sourceLinkData === undefined || sourceLinkData === null) continue;
if(sourceLinkData === undefined || sourceLinkData === null) {
element[name] = null;
continue;
}
// ------------------- 将连接声明字段 sourceLinkData 从 id 变为 Element -------------------
if(Array.isArray(sourceLinkData)) {
@@ -101,9 +107,8 @@ export class ModelConstructor {
targetElement = this.fetchTargetElements(elementContainer, element, item);
if(targetElement) {
link = new Link(name, element, targetElement, index);
link = this.createLink(name, element, targetElement, index);
linkContainer[name].push(link);
link.initProps(options);
}
return targetElement;
@@ -111,11 +116,10 @@ export class ModelConstructor {
}
else {
targetElement = this.fetchTargetElements(elementContainer, element, sourceLinkData);
if(targetElement) {
link = new Link(name, element, targetElement, null);
link = this.createLink(name, element, targetElement, null);
linkContainer[name].push(link);
link.initProps(options);
}
element[name] = targetElement;
@@ -145,7 +149,7 @@ export class ModelConstructor {
});
pointerNames.forEach(name => {
let options = pointerOptions[name];
for(let i = 0; i < elementList.length; i++) {
let element = elementList[i],
@@ -155,9 +159,8 @@ export class ModelConstructor {
if(!pointerData) continue;
let id = name + '#' + (Array.isArray(pointerData)? pointerData.join('-'): pointerData),
pointer = new Pointer(id, name, pointerData, element);
pointer = this.createPointer(id, name, pointerData, element);
pointer.initProps(options);
pointerContainer[name].push(pointer);
}
});
@@ -172,15 +175,52 @@ export class ModelConstructor {
*/
private createElement(sourceElement: SourceElement, elementName: string): Element {
let elementOption = this.engine.elementOptions[elementName],
element = new Element(elementName, sourceElement),
element: Element = undefined,
label = elementOption.label? this.parserElementContent(sourceElement, elementOption.label): '';
element = new Element(elementName, sourceElement);
element.initProps(elementOption);
element.set('label', label);
element.sourceElement = sourceElement;
return element;
}
/**
* 外部指针工厂,创建Pointer
* @param id
* @param pointerName
* @param label
* @param target
*/
private createPointer(id: string, pointerName: string, pointerData: string | string[], target: Element): Pointer {
let options = this.engine.pointerOptions[pointerName],
pointer = undefined;
pointer = new Pointer(id, pointerName, pointerData, target);
pointer.initProps(options);
return pointer;
};
/**
* 连线工厂,创建Link
* @param linkName
* @param element
* @param target
* @param index
*/
private createLink(linkName: string, element: Element, target: Element, index: number): Link {
let options: LinkOption = this.engine.linkOptions[linkName],
link = undefined,
id = `${element.id}-${target.id}`;
link = new Link(id, linkName, element, target, index);
link.initProps(options);
return link;
}
/**
* 解析元素文本内容
* @param sourceElement
+58 -34
View File
@@ -16,6 +16,7 @@ export interface G6NodeModel {
style: Style;
labelCfg: ElementLabelOption;
externalPointerId: string;
modelType: string;
};
@@ -32,25 +33,50 @@ export interface G6EdgeModel {
};
class Model {
export class Model {
id: string;
name: string;
type: string;
props: G6NodeModel | G6EdgeModel;
shadowG6Item;
renderG6Item;
G6Item;
constructor(id: string, name: string) {
this.id = id;
this.name = name;
this.shadowG6Item = null;
this.renderG6Item = null;
this.G6Item = null;
this.props = null;
this.props = <G6NodeModel | G6EdgeModel>{ };
}
/**
* @override
* 定义 G6 model 的属性
* @param option
*/
protected defineProps(option: ElementOption | LinkOption | PointerOption): G6NodeModel | G6EdgeModel {
return null;
}
/**
* 初始化 G6 model 的属性
* @param option
*/
initProps(option: ElementOption | LinkOption | PointerOption) { }
initProps(option: ElementOption | LinkOption | PointerOption) {
this.props = this.defineProps(option);
}
/**
* 克隆 G6 model 的属性
* @returns
*/
cloneProps(): G6NodeModel | G6EdgeModel {
return Util.objectClone(this.props);
// return this.props;
}
/**
* 获取 G6 model 的属性
@@ -66,7 +92,14 @@ class Model {
* @param value
* @returns
*/
set(attr: string, value: any) {
set(attr: string | object, value?: any) {
if(typeof attr === 'object') {
Object.keys(attr).map(item => {
this.set(item, attr[item]);
});
return;
}
if(this.props[attr] === undefined) {
return;
}
@@ -111,17 +144,13 @@ class Model {
if(this.G6Item === null) return null;
return this.G6Item.getContainer().getMatrix();
}
/**
* 钩子函数:在获取 G6Item 后执行
*/
afterInitG6Item() {
this.set('rotation', this.get('rotation'));
}
}
export class Element extends Model {
type = 'element';
sourceElement: SourceElement;
constructor(type: string, sourceElement: SourceElement) {
super(sourceElement.id.toString(), type);
@@ -132,12 +161,8 @@ export class Element extends Model {
});
}
/**
* 初始化 G6 model 的属性
* @param option
*/
initProps(option: ElementOption) {
this.props = {
protected defineProps(option: ElementOption) {
return {
id: this.id,
x: 0,
y: 0,
@@ -148,7 +173,8 @@ export class Element extends Model {
label: null,
style: Util.objectClone<Style>(option.style),
labelCfg: Util.objectClone<ElementLabelOption>(option.labelOptions),
externalPointerId: null
externalPointerId: null,
modelType: this.type
};
}
};
@@ -156,22 +182,20 @@ export class Element extends Model {
export class Link extends Model {
type = 'link';
element: Element;
target: Element;
index: number;
constructor(type: string, element: Element, target: Element, index: number) {
super(`${element.id}-${target.id}`, type);
constructor(id: string, type: string, element: Element, target: Element, index: number) {
super(id, type);
this.element = element;
this.target = target;
this.index = index;
}
/**
* 初始化 G6 model 的属性
* @param option
*/
initProps(option: LinkOption) {
protected defineProps(option: LinkOption) {
let sourceAnchor = option.sourceAnchor,
targetAnchor = option.targetAnchor;
@@ -183,7 +207,7 @@ export class Link extends Model {
targetAnchor = option.targetAnchor(this.index);
}
this.props = {
return {
id: this.id,
type: option.type,
source: this.element.id,
@@ -198,7 +222,9 @@ export class Link extends Model {
};
export class Pointer extends Model {
type = 'pointer';
target: Element;
label: string | string[];
@@ -207,15 +233,12 @@ export class Pointer extends Model {
this.target = target;
this.label = label;
this.target.set('externalPointerId', id);
this.target.set('externalPointerId',
id);
}
/**
* 初始化 G6 model 的属性
* @param option
*/
initProps(option: ElementOption) {
this.props = {
protected defineProps(option: ElementOption) {
return {
id: this.id,
x: 0,
y: 0,
@@ -226,7 +249,8 @@ export class Pointer extends Model {
label: typeof this.label === 'string'? this.label: this.label.join(', '),
style: Util.objectClone<Style>(option.style),
labelCfg: Util.objectClone<ElementLabelOption>(option.labelOptions),
externalPointerId: null
externalPointerId: null,
modelType: this.type
};
}
};
+7 -3
View File
@@ -14,7 +14,8 @@ export default G6.registerNode('binary-tree-node', {
y: height / 2,
width: width,
height: height,
stroke: '#333',
stroke: cfg.style.stroke,
cursor: cfg.style.cursor,
fill: 'transparent'
},
name: 'wrapper'
@@ -26,7 +27,9 @@ export default G6.registerNode('binary-tree-node', {
y: height / 2,
width: width / 2,
height: height,
fill: cfg.style.fill
fill: cfg.style.fill,
stroke: cfg.style.stroke,
cursor: cfg.style.cursor
},
name: 'mid',
draggable: true
@@ -42,7 +45,8 @@ export default G6.registerNode('binary-tree-node', {
textBaseline: 'middle',
text: cfg.label,
fill: style.fill || '#000',
fontSize: style.fontSize || 16
fontSize: style.fontSize || 16,
cursor: cfg.style.cursor
},
name: 'text',
draggable: true
+12 -13
View File
@@ -14,50 +14,49 @@ export default G6.registerNode('link-list-node', {
y: height / 2,
width: width,
height: height,
stroke: '#ddd'
stroke: cfg.style.stroke,
fill: 'transparent'
},
name: 'wrapper'
});
group.addShape('rect', {
attrs: {
x: width / 3,
x: width / 2,
y: height / 2,
width: width * (2 / 3),
height: height,
fill: cfg.style.fill
fill: cfg.style.fill,
stroke: cfg.style.stroke
},
name: 'main-rect'
name: 'main-rect',
draggable: true
});
if (cfg.label) {
const style = (cfg.labelCfg && cfg.labelCfg.style) || {};
group.addShape('text', {
attrs: {
x: cfg.size[0] + 2, // 居中
y: -cfg.size[1],
x: width * (5 / 6),
y: height,
textAlign: 'center',
textBaseline: 'middle',
text: cfg.label,
fill: style.fill || '#000',
fontSize: style.fontSize || 16
},
name: 'pointer-text-shape',
draggable: false,
name: 'text',
draggable: true
});
}
return wrapperRect;
},
update(cfg, item) {
console.log(88);
},
getAnchorPoints() {
return [
[0, 0.5],
[2 / 3, 0.5]
[5 / 6, 0.5]
];
}
});
View File
+123
View File
@@ -0,0 +1,123 @@
import { Engine } from "../engine";
import { Util } from "./../Common/util";
export class Behavior {
private engine: Engine;
private graphInstance;
constructor(engine: Engine, graphInstance) {
this.engine = engine;
this.graphInstance = graphInstance;
const interactionOptions = this.engine.interactionOptions;
if(interactionOptions.dragNode) {
this.initDragNode();
}
if(interactionOptions.selectNode) {
this.initSelectNode();
}
}
/**
* 初始化节点拖拽事件
*/
private initDragNode() {
let pointer = null,
pointerX = null,
pointerY = null,
dragStartX = null,
dragStartY = null;
this.graphInstance.on('node:dragstart', ev => {
pointer = this.graphInstance.findById(ev.item.getModel().externalPointerId);
if(pointer) {
pointerX = pointer.getModel().x,
pointerY = pointer.getModel().y;
dragStartX = ev.canvasX;
dragStartY = ev.canvasY;
}
});
this.graphInstance.on('node:dragend', ev => {
pointer = null;
pointerX = null,
pointerY = null,
dragStartX = null,
dragStartY = null;
});
this.graphInstance.on('node:drag', ev => {
if(!pointer) {
return;
}
let dx = ev.canvasX - dragStartX,
dy = ev.canvasY - dragStartY,
zoom = this.graphInstance.getZoom();
pointer.updatePosition({
x: pointerX + dx / zoom,
y: pointerY + dy / zoom
});
});
}
/**
* 初始化节/边选中
*/
private initSelectNode() {
let defaultHighlightColor = '#f08a5d',
curSelectItem = null,
curSelectItemStyle = null;
const selectCallback = ev => {
const item = ev.item,
type = item.getType(),
highlightColor = item.getModel().style.selectedColor;
if(curSelectItem && curSelectItem !== item) {
curSelectItem.update({
style: curSelectItemStyle
});
}
curSelectItem = item;
curSelectItemStyle = Util.objectClone(curSelectItem.getModel().style);
curSelectItem.update({
style: {
...curSelectItemStyle,
[type === 'node'? 'fill': 'stroke']: highlightColor || defaultHighlightColor
}
});
};
this.graphInstance.on('node:click', selectCallback);
this.graphInstance.on('edge:click', selectCallback);
this.graphInstance.on('click', ev => {
if(curSelectItem === null) {
return;
}
curSelectItem.update({
style: curSelectItemStyle
});
curSelectItem = null;
curSelectItemStyle = null;
});
}
/**
* 绑定 G6 事件
* @param eventName
* @param callback
*/
public on(eventName: string, callback: Function) {
if(this.graphInstance) {
this.graphInstance.on(eventName, callback)
}
}
};
+34 -18
View File
@@ -1,7 +1,7 @@
import { Util } from "../Common/util";
import { Engine } from "../engine";
import { ConstructedData } from "../Model/modelConstructor";
import { Element, Pointer } from "../Model/modelData";
import { Element, Model, Pointer } from "../Model/modelData";
import { LayoutOptions, PointerOption } from "../options";
import { Bound, BoundingRect } from "./boundingRect";
@@ -10,31 +10,31 @@ import { Bound, BoundingRect } from "./boundingRect";
export class Layouter {
private engine: Engine;
private containerWidth: number;
private containerHeight: number;
constructor(engine: Engine, containerWidth: number, containerHeight: number) {
constructor(engine: Engine) {
this.engine = engine;
this.containerWidth = containerWidth;
this.containerHeight = containerHeight;
}
/**
* 将视图调整至画布中心
* @param nodes
*/
private fiTCenter(nodes: (Element | Pointer)[]) {
const viewBound: BoundingRect = nodes.map(item => item.getBound()).reduce((prev, cur) => Bound.union(prev, cur));
private fitCenter(models: Model[]) {
const viewBound: BoundingRect = models.map(item => item.getBound()).reduce((prev, cur) => Bound.union(prev, cur));
let centerX = this.containerWidth / 2, centerY = this.containerHeight / 2,
let width = this.engine.getGraphInstance().getWidth(),
height = this.engine.getGraphInstance().getHeight(),
centerX = width / 2, centerY = height / 2,
boundCenterX = viewBound.x + viewBound.width / 2,
boundCenterY = viewBound.y + viewBound.height / 2,
dx = centerX - boundCenterX,
dy = centerY - boundCenterY;
nodes.forEach(item => {
item.set('x', item.get('x') + dx);
item.set('y', item.get('y') + dy)
models.forEach(item => {
item.set({
x: item.get('x') + dx,
y: item.get('y') + dy
});
});
}
@@ -50,8 +50,10 @@ export class Layouter {
pointerList.forEach(item => {
let targetBound: BoundingRect = item.target.getBound();
item.set('x', targetBound.x + targetBound.width / 2);
item.set('y', targetBound.y - offset);
item.set({
x: targetBound.x + targetBound.width / 2,
y: targetBound.y - offset
});
});
});
}
@@ -59,11 +61,21 @@ export class Layouter {
/**
* 主布局函数
* @param constructedData
* @param modelList
* @param layoutFn
*/
public layout(constructedData: ConstructedData, layoutFn: (element: { [ket: string]: Element[] }, layoutOptions: LayoutOptions) => void) {
const options: LayoutOptions = this.engine.layoutOptions,
nodes: (Element | Pointer)[] = [...Util.converterList(constructedData.element), ...Util.converterList(constructedData.pointer)]
public layout(constructedData: ConstructedData, modelList: Model[], layoutFn: (element: { [ket: string]: Element[] }, layoutOptions: LayoutOptions) => void) {
const options: LayoutOptions = this.engine.layoutOptions;
// 首先初始化所有节点的坐标为0,且设定旋转
modelList.forEach(item => {
item.G6Item = item.shadowG6Item;
if(item.type === 'element' || item.type === 'pointer') {
item.set('rotation', item.get('rotation'));
item.set({ x: 0, y: 0 });
}
});
// 布局节点
layoutFn.call(this.engine, constructedData.element, options);
@@ -72,6 +84,10 @@ export class Layouter {
this.layoutPointer(constructedData.pointer);
// 将视图调整到画布中心
options.fitCenter && this.fiTCenter(nodes);
options.fitCenter && this.fitCenter(modelList);
modelList.forEach(item => {
item.G6Item = item.renderG6Item;
});
}
}
+55 -48
View File
@@ -4,6 +4,7 @@ import { ConstructedData } from '../Model/modelConstructor';
import { Util } from '../Common/util';
import { Animations } from './animation';
import { SV } from '../StructV';
import { Model } from './../Model/modelData';
@@ -21,12 +22,14 @@ export class Renderer {
private isFirstRender: boolean;
private prevRenderData: G6Data;
private graphInstance;
private helpGraphInstance;
private shadowGraphInstance;
private modelList: Model[];
constructor(engine: Engine, DOMContainer: HTMLElement, containerWidth: number, containerHeight: number) {
constructor(engine: Engine, DOMContainer: HTMLElement) {
this.engine = engine;
this.DOMContainer = DOMContainer;
this.isFirstRender = true;
this.modelList = [];
this.prevRenderData = {
nodes: [],
edges: []
@@ -34,12 +37,33 @@ export class Renderer {
const enable: boolean = this.engine.animationOptions.enable === undefined? true: this.engine.animationOptions.enable,
duration: number = this.engine.animationOptions.duration,
timingFunction: string = this.engine.animationOptions.timingFunction;
timingFunction: string = this.engine.animationOptions.timingFunction,
interactionOptions = this.engine.interactionOptions;
const modeMap = {
drag: 'drag-canvas',
zoom: 'zoom-canvas',
dragNode: {
type: 'drag-node',
shouldBegin: n => {
// 不允许拖拽外部指针
if (n.item && n.item.getModel().modelType === 'pointer') return false;
return true;
}
}
},
defaultModes = [];
Object.keys(interactionOptions).forEach(item => {
if(interactionOptions[item] === true && modeMap[item] !== undefined) {
defaultModes.push(modeMap[item]);
}
});
this.graphInstance = new SV.G6.Graph({
container: DOMContainer,
width: containerWidth,
height: containerHeight,
width: DOMContainer.offsetWidth,
height: DOMContainer.offsetHeight,
animate: enable,
animateCfg: {
duration: duration,
@@ -47,40 +71,15 @@ export class Renderer {
},
fitView: this.engine.layoutOptions.fitView,
modes: {
default: ['drag-canvas', 'zoom-canvas', 'drag-node']
default: defaultModes
}
});
this.helpGraphInstance = new SV.G6.Graph({
this.shadowGraphInstance = new SV.G6.Graph({
container: DOMContainer.cloneNode()
});
this.animations = new Animations(duration, timingFunction);
this.initBehavior();
}
/**
* 初始化交互
*/
private initBehavior() {
this.graphInstance.on('node:drag', (() => {
let pointer = null;
return ev => {
if(pointer === null) {
pointer = this.graphInstance.findById(ev.item.getModel().externalPointerId);
}
if(pointer) {
pointer.updatePosition({
x: ev.canvasX,
y: ev.canvasY
});
}
console.log(ev);
}
})());
}
/**
@@ -147,21 +146,21 @@ export class Renderer {
let elementList: Element[] = Util.converterList(constructedData.element),
linkList: Link[] = Util.converterList(constructedData.link),
pointerList: Pointer[] = Util.converterList(constructedData.pointer),
nodeList = [...elementList.map(item => item.props), ...pointerList.map(item => item.props)],
edgeList = linkList.map(item => item.props),
list = [...elementList, ...linkList, ...pointerList];
nodeList = [...elementList.map(item => item.cloneProps()), ...pointerList.map(item => item.cloneProps())],
edgeList = linkList.map(item => item.cloneProps());
this.modelList = [...elementList, ...linkList, ...pointerList];
const data: G6Data = {
nodes: <G6NodeModel[]>nodeList,
edges: <G6EdgeModel[]>edgeList
};
this.helpGraphInstance.clear();
this.helpGraphInstance.read(data);
this.shadowGraphInstance.clear();
this.shadowGraphInstance.read(data);
list.forEach(item => {
item.G6Item = this.helpGraphInstance.findById(item.id);
item.afterInitG6Item();
this.modelList.forEach(item => {
item.shadowG6Item = this.shadowGraphInstance.findById(item.id);
});
}
@@ -194,20 +193,28 @@ export class Renderer {
this.handleAppendItems(appendData);
this.handleRemoveItems(removeData);
if(this.engine.layoutOptions.fitView) {
this.graphInstance.fitView();
}
this.modelList.forEach(item => {
item.renderG6Item = this.graphInstance.findById(item.id);
item.G6Item = item.renderG6Item;
});
}
/**
* 绑定 G6 事件
* @param eventName
* @param callback
* 获取 model 队列
*/
public on(eventName: string, callback: Function) {
if(this.graphInstance) {
this.graphInstance.on(eventName, callback)
}
getModelList(): Model[] {
return this.modelList;
}
/**
* 获取 G6 实例
*/
public getGraphInstance() {
return this.graphInstance;
}
}
+93 -24
View File
@@ -1,9 +1,11 @@
import { Element } from "./Model/modelData";
import { Element, Pointer } from "./Model/modelData";
import { Sources } from "./sources";
import { ConstructedData, ModelConstructor } from "./Model/modelConstructor";
import { Renderer } from "./View/renderer";
import { AnimationOptions, ElementOption, LayoutOptions, LinkOption, Options, PointerOption } from "./options";
import { AnimationOptions, ElementOption, InteractionOptions, LayoutOptions, LinkOption, Options, PointerOption } from "./options";
import { Layouter } from "./View/layouter";
import { Behavior } from "./View/behavior";
import { Util } from "./Common/util";
export class Engine {
@@ -12,14 +14,16 @@ export class Engine {
private modelConstructor: ModelConstructor = null;
private layouter: Layouter = null;
private renderer: Renderer = null;
private containerWidth: number;
private containerHeight: number;
private behavior: Behavior;
private graphInstance;
private constructedData: ConstructedData;
public elementOptions: { [key: string]: ElementOption } = { };
public linkOptions: { [key: string]: LinkOption } = { };
public pointerOptions: { [key: string]: PointerOption } = { };
public layoutOptions: LayoutOptions = null;
public animationOptions: AnimationOptions = null;
public interactionOptions: InteractionOptions = null;
constructor(DOMContainer: HTMLElement) {
const options: Options = this.defineOptions();
@@ -36,15 +40,21 @@ export class Engine {
this.animationOptions = Object.assign({
enable: true,
duration: 750,
timingFunction: 'linearEasing'
timingFunction: 'easePolyOut'
}, options.animation);
this.containerWidth = DOMContainer.offsetWidth,
this.containerHeight = DOMContainer.offsetHeight;
this.interactionOptions = Object.assign({
drag: true,
zoom: true,
dragNode: true,
selectNode: true
}, options.interaction);
this.modelConstructor = new ModelConstructor(this);
this.layouter = new Layouter(this, this.containerWidth, this.containerHeight);
this.renderer = new Renderer(this, DOMContainer, this.containerWidth, this.containerHeight);
this.layouter = new Layouter(this);
this.renderer = new Renderer(this, DOMContainer);
this.graphInstance = this.renderer.getGraphInstance();
this.behavior = new Behavior(this, this.renderer.getGraphInstance());
}
/**
@@ -61,20 +71,20 @@ export class Engine {
if(stringifySources === this.stringifySources) return;
this.stringifySources = stringifySources;
const constructedData: ConstructedData = this.modelConstructor.construct(sourceData);
this.constructedData = this.modelConstructor.construct(sourceData);
this.renderer.build(constructedData);
this.renderer.build(this.constructedData);
this.layouter.layout(constructedData, this.layout);
this.layouter.layout(this.constructedData, this.renderer.getModelList(), this.layout);
this.renderer.render(constructedData);
this.renderer.render(this.constructedData);
}
/**
* 定义配置项
* @returns
*/
public defineOptions(): Options {
protected defineOptions(): Options {
return null;
}
@@ -82,17 +92,64 @@ export class Engine {
* 设置布局函数
* @overwrite
*/
public layout(elementContainer: { [ket: string]: Element[] }, layoutOptions: LayoutOptions) { }
protected layout(elementContainer: { [ket: string]: Element[] }, layoutOptions: LayoutOptions) { }
/**
* 获取容器尺寸
* @returns
* 重新布局
*/
public getContainerSize(): { width: number, height: number } {
return {
width: this.containerWidth,
height: this.containerHeight
};
public reLayout() {
const modelList = this.renderer.getModelList();
this.layouter.layout(this.constructedData, modelList, this.layout);
modelList.forEach(item => {
if(item.type === 'link') return;
let model = item.G6Item.getModel(),
x = item.get('x'),
y = item.get('y');
model.x = x;
model.y = y;
});
this.graphInstance.refresh();
}
/**
* 获取 G6 实例
*/
public getGraphInstance() {
return this.graphInstance;
}
/**
* 获取所有 element
*/
public getElements(): Element[] {
return Util.converterList(this.constructedData.element);
}
/**
* 获取所有 pointer
*/
public getPointers(): Pointer[] {
return Util.converterList(this.constructedData.pointer);
}
/**
* 获取所有 link
*/
public getLinks() {
return Util.converterList(this.constructedData.link);
}
/**
* 调整容器尺寸
* @param width
* @param height
*/
public resize(width: number, height: number) {
this.graphInstance.changeSize(width, height);
}
/**
@@ -100,7 +157,19 @@ export class Engine {
* @param eventName
* @param callback
*/
public on(eventName: string, callback: Function) {
this.renderer.on(eventName, callback);
public on(eventName: string, callback: Function) {
this.behavior.on(eventName, callback);
}
/**
* 销毁引擎
*/
public destroy() {
this.graphInstance.destroy();
this.modelConstructor = null;
this.layouter = null;
this.renderer = null;
this.behavior = null;
this.graphInstance = null;
}
};
+9
View File
@@ -71,12 +71,21 @@ export interface AnimationOptions {
};
export interface InteractionOptions {
drag: boolean;
zoom: boolean;
dragNode: boolean;
selectNode: boolean;
};
export interface Options {
element: { [key: string]: ElementOption };
link?: { [key: string]: LinkOption }
pointer?: { [key: string]: PointerOption };
layout?: LayoutOptions;
animation?: AnimationOptions;
interaction?: InteractionOptions;
};