Giter Club home page Giter Club logo

Comments (12)

louking avatar louking commented on May 18, 2024 1

see https://observablehq.com/@louking/d3-bisector-with-object-comparison-function

I'm not sure the best way to get observable to print like console.log() but the debugger brings you into where you can see the console.log()

the compare1(x,x) causes the bisector to always return hi

from d3-array.

mbostock avatar mbostock commented on May 18, 2024 1

So, to flesh out the example, you could use a symmetric comparator like so:

bisectX = d3.bisector(xascending ? (a, b) => a.x - b.x : (a, b) => b.x - a.x).left

And then say

bisectX(array, {x})

Or you could use an accessor like so:

bisectX = d3.bisector(xascending ? (d) => d.x : (d) => -d.x).left

And then say

bisectX(array, xascending ? x : -x)

from d3-array.

mbostock avatar mbostock commented on May 18, 2024

Thanks for the feedback. This was changed in 3.0.2 to better handle undefined order. We consider this a bug fix. You can read about why we made this changes in #217 #219 #227.

from d3-array.

louking avatar louking commented on May 18, 2024

So you're saying bisector() compare function no longer supports object, right? Even though this case is mentioned (for sort()) in #217 (comment)

from d3-array.

mbostock avatar mbostock commented on May 18, 2024

I don’t follow. What are you trying to do?

from d3-array.

louking avatar louking commented on May 18, 2024

briefly: I have array of objects d, and want to bisect by d.x

the objects happen to have the x,y values

I can create new array of all d.x values if needed, but the change broke my current compare function

from d3-array.

mbostock avatar mbostock commented on May 18, 2024

There are a lot of tests of bisecting arrays of objects:

https://github.com/d3/d3-array/blob/main/test/bisector-test.js

How is your usage different? Can you share a minimal, complete, live example of how it is not doing what you expect, say as an Observable notebook?

from d3-array.

mbostock avatar mbostock commented on May 18, 2024

If you pass an accessor rather than a comparator,

bisectX = d3.bisector(d => d.x).left

then it works as intended.

https://observablehq.com/d/468b832f4f688643

But, I think you’re right that this might be a bug for bisector’s weird comparator that takes different arguments. I need to investigate a little more.

from d3-array.

mbostock avatar mbostock commented on May 18, 2024

Also, it works if you implement a “normal” (symmetric, non-weird) comparator:

bisectX = d3.bisector((a, b) => a.x - b.x).left

And then you pass in test values that have the same shape as the things you are bisecting, e.g.

bisectX(dataarr, {x: 2})

However, this approach deviates from the example given in the README, and also deviates from the more recommended pattern of using an accessor (whereby you pass in a search value equivalent to the accessor’s output, not its input). So, I think at a minimum we need to update some documentation here, but ideally we find a way to make this work.

from d3-array.

mbostock avatar mbostock commented on May 18, 2024

I have a fix up in #250. Thanks for the additional explanation that helped me understand the problem! 🙏

from d3-array.

louking avatar louking commented on May 18, 2024

If you pass an accessor rather than a comparator,

bisectX = d3.bisector(d => d.x).left

then it works as intended.

I don't think this works for me, because my actual comparator handles both ascending and descending arrays.

            that.bisectX = d3.bisector(function (d, x) {
                if (that.xascending) {
                    return d.x - x;
                } else {
                    return x - d.x;
                }
            }).left;

In the meantime, to work with d3 7.4.2, I've created a parallel array with just the x values, and changed d.x in the above function to d.

Thanks for your support!

from d3-array.

mbostock avatar mbostock commented on May 18, 2024

In the descending case, you could say

bisectX = d3.bisector(d => -d.x).left

and then pass -x as the search value. Or you can use the symmetric comparator as I described in the other comment. Here is the descending form:

bisectX = d3.bisector((a, b) => b.x - a.x).left

and then pass an object {x} to search.

from d3-array.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.