我正在使用D3库构建图形可视化。但它给出了一些问题。 可以有多个框,每个框内可以有多个节点。各种链接之间有链接。 节点应该是可拖动的,链接也应该与它们各自的链接一起拖动。 当我应用强制布局时,节点将在各自的框和各自的链接之外创建。 任何帮助将不胜感激。
这是我的jsfiddle链接:http://jsfiddle.net/qfhfzrL2/
var width = 700,
height = 600;
radius =10;
var svg = d3.select("body").append("svg")
.attr("width", 900)
.attr("height", 800)
.style("background-color","#ECE9E9")
.attr("overflow","scroll");
var graph = {
"nodes": [
{"name": "Probe1", "group": "A"},
{"name": "Probe2", "group": "A"},
{"name": "Probe3", "group": "A"},
{"name": "Probe4", "group": "B"},
{"name": "Probe5", "group": "B"},
{"name": "Probe6", "group": "B"},
{"name": "Probe7", "group": "C"}
],
"links": [
{"source": 1, "target": 0, "value": 1},
{"source": 2, "target": 0, "value": 8},
{"source": 3, "target": 0, "value": 10},
{"source": 3, "target": 2, "value": 6},
{"source": 4, "target": 0, "value": 1}
]
};
var outerData = [
{"group": "A"},
{"group": "B"},
{"group": "C"},
{"group": "D"}
];
var outerLayout = d3.layout.force()
.size([800,800])
.charge(-8000)
.gravity(0.1)
.friction(.7)
.links([])
.nodes(outerData)
.on("tick", outerTick)
.start();
var outerNodes = svg.selectAll("g.outer")
.data(outerData//, function (d) {return d.group;}
)
.enter()
.append("g")
.attr("class", "outer")
.attr("id", function (d) {return d.group;})
.call(outerLayout.drag());
outerNodes
.append("rect")
.style("fill", "#ECE9E9")
.style("stroke", "black")
.attr("height",150)
.attr("width",150);
var oNode = svg.selectAll(".outer")
//.data(graph.nodes)
.append("title")
.text(function(d) { return d.group; });
//---------functions
function outerTick (e) {outerNodes.attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")";});
//outerNodes.attr("x", function(d) { return d.x = Math.max(20, Math.min(width, d.x)); })
// .attr("y", function(d) { return d.y = Math.max(20, Math.min(height, d.y)); });
}
function changeForceouter(charge, gravity) {
var tmp = "inner"+"A"+"Layout";
outerLayout .charge(charge).gravity(gravity);
}
setTimeout(function(){ changeForceouter(0,0); }, 2000);
//---------------------------
for(var i=0;i<7;i++)
{
var ident = "#" + graph.nodes[i].group;
svg.select(ident).append("circle")
.attr("r", radius - 2)
.style("fill", "#8DD623" );
}
var force = d3.layout.force()
.gravity(.4)
.charge(-300)
.friction(.7)
.linkDistance(1000)
.linkStrength(0)
.size([width, height]);
var link = svg.selectAll("line")
.data(graph.links)
.enter().append("line")
.style("fill", "green" );
var node = svg.selectAll("circle")
.data(graph.nodes)
//.call(force.drag);
.call(force.drag()
.on("dragstart", function(){
d3.event.sourceEvent.stopPropagation();
})
);
node.append("title")
.text(function(d) { return d.name; });
force
.nodes(graph.nodes)
.links(graph.links)
.on("tick", tick)
.start();
//--------------------------
/*while (force.alpha() >0.005) {
force.tick();
}*/
function changeForce(charge, gravity) {
force.charge(charge).gravity(gravity);
}
//----------------------------
function tick() {
node.attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
.attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, 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; });
}
//---------------------------
/* var populateCell = function(i) {
var ident = "#" + graph.nodes[i].group;
d3.select(ident).append("circle")
.attr("r", radius - .75)
.style("fill", "#8DD623" );
}; */
setTimeout(function(){ changeForce(0, 0);}, 2000);
//changeForce(0, 0);