我遇到了让数据集之间的转换工作的问题。我希望单击按钮时数字,矩形和名称可以在彼此之间平滑过渡,但目前它们只会跳转。
我正在使用它们
players.select('.saves')
.transition().duration(200)
.attr('y', function(d, i) {
return i * (h / data.length);
})
.attr('width', function(d) {
return Scale(d['saves']) ;});
我的选择有问题吗?
https://jsfiddle.net/8voee4fm/1/
<button class="opts champ" value="championsleague">Champions League</button>
<button class="opts prem" value="premierleague">Premier League</button>
<div id="chart"></div>
var w = 300, h = 300;
var barHeight = 20;
var data =
championsleague = [{
"name": "Hart",
"saves": "9",
"total": "15",
}, {
"name": "Subasic",
"saves": "6",
"total": "10"
}, {
"name": "Neuer",
"saves": "5",
"total": "9"
},{
"name": "Olsen",
"saves": "9",
"total": "18"
}, ];
premierleague = [{
"name": "Hart",
"saves": "12",
"total": "27"
}, {
"name": "Forster",
"saves": "13",
"total": "22"
}, {
"name": "De Gea",
"saves": "17",
"total": "29"
}, {
"name": "Green",
"saves": "21",
"total": "39"
},];
data.forEach(function(d){
d.saves = +d.saves;
d.total = +d.total;
});
var canvas = d3.select('#chart')
.append('svg')
.attr('width', w)
.attr('height', h)
.append('g')
.attr("transform", "translate(10,30)");
var Scale = d3.scale.linear().domain([0, 39]).range([0, w]);
function updateLegend(data) {
var players = canvas
.selectAll(".player")
.data(data, function(d){
// always create a unique key for your data-binding
return d.name + d.saves + d.total;
});
var playersEnter = players
.enter()
.append("g")
.attr("class", "player");
playersEnter.append('rect')
.attr('class','total')
.style("fill", "#abcbc0")
.attr('x', 0)
.attr('height', barHeight);
playersEnter.append('text')
.attr('class','totaln')
.style("fill", "black")
.style("text-anchor", "right");
playersEnter.append('rect')
.attr('class','saves')
.style("fill", "#008c6c")
.attr('x', 0)
.attr('height', barHeight);
playersEnter.append('text')
.attr('class','savesn')
.style("text-anchor", "right")
.style("fill", "white");
playersEnter.append('text')
.attr('class','name')
.attr('x', 0);
players.select('.total').transition()
.duration(200)
.attr('y', function(d, i) {
return i * (h / data.length)
})
.attr('width', function(d) {
return Scale(d['total'])
})
.attr('height', barHeight);
players.select('.totaln').transition()
.duration(200).text(function(d) {
return d.total;
})
.attr('x', function(d) {
return Scale(d['total']) -20})
.attr('y', function(d,i) {
return i * (h / data.length ) +15
});
players.select('.saves')
.transition().duration(200)
.attr('y', function(d, i) {
return i * (h / data.length);
})
.attr('width', function(d) {
return Scale(d['saves']) ;});
players.select('.savesn')
.transition()
.duration(200).text(function(d) {
return d.saves;
})
.attr('x', function(d) {
return Scale(d['saves']) -18})
.attr('y', function(d,i) {
return i * (h / data.length ) +15
});
players.select('.name')
.transition().duration(200)
.text(function(d) {
return d.name;
})
.attr('y', function(d, i) {
return i * (h / data.length) -10
});
// remove old elements
players.exit().remove();
};
updateLegend(data);
d3.selectAll('.opts')
.on('click', function() {
var data = eval(d3.select(this).property('value'));
console.log(data)
updateLegend(data);
})
答案 0 :(得分:1)
您只需纠正一行代码:
而不是
var players = canvas
.selectAll(".player")
.data(data, function(d){
// always create a unique key for your data-binding
return d.name + d.saves + d.total;
});
你写道:
var players = canvas
.selectAll(".player")
.data(data);
现在它有效。 问题如下:您在输入选择中创建的DOM元素不是有效的SVG元素,因为至少缺少一个属性(例如,rect缺少宽度)。结果,转换创建了对象(来自未指定的SVG对象)。
因此,由于上述原因,您现在除了初始显示之外都有过渡。
这是工作的JSFiddle: https://jsfiddle.net/ee2todev/xjf0k2oy/
答案 1 :(得分:1)
如果您想避免使用 eval(),可以更改点击事件的句柄:
d3.selectAll('.opts')
.on('click', function() {
var data = eval(d3.select(this).property('value'));
console.log(data)
updateLegend(data);
})
这样的事情:
d3.selectAll('.opts')
.on('click', function() {
var newdata = d3.select(this).property('value');
newdata = window[newdata];
console.log(newdata)
updateLegend(newdata);
})
(不是真的答案,但我没有足够的评论意见)