上次文章虽然简单易懂,但很有些小伙伴不满意:你这TWaver和EasyUI结合,只不过生硬地把TWaver图形插进去了,数据和人家EasyUI没一毛钱关系。嘿嘿,不就是想发生关系嘛,没问题啊!咱就还用原来的EasyUI的代码,看看怎么把它表格中的数据用拓扑的方式显示出来。

在本机发布web程序

这次再干咱要有新路,不能再把数据写到代码里了,乱乱乎乎的很不专业,必须原汁原味就用json文件。别小看这一改变,需要在本机搭建服务器,要是原来没接触还真得忙活一阵子。不过这些工作可不白做,那是玩网页开发的基础,让你从此拥有自带专业光环的赶脚。据说现在Node.js比较时髦,咱就拿它开玩!

首先下载安装Node.js文件,接着在命令行状态进入工作目录,运行“npm install express”安装Express 框架,然后用记事本创建一个比如叫server.js的Node.js应用文件,里面输入如下代码:

var http = require('http'), express = require('express'), app = express();
app.use(express.static(__dirname));
http.createServer(app).listen(8080);
console.log("listening the port 8080");
最后使用命令“node server.js”运行之,会看到一个如下图的黑窗口:

怎么,你有黑暗恐惧症?受不了这个黑家伙躲在那里观察你的一举一动?你还千万别关掉它,有它就代表本机服务器运行正常,始终待命随时为你服务,是你开发过程中最好的朋友。那么怎么使用呢?很简单,将来在工作目录创建的网页文件a.html,通过在地址栏输入“http://127.0.0.1/:8080/a.html”,或者“localhost:8080/a.html”,就可以运行了。

接下来,把相关的东西都下载部署到位,别忘了那个json文件。现在只要把源码中相关的文件路径订正一下,熟悉的EasyUI例子页面就可以运行出来了!

读取本地json文件数据

不过,要想数据发生关系首先就要获取数据,当然可以从EasyUI的table中去拿,但是既然咱已经弄了json文件,就和它死磕到底。其实只需要写一个简单的函数,就可以拿到json数据了:

function loadJSON(path,callback){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
if (xhr.status === 200) {
dataJson = JSON.parse(xhr.responseText);
callback && callback();
}
}
};
xhr.open("GET", path, true);
xhr.send();
}

函数中,path是json文件的路径,callback是将来用于处理json数据的方法,dataJson是外部定义过用于存储json数据的变量。

利用json数据创建拓扑

拿到了json数据一切就很easy了,我们用一个循环就把所有产品变成了拓扑图元,再通过自动布局就完美地展示出来了。

不过很容易发现其中有的产品会有两个ProductID完全相同,似乎还可以更直观地表现一下他们这种关系。比如一种方案是,可以让他们成为同一个“虚拟节点”下的子节点,让虚拟节点显示子节点共同的ProductID,而每个子节点显示自己独特的ItemID。

“虚拟节点”——网元的隐身大法

不过TWaver中并没有“虚拟节点”这种东西,其实我们只要把一个正常节点隐藏起来就可以了。但虚拟节点的创建还要动点脑筋,因为没有一个具体的产品与之对应,只能用其子节点的产品来生成,还不能与子节点完全一样。当然这完全难不住我们,可以为创建节点的函数添加一个判断是否为虚拟节点的参数“empty”,就可以对其进行差异化定制了。

function initNode(json){
var item = new twaver.Node();
item.setName("EST");
box.add(item);
for (var i = 0; i < json.rows.length; i++) {
if(i < json.rows.length - 1 && json.rows[i].productid === json.rows[i+1].productid){
var node = createNode(json.rows, i, item, true);
node.s('whole.alpha',0); //隐藏节点
createNode(json.rows, i, node);
createNode(json.rows, i+1, node);
i += 1;
continue;
}else{
createNode(json.rows, i, item);
}
}
autoLayouter.doLayout('symmetry');
}
function createNode(array, i, parent, empty){
var node = new twaver.Node();
node.setName(empty ? array[i].productid : array[i].itemid);
node.setName2(array[i].attr1);
box.add(node);
node.setParent(parent);
var link = new twaver.Link(parent, node);
link.setName(link.getFromNode().getName()!='EST' ? "" : array[i].productid);
link.setName2(empty ? '' : array[i].listprice);
box.add(link);
twaver.Styles.setStyle('label2.color','#ec6c00');
return node;
}
 

不过“虚拟节点”还会带来另外一个问题,就是节点在tree中也会不可见,留下多处空白显得非常奇怪。当然只要恢复其在tree中的正常显示即可,添加以下代码即可解决问题:

tree.setVisibleFunction(function (element) {
return element instanceof twaver.Node;
});

让网元显示更丰富的信息

效果还不错!不过拓扑图上产品显示的信息,还是不如表格全面;要想把所有信息都加在产品网元上,又会显得过于凌乱拥挤。其实还有个很好的办法,就是利用getToolTip设置产品详细信息的标签,只有当鼠标移动到产品网元之上时,才会显示出来。不过这个getToolTip既可以加在node上,也可以加在network上,但效果还是略有不同的。加在node上最为方便,可以在创建node的循环体内直接添加,但这样添加后,不但在拓扑中的网元会显示标签,在tree中的网元也会显示标签,而且是没有换行的一大串。像我这样追求完美的人当然无法忍受了,还是知难而上将其加在了network上,虽然要通过setClient传递参数显得比较麻烦,但出来的效果就比较完美了!

