Поскольку в вашем вопросе говорилось «предоставьте мне решение» ... я пошел совершенно другим подходом!Я привел пример, который не является готовым к использованию решением, но, надеюсь, послужит хорошим вдохновением для него.
<div>
<svg viewBox="0 0 600 600">
<circle id="bal1"/>
<circle id="bal2" cx="300" cy="120" r="50" fill="magenta"/>
<circle id="bal3" cx="100" cy="500" r="60" fill="cyan" stroke="rgba(0,0,0,0.5)" stroke-width="3"/>
<circle id="bal4" cx="350" cy="450" r="30" fill="red"/>
<text id="txt1" dominant-baseline="middle" text-anchor="middle"><tspan id="tsp1"/></text>
<text id="txt2" x="300" y="120" dominant-baseline="middle" text-anchor="middle"><tspan>50%</tspan></text>
<text id="txt3" x="100" y="500" dominant-baseline="middle" text-anchor="middle"><tspan>60%</tspan></text>
<text id="txt4" x="350" y="450" dominant-baseline="middle" text-anchor="middle" dy="5"><tspan>30%</tspan></text>
</svg>
</div>
и
html, body, div, svg { height: 100vh;
width: 100vw }
html, body { font-size: 0.05em } /* needed for using rem */
#txt1 { font-size: 70rem }
#txt2 { font-size: 50rem }
#txt3 { font-size: 60rem }
#txt4 { font-size: 30rem } /* mind the corresponding to the radius */
#bal4 { fill: red }
#bal1 { fill: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><radialGradient id='grad'><stop offset='0%' stop-color='%23ff00cc'/><stop offset='100%' stop-color='%23333399'/></radialGradient></svg>#grad") purple }
и
/* first radius */
var br1 = 70;
/* here you will have to insert math to avoid overlapping */
var bal1 = document.getElementById('bal1');
var txt1 = document.getElementById('txt1');
bal1.setAttribute("cx", "100");
bal1.setAttribute("cy", "90");
bal1.setAttribute("r", br1);
txt1.setAttribute("x", "100");
txt1.setAttribute("y", "90");
document.getElementById("tsp1").innerHTML = br1 + "%";
Таким образом, позиция шара # 1 / значение текста # 1 являются динамическими.
Пожалуйста, лучше посмотрите это в действии на https://codepen.io/anon/pen/pqzpKP
Теперь я предполагаю, что вы будете использовать его с ограничением текста вокруг.В этом случае сделайте svg внешним (используя, например, PHP) и используйте CSS вроде
div#bla { shape-outside: url('/img/balls.php?r1=70&r2=etc'); /* url-encode? */
shape-margin: 8px;
shape-image-threshold: 0.5;