d97*_*996 12 ajax json d3.js force-layout
我正在使用d3.js和jquery与PHP后端(基于yii框架)来创建动态力导向图,以表示我们使用Nagios监视的网络上的主机和服务的当前状态.
该图显示了root - > hostgroups - > hosts - > services.我已经创建了一个服务器端函数来以下列格式返回JSON对象
{
"nodes": [
{
"name": "MaaS",
"object_id": 0
},
{
"name": "Convergence",
"object_id": "531",
"colour": "#999900"
},
{
"name": "maas-servers",
"object_id": "719",
"colour": "#999900"
},
{
"name": "hrg-cube",
"object_id": "400",
"colour": "#660033"
}
],
"links": [
{
"source": 0,
"target": "531"
},
{
"source": 0,
"target": "719"
},
{
"source": "719",
"target": "400"
}
]
}
Run Code Online (Sandbox Code Playgroud)
节点包含在链接中使用的对象id和用于显示节点状态的颜色(OK =绿色,WARNING =黄色等)链接具有节点的源对象id和目标对象id.在监视系统中添加或删除新主机时,节点和链接可能会发生变化
我有以下代码设置初始SVG,然后每10秒
力量开始了
$ .ajaxSetup({cache:false}); width = 960,height = 500; node = []; link = []; force = d3.layout.force().charge(-1000).linkDistance(1).size([width,height]);
svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g");
setInterval(function(){
$.ajax({
url: "<?php echo $url;?>",
type: "post",
async: false,
datatype: "json",
success: function(json, textStatus, XMLHttpRequest)
{
json = $.parseJSON(json);
var nodeMap = {};
json.nodes.forEach(function(x) { nodeMap[x.object_id] = x; });
json.links = json.links.map(function(x) {
return {
source: nodeMap[x.source],
target: nodeMap[x.target],
};
});
link = svg.selectAll("line")
.data(json.links);
node = svg.selectAll("circle")
.data(json.nodes,function(d){return d.object_id})
link.enter().append("line").attr("stroke-width",1).attr('stroke','#999');
link.exit().remove();
node.enter().append("circle").attr("r",5);
node.exit().remove();
node.attr("fill",function(d){return d.colour});
node.append("title")
.text(function(d) { return d.name; });
node.call(force.drag);
force
.nodes(node.data())
.links(link.data())
.start()
force.on("tick", function() {
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; });
node.attr("cx", function(d) { return d.x = Math.max(5, Math.min(width - 5, d.x)); })
.attr("cy", function(d) { return d.y = Math.max(5, Math.min(height - 5, d.y)); });
});
}
});
},10000);
Run Code Online (Sandbox Code Playgroud)可以在网络可视化中看到输出的示例
所有上述操作都正常,但每次代码循环时都会导致可视化重新启动,节点都会反弹直到它们稳定下来.我需要的是任何当前项目保持不变,但任何新节点和链接都添加到可视化中,并且可点击和拖动等.
如果有人可以提供帮助,我将永远感激不尽.
我已经设法使用上述所有建议的混合物找到问题的解决方案,下面是我使用的代码
var width = $(document).width();
var height = $(document).height();
var outer = d3.select("#chart")
.append("svg:svg")
.attr("width", width)
.attr("height", height)
.attr("pointer-events", "all");
var vis = outer
.append('svg:g')
.call(d3.behavior.zoom().on("zoom", rescale))
.on("dblclick.zoom", null)
.append('svg:g')
vis.append('svg:rect')
.attr('width', width)
.attr('height', height)
.attr('fill', 'white');
var force = d3.layout.force()
.size([width, height])
.nodes([]) // initialize with a single node
.linkDistance(1)
.charge(-500)
.on("tick", tick);
nodes = force.nodes(),
links = force.links();
var node = vis.selectAll(".node"),
link = vis.selectAll(".link");
redraw();
setInterval(function(){
$.ajax({
url: "<?php echo $url;?>",
type: "post",
async: false,
datatype: "json",
success: function(json, textStatus, XMLHttpRequest)
{
var current_nodes = [];
var delete_nodes = [];
var json = $.parseJSON(json);
$.each(json.nodes, function (i,data){
result = $.grep(nodes, function(e){ return e.object_id == data.object_id; });
if (!result.length)
{
nodes.push(data);
}
else
{
pos = nodes.map(function(e) { return e.object_id; }).indexOf(data.object_id);
nodes[pos].colour = data.colour;
}
current_nodes.push(data.object_id);
});
$.each(nodes,function(i,data){
if(current_nodes.indexOf(data.object_id) == -1)
{
delete_nodes.push(data.index);
}
});
$.each(delete_nodes,function(i,data){
nodes.splice(data,1);
});
var nodeMap = {};
nodes.forEach(function(x) { nodeMap[x.object_id] = x; });
links = json.links.map(function(x) {
return {
source: nodeMap[x.source],
target: nodeMap[x.target],
colour: x.colour,
};
});
redraw();
}
});
},2000);
function redraw()
{
node = node.data(nodes,function(d){ return d.object_id;});
node.enter().insert("circle")
.attr("r", 5)
node.attr("fill", function(d){return d.colour})
node.exit().remove();
link = link.data(links);
link.enter().append("line")
.attr("stroke-width",1)
link.attr('stroke',function(d){return d.colour});
link.exit().remove();
force.start();
}
function tick() {
link.attr("x1", function(d) { return Math.round(d.source.x); })
.attr("y1", function(d) { return Math.round(d.source.y); })
.attr("x2", function(d) { return Math.round(d.target.x); })
.attr("y2", function(d) { return Math.round(d.target.y); });
node.attr("cx", function(d) { return Math.round(d.x); })
.attr("cy", function(d) { return Math.round(d.y); });
}
function rescale() {
trans=d3.event.translate;
scale=d3.event.scale;
vis.attr("transform",
"translate(" + trans + ")"
+ " scale(" + scale + ")");
}
Run Code Online (Sandbox Code Playgroud)