This commit is contained in:
黎智洲 2022-04-13 18:23:07 +08:00
parent 3fbc12b8b5
commit 50efbad66b
5 changed files with 172 additions and 165 deletions

View File

@ -61,7 +61,7 @@ export function InitG6Behaviors(engine: Engine, viewContainer: ViewContainer): M
let node: SVNode = g6Item.SVModel; let node: SVNode = g6Item.SVModel;
if (g6Item === null || node.isNode() === false) { if (node.isNode() === false) {
return false; return false;
} }

View File

@ -256,20 +256,24 @@ export class Reconcile {
let { duration, timingFunction } = this.engine.animationOptions; let { duration, timingFunction } = this.engine.animationOptions;
appendModels.forEach(item => { appendModels.forEach(item => {
const G6Item = item.G6Item;
if (item instanceof SVNodeAppendage) { if (item instanceof SVNodeAppendage) {
G6Item.enableCapture(false);
// 先不显示泄漏区节点上面的地址文本 // 先不显示泄漏区节点上面的地址文本
if (item instanceof SVAddressLabel) { if (item instanceof SVAddressLabel) {
// 先将透明度改为0隐藏掉 // 先将透明度改为0隐藏掉
const AddressLabelG6Group = item.G6Item.getContainer(); const AddressLabelG6Group = G6Item.getContainer();
AddressLabelG6Group.attr({ opacity: 0 }); AddressLabelG6Group.attr({ opacity: 0 });
} else { } else {
Animations.FADE_IN(item.G6Item, { Animations.FADE_IN(G6Item, {
duration, duration,
timingFunction, timingFunction,
}); });
} }
} else { } else {
Animations.APPEND(item.G6Item, { Animations.APPEND(G6Item, {
duration, duration,
timingFunction, timingFunction,
callback: () => item.afterRender(), callback: () => item.afterRender(),

View File

@ -14,183 +14,185 @@ export type g6Behavior =
| { type: string; shouldBegin?: Function; shouldUpdate?: Function; shouldEnd?: Function }; | { type: string; shouldBegin?: Function; shouldUpdate?: Function; shouldEnd?: Function };
export class Renderer { export class Renderer {
private engine: Engine; private engine: Engine;
private g6Instance: Graph; // g6 实例 private g6Instance: Graph; // g6 实例
private shadowG6Instance: Graph; private shadowG6Instance: Graph;
constructor(engine: Engine, DOMContainer: HTMLElement, behaviorsModes: Modes, isForce: boolean) { constructor(engine: Engine, DOMContainer: HTMLElement, behaviorsModes: Modes, isForce: boolean) {
this.engine = engine; this.engine = engine;
const enable: boolean = this.engine.animationOptions.enable, const enable: boolean = this.engine.animationOptions.enable,
duration: number = this.engine.animationOptions.duration, duration: number = this.engine.animationOptions.duration,
timingFunction: string = this.engine.animationOptions.timingFunction; timingFunction: string = this.engine.animationOptions.timingFunction;
const tooltip = new Tooltip({ const tooltip = new Tooltip({
offsetX: 10, offsetX: 10,
offsetY: 20, offsetY: 20,
shouldBegin(event) { shouldBegin(event) {
return event.item['SVModel'].isNode(); return event.item['SVModel'].isNode();
}, },
getContent: event => this.getTooltipContent(event.item['SVModel'], { address: 'sourceId', data: 'data' }), getContent: event => this.getTooltipContent(event.item['SVModel'], { address: 'sourceId', data: 'data' }),
itemTypes: ['node'] itemTypes: ['node'],
}); });
this.shadowG6Instance = new Graph({ this.shadowG6Instance = new Graph({
container: DOMContainer.cloneNode() as HTMLElement container: DOMContainer.cloneNode() as HTMLElement,
}); });
// 力导向的配置选项 // 力导向的配置选项
const forceOption = { const forceOption = {
type: 'force', type: 'force',
linkDistance: 100, // 边长 linkDistance: 100, // 边长
preventOverlap: true, // boolean防止节点重叠 preventOverlap: true, // boolean防止节点重叠
// alphaDecay: 0, // 迭代阈值的衰减率。范围 [0, 1]。默认值0.028 // alphaDecay: 0, // 迭代阈值的衰减率。范围 [0, 1]。默认值0.028
workEnabled: true, // 启用以防布局计算时间过长阻塞页面交互 workEnabled: true, // 启用以防布局计算时间过长阻塞页面交互
nodeStrength: -1, // 节点作用力,正数标识引力,负数表示斥力 nodeStrength: -1, // 节点作用力,正数标识引力,负数表示斥力
nodeSpacing: (d) => { // 设置了防止重叠后,节点边缘间距的最小值 nodeSpacing: d => {
return 20; // 设置了防止重叠后,节点边缘间距的最小值
}, return 20;
center: [DOMContainer.offsetWidth / 2, DOMContainer.offsetHeight / 3], },
}; center: [DOMContainer.offsetWidth / 2, DOMContainer.offsetHeight / 3],
// 布局配置 };
const layout = isForce ? forceOption : null; // 布局配置
// 初始化g6实例 const layout = isForce ? forceOption : null;
this.g6Instance = new Graph({ // 初始化g6实例
container: DOMContainer, this.g6Instance = new Graph({
width: DOMContainer.offsetWidth, container: DOMContainer,
height: DOMContainer.offsetHeight, width: DOMContainer.offsetWidth,
groupByTypes: false, height: DOMContainer.offsetHeight,
animate: enable, groupByTypes: false,
animateCfg: { animate: enable,
duration: duration, animateCfg: {
easing: timingFunction duration: duration,
}, easing: timingFunction,
modes: behaviorsModes, },
plugins: [tooltip], modes: behaviorsModes,
layout, // 布局配置 plugins: [tooltip],
}); layout, // 布局配置
/** });
* /**
*/ *
function refreshDragedNodePosition(e) { */
const model = e.item.get('model'); function refreshDragedNodePosition(e) {
model.fx = e.x; const model = e.item.get('model');
model.fy = e.y; model.fx = e.x;
} model.fy = e.y;
this.g6Instance.on('node:dragstart', (e) => { }
this.g6Instance.layout(); this.g6Instance.on('node:dragstart', e => {
refreshDragedNodePosition(e); this.g6Instance.layout();
}); refreshDragedNodePosition(e);
this.g6Instance.on('node:drag', (e) => { });
refreshDragedNodePosition(e); this.g6Instance.on('node:drag', e => {
}); refreshDragedNodePosition(e);
if (typeof window !== 'undefined') { });
window.onresize = () => { if (typeof window !== 'undefined') {
if (!this.g6Instance || this.g6Instance.get('destroyed')) return; window.onresize = () => {
if (!DOMContainer || !DOMContainer.scrollWidth || !DOMContainer.scrollHeight) return; if (!this.g6Instance || this.g6Instance.get('destroyed')) return;
this.g6Instance.changeSize(DOMContainer.scrollWidth, DOMContainer.scrollHeight); if (!DOMContainer || !DOMContainer.scrollWidth || !DOMContainer.scrollHeight) return;
}; this.g6Instance.changeSize(DOMContainer.scrollWidth, DOMContainer.scrollHeight);
} };
} }
}
/** /**
* tooltip元素 * tooltip元素
* @param model * @param model
* @param items * @param items
* @returns * @returns
*/ */
private getTooltipContent(model: SVModel, items: { [key: string]: string }): HTMLDivElement { private getTooltipContent(model: SVModel, items: { [key: string]: string }): HTMLDivElement {
const wrapper = document.createElement('div'); const wrapper = document.createElement('div');
if (model === null || model === undefined) { if (model === null || model === undefined) {
return wrapper; return wrapper;
} }
Object.keys(items).map(key => { Object.keys(items).map(key => {
let value = model[items[key]]; let value = model[items[key]];
if (value !== undefined && value !== null) { if (value !== undefined && value !== null) {
let item = document.createElement('div'); let item = document.createElement('div');
item.innerHTML = `${key}${value}`; item.innerHTML = `${key}${value}`;
wrapper.appendChild(item); wrapper.appendChild(item);
} }
}); });
return wrapper; return wrapper;
} }
/** /**
* model Canvas G6 item * model Canvas G6 item
* @param renderModelList * @param renderModelList
*/ */
public build(renderModelList: SVModel[]) { public build(renderModelList: SVModel[]) {
const g6Data: GraphData = Util.convertModelList2G6Data(renderModelList); const g6Data: GraphData = Util.convertModelList2G6Data(renderModelList);
this.shadowG6Instance.clear(); this.shadowG6Instance.clear();
this.shadowG6Instance.read(g6Data); this.shadowG6Instance.read(g6Data);
renderModelList.forEach(item => { renderModelList.forEach(item => {
item.shadowG6Item = this.shadowG6Instance.findById(item.id); item.G6Item = null;
item.shadowG6Instance = this.shadowG6Instance; item.shadowG6Item = this.shadowG6Instance.findById(item.id);
}); item.shadowG6Instance = this.shadowG6Instance;
} });
}
/** /**
* *
* @param renderModelList * @param renderModelList
* @param isFirstRender * @param isFirstRender
*/ */
public render(renderModelList: SVModel[]) { public render(renderModelList: SVModel[]) {
const renderData: GraphData = Util.convertModelList2G6Data(renderModelList); const renderData: GraphData = Util.convertModelList2G6Data(renderModelList);
this.g6Instance.changeData(renderData); this.g6Instance.changeData(renderData);
renderModelList.forEach(item => { renderModelList.forEach(item => {
item.g6Instance = this.g6Instance; item.g6Instance = this.g6Instance;
item.G6Item = this.g6Instance.findById(item.id); item.G6Item = this.g6Instance.findById(item.id);
item.G6Item['SVModel'] = item; item.G6Item['SVModel'] = item;
}); });
this.g6Instance.getEdges().forEach(item => item.toFront()); this.g6Instance.getEdges().forEach(item => item.toFront());
this.g6Instance.paint(); this.g6Instance.paint();
} }
/** /**
* Model * Model
* @param model * @param model
*/ */
public removeModel(model: SVModel) { public removeModel(model: SVModel) {
this.g6Instance.removeItem(model.G6Item); this.g6Instance.removeItem(model.G6Item);
this.shadowG6Instance.removeItem(model.shadowG6Item); this.shadowG6Instance.removeItem(model.shadowG6Item);
} }
/** /**
* G6 * G6
*/ */
public getG6Instance() { public getG6Instance() {
return this.g6Instance; return this.g6Instance;
} }
/** /**
* *
*/ */
public refresh() { public refresh() {
this.g6Instance.refresh(); this.g6Instance.refresh();
this.shadowG6Instance.refresh(); this.shadowG6Instance.refresh();
} }
/** /**
* *
* @param width * @param width
* @param height * @param height
*/ */
public changeSize(width: number, height: number) { public changeSize(width: number, height: number) {
this.g6Instance.changeSize(width, height); this.g6Instance.changeSize(width, height);
this.shadowG6Instance.changeSize(width, height); this.shadowG6Instance.changeSize(width, height);
} }
/** /**
* *
*/ */
public destroy() { public destroy() {
this.shadowG6Instance.destroy(); this.shadowG6Instance.destroy();
this.g6Instance.destroy(); this.g6Instance.destroy();
} }
} }

View File

@ -47,6 +47,7 @@ export class ViewContainer {
this.hasLeak = false; // 判断是否已经发生过泄漏 this.hasLeak = false; // 判断是否已经发生过泄漏
this.brushSelectedModels = []; this.brushSelectedModels = [];
this.clickSelectNode = null; this.clickSelectNode = null;
this.lastLeakAreaTranslateY = 0;
const g6Instance = this.renderer.getG6Instance(), const g6Instance = this.renderer.getG6Instance(),
leakAreaHeight = this.engine.viewOptions.leakAreaHeight, leakAreaHeight = this.engine.viewOptions.leakAreaHeight,