How to set symbols in a legend?

Viewed 40

I'm newbie in D3 and I'm trying to set a symbol on the left of the text of a legend. The legend is on the right of the graphic and all the texts of the legend are correctly located but I cannot be able to located on their left the symbol which corresponds with the legend.

The function which locate the legend and try to do the same with the symbols are:

  setLegend(canvas, symbols, width, offset_right, height) {
    canvas
      .selectAll("legends")
      .data(symbols)
      .enter()
      .append("text")
      .attr("transform", function(d, i) {
        let x = width - offset_right + 50;
        let y = height / 2 - 100 + i * 24;
        return "translate( " + x + "," + y + ")";
      })
      .attr(
        "d",
        d3
          .symbol()
          .type(function(d) {
            return d.symbol;
          })
          .size("75")
      )
      .style("text-anchor", "left")
      .text(d => {
        return d.stats;
      })
      .attr("fill", "#FFFFFF")
      .style("font-size", "10pt")
      .style("font-weight", "bold");   }

You can check in this screen cap how the legend is correctly located but there are no any symbol on its left.

enter image description here

You can check all the code of the development in codesanbox:

Edit multiple-scatter-plot

What am I doing wrong?

1 Answers

Right now you're setting an attribute called d to text elements, which has no effect on those texts (only paths have the d attribute). On top of that, you're not appending any path.

A simple and common fix is appending groups in the enter selection, to which you append the paths and texts. Here is an example (I'm setting the x and y positions of the texts so they don't start right over the symbols):

setLegend(canvas, symbols, width, offset_right, height) {
    const groups = canvas
        .selectAll("legends")
        .data(symbols)
        .enter()
        .append("g")
        .attr("transform", function(d, i) {
            let x = width - offset_right + 50;
            let y = height / 2 - 100 + i * 24;
            return "translate( " + x + "," + y + ")";
        });

    groups.append("path")
        .attr("d", d3.symbol().type(function(d) {
            return d.symbol;
        }).size("75"))
        .attr("fill", function(d) {
            return d.color;
        });

    groups.append("text")
        .attr("x", 10)
        .attr("y", 5)
        .style("text-anchor", "left")
        .text(d => {
            return d.stats;
        })
        .attr("fill", function(d) {
            return d.color;
        })
        .style("font-size", "10pt")
        .style("font-weight", "bold");
}
Related