改进可视化细节: pointer改为marker
This commit is contained in:
parent
da2d43581e
commit
461a6242da
2
dist/sv.js
vendored
2
dist/sv.js
vendored
File diff suppressed because one or more lines are too long
@ -153,24 +153,26 @@ export class ModelConstructor {
|
|||||||
if(Array.isArray(sourceLinkData)) {
|
if(Array.isArray(sourceLinkData)) {
|
||||||
element[name] = sourceLinkData.map((item, index) => {
|
element[name] = sourceLinkData.map((item, index) => {
|
||||||
targetElement = this.fetchTargetElements(layoutGroupTable, element, item);
|
targetElement = this.fetchTargetElements(layoutGroupTable, element, item);
|
||||||
|
let isGeneralLink = this.isGeneralLink(sourceLinkData.toString());
|
||||||
|
|
||||||
if(targetElement) {
|
if(targetElement) {
|
||||||
link = this.createLink(name, element, targetElement, index, linkOptions[name]);
|
link = this.createLink(name, element, targetElement, index, linkOptions[name]);
|
||||||
linkList.push(link);
|
linkList.push(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetElement;
|
return isGeneralLink? targetElement: null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
targetElement = this.fetchTargetElements(layoutGroupTable, element, sourceLinkData);
|
targetElement = this.fetchTargetElements(layoutGroupTable, element, sourceLinkData);
|
||||||
|
let isGeneralLink = this.isGeneralLink(sourceLinkData.toString());
|
||||||
|
|
||||||
if(targetElement) {
|
if(targetElement) {
|
||||||
link = this.createLink(name, element, targetElement, null, linkOptions[name]);
|
link = this.createLink(name, element, targetElement, null, linkOptions[name]);
|
||||||
linkList.push(link);
|
linkList.push(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
element[name] = targetElement;
|
element[name] = isGeneralLink? targetElement: null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -356,6 +358,22 @@ export class ModelConstructor {
|
|||||||
return targetElement || null;
|
return targetElement || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测改指针是否为常规指针(指向另一个group)
|
||||||
|
* @param linkId
|
||||||
|
*/
|
||||||
|
private isGeneralLink(linkId: string): boolean {
|
||||||
|
let counter = 0;
|
||||||
|
|
||||||
|
for(let i = 0; i < linkId.length; i++) {
|
||||||
|
if(linkId[i] === '#') {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return counter <= 2;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 销毁
|
* 销毁
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -170,6 +170,10 @@ export class Element extends Model {
|
|||||||
layouterName: string;
|
layouterName: string;
|
||||||
freed: boolean;
|
freed: boolean;
|
||||||
markers: { [key: string]: Marker };
|
markers: { [key: string]: Marker };
|
||||||
|
links: {
|
||||||
|
inDegree: Link[];
|
||||||
|
outDegree: Link[];
|
||||||
|
};
|
||||||
|
|
||||||
constructor(id: string, type: string, group: string, layouter: string, sourceElement: SourceElement) {
|
constructor(id: string, type: string, group: string, layouter: string, sourceElement: SourceElement) {
|
||||||
super(id, type);
|
super(id, type);
|
||||||
@ -191,6 +195,7 @@ export class Element extends Model {
|
|||||||
this.sourceId = this.id.split('.')[1];
|
this.sourceId = this.id.split('.')[1];
|
||||||
this.sourceElement = sourceElement;
|
this.sourceElement = sourceElement;
|
||||||
this.markers = { };
|
this.markers = { };
|
||||||
|
this.links = { inDegree: [], outDegree: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected defineProps(option: ElementOption): G6NodeModel {
|
protected defineProps(option: ElementOption): G6NodeModel {
|
||||||
@ -226,6 +231,9 @@ export class Link extends Model {
|
|||||||
this.element = element;
|
this.element = element;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
|
||||||
|
element.links.outDegree.push(this);
|
||||||
|
target.links.inDegree.push(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export class Container {
|
|||||||
protected afterAppendModelsCallbacks: ((models: Model[]) => void)[] = [];
|
protected afterAppendModelsCallbacks: ((models: Model[]) => void)[] = [];
|
||||||
protected afterRemoveModelsCallbacks: ((models: Model[]) => void)[] = [];
|
protected afterRemoveModelsCallbacks: ((models: Model[]) => void)[] = [];
|
||||||
|
|
||||||
constructor(engine: Engine, DOMContainer: HTMLElement, g6Options: { [key: string]: any } = { }) {
|
constructor(engine: Engine, DOMContainer: HTMLElement, g6Options: { [key: string]: any } = {}) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.DOMContainer = DOMContainer;
|
this.DOMContainer = DOMContainer;
|
||||||
this.animationsOptions = engine.animationOptions;
|
this.animationsOptions = engine.animationOptions;
|
||||||
@ -28,24 +28,14 @@ export class Container {
|
|||||||
|
|
||||||
const g6Plugins = [];
|
const g6Plugins = [];
|
||||||
|
|
||||||
if(g6Options.tooltip) {
|
if (g6Options.tooltip) {
|
||||||
const tooltip = new SV.G6.Tooltip({
|
const tooltip = new SV.G6.Tooltip({
|
||||||
offsetX: 10,
|
offsetX: 10,
|
||||||
offsetY: 20,
|
offsetY: 20,
|
||||||
shouldBegin(event) {
|
shouldBegin(event) {
|
||||||
return event.item.getModel().SVModelType === 'element';
|
return event.item.getModel().SVModelType === 'element';
|
||||||
},
|
},
|
||||||
getContent(event) {
|
getContent: event => this.getTooltipContent(event.item.SVModel, { address: 'sourceId', data: 'data' }),
|
||||||
const data = event.item.SVModel.data,
|
|
||||||
wrapper = document.createElement('div');
|
|
||||||
|
|
||||||
wrapper.style.padding = '0 4px 0 4px';
|
|
||||||
wrapper.innerHTML = `
|
|
||||||
<h5>id: ${ event.item.SVModel.sourceId }</h5>
|
|
||||||
<h5>data: ${ data? data: '' }</h5>
|
|
||||||
`
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
itemTypes: ['node']
|
itemTypes: ['node']
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -63,6 +53,23 @@ export class Container {
|
|||||||
this.afterInitRenderer();
|
this.afterInitRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private getTooltipContent(model: Model, items: { [key: string]: string }): HTMLElement {
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化交互行为
|
* 初始化交互行为
|
||||||
* @param optionsTable
|
* @param optionsTable
|
||||||
@ -114,14 +121,14 @@ export class Container {
|
|||||||
list.forEach(item => {
|
list.forEach(item => {
|
||||||
const prevItem = this.prevModelList.find(prevItem => prevItem.id === item.id);
|
const prevItem = this.prevModelList.find(prevItem => prevItem.id === item.id);
|
||||||
|
|
||||||
if(prevItem === undefined) {
|
if (prevItem === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevLabel = prevItem.get('label'),
|
const prevLabel = prevItem.get('label'),
|
||||||
label = item.get('label');
|
label = item.get('label');
|
||||||
|
|
||||||
if(prevLabel !== label) {
|
if (prevLabel !== label) {
|
||||||
labelChangeModels.push(item);
|
labelChangeModels.push(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -143,7 +150,7 @@ export class Container {
|
|||||||
callback: () => {
|
callback: () => {
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
if(counter === appendModels.length) {
|
if (counter === appendModels.length) {
|
||||||
this.afterAppendModelsCallbacks.map(item => item(appendModels));
|
this.afterAppendModelsCallbacks.map(item => item(appendModels));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,14 +170,14 @@ export class Container {
|
|||||||
duration: this.animationsOptions.duration,
|
duration: this.animationsOptions.duration,
|
||||||
timingFunction: this.animationsOptions.timingFunction,
|
timingFunction: this.animationsOptions.timingFunction,
|
||||||
callback: () => {
|
callback: () => {
|
||||||
if(item.isLeak === false) {
|
if (item.isLeak === false) {
|
||||||
this.renderer.removeModel(item);
|
this.renderer.removeModel(item);
|
||||||
item.renderG6Item = item.G6Item = null;
|
item.renderG6Item = item.G6Item = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
if(counter === removeModels.length) {
|
if (counter === removeModels.length) {
|
||||||
this.afterRemoveModelsCallbacks.map(item => item(removeModels));
|
this.afterRemoveModelsCallbacks.map(item => item(removeModels));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +230,7 @@ export class Container {
|
|||||||
this.handleRemoveModels(removeModels);
|
this.handleRemoveModels(removeModels);
|
||||||
this.handleChangeModels(changeModels);
|
this.handleChangeModels(changeModels);
|
||||||
|
|
||||||
if(this.renderer.getIsFirstRender()) {
|
if (this.renderer.getIsFirstRender()) {
|
||||||
this.renderer.setIsFirstRender(false);
|
this.renderer.setIsFirstRender(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@ import { Container } from "./container";
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model.SVModelType === 'pointer') {
|
if(model.SVModelType === 'marker') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ import { Container } from "./container";
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model.SVModelType === 'pointer') {
|
if(model.SVModelType === 'marker') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,16 +105,16 @@ import { Container } from "./container";
|
|||||||
*/
|
*/
|
||||||
protected afterInitRenderer() {
|
protected afterInitRenderer() {
|
||||||
let g6Instance = this.getG6Instance(),
|
let g6Instance = this.getG6Instance(),
|
||||||
pointer = null,
|
marker = null,
|
||||||
pointerX = null,
|
markerX = null,
|
||||||
pointerY = null,
|
markerY = null,
|
||||||
dragStartX = null,
|
dragStartX = null,
|
||||||
dragStartY = null;
|
dragStartY = null;
|
||||||
|
|
||||||
g6Instance.on('node:dragstart', ev => {
|
g6Instance.on('node:dragstart', ev => {
|
||||||
const model = ev.item.getModel();
|
const model = ev.item.getModel();
|
||||||
|
|
||||||
if(model.SVModelType === 'pointer') {
|
if(model.SVModelType === 'marker') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,26 +128,26 @@ import { Container } from "./container";
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer = g6Instance.findById(model.externalPointerId);
|
marker = g6Instance.findById(model.markerId);
|
||||||
|
|
||||||
if(pointer) {
|
if(marker) {
|
||||||
pointerX = pointer.getModel().x,
|
markerX = marker.getModel().x,
|
||||||
pointerY = pointer.getModel().y;
|
markerY = marker.getModel().y;
|
||||||
dragStartX = ev.canvasX;
|
dragStartX = ev.canvasX;
|
||||||
dragStartY = ev.canvasY;
|
dragStartY = ev.canvasY;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
g6Instance.on('node:dragend', ev => {
|
g6Instance.on('node:dragend', ev => {
|
||||||
pointer = null;
|
marker = null;
|
||||||
pointerX = null,
|
markerX = null,
|
||||||
pointerY = null,
|
markerY = null,
|
||||||
dragStartX = null,
|
dragStartX = null,
|
||||||
dragStartY = null;
|
dragStartY = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
g6Instance.on('node:drag', ev => {
|
g6Instance.on('node:drag', ev => {
|
||||||
if(!pointer) {
|
if(!marker) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,9 +155,9 @@ import { Container } from "./container";
|
|||||||
dy = ev.canvasY - dragStartY,
|
dy = ev.canvasY - dragStartY,
|
||||||
zoom = g6Instance.getZoom();
|
zoom = g6Instance.getZoom();
|
||||||
|
|
||||||
pointer.updatePosition({
|
marker.updatePosition({
|
||||||
x: pointerX + dx / zoom,
|
x: markerX + dx / zoom,
|
||||||
y: pointerY + dy / zoom
|
y: markerY + dy / zoom
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,8 +92,11 @@ export class Renderer {
|
|||||||
|
|
||||||
modelList.forEach(item => {
|
modelList.forEach(item => {
|
||||||
item.renderG6Item = this.g6Instance.findById(item.id);
|
item.renderG6Item = this.g6Instance.findById(item.id);
|
||||||
|
|
||||||
|
if(item.renderG6Item) {
|
||||||
item.G6Item = item.renderG6Item;
|
item.G6Item = item.renderG6Item;
|
||||||
item.renderG6Item.SVModel = item;
|
item.renderG6Item.SVModel = item;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 把所有连线置顶
|
// 把所有连线置顶
|
||||||
|
|||||||
@ -68,7 +68,7 @@ export class ViewManager {
|
|||||||
removeModels: Model[] = [];
|
removeModels: Model[] = [];
|
||||||
|
|
||||||
layoutGroupTable.forEach((group, key) => {
|
layoutGroupTable.forEach((group, key) => {
|
||||||
let freedElements: Model[] = group.element.filter(item => item.freed);
|
let freedElements: Element[] = group.element.filter(item => item.freed);
|
||||||
|
|
||||||
if(freedElements.length) {
|
if(freedElements.length) {
|
||||||
freedGroupName = key;
|
freedGroupName = key;
|
||||||
@ -107,6 +107,7 @@ export class ViewManager {
|
|||||||
|
|
||||||
elements.forEach(item => {
|
elements.forEach(item => {
|
||||||
elementIds.push(item.id);
|
elementIds.push(item.id);
|
||||||
|
|
||||||
item.set('style', {
|
item.set('style', {
|
||||||
fill: '#ccc'
|
fill: '#ccc'
|
||||||
});
|
});
|
||||||
@ -189,7 +190,7 @@ export class ViewManager {
|
|||||||
renderAll(layoutGroupTable: LayoutGroupTable) {
|
renderAll(layoutGroupTable: LayoutGroupTable) {
|
||||||
this.shadowG6Instance.clear();
|
this.shadowG6Instance.clear();
|
||||||
|
|
||||||
const modelList = Util.convertGroupTable2ModelList(layoutGroupTable);
|
let modelList = Util.convertGroupTable2ModelList(layoutGroupTable);
|
||||||
|
|
||||||
this.build(modelList);
|
this.build(modelList);
|
||||||
|
|
||||||
@ -209,6 +210,8 @@ export class ViewManager {
|
|||||||
// 进行布局(设置model的x,y)
|
// 进行布局(设置model的x,y)
|
||||||
this.layouter.layoutAll(this.mainContainer, layoutGroupTable);
|
this.layouter.layoutAll(this.mainContainer, layoutGroupTable);
|
||||||
|
|
||||||
|
// 从新获取一次,因为第一次获取没有把freed节点筛选出去
|
||||||
|
modelList = Util.convertGroupTable2ModelList(layoutGroupTable);
|
||||||
this.mainContainer.render(modelList);
|
this.mainContainer.render(modelList);
|
||||||
|
|
||||||
if(this.leakContainer) {
|
if(this.leakContainer) {
|
||||||
|
|||||||
@ -55,6 +55,7 @@ export interface LinkOption {
|
|||||||
|
|
||||||
|
|
||||||
export interface MarkerOption extends ElementOption {
|
export interface MarkerOption extends ElementOption {
|
||||||
|
type: 'pointer' | 'cursor';
|
||||||
anchor: number;
|
anchor: number;
|
||||||
offset: number;
|
offset: number;
|
||||||
labelOffset: number;
|
labelOffset: number;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user