d3JS: Bisecting a Nested Array

穿精又带淫゛_ 提交于 2020-01-03 05:41:07

问题


As a follow up to this question, I've managed to create a multi-series line chart out of nested arrays. I'm now trying to add tooltips to chart similar to the one on this post by Mike Bostock.

This means that I have to figure out a method for bisecting the nested array and then selecting those values for a tooltip. How do I transfer the lines of code below to a nested array?

bisectDate = d3.bisector(function(d) { return d.date; }).left,

Further into the script:

i = bisectDate(data, x0, 1),
    d0 = data[i - 1],
    d1 = data[i],

Thanks for any help, here is an example JS Fiddle which I'd like to use to create tooltips: http://jsfiddle.net/JYS8n/2/


回答1:


You need to use bisect twice here, first to find the matching x value and then to find the matching y value. First, you'll need to define a second custom bisector that takes the value into account.

var bisectValue = d3.bisector(function(d) { return d.Value; }).left;

The first part of the handler is not changed a lot from the non-nested version. The only difference is that instead of considering only a single data series, we are iterating over all of them and collecting the closest data point for each.

var x0 = x.invert(d3.mouse(this)[0]),
    ds = data.map(function(e) {
        var i = bisectDate(e.Data, x0, 1),
            d0 = e.Data[i - 1],
            d1 = e.Data[i];
        return x0 - d0.Date > d1.Date - x0 ? d1 : d0;
    });

Now ds is a list of data points, the closest one to the cursor position for each series. All that remains to be done now is to bisect again to find the one with the closest value to the current cursor position.

var y0 = y.invert(d3.mouse(this)[1]),
    i = bisectValue(ds.sort(), y0, 1),
    d0 = ds[i - 1],
    d1 = ds[i],
    d = y0 - d0.Value > d1.Value - y0 ? d1 : d0;

The basic skeleton is the same as before, only this time we are comparing y and .Value. Now d is the data point to be highlighted.

focus.attr("transform", "translate(" + x(d.Date) + "," + y(d.Value) + ")");
focus.select("text").text(d.Value);

Full example here. I've also changed the line interpolation -- while that makes it look nicer, the line doesn't go through the actual points anymore.



来源:https://stackoverflow.com/questions/21122153/d3js-bisecting-a-nested-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!