在上一篇TWaver HTML5 + Node.js + express + socket.io + redis(三)中,您应该对Node.js的web框架express、实时通讯框架Socket.IO、redis客户端:redis有所了解了。这一篇将介绍TWaver HTML5的拓扑和通用组件功能,您将了解到:
1. 拓扑组件:twaver.network.Network
2. 树组件: twaver.controls.Tree
3. 属性页: twaver.controls.PropertySheet
4. 表格组件:twaver.controls.Table
5. 布局组件:twaver.controls.SplitPane、BorderPane等
一. 实现经典的左树右图效果 首先构造网元容器, 树和拓扑组件
//构造网元容器 var box = new twaver.ElementBox(); //构造拓扑 var network = new twaver.network.Network(box); //构造树 var tree = new twaver.controls.Tree(box);
再构造SplitPane, 添加树和拓扑组件
function init() { //构造左右分割面板, 左边为树, 右边为拓扑, 树占30%宽度 var split = new twaver.controls.SplitPane(tree, network, 'horizontal', 0.3); var view = split.getView(); //设置分割面板占满屏幕 view.style.position = 'absolute'; view.style.left = '0px'; view.style.right = '0px'; view.style.top = '0px'; view.style.bottom = '0px'; //添加分割面板 document.body.appendChild(view); //窗口变化后, 重画分割面板 window.onresize = function () { split.invalidate(); } }
二. 填充数据 TWaver HTML5和TWaver其他分支一样, 所有组件都体现了MVC思想. 用户使用时, 只需要将业务数据和TWaver的数据模型绑定, 既可以显示数据.
twaver.Data是所有数据模型的基类, 此类的构造函数支持Object类型的参数, Object对象里的属性和twaver.Data的属性一一对应. 所以, 拿到上一篇后台的数据后,
var data = { id: 'from', name: 'From', location: { x: 100, y: 100 } }
可以直接这样构造节点对象:
var node = new twaver.Node(data);
修改上一篇的onGetData方法, 构造节点和连线
//getData消息处理方法 function onGetData(datas) { var i, n, nodes, links, node, link, data, from, to; //添加节点 for(i=0, nodes=datas.nodes, n=nodes.length; i<n; i++) { data = nodes[i]; //构造节点 node = new twaver.Node(data); //添加节点 box.add(node); } //添加连线 for(i=0, links=datas.links, n=links.length; i<n; i++) { data = links[i]; //查找from节点 from = box.getDataById(data.from); //查找to节点 to = box.getDataById(data.to); //构造连线 link = new twaver.Link(data.id, from, to); //添加连线 box.add(link); } }
//创建工具条 function createToolbar () { var toolbar = document.createElement('div'); //默认交互模式 addButton(toolbar, 'Default Interaction', 'images/select.png', function () { network.setDefaultInteractions(); }); //放大 addButton(toolbar, 'Zoom In', 'images/zoomIn.png', function () { network.zoomIn(); }); //缩小 addButton(toolbar, 'Zoom Out', 'images/zoomOut.png', function () { network.zoomOut(); }); //缩放到全图 addButton(toolbar, 'Zoom Overview', 'images/zoomOverview.png', function () { network.zoomOverview(); }); //还原缩放 addButton(toolbar, 'Zoom Reset', 'images/zoomReset.png', function () { network.zoomReset(); }); //创建节点 addButton(toolbar, 'Create Node', 'images/node_icon.png', function () { network.setCreateElementInteractions(); }); //创建连线 addButton(toolbar, 'Create Link', 'images/link_icon.png', function () { network.setCreateLinkInteractions(); }); return toolbar; }
//创建工具条 var toolbar = createToolbar(); //创建拓扑面板 var networkPane = new twaver.controls.BorderPane(network, toolbar); //设置拓扑面板上方组件高度为20 networkPane.setTopHeight(20); //构造左右分割面板, 左边为树, 右边为拓扑, 树占30%宽度 var split = new twaver.controls.SplitPane(tree, networkPane, 'horizontal', 0.3); [/sourcecode] 添加按钮代码如下: [sourcecode language="javascript"] //添加按钮 function addButton (div, name, src, callback) { var button = document.createElement('input'); button.setAttribute('type', src ? 'image' : 'button'); button.setAttribute('title', name); if (src) { button.style.padding = '4px 4px 4px 4px'; button.setAttribute('src', src); } else { button.value = name; } button.onclick = callback; div.appendChild(button); return button; }
//添加按钮 function addButton (div, name, src, callback) { var button = document.createElement('input'); button.setAttribute('type', src ? 'image' : 'button'); button.setAttribute('title', name); if (src) { button.style.padding = '4px 4px 4px 4px'; button.setAttribute('src', src); } else { button.value = name; } button.onclick = callback; div.appendChild(button); return button; }
//构造表格 var table = new twaver.controls.Table(box);
//初始化表格列 function initTable () { table.setEditable(true); //网元名称 createColumn(table, 'Name', 'name', 'accessor', 'string', true); //网元位置 var column = createColumn(table, 'Location', 'location', 'accessor', 'string', false); column.getValue = function (data) { if (data.getLocation) { var location = data.getLocation(); return 'X:' + Math.round(location.x) + ', Y:' + Math.round(location.y); } return ''; }; //网元宽度 column = createColumn(table, 'Width', 'width', 'accessor', 'number', true); column.getValue = function (data) { if (data.getWidth) { return Math.round(data.getWidth()); } return ''; }; column.setWidth(50); //网元高度 column = createColumn(table, 'Height', 'height', 'accessor', 'number', true); column.getValue = function (data) { if (data.getHeight) { return Math.round(data.getHeight()); } return ''; }; column.setWidth(50); //连线起始节点 column = createColumn(table, 'From', 'from', 'accessor', 'string', false); column.getValue = function (data) { if (data.getFromNode) { return data.getFromNode().getName(); } return ''; }; //连线结束节点 column = createColumn(table, 'To', 'to', 'accessor', 'string', false); column.getValue = function (data) { if (data.getToNode) { return data.getToNode().getName(); } return ''; }; }
//初始化表格列 initTable(); //构造表格面板 var tablePane = new twaver.controls.TablePane(table); //中间分割面板, 包含拓扑面板和表格面板 var centerSplite = new twaver.controls.SplitPane(networkPane, tablePane, 'vertical', 0.7); //构造左右分割面板, 左边为树, 右边为拓扑, 树占30%宽度 var split = new twaver.controls.SplitPane(tree, centerSplite, 'horizontal', 0.3);
//创建表格列 function createColumn (table, name, propertyName, propertyType, valueType, editable) { var column = new twaver.Column(name); column.setName(name); column.setPropertyName(propertyName); column.setPropertyType(propertyType); if (valueType) column.setValueType(valueType); column.setEditable(editable); column.renderHeader = function (div) { var span = document.createElement('span'); span.style.whiteSpace = 'nowrap'; span.style.verticalAlign = 'middle'; span.style.padding = '1px 2px 1px 2px'; span.innerHTML = column.getName() ? column.getName() : column.getPropertyName(); span.setAttribute('title', span.innerHTML); span.style.font = 'bold 12px Helvetica'; div.style.textAlign = 'center'; div.appendChild(span); }; table.getColumnBox().add(column); return column; };
//构造属性页 var sheet = new twaver.controls.PropertySheet(box);
//初始化属性页 function initPropertySheet () { sheet.setEditable(true); var sheetBox = sheet.getPropertyBox(); //网元标识 addProperty(sheetBox, 'id', 'Id', 'string', 'accessor', false); //网元名称 addProperty(sheetBox, 'name', 'Name', 'string', 'accessor', true); //网元提示信息 addProperty(sheetBox, 'toolTip', 'ToolTip', 'string', 'accessor', true); //仅节点可见 var isNodeVisible = function (data) { return data instanceof twaver.Node; }; //网元x坐标 addProperty(sheetBox, 'x', 'X', 'number', 'accessor', true, isNodeVisible); //网元y坐标 addProperty(sheetBox, 'y', 'Y', 'number', 'accessor', true, isNodeVisible); //网元宽度 addProperty(sheetBox, 'width', 'Width', 'number', 'accessor', true, isNodeVisible); //网元高度 addProperty(sheetBox, 'height', 'Height', 'number', 'accessor', true, isNodeVisible); //仅连线可见 var isLinkVisible = function (data) { return data instanceof twaver.Link; }; //网元x坐标 addProperty(sheetBox, 'fromNode', 'From Node', 'string', 'accessor', false, isLinkVisible); //网元y坐标 addProperty(sheetBox, 'toNode', 'To Node', 'string', 'accessor', false, isLinkVisible); }
//初始化属性页 initPropertySheet(); //左分割面板, 包含树和属性页 var leftSplite = new twaver.controls.SplitPane(tree, sheet, 'vertical', 0.7); //构造左右分割面板, 左边为树, 右边为拓扑, 树占30%宽度 var split = new twaver.controls.SplitPane(leftSplite, centerSplite, 'horizontal', 0.3);
//添加属性页属性 function addProperty (box, propertyName, name, valueType, propertyType, editable, isVisible) { var property = new twaver.Property(); property.setEditable(editable); property.setPropertyType(propertyType); property.setPropertyName(propertyName); property.setName(name); property.setValueType(valueType); property.isVisible = isVisible; box.add(property); return property; }