其实说实话这还不能叫完美,因为twaver可以呈现的远远不止于此,还有许多神奇的功能值得我们不断挖掘探索!

还是老规矩,完整代码附后:

<html>
<head>
<meta charset="UTF-8">
<title>Basic Layout - jQuery EasyUI Demo</title>
<link rel="stylesheet" type="text/css" href="../jquery-easyui/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="../jquery-easyui/themes/icon.css">
<link rel="stylesheet" type="text/css" href="../jquery-easyui/demo/demo.css">
<script type="text/javascript" src="../jquery-easyui/jquery.min.js"></script>
<script type="text/javascript" src="../jquery-easyui/jquery.easyui.min.js"></script>
<script src="../twaver-html5/lib/twaver.js"></script>
<script type="text/javascript">
var dataJson = {};
var box = new twaver.ElementBox();
var network = new twaver.vector.Network(box);
var tree = new twaver.controls.Tree(box);
var autoLayouter = new twaver.layout.AutoLayouter(box)
function init(){
loadJSON("./datagrid_data1.json", function(){
initNetwork();
initNode(dataJson);
initTree();
});
}
function initNetwork(){
var centerDiv = document.getElementById('north2');
var view = network.getView();
centerDiv.appendChild(view);
network.adjustBounds({
x: 0,
y: 0,
width: centerDiv.clientWidth,
height: centerDiv.clientHeight
});
network.getToolTip = function (element) {
var array = element.getClient("array");
var i = element.getClient("i");
if(!array) return;
return 'Item ID: ' + array[i].itemid + '</br>' + 'Product ID: ' + array[i].productid + '</br>' + 'List Price: ' + array[i].listprice + '</br>' + 'Unit Cost: ' + array[i].unitcost+ '</br>' + 'Attribute: ' + array[i].attr1;
}
}
function initNode(json){
var item = new twaver.Node();
item.setName("EST");
box.add(item);
for (var i = 0; i < json.rows.length; i++) {
if(i < json.rows.length - 1 && json.rows[i].productid === json.rows[i+1].productid){
var node = createNode(json.rows, i, item, true);
node.s('whole.alpha',0);
createNode(json.rows, i, node);
createNode(json.rows, i+1, node);
i += 1;
continue;
}else{
createNode(json.rows, i, item);
}
}
autoLayouter.doLayout('symmetry', function(){
network.moveElementsToCenter();
});
}
function initTree(){
var treeDom = tree.getView();
var westDiv = document.getElementById('west');
treeDom.style.width = "100%";
treeDom.style.height = "100%";
westDiv.appendChild(treeDom);
tree.setVisibleFunction(function (element) {
return element instanceof twaver.Node;
});
tree.onDataRendered = function (div, data, row, selected) {
var style = div.style;
style.opacity = 1;
};
tree.expandAll();
}
function createNode(array, i, parent, empty){
var node = new twaver.Node();
node.setName(empty ? array[i].productid : array[i].itemid);
node.setName2(array[i].attr1);
node.setClient("array",array);
node.setClient("i",i);
box.add(node);
node.setParent(parent);
var link = new twaver.Link(parent, node);
link.setName(link.getFromNode().getName()!='EST' ? "" : array[i].productid);
link.setName2(empty ? '' : array[i].listprice);
box.add(link);
twaver.Styles.setStyle('label2.color','#ec6c00');
return node;
}
function loadJSON(path,callback){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
if (xhr.status === 200) {
dataJson = JSON.parse(xhr.responseText);
callback && callback();
}
}
};
xhr.open("GET", path, true);
xhr.send();
}
</script>
</head>
<body onload="init()">
<div class="easyui-layout" style="width:840px;height:640px;">
<div data-options="region:'north'" style="height:10px"></div>
<div data-options="region:'south',split:true" style="height:10px;"></div>
<div data-options="region:'east',split:true" title="East" style="width:100px;"></div>
<div data-options="region:'west',split:true" title="West" style="width:140px; position:relative;" id="west"></div>
<div data-options="region:'center',title:'Main Title',iconCls:'icon-ok'" style=" position:relative;" id="center" >
<div class="easyui-layout" data-options="fit:true">
<div data-options="region:'north',split:true,border:false" style="height:480px" id="north2"></div>
<div data-options="region:'center',border:false">
<table class="easyui-datagrid"
data-options="url:'./datagrid_data1.json',method:'get',border:false,singleSelect:true,fit:true,fitColumns:true">
<thead>
<tr>
<th data-options="field:'itemid',align:'center'" width="20%">Item ID</th>
<th data-options="field:'productid',align:'center'" width="20%">Product ID</th>
<th data-options="field:'listprice',align:'center'" width="15%">List Price</th>
<th data-options="field:'unitcost',align:'center'" width="10%">Unit Cost</th>
<th data-options="field:'attr1'" width="30%">Attribute</th>
<th data-options="field:'status',align:'center'" width="5%">Status</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</body>
</html>

  

 

