2
我在使用v4时遇到D3中缩放功能的问题。它会抛出一个错误,指出zoom.translate没有被定义。我主要使用下面的代码从这个答案d3 focus on node on click,完美的v3工作。但是,由于我对v3有问题,因为它对源和节点以字符串(而不是索引)形式存在的数据有限制,所以我切换到了v4。v4中的d3缩放功能问题
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height")
active = d3.select(null);
var zoom = d3.zoom()
.scaleExtent([1, 8])
.on("zoom", zoomed);
var color = d3.scaleOrdinal(d3.schemeCategory20);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width/2, height/2));
d3.json("graph.json", function(error, graph) {
if (error) throw error;
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) { return color(d.group); })
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", clicked);
node.append("title")
.text(function(d) { return d.id; });
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
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; })
.attr("cy", function(d) { return d.y; });
}
});
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;
}
function clicked(d){
if (active.node() === this) return reset();
active.classed("active", false);
active = d3.select(this).classed("active", true);
var bbox = active.node().getBBox(),
bounds = [[bbox.x, bbox.y],[bbox.x + bbox.width, bbox.y + bbox.height]];
var dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][1] - bounds[0][1],
x = (bounds[0][0] + bounds[1][0])/2,
y = (bounds[0][1] + bounds[1][1])/2,
scale = Math.max(1, Math.min(8, 0.9/Math.max(dx/width, dy/height))),
translate = [width/2 - scale * x, height/2 - scale * y];
svg.transition()
.duration(750)
.call(zoom.translate(translate).scale(scale).event);
}
function reset() {
active.classed("active", false);
active = d3.select(null);
svg.transition()
.duration(750)
.call(zoom.translate([0, 0]).scale(1).event);
}
function zoomed() {
console.log(d3.event)
g.style("stroke-width", 1.5/d3.event.scale + "px");
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
</script>
我改变d3.behaviour.zoom()
到d3.zoom()
甚至改变
.call(zoom.translate(translate).scale(scale).event);
到
.call(d3.zoom().on("zoom", function() {
svg.attr("transform", d3.event.transform)
}));
其抛出了一个奇怪的错误,错误:未知类型:轮
会是什么克服这种情况的最好方法是什么?
在[我的回答(http://stackoverflow.com/a/41917020/5768908)你刚才的问题,我没有”不要说你应该升级到v4。其实,我向你展示了如何使用v3来做到这一点。 –
不幸的是,我没有数据中的数据,而是在一个JSON文件中。它还能完成吗? – VerletIntegrator
是的,它可以。 JSON只是用于存储数据的语法:您的JSON可能包含一个数组。 –