线图悬停工具提示出现错误 - D3.js
2017-05-09
319
我正在制作折线图,其中有一个功能取自: http://www.d3noob.org/2014/07/my-favourite-tooltip-method-for-line.html
它在链接中的示例中运行良好,但对我来说,它给出了一个错误,并且悬停时没有显示任何内容,即使其他所有功能都运行良好:
Uncaught TypeError: Cannot read property 'data' of undefined
at SVGRectElement.mousemove (pen.js:366:28)
这是最有可能导致问题的代码:
function mousemove() {
var mouse_x = d3.mouse(this)[0]; // Finding mouse x position on rect
var graph_x = xScale.invert(mouse_x); //
//var mouse_y = d3.mouse(this)[1]; // Finding mouse y position on rect
//var graph_y = yScale.invert(mouse_y);
//console.log(graph_x);
var format = d3.time.format('%b %Y'); // Format hover date text to show three letter month and full year
hoverDate.text(format(graph_x)); // scale mouse position to xScale date and format it to show month and year
d3.select("#hover-line") // select hover-line and changing attributes to mouse position
.attr("x1", mouse_x)
.attr("x2", mouse_x)
.style("opacity", 1); // Making line visible
// Legend tooltips // http://www.d3noob.org/2014/07/my-favourite-tooltip-method-for-line.html
var x0 = xScale.invert(d3.mouse(this)[0]), /* d3.mouse(this)[0] returns the x position on the screen of the mouse. xScale.invert function is reversing the process that we use to map the domain (date) to range (position on screen). So it takes the position on the screen and converts it into an equivalent date! */
i = bisectDate(data, x0, 1), // use our bisectDate function that we declared earlier to find the index of our data array that is close to the mouse cursor
/*It takes our data array and the date corresponding to the position of or mouse cursor and returns the index number of the data array which has a date that is higher than the cursor position.*/
d0 = data[i - 1],
d1 = data[i],
/*d0 is the combination of date and rating that is in the data array at the index to the left of the cursor and d1 is the combination of date and close that is in the data array at the index to the right of the cursor. In other words we now have two variables that know the value and date above and below the date that corresponds to the position of the cursor.*/
d = x0 - d0.data > d1.data - x0 ? d1 : d0;
/*The final line in this segment declares a new array d that is represents the date and close combination that is closest to the cursor. It is using the magic JavaScript short hand for an if statement that is essentially saying if the distance between the mouse cursor and the date and close combination on the left is greater than the distance between the mouse cursor and the date and close combination on the right then d is an array of the date and close on the right of the cursor (d1). Otherwise d is an array of the date and close on the left of the cursor (d0).*/
//d is now the data row for the date closest to the mouse position
focus.select("text").text(function(columnName){
//because you didn't explictly set any data on the <text>
//elements, each one inherits the data from the focus <g>
return (d[columnName]);
});
};
我尝试解决这个问题,试图找出导致这个问题的原因,但到目前为止我还没有运气。如果有人能告诉我我做错了什么,导致这个功能无法像示例中那样工作,那就太好了。
完整代码可以在这里找到: http://codepen.io/kvyb/pen/ZeyRam?editors=0110
2个回答
为了使 bisectDate 函数返回有意义的值,数据必须按日期排序。下面是工作笔。在循环遍历数据并设置日期字段后立即添加此行。
http://codepen.io/voam/pen/xdYNaM
data = data.sort(function(a,b){ return a.date - b.date});
voam
2017-05-10
小错误。字段名称是日期,而不是数据。
d = x0 - d0.data > d1.data - x0 ? d1 : d0;
应该是
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
voam
2017-05-10