【发布时间】:2021-10-06 03:01:45
【问题描述】:
我是 D3 的初学者,并开始绘制从 API 检索到的一些数据,例如:
chartData = [
{ track: "A Kind of Magic", playcount: 2683110 },
{ track: "Another One Bites the Dust", playcount: 6425611 },
{ track: "Bohemian Rhapsody", playcount: 10167011 },
{ track: "Crazy Little Thing Called Love", playcount: 4360128},
{ track: "Don't Stop Me Now", playcount: 7762976 },
{ track: "Flash", playcount: 1248561 }];
根据一些在线示例,我已经渲染了条形图:
var margin = {
top: 50,
right: 40,
bottom: 80,
left: 100
},
width = 1200 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select('#queenChart')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g').attr('transform', `translate(${margin.left}, ${margin.top})`);
var x = d3.scaleBand()
.domain(chartData.map(d => d.track))
.range([0, width])
.padding(0.1);
svg.append('g')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(x))
.selectAll('text')
.attr('transform', 'translate(-10,0) rotate(-45)')
.style('text-anchor','end');
var y = d3.scaleLinear()
.domain([0, d3.max(chartData, d => { return d.playcount; })])
.range([height, 0]);
svg.append('g')
.call(d3.axisLeft(y));
svg.selectAll('rect')
.data(chartData)
.enter()
.append('rect')
.style('fill', 'steelblue')
.attr('x', d => x(d.track))
.attr('y', d => y(d.playcount))
.attr('height', d => { return height - y(d.playcount); })
.attr('width', x.bandwidth );
当我尝试对图表进行排序时,问题就来了:
setTimeout(() => {
svg.selectAll('rect')
.sort((a,b) => d3.ascending(a.playcount, b.playcount))
.transition()
.duration(500)
.attr('x', d => x(d.track));
}, 2500);
2.5 秒后,我可以看到 DOM 中的所有 <rect> 元素确实已正确排序,但图表 svg 本身完全没有变化。我是否遗漏了什么可以让图表重新渲染以反映 DOM 中的变化?
【问题讨论】:
标签: javascript html svg d3.js