I am creating a zoomable sunburst similar to this example. The problem is that I've got a lot of data in my sunburst, so the text labels are mushed together and hardly readable. Therefore I would like to hide the labels when they are too small, like in this d3.partition.layout example. How do I go about implementing this feature?
Asked
Active
Viewed 5,099 times
2 Answers
2
I just got this working by adding the following:
var kx = width / root.dx, ky = height / 1;
Then in the text declaration section do the following:
var text = g.append("text")
.attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
.attr("x", function(d) { return y(d.y); })
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.attr("opacity", function(d) { return d.dx * ky > 10 ? 1 : 0; })
.text(function(d) { return d.name; });
The key part of the above is this line:
.attr("opacity", function(d) { return d.dx * ky > 10 ? 1 : 0; })
This sets the opacity to 0 if it is not big enough. Then in the click function you need to do the same thing, as so:
function click(d) {
// fade out all text elements
text.transition().attr("opacity", 0);
kx = (d.y ? width - 40 : width) / (1 - d.y);
ky = height / d.dx;
path.transition()
.duration(750)
.attrTween("d", arcTween(d))
.each("end", function(e, i) {
// check if the animated element's data e lies within the visible angle span given in d
if (e.x >= d.x && e.x < (d.x + d.dx)) {
// get a selection of the associated text element
var arcText = d3.select(this.parentNode).select("text");
// fade in the text element and recalculate positions
arcText.transition().duration(750)
.attr("opacity", 1)
.text(function(d) { return d.name; })
.attr("opacity", function(d) { return e.dx * ky > 10 ? 1 : 0; })
.attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" })
.attr("x", function(d) { return y(d.y); });
}
});
}

Dan Herman
- 1,395
- 1
- 15
- 26
0
To implement this in general, you will need to draw the text element, get its actual size using getBBox()
and depending on that size, either show it or not. The code would look something like this.
svg.append("text")
.style("opacity", function() {
var box = this.getBBox();
if(box.width <= available.width && box.height <= available.height) {
return 1; // fits, show the text
} else {
return 0; // does not fit, make transparent
}
});
You can of course also remove the text
element completely, but that would require a separate pass.

Lars Kotthoff
- 107,425
- 16
- 204
- 204
-
In my case, `this.getBBox();` always return `SVGRect {height: 0, width: 0, y: 0, x: 0} `. =/ – Elfayer Jun 04 '14 at 09:13
-
Have you set the content? You may want to ask a separate question about this. – Lars Kotthoff Jun 04 '14 at 16:02