[英]"TypeError: undefined is not an object" when using .attr() to add data attribute
I'm creating a bar graph and I need to show a tooltip when hovering over each bar.我正在创建一个条形图,我需要在将鼠标悬停在每个条形上时显示一个工具提示。 The tooltip must include a data attribute with the bar's date information.
工具提示必须包含带有条形日期信息的数据属性。 Using .attr("data-date", d => d[0]) I added the attribute to the bars, and yet it shows an error when used in the tooltip.
使用 .attr("data-date", d => d[0]) 我将该属性添加到条形图中,但在工具提示中使用时显示错误。 (The tooltip works just fine if I remove line 53).
(如果我删除第 53 行,工具提示就可以正常工作)。
const w = 1000;
const h = 550;
const padding = 50;
const barPadding = 0.5;
d3.json(
"https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json",
json => {
const minDate = d3.min(json.data, d => d[0]);
const maxDate = d3.max(json.data, d => d[0]);
const max = d3.max(json.data, d => d[1]);
const xScale = d3
.scaleTime()
.domain([new Date(minDate), new Date(maxDate)])
.range([padding, w - padding]);
const yScale = d3
.scaleLinear()
.domain([0, max])
.range([h - padding, padding]);
const tooltip = d3
.select("#container")
.append("div")
.attr("id", "tooltip")
.style("width", padding);
const svg = d3
.select("#container")
.append("svg")
.attr("width", w)
.attr("height", h);
svg
.selectAll("rect")
.data(json.data)
.enter()
.append("rect")
.attr("x", (d, i) => xScale(new Date(d[0])))
.attr("y", d => yScale(d[1]))
.attr("width", w / json.data.length - barPadding)
.attr("height", d => h - yScale(d[1]) - padding)
.attr("class", "bar")
.attr("data-date", d => d[0])
.attr("data-gdp", d => d[1])
.on("mouseover", (d, i) => {
console.log(d[0]);
tooltip
.style("visibility", "visible")
.style("top", `${yScale(d[1])}px`)
.style("left", `${xScale(new Date(d[0])) - padding}px`)
.attr("data-date", d => d[0])
.html(`${d[0]} <br/> $${d[1]} Billion`);
})
.on("mouseout", () => tooltip.style("visibility", "hidden"));
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);
svg
.append("g")
.attr("transform", `translate(0, ${h - padding})`)
.attr("id", "x-axis")
.call(xAxis);
svg
.append("g")
.attr("transform", `translate(${padding}, 0)`)
.attr("id", "y-axis")
.call(yAxis);
}
);
Any help is appreciated.任何帮助表示赞赏。 Fiddle: http://jsfiddle.net/s1tpyuoc/
小提琴: http : //jsfiddle.net/s1tpyuoc/
Let's simplify your code and see what you have:让我们简化你的代码,看看你有什么:
selection.on("mouseover", (d, i) => {
tooltip.attr("data-date", d => d[0]);
})
You may think that this sets the first element of d
as the "data-date"
property of tooltip
.您可能认为这将
d
的第一个元素设置为tooltip
的"data-date"
属性。 But it doesn't: that second d
in the callback of the attr
method is not the same d
of the selection:但事实并非如此:这第二
d
的回调attr
方法是不一样的d
的选择:
selection.on("mouseover", (d, i) => {
//this datum... -------^
tooltip.attr("data-date", d => d[0]);
//...is not the same of this---^
})
And, since there is no data bound to tooltip
, that inner d
is undefined
.而且,由于没有绑定到
tooltip
数据,因此内部d
是undefined
。
The solution here is simply removing that line or, for whatever reason you want to set that attribute, doing:这里的解决方案是简单地删除该行,或者无论出于何种原因要设置该属性,请执行以下操作:
tooltip.attr("data-date", d[0])
Here is the updated JSFiddle: http://jsfiddle.net/vxq9gcwr/这是更新的 JSFiddle: http : //jsfiddle.net/vxq9gcwr/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.