TWaver HTML5 + Node.js + express + socket.io + redis(四)
Posted on 2012-02-17 16:45 TWaver 閱讀(2501) 評(píng)論(1) 編輯 收藏在上一篇TWaver HTML5 + Node.js + express + socket.io + redis(三)中,您應(yīng)該對(duì)Node.js的web框架express、實(shí)時(shí)通訊框架Socket.IO、redis客戶端:redis有所了解了。這一篇將介紹TWaver HTML5的拓?fù)浜屯ㄓ媒M件功能,您將了解到:
1. 拓?fù)浣M件:twaver.network.Network2. 樹組件: twaver.controls.Tree
3. 屬性頁(yè): twaver.controls.PropertySheet
4. 表格組件:twaver.controls.Table
5. 布局組件:twaver.controls.SplitPane、BorderPane等
一. 實(shí)現(xiàn)經(jīng)典的左樹右圖效果 首先構(gòu)造網(wǎng)元容器, 樹和拓?fù)浣M件
1 //構(gòu)造網(wǎng)元容器
2 var box = new twaver.ElementBox();
3 //構(gòu)造拓?fù)?/span>
4 var network = new twaver.network.Network(box);
5 //構(gòu)造樹
6 var tree = new twaver.controls.Tree(box);
2 var box = new twaver.ElementBox();
3 //構(gòu)造拓?fù)?/span>
4 var network = new twaver.network.Network(box);
5 //構(gòu)造樹
6 var tree = new twaver.controls.Tree(box);
再構(gòu)造SplitPane, 添加樹和拓?fù)浣M件
1 function init() {
2 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
3 var split = new twaver.controls.SplitPane(tree, network, 'horizontal', 0.3);
4 var view = split.getView();
5 //設(shè)置分割面板占滿屏幕
6 view.style.position = 'absolute';
7 view.style.left = '0px';
8 view.style.right = '0px';
9 view.style.top = '0px';
10 view.style.bottom = '0px';
11 //添加分割面板
12 document.body.appendChild(view);
13 //窗口變化后, 重畫分割面板
14 window.onresize = function () {
15 split.invalidate();
16 }
17 }
2 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
3 var split = new twaver.controls.SplitPane(tree, network, 'horizontal', 0.3);
4 var view = split.getView();
5 //設(shè)置分割面板占滿屏幕
6 view.style.position = 'absolute';
7 view.style.left = '0px';
8 view.style.right = '0px';
9 view.style.top = '0px';
10 view.style.bottom = '0px';
11 //添加分割面板
12 document.body.appendChild(view);
13 //窗口變化后, 重畫分割面板
14 window.onresize = function () {
15 split.invalidate();
16 }
17 }
二. 填充數(shù)據(jù) TWaver HTML5和TWaver其他分支一樣, 所有組件都體現(xiàn)了MVC思想. 用戶使用時(shí), 只需要將業(yè)務(wù)數(shù)據(jù)和TWaver的數(shù)據(jù)模型綁定, 既可以顯示數(shù)據(jù).
twaver.Data是所有數(shù)據(jù)模型的基類, 此類的構(gòu)造函數(shù)支持Object類型的參數(shù), Object對(duì)象里的屬性和twaver.Data的屬性一一對(duì)應(yīng). 所以, 拿到上一篇后臺(tái)的數(shù)據(jù)后,
1 var data = {
2 id: 'from',
3 name: 'From',
4 location: { x: 100, y: 100 }
5 }
2 id: 'from',
3 name: 'From',
4 location: { x: 100, y: 100 }
5 }
可以直接這樣構(gòu)造節(jié)點(diǎn)對(duì)象:
1 var node = new twaver.Node(data);
修改上一篇的onGetData方法, 構(gòu)造節(jié)點(diǎn)和連線
1 //getData消息處理方法
2 function onGetData(datas) {
3 var i, n, nodes, links, node, link, data, from, to;
4 //添加節(jié)點(diǎn)
5 for(i=0, nodes=datas.nodes, n=nodes.length; i<n; i++) {
6 data = nodes[i];
7 //構(gòu)造節(jié)點(diǎn)
8 node = new twaver.Node(data);
9 //添加節(jié)點(diǎn)
10 box.add(node);
11 }
12 //添加連線
13 for(i=0, links=datas.links, n=links.length; i<n; i++) {
14 data = links[i];
15 //查找from節(jié)點(diǎn)
16 from = box.getDataById(data.from);
17 //查找to節(jié)點(diǎn)
18 to = box.getDataById(data.to);
19 //構(gòu)造連線
20 link = new twaver.Link(data.id, from, to);
21 //添加連線
22 box.add(link);
23 }
24 }
2 function onGetData(datas) {
3 var i, n, nodes, links, node, link, data, from, to;
4 //添加節(jié)點(diǎn)
5 for(i=0, nodes=datas.nodes, n=nodes.length; i<n; i++) {
6 data = nodes[i];
7 //構(gòu)造節(jié)點(diǎn)
8 node = new twaver.Node(data);
9 //添加節(jié)點(diǎn)
10 box.add(node);
11 }
12 //添加連線
13 for(i=0, links=datas.links, n=links.length; i<n; i++) {
14 data = links[i];
15 //查找from節(jié)點(diǎn)
16 from = box.getDataById(data.from);
17 //查找to節(jié)點(diǎn)
18 to = box.getDataById(data.to);
19 //構(gòu)造連線
20 link = new twaver.Link(data.id, from, to);
21 //添加連線
22 box.add(link);
23 }
24 }
運(yùn)行效果如下:

三. 添加工具條: 縮放拓?fù)? 添加節(jié)點(diǎn)和連線
首先創(chuàng)建工具條:
1 //創(chuàng)建工具條
2 function createToolbar () {
3 var toolbar = document.createElement('div');
4 //默認(rèn)交互模式
5 addButton(toolbar, 'Default Interaction', 'images/select.png', function () {
6 network.setDefaultInteractions();
7 });
8 //放大
9 addButton(toolbar, 'Zoom In', 'images/zoomIn.png', function () {
10 network.zoomIn();
11 });
12 //縮小
13 addButton(toolbar, 'Zoom Out', 'images/zoomOut.png', function () {
14 network.zoomOut();
15 });
16 //縮放到全圖
17 addButton(toolbar, 'Zoom Overview', 'images/zoomOverview.png', function () {
18 network.zoomOverview();
19 });
20 //還原縮放
21 addButton(toolbar, 'Zoom Reset', 'images/zoomReset.png', function () {
22 network.zoomReset();
23 });
24 //創(chuàng)建節(jié)點(diǎn)
25 addButton(toolbar, 'Create Node', 'images/node_icon.png', function () {
26 network.setCreateElementInteractions();
27 });
28 //創(chuàng)建連線
29 addButton(toolbar, 'Create Link', 'images/link_icon.png', function () {
30 network.setCreateLinkInteractions();
31 });
32 return toolbar;
33 }
2 function createToolbar () {
3 var toolbar = document.createElement('div');
4 //默認(rèn)交互模式
5 addButton(toolbar, 'Default Interaction', 'images/select.png', function () {
6 network.setDefaultInteractions();
7 });
8 //放大
9 addButton(toolbar, 'Zoom In', 'images/zoomIn.png', function () {
10 network.zoomIn();
11 });
12 //縮小
13 addButton(toolbar, 'Zoom Out', 'images/zoomOut.png', function () {
14 network.zoomOut();
15 });
16 //縮放到全圖
17 addButton(toolbar, 'Zoom Overview', 'images/zoomOverview.png', function () {
18 network.zoomOverview();
19 });
20 //還原縮放
21 addButton(toolbar, 'Zoom Reset', 'images/zoomReset.png', function () {
22 network.zoomReset();
23 });
24 //創(chuàng)建節(jié)點(diǎn)
25 addButton(toolbar, 'Create Node', 'images/node_icon.png', function () {
26 network.setCreateElementInteractions();
27 });
28 //創(chuàng)建連線
29 addButton(toolbar, 'Create Link', 'images/link_icon.png', function () {
30 network.setCreateLinkInteractions();
31 });
32 return toolbar;
33 }
然后將工具條和拓?fù)浞湃隑orderPane
1 //創(chuàng)建工具條
2 var toolbar = createToolbar();
3 //創(chuàng)建拓?fù)涿姘?/span>
4 var networkPane = new twaver.controls.BorderPane(network, toolbar);
5 //設(shè)置拓?fù)涿姘迳戏浇M件高度為20
6 networkPane.setTopHeight(20);
7 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
8 var split = new twaver.controls.SplitPane(tree, networkPane, 'horizontal', 0.3);
2 var toolbar = createToolbar();
3 //創(chuàng)建拓?fù)涿姘?/span>
4 var networkPane = new twaver.controls.BorderPane(network, toolbar);
5 //設(shè)置拓?fù)涿姘迳戏浇M件高度為20
6 networkPane.setTopHeight(20);
7 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
8 var split = new twaver.controls.SplitPane(tree, networkPane, 'horizontal', 0.3);
添加按鈕代碼如下:
1 //添加按鈕
2 function addButton (div, name, src, callback) {
3 var button = document.createElement('input');
4 button.setAttribute('type', src ? 'image' : 'button');
5 button.setAttribute('title', name);
6 if (src) {
7 button.style.padding = '4px 4px 4px 4px';
8 button.setAttribute('src', src);
9 } else {
10 button.value = name;
11 }
12 button.onclick = callback;
13 div.appendChild(button);
14 return button;
15 }
2 function addButton (div, name, src, callback) {
3 var button = document.createElement('input');
4 button.setAttribute('type', src ? 'image' : 'button');
5 button.setAttribute('title', name);
6 if (src) {
7 button.style.padding = '4px 4px 4px 4px';
8 button.setAttribute('src', src);
9 } else {
10 button.value = name;
11 }
12 button.onclick = callback;
13 div.appendChild(button);
14 return button;
15 }
效果如下:

