Home > Software design >  Issue with displaying label for the discrete legends after using view box attribute for svg
Issue with displaying label for the discrete legends after using view box attribute for svg

Time:03-26

I have created the discrete legend using svg and I want to show the index as its label.

// creating svg
selectedLegend
.append("svg")
.attr("viewBox", `0 0 ${count} 1`)
.attr("preserveAspectRatio", "none")

function legend(g: any) {
// appending data
g.selectAll("g.legendCells")
.data(itemColor)
.enter()
.append("rect");
// appending text for label, which is not working as expected
g.selectAll("rect")
.append("text")
.attr("class", "breakLabels")
.style("fill", "red")
.attr("x", cellWidth   cellPadding)
.attr("y", 5   cellHeight / 2)
.text(function (d: Record<string, unknown>, i: any) {
// return the index, which should be label for legend
return i;
});
}

Fiddle link : enter image description here

CodePudding user response:

Be careful not to place the <text> elements as children to <rect>. They are independent. The scaling (preserveAspectRatio="none") also apply to the text, so it could be a good idea to have an SVG inside another SVG. The inner SVG has the scaling and the outer SVG has the texts. The outer SVG has a viewBox that matches the height/width ratio (10 to 1 is = to 250 to 25).

On the <text> I added the attributes dominant-baseline="middle" and text-anchor="middle" to position the handle of the text in the middle of it.

<div id="container">
  <svg viewBox="0 0 20 2" width="400px">
    <svg viewBox="0 0 4 1" preserveAspectRatio="none" width="100%" height="1" >
      <rect x="0" y="0" height="1" width="1" style="fill: rgb(255, 46, 0);"/>
      <rect x="1" y="0" height="1" width="1" style="fill: rgb(0, 184, 0);"/>
      <rect x="2" y="0" height="1" width="1" style="fill: rgb(0, 25, 255);"/>
      <rect x="3" y="0" height="1" width="1" style="fill: rgb(179, 179, 179);"/>
    </svg>
    <g dominant-baseline="middle" text-anchor="middle" font-size=".73">
      <text x="2.5" y="1.5" style="fill: black;">0</text>
      <text x="7.5" y="1.5" style="fill: black;">1</text>
      <text x="12.5" y="1.5" style="fill: black;">2</text>
      <text x="17.5" y="1.5" style="fill: black;">3</text>
    </g>
  </svg>
</div>

  • Related