diff --git a/demo/dataStruct/DirectedGraph.js b/demo/dataStruct/DirectedGraph.js
new file mode 100644
index 0000000..2de5e83
--- /dev/null
+++ b/demo/dataStruct/DirectedGraph.js
@@ -0,0 +1,66 @@
+
+
+
+class DirectedGraph extends Graph {
+ defineOptions() {
+ return {
+ element: {
+ default: {
+ label: '[id]',
+ size: 30,
+ style: {
+ stroke: '#333',
+ fill: '#b83b5e'
+ }
+ }
+ },
+ link: {
+ neighbor: {
+ type: 'line',
+ style: {
+ stroke: '#333',
+ endArrow: {
+ path: G6.Arrow.triangle(8, 6, 0),
+ fill: '#333'
+ }
+ }
+ }
+ },
+ pointer: {
+ external: {
+ offset: 8,
+ style: {
+ fill: '#f08a5d'
+ }
+ }
+ },
+ layout: {
+ radius: 150
+ }
+ };
+ }
+}
+
+
+
+const DG = function(container) {
+ return{
+ engine: new DirectedGraph(container),
+ data: [[
+ { id: 1, neighbor: 2 },
+ { id: 2, neighbor: [ 3, 4, 5 ] },
+ { id: 3, neighbor: [ 4, 6 ] },
+ { id: 4, neighbor: 5 },
+ { id: 5, neighbor: 6 },
+ { id: 6, neighbor: 1 }
+ ],
+ [
+ { id: 1, neighbor: 3 },
+ { id: 3 },
+ { id: 4, neighbor: 5 },
+ { id: 5, neighbor: 6 },
+ { id: 6, neighbor: 1 }
+ ]]
+ }
+};
+
diff --git a/demo/dataStruct/Graph.js b/demo/dataStruct/Graph.js
new file mode 100644
index 0000000..279c061
--- /dev/null
+++ b/demo/dataStruct/Graph.js
@@ -0,0 +1,73 @@
+
+
+class Graph extends Engine {
+
+ defineOptions() {
+ return {
+ element: {
+ default: {
+ type: 'circle',
+ label: '[id]',
+ size: 30,
+ style: {
+ stroke: '#333',
+ fill: '#b83b5e'
+ }
+ }
+ },
+ link: {
+ neighbor: {
+ style: {
+ stroke: '#333'
+ }
+ }
+ },
+ pointer: {
+ external: {
+ offset: 8,
+ style: {
+ fill: '#f08a5d'
+ }
+ }
+ },
+ layout: {
+ radius: 150
+ }
+ };
+ }
+
+ layout(elements, layoutOptions) {
+ let nodes = elements.default,
+ radius = layoutOptions.radius,
+ intervalAngle = 2 * Math.PI / nodes.length;
+
+ for (let i = 0; i < nodes.length; i++) {
+ let [x, y] = Vector.rotation(-intervalAngle * i, [0, -radius]);
+
+ nodes[i].set({x, y});
+ }
+ }
+}
+
+
+
+const G = function(container) {
+ return{
+ engine: new Graph(container),
+ data: [[
+ { id: 1, neighbor: 2 },
+ { id: 2, neighbor: [ 3, 4, 5 ] },
+ { id: 3, neighbor: [ 4, 6] },
+ { id: 4, neighbor: 5 },
+ { id: 5, neighbor: 6 },
+ { id: 6, neighbor: 1 }
+ ],
+ [
+ { id: 1, neighbor: 3 },
+ { id: 3 },
+ { id: 4, neighbor: 5 },
+ { id: 5, neighbor: 6 },
+ { id: 6, neighbor: 1 }
+ ]]
+ }
+};
\ No newline at end of file
diff --git a/demo/dataStruct/LinkQueue.js b/demo/dataStruct/LinkQueue.js
new file mode 100644
index 0000000..0c66762
--- /dev/null
+++ b/demo/dataStruct/LinkQueue.js
@@ -0,0 +1,237 @@
+
+
+G6.registerNode('link-Queue-head', {
+ draw(cfg, group) {
+ cfg.size = cfg.size || [30, 10];
+
+ const width = cfg.size[0],
+ height = cfg.size[1];
+
+ const wrapperRect = group.addShape('rect', {
+ attrs: {
+ x: width / 2,
+ y: height / 2,
+ width: width,
+ height: height,
+ stroke: cfg.style.stroke,
+ fill: 'transparent'
+ },
+ name: 'wrapper'
+ });
+
+ group.addShape('rect', {
+ attrs: {
+ x: width / 2,
+ y: height / 2,
+ width: width,
+ height: height / 2,
+ fill: cfg.style.fill,
+ stroke: cfg.style.stroke
+ },
+ name: 'top-rect'
+ });
+
+ group.addShape('rect', {
+ attrs: {
+ x: width / 2,
+ y: height,
+ width: width,
+ height: height / 2,
+ fill: cfg.style.fill,
+ stroke: cfg.style.stroke
+ },
+ name: 'bottom-rect'
+ });
+
+ group.addShape('text', {
+ attrs: {
+ x: width,
+ y: height * (3 / 4),
+ textAlign: 'center',
+ textBaseline: 'middle',
+ text: 'front',
+ fill: '#000',
+ fontSize: 16
+ },
+ name: 'front'
+ });
+
+ group.addShape('text', {
+ attrs: {
+ x: width,
+ y: height * (5 / 4),
+ textAlign: 'center',
+ textBaseline: 'middle',
+ text: 'rear',
+ fill: '#000',
+ fontSize: 16
+ },
+ name: 'rear'
+ });
+
+ return wrapperRect;
+ },
+
+ getAnchorPoints() {
+ return [
+ [1, 0.25],
+ [1, 0.75]
+ ];
+ }
+});
+
+
+ class LinkQueue extends Engine {
+ defineOptions() {
+ return {
+ element: {
+ head: {
+ type: 'link-Queue-head',
+ label: '[id]',
+ size: [60, 80],
+ style: {
+ stroke: '#333',
+ fill: '#b83b5e'
+ }
+ },
+ node: {
+ type: 'link-list-node',
+ label: '[id]',
+ size: [60, 30],
+ style: {
+ stroke: '#333',
+ fill: '#b83b5e'
+ }
+ }
+ },
+ link: {
+ front: {
+ type: 'line',
+ sourceAnchor: 0,
+ targetAnchor: 0,
+ style: {
+ stroke: '#333',
+ endArrow: {
+ path: G6.Arrow.triangle(8, 6, 0),
+ fill: '#333'
+ }
+ }
+ },
+ rear: {
+ type: 'polyline',
+ sourceAnchor: 1,
+ targetAnchor: 3,
+ style: {
+ stroke: '#333',
+ endArrow: {
+ path: G6.Arrow.triangle(8, 6, 0),
+ fill: '#333'
+ }
+ }
+ },
+ next: {
+ type: 'line',
+ sourceAnchor: 1,
+ targetAnchor: 0,
+ style: {
+ stroke: '#333',
+ endArrow: {
+ path: G6.Arrow.triangle(8, 6, 0),
+ fill: '#333'
+ },
+ startArrow: {
+ path: G6.Arrow.circle(2, -1),
+ fill: '#333'
+ }
+ }
+ }
+ },
+ pointer: {
+ external: {
+ offset: 8,
+ style: {
+ fill: '#f08a5d'
+ }
+ }
+ },
+ layout: {
+ xInterval: 50,
+ yInterval: 50
+ }
+ };
+ }
+
+
+ /**
+ * 对子树进行递归布局
+ * @param node
+ * @param parent
+ */
+ layoutItem(node, prev, layoutOptions) {
+ if(!node) {
+ return null;
+ }
+
+ let width = node.get('size')[0];
+
+ if(prev) {
+ node.set('y', prev.get('y'));
+ node.set('x', prev.get('x') + layoutOptions.xInterval + width);
+ }
+
+ if(node.next) {
+ this.layoutItem(node.next, node, layoutOptions);
+ }
+ }
+
+
+ layout(elements, layoutOptions) {
+ let head = elements.head[0];
+
+ if(head.front) {
+ let d = head.get('size')[1] / 2 - head.front.get('size')[1],
+ x = layoutOptions.xInterval * 2.5,
+ y = head.front.get('size')[1] / 2 + 1.5 * d;
+
+ head.front.set({ x, y });
+ }
+
+ if(head.front.next) {
+ this.layoutItem(head.front.next, head.front, layoutOptions);
+ }
+ }
+}
+
+
+
+
+const LQueue = function(container) {
+ return{
+ engine: new LinkQueue(container),
+ data: [{
+ head: [{
+ type: "QPtr",
+ id: 44,
+ front: 'node#1',
+ rear: 'node#13'
+ }],
+ node: [
+ {
+ id: 1,
+ next: 12,
+ root: true
+ },
+ {
+ id: 12,
+ next: 13
+ },
+ {
+ id: 13,
+ next: null
+ }
+ ]
+ }]
+ }
+};
+
+
diff --git a/demo/demo.html b/demo/demo.html
index 25383bb..401ac6c 100644
--- a/demo/demo.html
+++ b/demo/demo.html
@@ -35,7 +35,8 @@
const Engine = SV.Engine,
Group = SV.Group,
Bound = SV.Bound,
- G6 = SV.G6;
+ G6 = SV.G6,
+ Vector = SV.Vector;
@@ -44,11 +45,14 @@ const Engine = SV.Engine,
+
+
+