Я думаю, что вы в значительной степени были там.
Как вы сказали, сначала нужно добавить большие круги к svg, чтобы они не блокировали меньшие круги под ними. Я думаю, что это проще всего сделать, просто изменив порядок массива данных сразу после того, как вы получите результаты файла json:
d3.json(nameFile).then(function(data) {
data = data.reverse();
...
Затем, чтобы показать круги изнутри, выможно изменить функцию задержки так, чтобы элементы в конце массива, которые вы хотите показать первыми (меньшие кружки), имели наименьшую задержку, а элементы в начале массива, которые вы хотите показать последними (большие кружки)) имеют наибольшую задержку.
Третьим аргументом функции delay()
является NodesList
, содержащий все выбранные элементы DOM, поэтому вы можете использовать свойство length этого массива в своих вычислениях.
...
.delay(function(d, i, circleNodes) {
return 3.4 * ((circleNodes.length - 1) - i);
})
...
let data = [
{"r":5,"cx":100,"cy":100,"fill":"red"}, {"r":10,"cx":100,"cy":100,"fill":"magenta"},{"r":15,"cx":100,"cy":100,"fill":"orange"},{"r":20,"cx":100,"cy":100,"fill":"green"},{"r":25,"cx":100,"cy":100,"fill":"blue"}
];
data = data.reverse();
function plotConsecutively() {
var svg = d3.select('#svg')
.append('svg')
.attr('width', 200)
.attr('height', 200);
svg.selectAll("circle")
.data(data)
.enter()
.append('circle')
.attr('r', function(d) {
return d.r;
})
.attr('cx', function(d) {
return d.cx;
})
.attr('cy', function(d) {
return d.cy;
})
.attr('fill', function(d) {
return d.fill;
})
.attr('visibility', 'hidden')
svg.selectAll('circle')
.transition()
.delay(function(d, i, nodes) {
return 150 * ((nodes.length - 1) - i);
})
.duration(10)
.attr('visibility', 'visible');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<button onclick="plotConsecutively()">Draw Dynamic ►</button>
<div id="svg"></div>