我是D3的新手,我似乎找不到在D3.js v4强制导向图上同时实现节点标签和缩放/平移的方法。我的代码如下。
非常感谢任何帮助
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: black ;
stroke-width: 0px;
}
.svg-container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%;
vertical-align: top;
overflow: hidden;
}
.svg-content {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
</style>
<div id="container" class="svg-container">
</div>
<!--<svg viewBox="0 0 300 300"></svg>-->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var width = 3000;
var height = 3000;
//create somewhere to put the force directed graph
var svg = d3.select("div#container")
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 3000 3000")
.classed("svg-content", true);
var color = d3.scaleOrdinal(d3.schemeCategory20);
var radius = 5;
var nodes_data; // global
var links_data; // global
d3.json("features_map_export.json", function(error, data) {
nodes_data = data.nodes
links_data = data.links
var simulation = d3.forceSimulation()
.nodes(nodes_data);
var link_force = d3.forceLink(links_data)
.id(function(d) { return d.name; });
var charge_force = d3.forceManyBody()
.strength(-100);
var center_force = d3.forceCenter(width / 2, height / 2);
simulation
.force("charge_force", charge_force)
.force("center_force", center_force)
.force("links",link_force)
;
//add tick instructions:
simulation.on("tick", tickActions );
//add encompassing group for the zoom
var g = svg.append("g")
.attr("class", "everything");
//draw lines for the links
var link = g.append("g")
.attr("class", "links")
.selectAll("line")
.data(links_data)
.enter().append("line")
.attr("stroke-width", 2)
.style("stroke", linkColour);
//draw circles for the nodes
var node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes_data)
.enter()
.append("circle")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); });
node.append("title")
.text(function(d) { return d.name; });
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.category });
//add drag capabilities
var drag_handler = d3.drag()
.on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end);
drag_handler(node);
//add zoom capabilities
var zoom_handler = d3.zoom()
.on("zoom", zoom_actions);
zoom_handler(svg);
/** Functions **/
//Function to choose what color circle we have
//Let's return blue for males and red for females
function circleColour(d){
return "pink";
}
//Function to choose the line colour and thickness
//If the link type is "A" return green
//If the link type is "E" return red
function linkColour(d){
return "green";
}
//Drag functions
//d is the node
function drag_start(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
//make sure you can't drag the circle outside the box
function drag_drag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function drag_end(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
//Zoom functions
function zoom_actions(){
g.attr("transform", d3.event.transform)
}
function tickActions() {
//update circle positions each tick of the simulation
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 + ")"; });;
//update link positions
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>
答案 0 :(得分:3)
我最近在这个领域做了很多工作,看看这个完整的解决方案... ...
http://plnkr.co/edit/ZSmvH05nnAD6cYZb0EM4?p=preview
这里的关键点是:
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
然后只包括锅炉板拖动功能:
//Used to drag the graph round the screen
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
对于缩放,这只是将缩放处理程序附加到顶级svg容器的情况...有关详细信息,请参阅Plunker。
svg.call(zoom_handler)
.call(zoom_handler.transform, d3.zoomIdentity.scale(1,1))
;
可以通过更改比例值来设置初始缩放:
.call(zoom_handler.transform, d3.zoomIdentity.scale(0.5,0.5))
将是一半大小。
至于贴上你的标签,这应该是从Plunker中显而易见的。
希望这有帮助