我最近了解了一个优秀的JS库cola.js。它可以进行部队布局和支援小组。在此了解更多信息:

Cola.js

我创建了一个简单的演示来展示一个带有开放组功能的强制布局。但我对这种开放的行为感到困惑。

我认为当打开一个组时,新的布局应该是基于最后一个布局的微小调整。但现在它重新传输所有节点。为什么?

我从这个环节学到了一些理念:

Offical Demo : Online Graph Exploration

这看起来很复杂。新节点动态添加到图形的坐标应设置为打开组的坐标。不幸的是,它也不能解决我的问题。

以下是我的演示:

var w = 480, h = 420, cola;

var data = {

"nodes": [

{"name": "Top","width": 60,"height": 60},

{"name": "A","width": 60,"height": 60},

{"name": "B","width": 60,"height": 60},

{"name": "C","width": 60,"height": 60},

{"name": "D","width": 60,"height": 60},

{"name": "E","width": 60,"height": 60},

{"name": "F","width": 60,"height": 60},

{"name": "G","width": 60,"height": 60},

{"name": "H","width": 60,"height": 60},

{"name": "I","width": 60,"height": 60}

],

"links": [

{"source": 0,"target": 6},

{"source": 0,"target": 4},

{"source": 0,"target": 3},

{"source": 0,"target": 7},

{"source": 0,"target": 8},

{"source": 6,"target": 0},

{"source": 6,"target": 7},

{"source": 4,"target": 0},

{"source": 4,"target": 3},

{"source": 3,"target": 0},

{"source": 3,"target": 4},

{"source": 7,"target": 0},

{"source": 7,"target": 6},

{"source": 7,"target": 4},

{"source": 8,"target": 0},

{"source": 8,"target": 7}

],

"groups": [

{"leaves": [0,1,2],"groups": [1],"name": "Product"},

{"leaves": [7],"name": "Businness"},

{"leaves": [3,4,6,8,9],"name": "Tech"}

]

};

cola = cola.d3adaptor()

.linkDistance(150)

.avoidOverlaps(true)

.handleDisconnected(true)

.size([w, h]);

svg = d3.select("body").append("svg")

.attr("width", w)

.attr("height", h)

.on("dblclick.zoom", null);

svg.append('rect')

.attr("width", w)

.attr("height", h)

.style("fill", "none")

.style("pointer-events", "all");

svg = svg.append('g');

update(data);

cola.on("tick", function () {

svg.selectAll(".link")

.attr("x1", function (d) { return d.source.x; })

.attr("y1", function (d) { return d.source.y; })

.attr("x2", function (d) { return d.target.x; })

.attr("y2", function (d) { return d.target.y; });

svg.selectAll(".nodeimage").attr("x", function(d){ return d.x - 25 / 2 }).attr("y", function(d){ return d.y - 25 / 2 });

svg.selectAll(".group")

.attr("x", function (d) { return d.bounds.x; })

.attr("y", function (d) { return d.bounds.y; })

.attr("width", function (d) { return d.bounds.width(); })

.attr("height", function (d) { return d.bounds.height(); });

svg.selectAll(".label").attr("x", function (d) {

var w = this.getBBox().width;

return d.x - w/2;

})

.attr("y", function (d) {

var h = this.getBBox().height;

return d.y + 25;

});

svg.selectAll('.groupclosebutton')

.attr("x", function (d) { return d.bounds.x + d.bounds.width() - 20; })

.attr("y", function (d) { return d.bounds.y + 2; });

svg.selectAll('.groupname')

.attr("x", function (d) { return d.bounds.x + 5; })

.attr("y", function (d) { return d.bounds.y + 15; });

});

