我正在尝试绘制D3雷达图表,用户可以在其中选择下拉菜单选项,数据将更新。但是,绘制了所选的第一个,但之后如果我选择了其他任何数据,则数据不会更新。代码粘贴在下面,我强调了有问题的部分:
var width = 700,
height = 500,
barHeight = height / 2 - 40;
var color = d3.scale.ordinal()
.range(["#a50f15","#de2d26", "#fb6a4a","#fc9272", "#fcbba1"]);
var tickValues = [2,4,6,8,10];
var svg = d3.select('#radial').append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/2 + "," + height/2 + ")");
var data = pangolins[0];
var numBars = data.data.length;
var radius = d3.scale.linear()
.domain([0,10])
.range([0, barHeight]);
var line = d3.svg.line.radial()
.interpolate("linear-closed")
.radius(function(d) { return radius(d.count); })
.angle(function(d,i) { return (i * 2 * Math.PI / numBars); });
var area = d3.svg.area.radial()
.interpolate(line.interpolate())
.innerRadius(radius(0))
.outerRadius(line.radius())
.angle(line.angle());
tickValues.sort(function(a,b) { return b - a; });
var tickPath = svg.selectAll(".tickPath")
.data(tickValues).enter()
.append("path")
.attr("class", "tickPath")
.attr("d", function(d) {
var tickArray = [];
for (i=0;i<numBars;i++) tickArray.push({count : d});
return area(tickArray);
})
.style("fill", function(d) { return color(d); })
.style("stroke", function(d,i) { return (i === 0) ? "black" : "white"; })
.style("stroke-width", function(d,i) { return (i === 0) ? "1px" : ".5px"; });
var lines = svg.selectAll("line")
.data(data.data)
.enter().append("g")
.attr("class","lines");
lines.append("line")
.attr("y2", - barHeight )
.style("stroke", "white")
.style("stroke-width",".5px")
.attr("transform", function(d, i) { return "rotate(" + (i * 360 / numBars) + ")"; });
lines.append("text")
.attr("class", "names")
.attr("x", function(d, i) { return (barHeight + 15) * Math.sin((i * 2 * Math.PI / numBars)); })
.attr("y", function(d, i) { return -(barHeight + 15) * Math.cos((i * 2 * Math.PI / numBars)); })
.attr("text-anchor", function(d,i) {
if (i===0 || i===numBars/2) {
return "middle";
}else if (i <= numBars/2) {
return "begin";
}else {
return "end";
}
})
.style("font-weight","bold")
.text(function(d) { return d.threat; });
$('#pangolinSelect').change(function() {
var selected = $( "#pangolinSelect option:selected" ).text();
console.log(selected);
var selected_d;
pangolins.forEach(function(d){
if(selected ==d.id){
selected_d = d;
}
});
console.log("selected_d");
console.log(selected_d);
changePangolin(selected_d);
});
// changePangolin(data);
//问题在这里!!!!!!!!!!!!!!!!!! // //问题在这里!!!!!!!!!!!!!!!!!! // //问题在这里!!!!!!!!!!!!!!!!!! //
function changePangolin(newdata) {
console.log('change pangolin');
console.log(newdata);
var t = d3.transition()
.duration(750);
// JOIN new data with old elements.
var layer = svg.selectAll(".layer")
.data([newdata])
.enter()
.append("path")
.attr("class", "layer")
.transition(t)
.attr("d", function(d) { console.log(d); return area(d.data); })
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", "2px");
}
以下是初始选择的屏幕截图,但是当选择了另一个选项时,该区域保持不变:
下面是一个示例数据集:
var pangolins = [{
"id": "Philippine Pangolin",
"idd":"PhilippinePangolin",
"description": "",
"status": "",
"data": [
{
"threat": "Local Hunting / Domestic Trade",
"note": "Meat + Scales + Skin",
"count": 7
},
{
"threat": "International Trade",
"note": "Meat + Scales + Skin + Whole Animal",
"count": 7
},
{
"threat": "Habitat Loss",
"count": 5
},
{
"threat": "Pesticide use",
"count": 0
},
{
"threat": "Deforestation",
"count": 4
},
{
"threat": "Road Kill",
"count": 0
}
]
},
{
"id": "Sunda Pangolin",
"idd":"SundaPangolin",
"description": "",
"status": "",
"data": [
{
"threat": "Local Hunting / Domestic Trade",
"count": 3
},
{
"threat": "International Trade",
"note": "Meat + Scales + Skin + Whole Animal",
"count": 10
},
{
"threat": "Habitat Loss",
"count": 7
},
{
"threat": "Pesticide use",
"count": 0
},
{
"threat": "Deforestation",
"count": 4
},
{
"threat": "Road Kill",
"count": 1
}
]
}
]
答案 0 :(得分:1)
这里的问题是这一行:
var layer = svg.selectAll(".layer")
第一次运行changePangolin
时,没有类layer
的元素,并且路径按预期附加。但是,从第二次开始,因为在DOM中已经存在一个名为“layer”的类的元素,所以“enter”选择将始终为空。
<强>解决方案强>:
将您的路径追加到changePangolin
函数之外:
var layer = svg.append("path")
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", "2px");;
而且,在changePangolin
内,只需更改它:
layer.transition(t)
.attr("d", area(newdata.data))