TWaver初学实战——如何在EasyUI中插入TWaver(续)的更多相关文章

  1. TWaver初学实战——如何在EasyUI中插入TWaver

    TWaver是一款强大的图形界面开发组件,可以很方便地集成到其他开发工具中.今天就用一个小例子来操练如何结合TWaver和EasyUI进行网页开发. 准备工作 俗话说他山之玉可以直接拿来,EasyUI ...

  2. TWaver初学实战——如何在TWaver属性表中添加日历控件?

    在日期输入框中添加日历控件,是一种非常流行和实用的做法.临渊羡鱼不如退而写代码,今天就看看在TWaver中是如何实现的.   资源准备   TWaver的在线使用文档中,就有TWaver Proper ...

  3. 如何在github中插入图片,链接,图片链接(给图片加上链接),文字+图片链接,的实战分享!

    如何在github中插入图片,链接,图片链接(给图片加上链接),文字+图片链接,的实战分享! markdown 1.文字链接: [link-Text](link-URL) [home](https:/ ...

  4. 如何在latex 中插入EPS格式图片

    如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所 ...

  5. 如何在html中插入视频

    如何在html中插入视频 1,插入优酷视频: 在优酷分享界面有个html代码,直接复制放入body中,定义div的align居中即可 2.插入本地视频:用video属性  用mp4格式 <vid ...

  6. 如何在Visio 中插入各种数学公式?

    在Visio 2007老版本中,插入公式可以直接在插入图片中选择,但是在后来的Visio2013中却无法直接通过插入图片的方法插入,那么该如何在visio 2013中插入公式呢? 具体的操作步骤如下: ...

  7. 关于如何在mysql中插入一条数据后,返回这条数据的id

    简单的总结一下如何在mysql中出入一条数据后,返回该条数据的id ,假如之后代码需要这个id,这样做起来就变得非常方便,内容如下: <insert id="insertAndGetI ...

  8. TWaver初学实战——基于HTML5的交互式地铁图

    每天坐地铁,经常看地铁图,有一天突然想到,地铁图不也是一种拓扑结果吗?TWaver到底能与地铁图擦出怎样的火花呢?   想到就干,先到网上找幅参考图.各种风格的地铁图还挺多,甚至有大学生自主设计制作, ...

  9. 如何在office2007中插入MathType教学

    很多人在安装MathType数学公式编辑器时可能会遇到这个问题,MathType安装好了,可是在office2007的菜单栏中没有MathType这个选项卡,也就是说MathType没有成功加载在of ...

随机推荐

  1. mac下svn问题——“.a”(静态库)文件无法上传解决

    mac下svn问题——“.a”(静态库)文件无法上传解决    “.a”(静态库)文件无法上传(svn工具:Versions)          网上查询了一下,说是Xcode自带的svn和Versi ...

  2. zend studio 的注册码-php的编辑器

    zend studio 12.5 patch包: 组织名(倒过来写)+ jar包名称 : com.zend.verifier-xxx.jar 将破解包中的jar包 覆盖原来就有的那个 verifier ...

  3. ios 检测应用程序升级问题

    app 上其实已经有自动检测我们版本的功能.  其实我也觉得对于一个程序员来说检测功能让,系统来维护更合适和合理.开发者只要告诉苹果即可. 然而今天老大非要实现自己版本更新的问题,因此也查找了相关的资 ...

  4. Shell命令合集

    Ccat zdd 浏览文件zdd的内容cat zdd1 zdd2 浏览多个文件的内容cat -n zdd浏览文件zdd的内容并显示行号 cd 回到起始目录,也即刚登陆到系统的目录,cd后面无参数cd ...

  5. JavaScript多线程初步学习

    一.多线程理解 首先,我们要理解什么是多线程,百度百科上说:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一 ...

  6. ArrayList与数组间的转换

    关键句:String[] array = (String[])list.toArray(new String[size]); public class Test { public static voi ...

  7. centos6.5环境下的web项目mysql编码方式导致的中文乱码问题

    最近在centos6.5下部署web项目时网页出现中文乱码的问题,在排除掉php之后,把问题锁定在mysql的编码方式上. 解决方法如下: 首先进入mysql命令行,输入命令:SHOW VARIABL ...

  8. 垂直对齐:vertical-align:super属性

    <p style=”vertical-align:super;”>垂直对齐<span>上标</span></p> <p>元素默认为块级元素, ...

  9. Thinkphp5.0支付宝支付扩展库类库大全

    Thinkphp5.0支付宝支付扩展库类库大全,包括手机网站支付.电脑网站支付.支付查询.退款.退款查询.对账单等. Thinkphp5.0支付宝调用方法: 电脑网站支付 Pagepay.php 调用 ...

  10. 内核驱动程序中如何读写user space的文件,方便调试程序

    需要在Linux kernel--大多是在需要调试的驱动程序--中读写文件数据.但是在kernel中操作文件没有标准库可用,需要利用kernel的一些函数,这些函数主要有: filp_open() f ...