function update(data){

//data.groups.forEach(function (g) { g.padding = 15; });

cola.nodes(data.nodes).links(data.links).groups(data.groups).start();

var color = ['#d3d4e5', '#f7e0c8', '#dee8f2', '#cbe5c4', '#ededeb'];

var group = svg.selectAll(".group").data(data.groups, function(d) { return d.name;});

group.enter().append("rect")//, ":last-child"

.attr("rx", 8).attr("ry", 8)

.attr("class", "group")

.style("fill", function (d, i) { return color[i%5]; })

.call(cola.drag);

group.exit().remove();

var groupName = svg.selectAll(".groupname").data(data.groups, function(d) { return d.name;});

groupName.enter().append("text")

.attr("class", "groupname")

.attr("width", "40px")

.attr("height", "13px")

.text(function (d) { return d.name; });

groupName.exit().remove();

var link = svg.selectAll(".link").data(data.links, function(d) { return d.source.name+'-'+d.target.name;});

link.enter().append("line").attr("class", "link").style("stroke", "rgb(168, 168, 168)");

link.exit().remove();

var nodes = svg.selectAll('.nodeimage').data(data.nodes, function(d) { return d.name;});

nodes.enter().append('svg:image')

.attr("class", "nodeimage")

.call(cola.drag)

.attr("xlink:href", function(d){

var img = "http://icons.iconarchive.com/icons/hopstarter/sleek-xp-basic/24/Folder-icon.png";

return img;

})

.attr('temp', function(d){

var self = d3.select(this);

self.attr("width", 25);

self.attr("height", 25);

})

.on("dblclick", function(node, index, selection){

d3.event.preventDefault();

openGroup(node);

});

nodes.exit().transition().attr("width", 0).attr("width", 0).remove();

var label = svg.selectAll(".label").data(data.nodes, function(d) { return d.name;});

label.enter().append("text")

.attr("class", "label")

.attr("width", "40")

.attr("height", 15)

.text(function (d) { return d.name; })

.call(cola.drag);

label.exit().remove();

}

function openGroup(node){

var i,j, flag,maxnodes = 3, groupDeletedIndex = -1;

// Delete the node

for(i = 0; i < this.data.nodes.length; i++){

if(this.data.nodes[i].name == node.name){

this.data.nodes.splice(i, 1);

break;

}

}

// Delete old links linked to the node

for(i = this.data.links.length - 1; i >= 0; i--){

if(this.data.links[i].source.name == node.name

|| this.data.links[i].target.name == node.name){

this.data.links.splice(i, 1);

}

}

// Delete the relationship of the node

flag = false;

for(i = 0; i < this.data.groups.length; i++){

for(j = 0; j < this.data.groups[i].leaves.length; j++){

if(this.data.groups[i].leaves[j].name == node.name){

this.data.groups[i].leaves.splice(j, 1);

flag = true;

groupDeletedIndex = i;

break;

}

}

if(flag)break;

}

// Create new nodes belong to openning group

for(var i = 0; i < maxnodes; i++){

var obj = {

name : node.name+'child'+i ,

width : 100,

height : 100,

x:node.x,

y:node.y,

px:node.px,

py:node.py

};

this.data.nodes.push(obj);

if(i%3!=0){

this.data.links.push({// Create demo links

source : this.data.nodes.length-1,

target : Math.floor(Math.random(this.data.nodes.length-1))

});

}

}

// Create a group to contain the new nodes and push to groups

this.data.groups.push({

leaves : [],

name : node.name,

bounds : {x:node.x, y:node.y, X:node.x+100, Y:node.y+100},

padding : 15

});

var begin = this.data.nodes.length - maxnodes;

for(var i = 0; i < maxnodes; i++){

this.data.groups[this.data.groups.length-1].leaves.push(begin+i);

}

if(groupDeletedIndex > -1){

if(!this.data.groups[groupDeletedIndex].groups){

this.data.groups[groupDeletedIndex].groups = [];

}

this.data.groups[groupDeletedIndex].groups.push(this.data.groups.length-1);

}

update(this.data);

}