四. 添加表格
首先創(chuàng)建表格
1 //構(gòu)造表格
2 var table = new twaver.controls.Table(box);
2 var table = new twaver.controls.Table(box);
然后初始化表格的列
1 //初始化表格列
2 function initTable () {
3 table.setEditable(true);
4 //網(wǎng)元名稱
5 createColumn(table, 'Name', 'name', 'accessor', 'string', true);
6 //網(wǎng)元位置
7 var column = createColumn(table, 'Location', 'location', 'accessor', 'string', false);
8 column.getValue = function (data) {
9 if (data.getLocation) {
10 var location = data.getLocation();
11 return 'X:' + Math.round(location.x) + ', Y:' + Math.round(location.y);
12 }
13 return '';
14 };
15 //網(wǎng)元寬度
16 column = createColumn(table, 'Width', 'width', 'accessor', 'number', true);
17 column.getValue = function (data) {
18 if (data.getWidth) {
19 return Math.round(data.getWidth());
20 }
21 return '';
22 };
23 column.setWidth(50);
24 //網(wǎng)元高度
25 column = createColumn(table, 'Height', 'height', 'accessor', 'number', true);
26 column.getValue = function (data) {
27 if (data.getHeight) {
28 return Math.round(data.getHeight());
29 }
30 return '';
31 };
32 column.setWidth(50);
33 //連線起始節(jié)點(diǎn)
34 column = createColumn(table, 'From', 'from', 'accessor', 'string', false);
35 column.getValue = function (data) {
36 if (data.getFromNode) {
37 return data.getFromNode().getName();
38 }
39 return '';
40 };
41 //連線結(jié)束節(jié)點(diǎn)
42 column = createColumn(table, 'To', 'to', 'accessor', 'string', false);
43 column.getValue = function (data) {
44 if (data.getToNode) {
45 return data.getToNode().getName();
46 }
47 return '';
48 };
49 }
2 function initTable () {
3 table.setEditable(true);
4 //網(wǎng)元名稱
5 createColumn(table, 'Name', 'name', 'accessor', 'string', true);
6 //網(wǎng)元位置
7 var column = createColumn(table, 'Location', 'location', 'accessor', 'string', false);
8 column.getValue = function (data) {
9 if (data.getLocation) {
10 var location = data.getLocation();
11 return 'X:' + Math.round(location.x) + ', Y:' + Math.round(location.y);
12 }
13 return '';
14 };
15 //網(wǎng)元寬度
16 column = createColumn(table, 'Width', 'width', 'accessor', 'number', true);
17 column.getValue = function (data) {
18 if (data.getWidth) {
19 return Math.round(data.getWidth());
20 }
21 return '';
22 };
23 column.setWidth(50);
24 //網(wǎng)元高度
25 column = createColumn(table, 'Height', 'height', 'accessor', 'number', true);
26 column.getValue = function (data) {
27 if (data.getHeight) {
28 return Math.round(data.getHeight());
29 }
30 return '';
31 };
32 column.setWidth(50);
33 //連線起始節(jié)點(diǎn)
34 column = createColumn(table, 'From', 'from', 'accessor', 'string', false);
35 column.getValue = function (data) {
36 if (data.getFromNode) {
37 return data.getFromNode().getName();
38 }
39 return '';
40 };
41 //連線結(jié)束節(jié)點(diǎn)
42 column = createColumn(table, 'To', 'to', 'accessor', 'string', false);
43 column.getValue = function (data) {
44 if (data.getToNode) {
45 return data.getToNode().getName();
46 }
47 return '';
48 };
49 }
添加表格:
1 //初始化表格列
2 initTable();
3 //構(gòu)造表格面板
4 var tablePane = new twaver.controls.TablePane(table);
5 //中間分割面板, 包含拓?fù)涿姘搴捅砀衩姘?/span>
6 var centerSplite = new twaver.controls.SplitPane(networkPane, tablePane, 'vertical', 0.7);
7 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
8 var split = new twaver.controls.SplitPane(tree, centerSplite, 'horizontal', 0.3);
2 initTable();
3 //構(gòu)造表格面板
4 var tablePane = new twaver.controls.TablePane(table);
5 //中間分割面板, 包含拓?fù)涿姘搴捅砀衩姘?/span>
6 var centerSplite = new twaver.controls.SplitPane(networkPane, tablePane, 'vertical', 0.7);
7 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
8 var split = new twaver.controls.SplitPane(tree, centerSplite, 'horizontal', 0.3);
創(chuàng)建表格列代碼如下:
1 //創(chuàng)建表格列
2 function createColumn (table, name, propertyName, propertyType, valueType, editable) {
3 var column = new twaver.Column(name);
4 column.setName(name);
5 column.setPropertyName(propertyName);
6 column.setPropertyType(propertyType);
7 if (valueType) column.setValueType(valueType);
8 column.setEditable(editable);
9 column.renderHeader = function (div) {
10 var span = document.createElement('span');
11 span.style.whiteSpace = 'nowrap';
12 span.style.verticalAlign = 'middle';
13 span.style.padding = '1px 2px 1px 2px';
14 span.innerHTML = column.getName() ? column.getName() : column.getPropertyName();
15 span.setAttribute('title', span.innerHTML);
16 span.style.font = 'bold 12px Helvetica';
17 div.style.textAlign = 'center';
18 div.appendChild(span);
19 };
20 table.getColumnBox().add(column);
21 return column;
22 };
2 function createColumn (table, name, propertyName, propertyType, valueType, editable) {
3 var column = new twaver.Column(name);
4 column.setName(name);
5 column.setPropertyName(propertyName);
6 column.setPropertyType(propertyType);
7 if (valueType) column.setValueType(valueType);
8 column.setEditable(editable);
9 column.renderHeader = function (div) {
10 var span = document.createElement('span');
11 span.style.whiteSpace = 'nowrap';
12 span.style.verticalAlign = 'middle';
13 span.style.padding = '1px 2px 1px 2px';
14 span.innerHTML = column.getName() ? column.getName() : column.getPropertyName();
15 span.setAttribute('title', span.innerHTML);
16 span.style.font = 'bold 12px Helvetica';
17 div.style.textAlign = 'center';
18 div.appendChild(span);
19 };
20 table.getColumnBox().add(column);
21 return column;
22 };
最后效果如下:

