Edit I have found a solution involving using a slightly older version of the dagre-d3 library (4.11). If anyone can find the problem with the latest version, that would help too. Thank you
I'm using Dagre d3 to draw some graphs.
When I initially render my graph, I do
g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function() { return {}; });
var svg = d3.select("svg"),
inner = svg.select("g");
svgGroup = svg.append("g");
var render = new dagreD3.render();
render(d3.select("svg g"), g);
var zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")");
currentZoomScale = d3.event.scale;
currentPosition = d3.event.translate;
});
svg.call(zoom);
Then, when a user clicks on a certain node, I want to append HTML to that node's label. This doesn't show unless I re-render the graph, which I do with the following:
g.node(id).label += "<div>" + inputTemplate + "</div>";
var zoom = d3.behavior.zoom()
.scale(currentZoomScale)
.on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" + "scale(" + d3.event.scale + ")")
});
svg.call(zoom);
d3.select("svg").on("dblclick.zoom", null);
inner.attr("transform", "translate(" + currentPosition + ")" + "scale(" + currentZoomScale + ")");
I thought that by maintaining currentPosition
and currentZoomScale
I would be able to make sure the graph stays well after zooming and re-rendering. But this is not the case. All my nodes become smaller if I zoom out, and larger if I zoom in.
I'm not crystal clear on the problem but could it be because you have included .scale(currentZoomScale)
in the second line of
var zoom = d3.behavior.zoom()
.scale(currentZoomScale)
.on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" + "scale(" + d3.event.scale + ")")
});
svg.call(zoom);
d3.select("svg").on("dblclick.zoom", null);
inner.attr("transform", "translate(" + currentPosition + ")" + "scale(" + currentZoomScale + ")");
and then you're scaling it again in the innner.attr()
?
It seems to me that the problem lies here:
var svg = d3.select("svg"),
inner = svg.select("g");
svgGroup = svg.append("g");
If you look at the order of your code, there is no <g>
when you define inner
. So, at this point, inner
is null
. When you re-render the chart the group is now there, and inner
is no more a null
selection.
Thus, a possible solution is just changing the order:
var svg = d3.select("svg"),
svgGroup = svg.append("g");//we first append the <g>..
inner = svg.select("g");//and only after that we select it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With