根据动态JSON数据更新力导向图上的链接

我是D3的新手,正在研究json数据是动态的强制图。我能够在接收到新数据后更改力图,但这会产生弹跳效果。创建我的力图的代码是:

<div class="graph"></div>

<script>

var w = 660,

h = 700,

r = 10;

var vis = d3.select(".graph")

.append("svg:svg")

.attr("width", w)

.attr("height", h)

.attr("pointer-events", "all")

.append('svg:g')

.call(d3.behavior.zoom().on("zoom", redraw))

.append('svg:g');

vis.append('svg:rect')

.attr('width', w)

.attr('height', h)

.attr('fill', 'rgba(1,1,1,0)');

function redraw() {

console.log("here", d3.event.translate, d3.event.scale);

vis.attr("transform", "translate(" + d3.event.translate + ")" +

" scale(" + d3.event.scale + ")");

};

var force = d3.layout.force()

.gravity(.05)

.charge(-200)

.linkDistance( 260 )

.size([w, h]);

var svg = d3.select(".text")

.append("svg")

.attr("width", w)

.attr("height", h);

d3.json(graph, function(json) {

var nodeList = json.nodes;

var link = vis.selectAll("line")

.data(json.links)

.enter()

.append("line")

.attr("stroke-opacity", function(d) {

if(d.label == 'is a') {

return '0.8';

} else {

return '0.2';

};

})

.attr("stroke-width", function(d) {

if(d.value !== null) {

return d.value;

} else {

return 2;

};

})

.style("stroke", function(d) {

if(d.color !== null) {

return d.color;

};

})

.on("mouseover", function() {

d3.select(this)

.style("stroke", "#999999")

.attr("stroke-opacity", "1.0");

})

.on("mouseout", function() {

d3.select(this)

.style("stroke", function(d) {

if(d.color !== null) {

return d.color;

};

})

.attr("stroke-opacity", function(d) {

if(d.label == 'is a') {

return '0.8';

} else {

return '0.2';

};

})

});

link.append("title")

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

var node = vis.selectAll("g.node")

.data(json.nodes)

.enter()

.append("svg:g")

.attr("class","node")

.call(force.drag);

node.append("svg:circle")

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

if (d.size > 0) {

return 10+(d.size*2);

} else {

return 10;

}

})

.attr("id", function(d) { return "Node;"+d.id; } )

.style("fill", function(d) {

if(d.style == 'filled') {

return d.color;

};

})

.style("stroke", function(d) {

if(d.style !== 'filled') {

return d.color;

};

})

.style("stroke-width", "2")

.on("mouseover", function() {

d3.select(this).style("fill", "#999");

fade(.1);

})

.on("mouseout", function(d) {

if (d.style == 'filled') {

d3.select(this).style("fill",d.color);fade(1);

} else {

d3.select(this).style("stroke",d.color);

d3.select(this).style("fill","black");

}

fade(1);

});

node.append("title")

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

force.nodes(json.nodes)

.links(json.links)

.on("tick", tick)

.alpha(1)

.start();

function tick() {

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

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

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

return "translate(" + d.x + "," + d.y + ")";

});

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; });

}

});

</script>

我可以通过再次调用整个函数来在接收到新的json字符串时创建新图。这将创建一个新图代替旧图。接收到值后,我无法使用新的值集更新旧图;我图中的节点没有改变,只是它们之间的关系改变了。

我确实偶然发现了一个示例(http://bl.ocks.org/1095795),其中删除并重新创建了一个新节点,但是实现有些不同。

任何指针或帮助将不胜感激。

回答:

好吧,我可以找到浏览解决方案的方法,并将其发布在此处,以供需要此主题的任何人使用。这个想法是创建图的对象,并处理节点和链接数组。JS代码如下:

var graph;

function myGraph(el) {

// Add and remove elements on the graph object

this.addNode = function (id) {

nodes.push({"id":id});

update();

};

this.removeNode = function (id) {

var i = 0;

var n = findNode(id);

while (i < links.length) {

if ((links[i]['source'] == n)||(links[i]['target'] == n))

{

links.splice(i,1);

}

else i++;

}

nodes.splice(findNodeIndex(id),1);

update();

};

this.removeLink = function (source,target){

for(var i=0;i<links.length;i++)

{

if(links[i].source.id == source && links[i].target.id == target)

{

links.splice(i,1);

break;

}

}

update();

};

this.removeallLinks = function(){

links.splice(0,links.length);

update();

};

this.removeAllNodes = function(){

nodes.splice(0,links.length);

update();

};

this.addLink = function (source, target, value) {

links.push({"source":findNode(source),"target":findNode(target),"value":value});

update();

};

var findNode = function(id) {

for (var i in nodes) {

if (nodes[i]["id"] === id) return nodes[i];};

};

var findNodeIndex = function(id) {

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

if (nodes[i].id==id){

return i;

}

};

};

// set up the D3 visualisation in the specified element

var w = 500,

h = 500;

var vis = d3.select("#svgdiv")

.append("svg:svg")

.attr("width", w)

.attr("height", h)

.attr("id","svg")

.attr("pointer-events", "all")

.attr("viewBox","0 0 "+w+" "+h)

.attr("perserveAspectRatio","xMinYMid")

.append('svg:g');

var force = d3.layout.force();

var nodes = force.nodes(),

links = force.links();

var update = function () {

var link = vis.selectAll("line")

.data(links, function(d) {

return d.source.id + "-" + d.target.id;

});

link.enter().append("line")

.attr("id",function(d){return d.source.id + "-" + d.target.id;})

.attr("class","link");

link.append("title")

.text(function(d){

return d.value;

});

link.exit().remove();

var node = vis.selectAll("g.node")

.data(nodes, function(d) {

return d.id;});

var nodeEnter = node.enter().append("g")

.attr("class", "node")

.call(force.drag);

nodeEnter.append("svg:circle")

.attr("r", 16)

.attr("id",function(d) { return "Node;"+d.id;})

.attr("class","nodeStrokeClass");

nodeEnter.append("svg:text")

.attr("class","textClass")

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

node.exit().remove();

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

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

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; });

});

// Restart the force layout.

force

.gravity(.05)

.distance(50)

.linkDistance( 50 )

.size([w, h])

.start();

};

// Make it all go

update();

}

function drawGraph()

{

graph = new myGraph("#svgdiv");

graph.addNode('A');

graph.addNode('B');

graph.addNode('C');

graph.addLink('A','B','10');

graph.addLink('A','C','8');

graph.addLink('B','C','15');

}

以上是 根据动态JSON数据更新力导向图上的链接 的全部内容, 来源链接: utcz.com/qa/415258.html

回到顶部