Это ...
let u2 = chart2.selectAll()
... - это то же самое, что и ...
let u2 = chart2.selectAll(null)
... что является лучшим способом гарантировать ваш выбор ввода всегда имеет все элементов в массиве данных. Вы можете прочитать об этом здесь: Выбор нуля: что является причиной выбора 'selectAll (null)' в D3.js?
Очевидно, это не то, что вы хотите. Итак, простое исправление:
let u2 = chart2.selectAll("rect")
Кроме того, рассмотрите возможность использования ключевой функции, иначе вы будете объединять данные по их индексам.
Вот ваш код с этим изменением:
<body>
<button onclick="updateData()">Update</button>
<!-- Bar Chart for SVG-->
<svg width="500" height="500" id="svg2">
</svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//Bar Chart
//Creating data
let data2 = [{
name: 'A',
value: Math.floor(Math.random() * 100)
},
{
name: 'B',
value: Math.floor(Math.random() * 100)
},
{
name: 'C',
value: Math.floor(Math.random() * 100)
},
{
name: 'D',
value: Math.floor(Math.random() * 100)
},
{
name: 'E',
value: Math.floor(Math.random() * 100)
},
{
name: 'F',
value: Math.floor(Math.random() * 100)
},
{
name: 'G',
value: Math.floor(Math.random() * 100)
},
{
name: 'H',
value: Math.floor(Math.random() * 100)
},
{
name: 'I',
value: Math.floor(Math.random() * 100)
},
{
name: 'J',
value: Math.floor(Math.random() * 100)
}
]
//Creating svg, margin, width, height
let svg2 = d3.select("#svg2")
let margin = 30;
let width = 500 - 2 * margin;
let height = 500 - 2 * margin;
//Creating chart by using g in svg2.
let chart2 = svg2.append('g')
.attr('transform', 'translate(30, 30)');
//yScale
let yScale2 = d3.scaleLinear()
.range([height, 0])
.domain([0, 100]);
//append g to create y axis
chart2.append('g')
.call(d3.axisLeft(yScale2));
//xScale
let xScale2 = d3.scaleBand()
.range([0, width])
.domain(data2.map((d) => d.name))
.padding(0.2);
//append g to create x axis
chart2.append('g')
.attr('transform', 'translate(0, 440)')
.call(d3.axisBottom(xScale2));
//Creating color scale using scaleOrdinal and schemeCategory10
let colorScale = d3.scaleOrdinal(d3.schemeCategory10)
//Selecting all in chart2 to set/append rectangular, and axis.
chart2.selectAll()
.data(data2)
.enter()
.append('rect')
.attr('x', (d) => xScale2(d.name))
.attr('y', (d) => yScale2(d.value))
.attr('height', (d) => height - yScale2(d.value))
.attr('width', xScale2.bandwidth())
//Putting colors on the bar
chart2.selectAll('rect')
.style('fill', d => colorScale(d.name));
function updateData() {
let data2 = [{
name: 'A',
value: Math.floor(Math.random() * 100)
},
{
name: 'B',
value: Math.floor(Math.random() * 100)
},
{
name: 'C',
value: Math.floor(Math.random() * 100)
},
{
name: 'D',
value: Math.floor(Math.random() * 100)
},
{
name: 'E',
value: Math.floor(Math.random() * 100)
},
{
name: 'F',
value: Math.floor(Math.random() * 100)
},
{
name: 'G',
value: Math.floor(Math.random() * 100)
},
{
name: 'H',
value: Math.floor(Math.random() * 100)
},
{
name: 'I',
value: Math.floor(Math.random() * 100)
},
{
name: 'J',
value: Math.floor(Math.random() * 100)
}
]
let u2 = chart2.selectAll("rect")
.data(data2)
u2
.enter()
.append('rect')
.merge(u2)
.transition()
.duration(1000)
.attr('x', (d) => xScale2(d.name))
.attr('y', (d) => yScale2(d.value))
.attr('height', (d) => height - yScale2(d.value))
.attr('width', xScale2.bandwidth())
chart2.selectAll('rect')
.style('fill', d => colorScale(d.name));
}
</script>