五. 添加屬性頁(yè)
首先創(chuàng)建屬性頁(yè)
1 //構(gòu)造屬性頁(yè)
2 var sheet = new twaver.controls.PropertySheet(box);
2 var sheet = new twaver.controls.PropertySheet(box);
然后初始化屬性頁(yè)的屬性
1 //初始化屬性頁(yè)
2 function initPropertySheet () {
3 sheet.setEditable(true);
4 var sheetBox = sheet.getPropertyBox();
5 //網(wǎng)元標(biāo)識(shí)
6 addProperty(sheetBox, 'id', 'Id', 'string', 'accessor', false);
7 //網(wǎng)元名稱
8 addProperty(sheetBox, 'name', 'Name', 'string', 'accessor', true);
9 //網(wǎng)元提示信息
10 addProperty(sheetBox, 'toolTip', 'ToolTip', 'string', 'accessor', true);
11 //僅節(jié)點(diǎn)可見
12 var isNodeVisible = function (data) {
13 return data instanceof twaver.Node;
14 };
15 //網(wǎng)元x坐標(biāo)
16 addProperty(sheetBox, 'x', 'X', 'number', 'accessor', true, isNodeVisible);
17 //網(wǎng)元y坐標(biāo)
18 addProperty(sheetBox, 'y', 'Y', 'number', 'accessor', true, isNodeVisible);
19 //網(wǎng)元寬度
20 addProperty(sheetBox, 'width', 'Width', 'number', 'accessor', true, isNodeVisible);
21 //網(wǎng)元高度
22 addProperty(sheetBox, 'height', 'Height', 'number', 'accessor', true, isNodeVisible);
23 //僅連線可見
24 var isLinkVisible = function (data) {
25 return data instanceof twaver.Link;
26 };
27 //網(wǎng)元x坐標(biāo)
28 addProperty(sheetBox, 'fromNode', 'From Node', 'string', 'accessor', false, isLinkVisible);
29 //網(wǎng)元y坐標(biāo)
30 addProperty(sheetBox, 'toNode', 'To Node', 'string', 'accessor', false, isLinkVisible);
31 }
2 function initPropertySheet () {
3 sheet.setEditable(true);
4 var sheetBox = sheet.getPropertyBox();
5 //網(wǎng)元標(biāo)識(shí)
6 addProperty(sheetBox, 'id', 'Id', 'string', 'accessor', false);
7 //網(wǎng)元名稱
8 addProperty(sheetBox, 'name', 'Name', 'string', 'accessor', true);
9 //網(wǎng)元提示信息
10 addProperty(sheetBox, 'toolTip', 'ToolTip', 'string', 'accessor', true);
11 //僅節(jié)點(diǎn)可見
12 var isNodeVisible = function (data) {
13 return data instanceof twaver.Node;
14 };
15 //網(wǎng)元x坐標(biāo)
16 addProperty(sheetBox, 'x', 'X', 'number', 'accessor', true, isNodeVisible);
17 //網(wǎng)元y坐標(biāo)
18 addProperty(sheetBox, 'y', 'Y', 'number', 'accessor', true, isNodeVisible);
19 //網(wǎng)元寬度
20 addProperty(sheetBox, 'width', 'Width', 'number', 'accessor', true, isNodeVisible);
21 //網(wǎng)元高度
22 addProperty(sheetBox, 'height', 'Height', 'number', 'accessor', true, isNodeVisible);
23 //僅連線可見
24 var isLinkVisible = function (data) {
25 return data instanceof twaver.Link;
26 };
27 //網(wǎng)元x坐標(biāo)
28 addProperty(sheetBox, 'fromNode', 'From Node', 'string', 'accessor', false, isLinkVisible);
29 //網(wǎng)元y坐標(biāo)
30 addProperty(sheetBox, 'toNode', 'To Node', 'string', 'accessor', false, isLinkVisible);
31 }
最后添加屬性頁(yè)
1 //初始化屬性頁(yè)
2 initPropertySheet();
3 //左分割面板, 包含樹和屬性頁(yè)
4 var leftSplite = new twaver.controls.SplitPane(tree, sheet, 'vertical', 0.7);
5 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
6 var split = new twaver.controls.SplitPane(leftSplite, centerSplite, 'horizontal', 0.3);
2 initPropertySheet();
3 //左分割面板, 包含樹和屬性頁(yè)
4 var leftSplite = new twaver.controls.SplitPane(tree, sheet, 'vertical', 0.7);
5 //構(gòu)造左右分割面板, 左邊為樹, 右邊為拓?fù)? 樹占30%寬度
6 var split = new twaver.controls.SplitPane(leftSplite, centerSplite, 'horizontal', 0.3);
創(chuàng)建屬性頁(yè)屬性的代碼如下:
1 //添加屬性頁(yè)屬性
2 function addProperty (box, propertyName, name, valueType, propertyType, editable, isVisible) {
3 var property = new twaver.Property();
4 property.setEditable(editable);
5 property.setPropertyType(propertyType);
6 property.setPropertyName(propertyName);
7 property.setName(name);
8 property.setValueType(valueType);
9 property.isVisible = isVisible;
10
11 box.add(property);
12 return property;
13 }
2 function addProperty (box, propertyName, name, valueType, propertyType, editable, isVisible) {
3 var property = new twaver.Property();
4 property.setEditable(editable);
5 property.setPropertyType(propertyType);
6 property.setPropertyName(propertyName);
7 property.setName(name);
8 property.setValueType(valueType);
9 property.isVisible = isVisible;
10
11 box.add(property);
12 return property;
13 }
最后效果如下:


本文完整代碼見附件TWaver HTML5 Demo(附件只包含demo代碼, 如需要TWaver HTML5產(chǎn)品包, 請(qǐng)參見論壇TWaver HTML5版本即將發(fā)布,敬請(qǐng)期待)