0

I'm trying to do some logic based on the coordinates of a rectangle, when dragged. I want to select all circles within the rectangle.

function dragmove(d) {
    var barz = document.querySelector("#visual");

    var point = d3.mouse(barz),
        tempP = {
            x: point[0],
            y: point[1]
        };

        d3.event.sourceEvent.stopPropagation();

        d3.select(this).style({
            opacity: 0.05
        })
        console.log(selectionBox.x); //turns out undefined
        console.log(d.x); //also undefined
        console.log(d3.select(this)); //undefined

        vis.selectAll("circle").filter(function (d, i) {
            return (d.x > d3.select(this).x && d.x < (d3.select(this).x + d3.select(this).width))
        }).style({
            opacity: 0.1
        });

If you didn't already notice, right now I only have it checking within the x coordinates, at least until I finish fixing this. Here's the fiddle.

Whenever I try to run it, it doesn't pull any errors, but it doesn't work as intended because the reference is undefined. Is there any reason why none of the references work at all?

To reproduce this you need to first drag on the canvas to draw a rectangle, and then drag that rectangle

gamehen
  • 324
  • 1
  • 5
  • 18
  • I don’t get any `undefined` in my console. What are the conditions to reproduce this? – Sebastian Simon Oct 28 '15 at 00:26
  • Also, why is there JavaScript code inside a ` – Sebastian Simon Oct 28 '15 at 00:27
  • Which of those references are defined depends on what you have clicked on and dragged. – S McCrohan Oct 28 '15 at 00:32
  • @Xufox Oh I'm so sorry. To reproduce this you need to first drag on the canvas to draw a rectangle, and then drag that rectangle – gamehen Oct 28 '15 at 00:33
  • @Xufox the code within the src is for enabling mathJax bits but that's not really related, so I wouldn't worry about it. – gamehen Oct 28 '15 at 00:34
  • @SMcCrohan I updated to represent what should be done to recreate but the idea is that all of them represent the same one rectangle. – gamehen Oct 28 '15 at 00:35
  • I added `console.log(d)` to the drag handler and d is *always* undefined, even when you're initially selecting a rectangle. – James Oct 28 '15 at 00:52
  • @James yeah, that's what I'm struggling with right now. For some reason the entire rectangle object becomes undefined before dragging – gamehen Oct 28 '15 at 00:53
  • To me that means the function doesn't receive a parameter. Can you get the values expected in d from the event perhaps? – James Oct 28 '15 at 00:55
  • @James well, I cut it down in the code block above, but all drag functions, including the canvas drag, use this one function, so the parameters are in order. Is that what you mean? – gamehen Oct 28 '15 at 00:58
  • @James I inserted a console.log(this) at the start of the drag, and it's still defined at that point – gamehen Oct 28 '15 at 01:00
  • For some reason `d3.select(this)` is undefined even though `this` is defined, but I can't work with just `this` – gamehen Oct 28 '15 at 01:05

1 Answers1

1

It seems like your origin function isn't quite right. I tried the one from this answer

var drag = d3.behavior.drag()
    .origin(function(d) {
        var t = d3.select(this);
        return {x: t.attr("x"), y: t.attr("y")}; 
    })
    .on("dragstart", dragstarter)
    .on("drag", dragmove);

Now it passes in a valid object to the dragmove function.

In the following code:

vis.selectAll("circle").filter(function (d, i) {
    return (d.x > d3.select(this).x && d.x < (d3.select(this).x + d3.select(this).width))
})...

the reference to this is undefined because of how the Array.prototype.filter function works. According to the specs, we can provide our own this as the second parameter to the filter function, so:

vis.selectAll("circle").filter(function (d, i) {
    return (d.x > d3.select(this).x && d.x < (d3.select(this).x + d3.select(this).width))
}, this)...

Updated your fiddle

Community
  • 1
  • 1
James
  • 20,957
  • 5
  • 26
  • 41
  • Hold on a sec, dragmove has a parameter, `d`, seen in `function dragmove(d) {code}`. Also, d3.select(this) is still undefined, inside or outside of the filter function. – gamehen Oct 28 '15 at 02:16
  • You're right, the origin function wasn't returning the proper object, and it was passing undefined to the dragmove function. – James Oct 28 '15 at 02:45
  • Yeah, but `d3.select(this).x` is still undefined for me in your fiddle. Is there anything else that is wrong? – gamehen Oct 28 '15 at 03:15
  • d3.select(whatever) returns a collection of stuff, so you have to use .attr("x") instead of .x – James Oct 28 '15 at 03:27
  • one last question, but I'm trying to use `d3.select(this).attr("initx")` to get the value of `initx`, a property of the circle that is defined with `x`, but for some reason, it keeps popping up as undefined, [as can be seen from the console from here](http://jsfiddle.net/gamea12/rm48pcwL/5/). Is there any reason why it doesn't work? – gamehen Nov 06 '15 at 21:47
  • A new question doesn't belong in the comments. Your makedots function sets nodes to an array of objects with initx properties. Are you sure that setting .data(nodes) creates those attributes in the svg elements? I would assume not. You already have some other attributes you are adding with .attr, I would think you should do that. Please ask a new question for any follow-up. – James Nov 07 '15 at 05:23
  • ok, thanks, and one last question that is actually relevant to this one, but is there any way to set the origin for each object to the pixel coordinates of (0,0) for the graph? Using this origin function is actually messing my program up, because the (0,0) coordinate for each point shifts whenever a drag first occurs – gamehen Nov 07 '15 at 17:49
  • [Here's a link to a new question about the one that I just asked you](http://stackoverflow.com/questions/33586479/how-do-i-set-the-origin-for-my-objects-to-the-svgs-0-0-in-d3) – gamehen Nov 07 '15 at 18:57