I am using D3 Js for creating stacked bar chart
DOM currently getting created -
<g fill="#ff7f50">
<rect
id="24-May-2022 02:46 PM (EST)"
x="91.14551083591323"
width="106.99690402476782"
y="320"
height="80"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="30-Apr-2022 12:00 AM (EST)"
x="289.28792569659436"
width="106.99690402476782"
y="294.7368421052632"
height="105.26315789473682"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="31-Mar-2022 12:00 AM (EST)"
x="487.4303405572755"
width="106.99690402476782"
y="144"
height="256"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="28-Feb-2022 12:00 AM (EST)"
x="685.5727554179566"
width="106.99690402476782"
y="377.77777777777777"
height="22.22222222222223"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="31-Jan-2022 12:00 AM (EST)"
x="883.7151702786377"
width="106.99690402476782"
y="352"
height="48"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="31-Dec-2021 12:00 AM (EST)"
x="1081.8575851393189"
width="106.99690402476782"
y="361.9047619047619"
height="38.095238095238074"
>
<text x=".." y="..">Some Text</text>
</rect>
</g>
<g fill="#FF0000">
<rect
id="24-May-2022 02:46 PM (EST)"
x="91.14551083591323"
width="106.99690402476782"
y="280"
height="40"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="30-Apr-2022 12:00 AM (EST)"
x="289.28792569659436"
width="106.99690402476782"
y="84.21052631578947"
height="210.5263157894737"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="31-Mar-2022 12:00 AM (EST)"
x="487.4303405572755"
width="106.99690402476782"
y="127.99999999999999"
height="16.000000000000014"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="28-Feb-2022 12:00 AM (EST)"
x="685.5727554179566"
width="106.99690402476782"
y="355.55555555555554"
height="22.22222222222223"
>
<text x=".." y="..">Some Text</text>
</rect>
<rect
id="31-Jan-2022 12:00 AM (EST)"
x="883.7151702786377"
width="106.99690402476782"
y="320"
height="32"
><text x=".." y="..">Some Text</text></rect>
<rect
id="31-Dec-2021 12:00 AM (EST)"
x="1081.8575851393189"
width="106.99690402476782"
y="361.9047619047619"
height="0"
><text x=".." y="..">Some Text</text></rect>
</g>
<g fill="#90ee90">
<rect
id="24-May-2022 02:46 PM (EST)"
x="91.14551083591323"
width="106.99690402476782"
y="120.00000000000001"
height="160"
><text x=".." y="..">Some Text</text></rect>
<rect
id="30-Apr-2022 12:00 AM (EST)"
x="289.28792569659436"
width="106.99690402476782"
y="31.578947368421062"
height="52.6315789473684"
><text x=".." y="..">Some Text</text></rect>
<rect
id="31-Mar-2022 12:00 AM (EST)"
x="487.4303405572755"
width="106.99690402476782"
y="79.99999999999999"
height="48"
><text x=".." y="..">Some Text</text></rect>
<rect
id="28-Feb-2022 12:00 AM (EST)"
x="685.5727554179566"
width="106.99690402476782"
y="0"
height="355.55555555555554"
><text x=".." y="..">Some Text</text></rect>
<rect
id="31-Jan-2022 12:00 AM (EST)"
x="883.7151702786377"
width="106.99690402476782"
y="79.99999999999999"
height="240"
><text x=".." y="..">Some Text</text></rect>
<rect
id="31-Dec-2021 12:00 AM (EST)"
x="1081.8575851393189"
width="106.99690402476782"
y="0"
height="361.9047619047619"
><text x=".." y="..">Some Text</text></rect>
</g>
In this DOM currently <text>
is getting appended inside <rect>
.
I want this <text>
to be outside <rect>
and within <g>
For each <rect>
there is <text>
. Every <text>
should go outside <rect>
so that it will be viewed as a label on stack.
Code I have written -
var vLayer = svg
.selectAll(".layer")
.data(layers)
.enter()
.join("g")
.attr("class", "layer")
.attr("fill", (layer) => colors[layer.key])
vLayer.selectAll("rect")
.data((layer) => layer)
.join("rect")
.attr("class", "rec")
.attr("id", (sequence) => sequence.data.name)
.attr(
"x",
(sequence) => x0Scale(sequence.data.name) // x1Scale(sequence.data.type)
)
.attr("width", x0Scale.bandwidth())
.attr("y", (sequence) => yScale(sequence[1]))
.attr("height", (sequence) => yScale(sequence[0]) - yScale(sequence[1]))
vLayer.selectAll("rect")
.append("text")
.style("text-anchor", "middle")
.style("font-size", "26px")
.style("font-family", "poppins_regular")
.style("font-weight", "bold")
.style("fill", "white")
.attr("x", width - x0Scale.bandwidth())
.attr("y", 50)
.text(function (data, i) {
return "some text";
});
CodePudding user response:
Instead of doing a selection for "rects" and trying to append "texts" right after, you could simply make a selection for "texts" and join those with the already bound data, similar as to what you did when appending "rects":
// vLayer.selectAll("rect")
// .append("text")
vLayer.selectAll("text")
.data((layer) => layer)
.join("text")
.style("text-anchor", "middle")
.style("font-size", "26px")
.style("font-family", "poppins_regular")
.style("font-weight", "bold")
.style("fill", "white")
.attr("x", width - x0Scale.bandwidth())
.attr("y", 50)
.text(function (data, i) {
return "some text";
});
Not sure if this will completely solve your issue, especially with the groups. It would be great if you could provide "layers" dataset to verify.
On a sidenote, your .svg seems to contain nested rects, is that intended?