В вашем цикле вы добавляете элементы только первый раз в цикле: в массиве данных 20 элементов, прямоугольников в svg нет, поэтому вводятся все 20 элементов. Во второй раз в массиве данных 20 элементов, в svg 20 прямоугольников, поэтому выбор ввода пуст, новые данные просто связаны с 20 существующими прямоугольниками.
В качестве альтернативного подхода к другому ответу ваши данные не выглядят иерархическими, но у вас есть иерархическая структура. Если ваша структура данных совпадает с вашей структурой DOM, то это будет гораздо проще. Давайте немного реструктурируем ваши данные:
var combined = [];
for (let i = 0; i < data.length; i++) {
combined.push(...data[i].results);
}
Теперь наши данные:
[
{vote_count: 17968, id: 19995, video: false, vote_average: 7.4, title: "Avatar", …,}
{...},
{...},
...
И все объекты, которые должны отображаться, находятся в одном массиве, один элемент в массиве, один элемент для добавления на диаграмму. Теперь мы можем сделать простой цикл ввода:
svg.selectAll('rect')
.data(combined)
.enter()
.append('rect')
.style('fill', 'red')
.attr('width', xScale.bandwidth())
.attr('height', 70)
.attr('x', function (d) {
return xScale(d.title);
})
.attr('y', function (d) {
return yScale.bandwidth() + 175;
});
Как правило, если вам нужен цикл для ввода элементов в DOM, вы не используете idiomatic d3. Избегая цикла for для ввода элементов, масштабирование также становится проще, потому что мы не обновляем его постоянно, поскольку мы циклически перебираем родительский массив. Домен масштаба и диапазон должны быть установлены только один раз.
Вот обновленный codepen .
Теперь 2000 элементов приведут к очень маленьким прямоугольникам, возможно, шириной менее одного пикселя, и я не уверен, почему вы так масштабируете высоту столбцов, но это разные вопросы.