1

How to place the value text inside each pie chart without framework d3.js.

i have tried using some javascript to get the width. It is the default

getBBox()); // get the SVG width.

I use stroke-dasharray to expand the pie space.

Which way i can get the correct stroke-dasharray size from javascript?

figure {
  background-color: #eee;
  display: block;
  height: 0;
  margin: 0 auto;
  position: relative;
  font-size:16px;
  font-size:1vw;
  width: 40em;
  padding-bottom: 40em;
}

svg {
  display: block;
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  overflow: visible;
}
circle {
 fill:transparent;
  stroke-width:31.8309886184;
  stroke-dasharray: 0,0,0,100;
  stroke-dashoffset: 25;
  animation: pie1 4s ease both;
}
.pie1 {
  stroke:pink;
}
.pie2 {
  stroke: green;
  -webkit-animation-name: pie2;
  animation-name: pie2;
}
.pie3 {
  stroke: aqua;
  -webkit-animation-name: pie3;
  animation-name: pie3;
}

@keyframes pie1 {
  50%,100% {stroke-dasharray: 40,60,0,0;}
}

@keyframes pie2 {
  50%,100% {stroke-dasharray: 0,40,30,30;}
}

@keyframes pie3 {
  50%,100% {stroke-dasharray: 0,70,30,0;}
}
<body>
<figure>
    <svg class="chart" viewBox="0 0 63.6619772368 63.6619772368">
      <circle class="pie1" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />

      <circle class="pie2" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />
      <circle class="pie3" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />
    </svg>
  </figure>
</body>
Wilker
  • 551
  • 2
  • 6
  • 21

1 Answers1

3

You can't. The getBBox() gets the bounds of the shape. In your case, the shapes are circles centred on the middle of the graph. You would need to use trigonometry to calculate the position for your text.

makeLabel('Pink', 340, 15.9);
makeLabel('Green', 110, 15.9);
makeLabel('Cyan', 210, 15.9);


function makeLabel(text, angle, radius)
{
  const chart = document.getElementById("chart");
  const label = document.createElementNS(chart.namespaceURI, "text");
  label.classList.add("label");
  label.setAttribute("x", 31.83 + Math.cos(angle * Math.PI/180) * radius);
  label.setAttribute("y", 31.83 + Math.sin(angle * Math.PI/180) * radius);
  label.textContent = text;
  chart.appendChild(label);
}
figure {
  background-color: #eee;
  display: block;
  height: 0;
  margin: 0 auto;
  position: relative;
  font-size:16px;
  font-size:1vw;
  width: 40em;
  padding-bottom: 40em;
}

svg {
  display: block;
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  overflow: visible;
}

circle {
 fill:transparent;
  stroke-width:31.8309886184;
  stroke-dasharray: 0,0,0,100;
  stroke-dashoffset: 25;
  animation: pie1 4s ease both;
}

.pie1 {
  stroke:pink;
  stroke-dasharray: 40,60,0,0;
}
.pie2 {
  stroke: green;
  stroke-dasharray: 0,40,30,30;
}
.pie3 {
  stroke: aqua;
  stroke-dasharray: 0,70,30,0;
}

.label {
  font: 3px sans-serif;
  text-anchor: middle;
}
<body>
<figure>
    <svg id="chart" class="chart" viewBox="0 0 63.6619772368 63.6619772368">
      <circle class="pie1" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />
      <circle class="pie2" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />
      <circle class="pie3" cx="31.8309886184" cy="31.8309886184" r="15.9154943092" />
    </svg>
  </figure>
</body>

BTW, that approach for doing pie graphs works most of the time. And may be alright for your case. But in general it is not recommended. Some browsers have trouble rendering circles drawn that way. You might want to consider switching to drawing proper circular sectors.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • 1
    Not so much some browsers as some browsers on some operating systems. Firefox works on some OS, doesn't work on others. May depend on graphics cards too. – Robert Longson Jan 06 '20 at 18:21
  • Cool. trigonometry! Other, reminders some browser didn't get support. Thank Paul. – Wilker Jan 07 '20 at 01:19
  • @Wilker What I mean by "trouble rendering circles like that" is this: When the stroke-width is such that the inside of the stroke for the entire circle coincides at a single point (the centre of the circle), sometimes weirdness can be visible at that location. Especially when the circle is blown up to a large size, So, if possible, avoiding that is recommended. – Paul LeBeau Jan 07 '20 at 18:30