Я пытаюсь понять, как работают методы d3.Я думаю, что я довольно хорошо получаю d3, базовый уровень, конечно, но есть одна странная вещь в методе selectAll, которого я не понимаю.Поэтому, когда я пытаюсь создать и добавить узлы dom к выбранному элементу dom, независимо от того, существует он или нет, иногда он создает четыре узла, два или шесть в других случаях.Чтобы прояснить вопрос, я собираюсь использовать простые примеры.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<svg></svg>
</body>
</html>
JS:
dummyData = [
{
name: 'A',
age: 50
},
{
name: 'B',
age: 20
}
]
svg = d3.select('svg')
.attr('width','500')
.attr('height', '300')
.append('g')
.attr('transform','translate(40, 40)');
function example_1() {
svg.selectAll('circle')
.data(dummyData)
.enter()
.append('circle')
.attr('transform', d => `translate(${d.age}, 20)`)
.attr('cx',32).attr('cy',53)
.attr('r',15);
}
function example_2() {
svg.selectAll('g')
.data(dummyData)
.enter()
.append('circle')
.attr('transform', d => `translate(${d.age}, 20)`)
.attr('cx',32)
.attr('cy',53)
.attr('r',15);
}
function example_3() {
svg.selectAll('div') // This div is an arbitrary value. It can be any html tag to output the same result
.data(dummyData)
.enter()
.append('circle')
.attr('transform', d => `translate(${d.age}, 20)`)
.attr('cx',32)
.attr('cy',53)
.attr('r',15);
}
function example_4() {
svg.selectAll('g')
.data(dummyData)
.enter()
.append('circle')
.attr('transform', d => `translate(${d.age}, 20)`)
.attr('cx',32)
.attr('cy',53)
.attr('r',15);
svg.selectAll('g')
.data(dummyData)
.enter()
.append('path')
.attr('stroke','#000')
.attr('d',`M5,5H500`)
}
function example_5() {
svg.selectAll('g')
.data(dummyData)
.enter()
.append('circle')
.attr('transform', d => `translate(${d.age}, 20)`)
.attr('cx',32)
.attr('cy',53)
.attr('r',15);
svg.selectAll('g')
.data(dummyData)
.enter()
.append('g')
.append('path')
.attr('stroke','#000')
.attr('d',`M5,5H500`)
}
example_1(); // This one creates DOM as:
<svg>
<g>
<circle></circle>
<circle></circle>
</g>
</svg>
example_2(); // This one creates DOM as:
<svg>
<g>
<circle></circle>
<circle></circle>
<circle></circle>
<circle></circle>
</g>
</svg>
example_3(); // This one creates DOM as:
<svg>
<g>
<circle></circle>
<circle></circle>
<circle></circle>
<circle></circle>
</g>
</svg>
example_4(); // This one creates DOM as:
<svg>
<g>
<circle></circle>
<circle></circle>
<path></path>
<path></path>
<circle></circle>
<circle></circle>
<path></path>
<path></path>
</g>
</svg>
example_5(); // This one creates DOM as:
<svg>
<g>
<circle></circle>
<circle></circle>
<g>
<path></path>
</g>
<g>
<path></path>
</g>
</g>
</svg>
Переменная svg is domузел g как дочерний элемент SVG в моем примере.Это означает, что у него нет ни круга, ни g, ни div в качестве дочернего элемента.Тогда для чего используется метод selectAll?Почему мы не можем просто написать как
svg.data(dummyData)
.enter()
.append('circle')
.attr('transform', d => `translate(${d.age}, 20)`)
.attr('cx',32).attr('cy',53)
.attr('r',15);
Хотя я пробовал с более разными примерами, все ведет себя по-разному, но я действительно не вижу, что происходит за кулисами.Пожалуйста, помогите мне понять хотя бы немного.Я очень смущен.