I'm trying to implement something like "Gauge graph" (or donut chart) using D3.js for dataset that represents binding between statuses of network devices and quantity of devices having such status:
{
"Operational": 1,
"Warning": 4,
"Offline": 2,
...
}
Dataset may change over time: some other statuses can be added, some of the statuses can be removed, and/or quantity numbers can be also changed.
I've implemented the logic to do that, but sometimes on some particular datasets it breaks the structure of the root SVG element.
Steps to reproduce
To reproduce it open this JSFiddle: as you see, everything works fine: each <path> is under their parent <g>.
<svg width="400" height="200" viewBox="-200,-150,400,200" style="display: block; max-width: 100%; height: auto; margin: 0 auto;">
<g>
<path d="M-98.99819570566463,-0.5977014496607642A99,99,0,0,1,-80.2110753965349,-58.02743647389048L-54.39727983232389,-39.11439564717636A67,67,0,0,0,-66.99733392439637,-0.5977014496607781Z" fill="green"></path>
</g>
<g>
<path d="M-79.50457242815314,-58.991719444482634A99,99,0,0,1,-0.10270506233973228,-98.9999467255926L-0.2627087045622808,-66.99948495426325A67,67,0,0,0,-53.69077686394212,-40.078678617768546Z" fill="lightblue"></path>
</g>
<g>
<path d="M1.0926828944767046,-98.99396973600017A99,99,0,0,1,98.99819570566463,-0.5977014496607955L66.99733392439637,-0.5977014496607884A67,67,0,0,0,0.9326792522541477,-66.99350796467084Z" fill="red"></path>
</g>
</svg>
Screenshot: JSFiddle - correct example
But when I change the dataset by clicking on "Use 2nd dataset" button, I see that 2 of the <path>s are under the same <g>, and one of the <g>s is empty:
<svg width="400" height="200" viewBox="-200,-150,400,200" style="display: block; max-width: 100%; height: auto; margin: 0 auto;">
<g>
<path d="M-98.99819570566463,-0.5977014496607642A99,99,0,0,1,-70.25076521837927,-69.75550147645815L-47.67937956857289,-47.07097581265926A67,67,0,0,0,-66.99733392439637,-0.5977014496607781Z" fill="lightblue"></path>
<path d="M-69.4033771719701,-70.59866313978799A99,99,0,0,1,90.99166365362825,-39.006629507623266L61.5038381189291,-26.575889385692513A67,67,0,0,0,-46.83199152216371,-47.914137475989136Z" fill="green"></path>
</g>
<g>
</g>
<g>
<path d="M91.45601811020627,-37.905101918153754A99,99,0,0,1,98.99819570566463,-0.5977014496607516L66.99733392439637,-0.5977014496607587A67,67,0,0,0,61.9681925755071,-25.474361796223004Z" fill="red"></path>
</g>
</svg>
Screenshot: JSFiddle - broken layout
It still looks fine, but this incorrect structure breaks the logic when data changes again.
Question
My question is: what I'm doing wrong? I suppose that the problem is in the data join key function, but I cannot understand the root cause.
Playground
See my JSFiddle.
I think it has to do with modifying the same svg each time. I'm not sure exactly why your error is happening, but it seems like the pieces of the pie reach a point where they no longer adjust between the two dataset values. I was able to fix the issue by resetting the svg each time the button is clicked. The code below removes the old svg and creates a new one.