142 lines
4.0 KiB
TypeScript
142 lines
4.0 KiB
TypeScript
import { Engine } from '../engine';
|
||
import { SVModel } from '../Model/SVModel';
|
||
import { Util } from '../Common/util';
|
||
import G6 from '@antv/g6';
|
||
import { InitViewBehaviors } from '../BehaviorHelper/initViewBehaviors';
|
||
import { Graph, GraphData, IGroup } from '@antv/g6-pc';
|
||
|
||
|
||
|
||
export interface RenderModelPack {
|
||
leaKModels: SVModel[];
|
||
generalModel: SVModel[];
|
||
}
|
||
|
||
|
||
export type g6Behavior = string | { type: string; shouldBegin?: Function; shouldUpdate?: Function; shouldEnd?: Function; };
|
||
|
||
|
||
export class Renderer {
|
||
private engine: Engine;
|
||
private g6Instance: Graph; // g6 实例
|
||
private shadowG6Instance: Graph;
|
||
|
||
constructor(engine: Engine, DOMContainer: HTMLElement) {
|
||
this.engine = engine;
|
||
|
||
const enable: boolean = this.engine.animationOptions.enable,
|
||
duration: number = this.engine.animationOptions.duration,
|
||
timingFunction: string = this.engine.animationOptions.timingFunction;
|
||
|
||
const tooltip = new G6.Tooltip({
|
||
offsetX: 10,
|
||
offsetY: 20,
|
||
shouldBegin(event) {
|
||
return event.item['SVModel'].isNode();
|
||
},
|
||
getContent: event => this.getTooltipContent(event.item['SVModel'], { address: 'sourceId', data: 'data' }),
|
||
itemTypes: ['node']
|
||
});
|
||
|
||
this.shadowG6Instance = new G6.Graph({
|
||
container: DOMContainer.cloneNode() as HTMLElement
|
||
});
|
||
|
||
// 初始化g6实例
|
||
this.g6Instance = new G6.Graph({
|
||
container: DOMContainer,
|
||
width: DOMContainer.offsetWidth,
|
||
height: DOMContainer.offsetHeight,
|
||
groupByTypes: false,
|
||
animate: enable,
|
||
animateCfg: {
|
||
duration: duration,
|
||
easing: timingFunction
|
||
},
|
||
fitView: false,
|
||
modes: {
|
||
default: InitViewBehaviors()
|
||
},
|
||
plugins: [tooltip]
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 创造tooltip元素
|
||
* @param model
|
||
* @param items
|
||
* @returns
|
||
*/
|
||
private getTooltipContent(model: SVModel, items: { [key: string]: string }): HTMLDivElement {
|
||
const wrapper = document.createElement('div');
|
||
|
||
if(model === null || model === undefined) {
|
||
return wrapper;
|
||
}
|
||
|
||
Object.keys(items).map(key => {
|
||
let value = model[items[key]];
|
||
if (value !== undefined && value !== null) {
|
||
let item = document.createElement('div');
|
||
item.innerHTML = `${key}:${value}`;
|
||
wrapper.appendChild(item);
|
||
}
|
||
});
|
||
|
||
return wrapper;
|
||
}
|
||
|
||
/**
|
||
* 对每一个 model 在离屏 Canvas 上构建 G6 item,用作布局
|
||
* @param renderModelList
|
||
*/
|
||
public build(renderModelList: SVModel[]) {
|
||
const g6Data: GraphData = Util.convertModelList2G6Data(renderModelList);
|
||
|
||
this.shadowG6Instance.clear();
|
||
this.shadowG6Instance.read(g6Data);
|
||
renderModelList.forEach(item => {
|
||
item.shadowG6Item = this.shadowG6Instance.findById(item.id);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 渲染函数
|
||
* @param renderModelList
|
||
* @param isFirstRender
|
||
*/
|
||
public render(renderModelList: SVModel[]) {
|
||
const renderData: GraphData = Util.convertModelList2G6Data(renderModelList);
|
||
|
||
this.g6Instance.changeData(renderData);
|
||
|
||
renderModelList.forEach(item => {
|
||
item.G6Item = this.g6Instance.findById(item.id);
|
||
item.G6Item['SVModel'] = item;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 从视图中移除一个 Model
|
||
* @param model
|
||
*/
|
||
public removeModel(model: SVModel) {
|
||
this.g6Instance.removeItem(model.G6Item);
|
||
this.shadowG6Instance.removeItem(model.shadowG6Item);
|
||
}
|
||
|
||
/**
|
||
* 获取 G6 实例
|
||
*/
|
||
public getG6Instance() {
|
||
return this.g6Instance;
|
||
}
|
||
|
||
/**
|
||
* 销毁
|
||
*/
|
||
public destroy() {
|
||
this.shadowG6Instance.destroy();
|
||
this.g6Instance.destroy();
|
||
}
|
||
} |