Reputation: 61
I have been trying to add a horizontal legend to my pie chart. How can I space the groups out depending on the text length?
const legend = d3
.select("svg")
.append("g")
.attr(
"transform",
"translate("200, 10")"
)
.selectAll("g")
.data(this.dataset)
.enter()
.append("g");
legend
.append("rect")
.attr("fill", "green")
.attr("height", 15)
.attr("width", 15);
legend
.append("text")
.attr("x", 18)
.attr("y", 10)
.attr("dy", ".15em")
.text((d) => d.label)
.style("text-anchor", "start")
.style("font-size", 12);
Upvotes: 2
Views: 510
Reputation: 737
First, you should add classes for your containers, as you will need to reselect them.
Then you should try to implement the full d3 update pattern (unless you are not changing the data, otherwise your legend will not update)
Let's assume that g.legend is your legend container and g.legendItem are the different items, each with a rect and a text.
You need to select all the legendItems and cycle through them, eg, with a .each.
Start with a totalWidth = 0
For each one, measure the width (item.getBBox().width), translate the container to the right place and add increment your totalWidth and move to the next.
Here's an example:
var totalWidth = 0;
items = svg.selectAll('g.legendItems')
.each(function() {
var current = d3.select(this);
current.attr('transform', `translate(${totalWidth}, 0)`);
totalWidth += current.node().getBBox().width + 5;
});
Upvotes: 3