Wilker
Wilker

Reputation: 651

Pure svg pie chart, text align center

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>

Upvotes: 1

Views: 1175

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101820

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.

Upvotes: 3

Related Questions