我很困惑为什么设置元素属性的d3方法在传统的JS方法工作时失败(在这段代码中)。 (我尝试更新chloropleth颜色,因为用户单击HTML按钮来更改正在绘制的数据,所有这些都来自相同的JSON。)
HTML很简单:
<div id="buttons">
<button id="party">Parties</button>
<button id="tenure">Tenure</button>
</div>
这里有相关的JS并列两条线。当我在Chrome中运行它时,我得到了#34;对象#没有方法&#39; attr&#39;&#34;:
var paths = svg.selectAll("path");
var plot = {
"mode": "party",
"redraw": function() {
var e = e || window.event;
var targ = e.target || e.srcElement;
if (targ.nodeType == 3) targ = targ.parentNode;
switch (targ.id) {
case "party":
// some code in here
break;
case "tenure":
paths.each(function(d,i) {
this.setAttribute("class",""); // Same question here actually
if (d.In_Office_Full_Date) {
//此行错误:
this.attr("style", "fill: " + t_scale(getJSDateFromExcel(d.In_Office_Full_Date).getFullYear()));
// ...但这条线有效:
this.setAttribute("style", "fill: " + t_scale(getJSDateFromExcel(d.In_Office_Full_Date).getFullYear()));
}
else
this.setAttribute("style", "fill: #111"); // Neutral colour
});
break;
default:
console.log("Unknown event trigger in redraw()");
}
}
}
var t_scale = d3.scale.linear()
.domain([1973,2013])
.range(['red','white']);
d3.select("body").selectAll("#buttons button")
.on("click",plot.redraw);
我希望你能帮忙!
答案 0 :(得分:7)
问题在于您从this
内调用each(function(d, i) { ... })
的方法。
您正朝着正确的方向前进:this
指的是您正在修改的普通html元素。但是,您期望调用的attr
函数是d3选择的方法 - 而不是html元素。因此,您需要将this
包装在d3选择中:
paths.each(function(d,i) {
d3.select(this)
.attr("class","");
});
调用setAttribute
之所以有效,是因为它是普通html元素的一种方法,但显然d3的attr
更强大。
但是说了这么多,实现你正在做的事情的更惯用的方法是:
paths
.attr("class", "")
.style("fill", function(d, i) {
if (d.In_Office_Full_Date) {
return t_scale(getJSDateFromExcel(d.In_Office_Full_Date).getFullYear());
}
return "#111";
});