cola ui ajax,打开组后的新布局不基于最后一个cola.js布局相关推荐

  1. cola ui ajax,Cola-UI 文档中心

    Model可以根据名称管理一到N组数据,这里的数据既可以是string.bool这样的简单数据,也可以是复杂的数据实体和集合.数据的读写通常都是通过Model的get和set方法完成的,Model的g ...

  2. ajax实现两个aspx跳转,请问ajax执行成功后可以跳转到另一个页面吗?

    一只名叫tom的猫 通过ajax读取到写好的jsp,另一个jsp可以放framse或者层都可以,显示就行了123456789$.ajax({                    type: &quo ...

  3. win10家庭版如何打开组策略

    win10家庭版默认是没有组策略的,那我们是不是要重装系统?NO NO NO 我们只需要粘贴一段代码就可以打开组策略. (1)新建一个文本文档,如下图所示 (2)打开文本文件,将下面的代码复制进入, ...

  4. ajax请求成功后打开新开窗口(window.open())被拦截的解决方法

    问题:今天在做项目时需要在ajax请求成功后打开一个新的窗口,此时遇到浏览拦截了新窗口的问题,尝试在ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('clic ...

  5. 使用 Ajax 实现本地化后的客户端消息验证

    來源:http://www.ibm.com/developerworks/cn/web/wa-aj-local/?S_TACT=105AGX52&S_CMP=tec-csdn#download ...

  6. ajax请求 拦截窗口,ajax请求成功后新开窗口window.open()被拦截解决方法

    ajax请求成功后新开窗口window.open()被拦截解决方法 问题: 前面开发项目时碰到一个问题,ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但 ...

  7. win7计算机管理找不到文件夹,Win7系统打开组策略提示找不到文件gpedit.msc怎么办...

    组策略是Windows系统管理员为用户和计算机定义并控制程序.网络资源及操作系统行为的主要工具,不过有win7旗舰版系统用户在打开组策略的时候,却提示"找不到文件gpedit.msc,请确定 ...

  8. win7 找不到 计算机策略组,win7打开组策略报错:找不到资源string.Advanced_EnableSSL3Fallback...

    今天要在组策略里关闭几个端口,每次打开组策略时都弹出一个错误提示框,说是找不到资源"string.Advanced_EnableSSL3Fallback". 找不到资源string ...

  9. win7 找不到 计算机策略组,win7打开组策略提示无权限怎么解决 win7系统组策略如何开启...

    很多win7用户在打开组策略的时候提示无权限打开,无权限打开不是只有在打开或者删除c盘中的文件时才会遇到吗?相信很多win7用户都很好奇,那么遇到组策略需要权限打开的情况怎么解决呢?其实很简单,下面小 ...

最新文章

  1. 机器学习练习数据哪里找?两行代码搞定!
  2. ScrollView’s handy trick--android:fillViewport=quot;truequot;
  3. 由浅到深理解ROS(7)-URDF
  4. python查看数据类型type_python——获取数据类型:type()、isinstance()的使用方法:...
  5. Android 工程师如何快速学会web前段
  6. jar包里java.lang.NoSuchMethodError异常,
  7. 林期苏曼属性标签编辑_标签打印软件如何打印指定日期
  8. solr配置oracle数据源,Solr索引Oracle数据库的基本配置
  9. python调用perl_从Python调用Perl脚本不断返回值
  10. 《终极算法》阅读笔记与摘要(1)-序和第1-2章
  11. 托马斯微积分10版积分简表101 公式修正
  12. php html页面显示乱码怎么解决方法,html网页乱码原因以及解决办法
  13. java date 格式化 yyyymmdd_如何将LocalDate格式化为yyyyMMDD(不含JodaTime)
  14. 软件测试 中静态测试与动态测试的区别
  15. 发表skiller的几个版本
  16. 1575万美元!2023科学突破奖揭晓,AlphaFold、量子计算等突破斩获殊荣
  17. SVO (1)跑数据集
  18. 稍微挖掘一下思维导图XMind潜力以及那个使用XMind的你
  19. mysql嵌套查询;去重,分页综合查询
  20. 6 如何保障项目按期完工? 人人都是项目经理系列(第6/13篇)

热门文章

  1. mysql 删除重复_MySQL查询和删除重复记录
  2. principal java_CAS 单点登录服务端 如何获取到principal
  3. 智源社区AI周刊No.101:DeepMind推出AlphaTensor登Nature封面;stateof.ai发布AI情况报告...
  4. Android GoogleMap接入
  5. 钰泰半导体ETA4034爆款OVP+OCP+NTC+OTP+FAULT五合一方案, 兼容BQ24314
  6. L1正则化降噪,对偶函数的构造,求解含L1正则项的优化问题,梯度投影法
  7. nginx 反向代理和正向代理区别
  8. ffmpeg 常用命令行 (视频-转码)
  9. 软件体系结构描述与建模
  10. EXCEL怎么批量在两字姓名中间加空格