我很困惑为什么设置元素属性的d3方法在传统的JS方法工作时失败(在这段代码中).(我正在尝试更新chloropleth颜色,因为用户单击HTML按钮来更改正在绘制的数据,所有这些都来自相同的JSON.)
HTML很简单:
这是相关的JS与两条线并排.当我在Chrome中运行它时,我得到"对象#没有方法'attr'":
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);
希望你能帮忙!
问题在于你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"; });