添加多种数据结构支持
This commit is contained in:
parent
579c72939c
commit
7e6789c8de
@ -43,6 +43,11 @@ class BinaryTree extends Engine {
|
|||||||
offset: 14,
|
offset: 14,
|
||||||
style: {
|
style: {
|
||||||
fill: '#f08a5d'
|
fill: '#f08a5d'
|
||||||
|
},
|
||||||
|
labelOptions: {
|
||||||
|
style: {
|
||||||
|
fill: '#000099'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -165,63 +170,26 @@ const BTree = function(container) {
|
|||||||
return{
|
return{
|
||||||
engine: new BinaryTree(container),
|
engine: new BinaryTree(container),
|
||||||
data: [
|
data: [
|
||||||
// [
|
|
||||||
// { id: 1, child: [2, 3], root: true, external: ['treeA', 'gear'] },
|
|
||||||
// { id: 2, child: [null, 6] },
|
|
||||||
// { id: 3, child: [5, 4] },
|
|
||||||
// { id: 4, external: 'foo' },
|
|
||||||
// { id: 5 },
|
|
||||||
// { id: 6, external: 'bar', child: [null, 7] },
|
|
||||||
// { id: 7 },
|
|
||||||
// { id: 8, child: [9, 10], root: true },
|
|
||||||
// { id: 9, child: [11, null] },
|
|
||||||
// { id: 10 },
|
|
||||||
// { id: 11 }
|
|
||||||
// ],
|
|
||||||
// [
|
|
||||||
// { id: 1, child: [2, 3], root: true, external: 'treeA' },
|
|
||||||
// { id: 2, external: 'gear' },
|
|
||||||
// { id: 3, child: [5, 4] },
|
|
||||||
// { id: 4, external: 'foo' },
|
|
||||||
// { id: 5, child: [12, 13] },
|
|
||||||
// { id: 12 }, { id: 13 }
|
|
||||||
// ]
|
|
||||||
[
|
[
|
||||||
{
|
{ id: 1, child: [2, 3], root: true, external: ['treeA', 'gear'] },
|
||||||
"external": [
|
{ id: 2, child: [null, 6] },
|
||||||
"r",
|
{ id: 3, child: [5, 4] },
|
||||||
"T1"
|
{ id: 4, external: 'foo', child: [5, null] },
|
||||||
|
{ id: 5 },
|
||||||
|
{ id: 6, external: 'bar', child: [null, 7] },
|
||||||
|
{ id: 7 },
|
||||||
|
{ id: 8, child: [9, 10], root: true },
|
||||||
|
{ id: 9, child: [11, null] },
|
||||||
|
{ id: 10 },
|
||||||
|
{ id: 11 }
|
||||||
],
|
],
|
||||||
"child": [
|
[
|
||||||
6385376,
|
{ id: 1, child: [2, 3], root: true, external: 'treeA' },
|
||||||
6385424
|
{ id: 2, external: 'gear' },
|
||||||
],
|
{ id: 3, child: [5, 4] },
|
||||||
"id": 6385328,
|
{ id: 4, external: 'foo' },
|
||||||
"name": "T1",
|
{ id: 5, child: [12, 13] },
|
||||||
"data": "Z",
|
{ id: 12 }, { id: 13 }
|
||||||
"root": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"child": [
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"id": 6385376,
|
|
||||||
"name": "T1.lchild",
|
|
||||||
"data": "A"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"external": [
|
|
||||||
"t"
|
|
||||||
],
|
|
||||||
"child": [
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"id": 6385424,
|
|
||||||
"name": "T1.rchild",
|
|
||||||
"data": "B"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
74
demo/dataStruct/RingArray.js
Normal file
74
demo/dataStruct/RingArray.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RingArray extends Engine {
|
||||||
|
defineOptions() {
|
||||||
|
return {
|
||||||
|
element: {
|
||||||
|
default: {
|
||||||
|
type: 'rect',
|
||||||
|
label: '[id]',
|
||||||
|
size: [60, 30],
|
||||||
|
style: {
|
||||||
|
stroke: '#333',
|
||||||
|
fill: '#95e1d3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
external: {
|
||||||
|
offset: 8,
|
||||||
|
style: {
|
||||||
|
fill: '#f08a5d'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
interaction: {
|
||||||
|
dragNode: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(elements) {
|
||||||
|
let arr = elements.default,
|
||||||
|
width = arr[0].get('size')[0],
|
||||||
|
radius = width * 1.1 / (2 * Math.sin(Math.PI / arr.length)),
|
||||||
|
intervalAngle = 2 * Math.PI / arr.length;
|
||||||
|
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
let [x, y] = Vector.rotation(-intervalAngle * i, [0, radius]);
|
||||||
|
|
||||||
|
arr[i].set({x, y});
|
||||||
|
arr[i].set('rotation', intervalAngle * i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const RA = function(container) {
|
||||||
|
return{
|
||||||
|
engine: new RingArray(container),
|
||||||
|
data: [[
|
||||||
|
{ id: 1 },
|
||||||
|
{ id: 2 },
|
||||||
|
{ id: 3 },
|
||||||
|
{ id: 4 },
|
||||||
|
{ id: 5 },
|
||||||
|
{ id: 6 },
|
||||||
|
{ id: 7 },
|
||||||
|
{ id: 8 },
|
||||||
|
{ id: 9 },
|
||||||
|
{ id: 10 }
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ id: 1 },
|
||||||
|
{ id: 2 },
|
||||||
|
{ id: 3 },
|
||||||
|
{ id: 6 },
|
||||||
|
{ id: 7 },
|
||||||
|
{ id: 8 }
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -33,6 +33,23 @@ class LinkList extends Engine {
|
|||||||
fill: '#333'
|
fill: '#333'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
loopNext: {
|
||||||
|
type: 'arc',
|
||||||
|
curveOffset: 50,
|
||||||
|
sourceAnchor: 1,
|
||||||
|
targetAnchor: 3,
|
||||||
|
style: {
|
||||||
|
stroke: '#333',
|
||||||
|
endArrow: {
|
||||||
|
path: G6.Arrow.triangle(6, 6, -2),
|
||||||
|
fill: '#333'
|
||||||
|
},
|
||||||
|
startArrow: {
|
||||||
|
path: G6.Arrow.circle(2, -1),
|
||||||
|
fill: '#333'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pointer: {
|
pointer: {
|
||||||
@ -107,7 +124,7 @@ const LList = function(container) {
|
|||||||
{ id: 2, next: 3 },
|
{ id: 2, next: 3 },
|
||||||
{ id: 3, next: 4 },
|
{ id: 3, next: 4 },
|
||||||
{ id: 4, next: 5 },
|
{ id: 4, next: 5 },
|
||||||
{ id: 5 },
|
{ id: 5, loopNext: 6 },
|
||||||
{ id: 6, root: true, next: 7 },
|
{ id: 6, root: true, next: 7 },
|
||||||
{ id: 7, next: 8 },
|
{ id: 7, next: 8 },
|
||||||
{ id: 8, next: 4 },
|
{ id: 8, next: 4 },
|
||||||
|
|||||||
@ -48,11 +48,12 @@ const Engine = SV.Engine,
|
|||||||
<script src="./dataStruct/LinkQueue.js"></script>
|
<script src="./dataStruct/LinkQueue.js"></script>
|
||||||
<script src="./dataStruct/Graph.js"></script>
|
<script src="./dataStruct/Graph.js"></script>
|
||||||
<script src="./dataStruct/DirectedGraph.js"></script>
|
<script src="./dataStruct/DirectedGraph.js"></script>
|
||||||
|
<script src="./dataStruct/RingArray.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
const engines = [BTree, LList, A, CHT, St, LStack, LQueue, G, DG];
|
const engines = [BTree, LList, A, CHT, St, LStack, LQueue, G, DG, RA];
|
||||||
|
|
||||||
let cur = engines[8](document.getElementById('container'));
|
let cur = engines[9](document.getElementById('container'));
|
||||||
|
|
||||||
cur.engine.render(cur.data[0]);
|
cur.engine.render(cur.data[0]);
|
||||||
|
|
||||||
|
|||||||
2
dist/sv.js
vendored
2
dist/sv.js
vendored
File diff suppressed because one or more lines are too long
@ -1,7 +1,6 @@
|
|||||||
import { Engine } from "../engine";
|
|
||||||
import { ConstructedData } from "../Model/modelConstructor";
|
import { ConstructedData } from "../Model/modelConstructor";
|
||||||
import { SV } from "../StructV";
|
import { SV } from "../StructV";
|
||||||
import { G6Data, Renderer } from "../View/renderer";
|
import { G6Data } from "../View/renderer";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { Util } from "../Common/util";
|
|||||||
import { ElementLabelOption, ElementOption, LinkLabelOption, LinkOption, PointerOption, Style } from "../options";
|
import { ElementLabelOption, ElementOption, LinkLabelOption, LinkOption, PointerOption, Style } from "../options";
|
||||||
import { SourceElement } from "../sources";
|
import { SourceElement } from "../sources";
|
||||||
import { BoundingRect } from "../View/boundingRect";
|
import { BoundingRect } from "../View/boundingRect";
|
||||||
|
import { SV } from './../StructV';
|
||||||
|
|
||||||
|
|
||||||
export interface G6NodeModel {
|
export interface G6NodeModel {
|
||||||
@ -26,6 +27,8 @@ export interface G6EdgeModel {
|
|||||||
source: string | number;
|
source: string | number;
|
||||||
target: string | number;
|
target: string | number;
|
||||||
type: string;
|
type: string;
|
||||||
|
controlPoints: { x: number, y: number }[];
|
||||||
|
curveOffset: number;
|
||||||
sourceAnchor: number | ((index: number) => number);
|
sourceAnchor: number | ((index: number) => number);
|
||||||
targetAnchor: number | ((index: number) => number);
|
targetAnchor: number | ((index: number) => number);
|
||||||
label: string;
|
label: string;
|
||||||
@ -105,6 +108,10 @@ export class Model {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.props[attr] === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(attr === 'style' || attr === 'labelCfg') {
|
if(attr === 'style' || attr === 'labelCfg') {
|
||||||
Object.assign(this.props[attr], value);
|
Object.assign(this.props[attr], value);
|
||||||
}
|
}
|
||||||
@ -143,7 +150,9 @@ export class Model {
|
|||||||
*/
|
*/
|
||||||
getMatrix(): number[] {
|
getMatrix(): number[] {
|
||||||
if(this.G6Item === null) return null;
|
if(this.G6Item === null) return null;
|
||||||
return this.G6Item.getContainer().getMatrix();
|
// return this.G6Item.getContainer().getMatrix();
|
||||||
|
const Mat3 = SV.G6.Util.mat3;
|
||||||
|
return Mat3.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +161,7 @@ export class Element extends Model {
|
|||||||
modelType = 'element';
|
modelType = 'element';
|
||||||
sourceElement: SourceElement;
|
sourceElement: SourceElement;
|
||||||
sourceId: string;
|
sourceId: string;
|
||||||
|
free: boolean;
|
||||||
|
|
||||||
constructor(id: string, type: string, sourceElement: SourceElement) {
|
constructor(id: string, type: string, sourceElement: SourceElement) {
|
||||||
super(id, type);
|
super(id, type);
|
||||||
@ -163,6 +173,7 @@ export class Element extends Model {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.sourceId = this.id.split('.')[1];
|
this.sourceId = this.id.split('.')[1];
|
||||||
|
this.free = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected defineProps(option: ElementOption) {
|
protected defineProps(option: ElementOption) {
|
||||||
@ -222,8 +233,11 @@ export class Link extends Model {
|
|||||||
label: option.label,
|
label: option.label,
|
||||||
style: Util.objectClone<Style>(option.style),
|
style: Util.objectClone<Style>(option.style),
|
||||||
labelCfg: Util.objectClone<LinkLabelOption>(option.labelOptions),
|
labelCfg: Util.objectClone<LinkLabelOption>(option.labelOptions),
|
||||||
|
controlPoints: option.controlPoints,
|
||||||
|
curveOffset: option.curveOffset,
|
||||||
modelType: this.modelType,
|
modelType: this.modelType,
|
||||||
modelName: this.modelName
|
modelName: this.modelName,
|
||||||
|
zIndex: 20
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export default G6.registerNode('binary-tree-node', {
|
|||||||
height: height,
|
height: height,
|
||||||
stroke: cfg.style.stroke,
|
stroke: cfg.style.stroke,
|
||||||
cursor: cfg.style.cursor,
|
cursor: cfg.style.cursor,
|
||||||
fill: 'transparent'
|
fill: '#eee'
|
||||||
},
|
},
|
||||||
name: 'wrapper'
|
name: 'wrapper'
|
||||||
});
|
});
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export default G6.registerNode('link-list-node', {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
stroke: cfg.style.stroke,
|
stroke: cfg.style.stroke,
|
||||||
fill: 'transparent'
|
fill: '#eee'
|
||||||
},
|
},
|
||||||
name: 'wrapper'
|
name: 'wrapper'
|
||||||
});
|
});
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export default G6.registerNode('two-cell-node', {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
stroke: cfg.style.stroke,
|
stroke: cfg.style.stroke,
|
||||||
fill: 'transparent'
|
fill: '#eee'
|
||||||
},
|
},
|
||||||
name: 'wrapper'
|
name: 'wrapper'
|
||||||
});
|
});
|
||||||
|
|||||||
@ -43,6 +43,7 @@ export class Renderer {
|
|||||||
container: DOMContainer,
|
container: DOMContainer,
|
||||||
width: DOMContainer.offsetWidth,
|
width: DOMContainer.offsetWidth,
|
||||||
height: DOMContainer.offsetHeight,
|
height: DOMContainer.offsetHeight,
|
||||||
|
groupByTypes: false,
|
||||||
animate: enable,
|
animate: enable,
|
||||||
animateCfg: {
|
animateCfg: {
|
||||||
duration: duration,
|
duration: duration,
|
||||||
@ -133,6 +134,14 @@ export class Renderer {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找被释放的节点
|
||||||
|
* @param constructedData
|
||||||
|
*/
|
||||||
|
private findFreedItems(constructedData: ConstructedData): G6NodeModel[] {
|
||||||
|
return Util.converterList(constructedData.element).filter(item => item.free).map(item => item.G6Item);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理新增的 G6Item(主要是动画)
|
* 处理新增的 G6Item(主要是动画)
|
||||||
* @param appendData
|
* @param appendData
|
||||||
@ -165,6 +174,12 @@ export class Renderer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理被 free 的 G6Item
|
||||||
|
* @param freedItems
|
||||||
|
*/
|
||||||
|
private handleFreedItems(freedItems: G6NodeModel[]) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建 G6 元素
|
* 构建 G6 元素
|
||||||
* @param constructedData
|
* @param constructedData
|
||||||
@ -197,6 +212,7 @@ export class Renderer {
|
|||||||
*/
|
*/
|
||||||
public render(constructedData: ConstructedData) {
|
public render(constructedData: ConstructedData) {
|
||||||
let data: G6Data = Util.convertG6Data(constructedData),
|
let data: G6Data = Util.convertG6Data(constructedData),
|
||||||
|
freedItems = this.findFreedItems(constructedData),
|
||||||
renderData: G6Data = null,
|
renderData: G6Data = null,
|
||||||
appendData: G6Data = null,
|
appendData: G6Data = null,
|
||||||
removeData: G6Data = null;
|
removeData: G6Data = null;
|
||||||
@ -212,7 +228,6 @@ export class Renderer {
|
|||||||
|
|
||||||
if(this.isFirstRender) {
|
if(this.isFirstRender) {
|
||||||
this.graphInstance.read(renderData);
|
this.graphInstance.read(renderData);
|
||||||
this.isFirstRender = false;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.graphInstance.changeData(renderData);
|
this.graphInstance.changeData(renderData);
|
||||||
@ -229,6 +244,15 @@ export class Renderer {
|
|||||||
item.renderG6Item = this.graphInstance.findById(item.id);
|
item.renderG6Item = this.graphInstance.findById(item.id);
|
||||||
item.G6Item = item.renderG6Item;
|
item.G6Item = item.renderG6Item;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(this.isFirstRender) {
|
||||||
|
this.graphInstance.getEdges().forEach(item => item.toFront());
|
||||||
|
this.graphInstance.paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.isFirstRender) {
|
||||||
|
this.isFirstRender = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -46,6 +46,8 @@ export interface LinkOption {
|
|||||||
sourceAnchor: number | ((index: number) => number);
|
sourceAnchor: number | ((index: number) => number);
|
||||||
targetAnchor: number | ((index: number) => number);
|
targetAnchor: number | ((index: number) => number);
|
||||||
label: string;
|
label: string;
|
||||||
|
controlPoints: { x: number, y: number }[];
|
||||||
|
curveOffset: number;
|
||||||
labelOptions: LinkLabelOption;
|
labelOptions: LinkLabelOption;
|
||||||
style: Style;
|
style: Style;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user