Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DragInteraction callbacks for dragstart, drag, and dragend #743

Merged
merged 26 commits into from
Aug 19, 2014

Conversation

fent
Copy link
Contributor

@fent fent commented Jul 29, 2014

Working towards #365, and realized I needed this.

This takes care of #630 too.

@teamdandelion
Copy link
Contributor

Sweet, I retriggered the build (saucelabs, our cross-browser CI solution, is kind of flaky), aim to CR later today

@@ -9,7 +9,9 @@ export module Interaction {
public location = [0,0];
private constrainX: (n: number) => number;
private constrainY: (n: number) => number;
public callbackToCall: (dragInfo: any) => any;
public ondragstart: (dragInfo: any) => any;
public ondrag: (dragInfo: any) => any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you line these up pretty please :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to know that y'all care about coding style. If there's anything more let me know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, i meant space align so the interfaces line up

@teamdandelion
Copy link
Contributor

the implementation looks good to me, i think that enabling the user to put in seperate callbacks for the different events (start/drag/end) makes sense and is better than sneakily indicating it with some sort of flag. although @jtlan should take a look since he's been working on interactions and refactoring them going forward.

re api design / interfaces, i think there's room for discussion. i'm not super excited by the interface inconsistency (DragInteraction puts different types into the callback than XYDragBox, also different from XDragBox, etc), and this results in a lot of any typing which makes the typing a lot less useful. maybe we can define consistent interfaces; for example, IPoint = {x: number, y: number} with null being acceptable values for the XDragBox and YDragBox (although arguably for XDragBox and YDragBox, the important part is that the visual box gets drawn only using data from its primary dimension, but we could pass the callback the full 2-dimensional data and there's no harm in that). Then the drag could always return 2 points (as in origin, location or lowerLeftCorner, upperRightCorer) and we have a consistent interface across all the drags and can add in strong typing accordingly.

see also #631

@fent
Copy link
Contributor Author

fent commented Aug 1, 2014

As per suggestions, getPixelData() now returns the type IPixelData. On XDragBox it also gives yMin and yMax and on YDragBox, xMin and xMax.

@teamdandelion
Copy link
Contributor

So, looks good and could probably merge in present form, but I feel like we can still make the API surface cleaner:
As written DragBoxInteraction extends DragInteraction but the typing of the callback argument is different - two points for DragInteraction, a PixelArea for DragInteraction. I think we should standardize by having the DragInteraction give back two points as well (maybe instead of origin, destination, they are upperLeft, lowerRight, i.e. {xmin, ymin} {xmax,ymax}). May as well go for consistency here. (It's a minor API break, so @jtlan @oefirouz be aware...) Then also it simplifies the implementation of XDragBox and YDragBox. I dont think theres any reason to preclude those interactions from giving back the full 2-dimensional user interaction data, even though they visually have the box correspond to only one dimension. If the programmer wants to use that info somehow more power to them.

@fent
Copy link
Contributor Author

fent commented Aug 1, 2014

Not sure I understand the API suggestions for upperLeft and lowerRight. It seems we would be giving the same information but in two objects.

The XDragBox, YDragBox and XYDragBox implementation of getPixelArea() has been removed, since they all return the same 4 values.

@teamdandelion
Copy link
Contributor

So, upperLeft and lowerRight would be {x: number, y: number} points rather than pixel areas. So the information would not be duplicated

@fent
Copy link
Contributor Author

fent commented Aug 2, 2014

Alright, files have been updated. A lot was removed from X/YDragBoxInteraction classes, it's good. The only difference between them now is the way they draw the dragBox. Let me know what you think.

Also, as you've said, this introduces API changes. I couldn't find examples/tutorials or other pages where a DragBox is used and needs to be updated. If I've missed something let me know.

@lewin
Copy link
Contributor

lewin commented Aug 4, 2014

d3.brush link seems to do the drag boxes already. We could adopt a similar API, and possibly use d3.brush to back the DragBoxInteractions. This may also eliminate the need for separate X/YDragBoxInteraction classes.

@oefirouz
Copy link

oefirouz commented Aug 5, 2014

Curious, why did you decide to change from returning two tuples instead of 4 labeled points?

@fent
Copy link
Contributor Author

fent commented Aug 5, 2014

The dragstart event only uses one.

* Adds a callback to be called when the AreaInteraction triggers.
* Adds a callback to be called when dragging starts.
*
* @param {(a: SelectionArea) => any} cb The function to be called.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm mistaken the param here does not match the underlying code, your callback does not take in selectionAreas, rather it takes in ICoord's.

If this is in fact an error, please fix it in all instances (I see it repeated below).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are not mistaken. The jsdoc is incorrect/inaccurate

@oefirouz
Copy link

oefirouz commented Aug 5, 2014

Yes only using one is a good point... Then I would prefer not to have lowerLeft upperRight. If I remember my Cocos then it's usually more common to have the location of the interaction, so for dragEnd you'd have a callback (dragEndLocation: ICoord, dragStartLocation: ICoord).

I don't really like the bottomLeft/upperRight since it loses information, the callback has no knowledge of the drag direction/which corners created the drag.

@crmorford
Copy link
Contributor

Hold up, what's a good argument for top left/ bottom right?

we were doing stuff like this:

renderAreaD1.selectBar({min: xMin, max: xMax}, 
                                       {min: yMin, max: yMax}, 
                                       true);
}   

because we already have this interface:

interface IExtent {
    min: number;
    max: number;
}

@teamdandelion
Copy link
Contributor

Fent - sorry, you happen to be touching the least mature / most controversial part of our API, so this PR is going very slowly compared to the complexity of the changes :)

OK, so I don't think bottomLeft / topRight is the best for a generic DragInteraction, because it destroys information (where was the start of the drag, where was the end) which can be relevant for various interaction patterns.

So maybe we should standardize on just 2 points, dragEndLocation: ICoord, dragStartLocation: ICoord, like @oefirouz suggested. This brings API consistency across all DragInteraction derivatives and the callbacks, and can be used to bring it into sync with ClickInteraction etc, any other interactions where the mouse pixel position is relevant. Thoughts?

@fent
Copy link
Contributor Author

fent commented Aug 5, 2014

I agree with not losing information. But I think dragStartLocation should come before dragEndLocation to have dragStartLocation match the same argument position as in the dragstart callback.

@teamdandelion
Copy link
Contributor

Yeah that makes sense to me.

@@ -9,7 +9,9 @@ export module Interaction {
public location = [0,0];
private constrainX: (n: number) => number;
private constrainY: (n: number) => number;
public callbackToCall: (dragInfo: any) => any;
public ondragstart: (origin: ICoord) => void;
public ondrag: (upperLeft: ICoord, lowerRight: ICoord) => void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git diff is showing this as a tab I believe. If this is a tab, I think single-space is preferred for consistency

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, strange. It shows it as spaces.

I have vim set up so that it uses spaces for everything except golang. would be odd if it decided to insert a tab here.

@teamdandelion
Copy link
Contributor

Please ignore the fact that it's failing travis, and CR it

@lewin
Copy link
Contributor

lewin commented Aug 14, 2014

It seems that Travis won't give the environment variables to pull requests from forked repositories. This probably explains why it's failing. I'll try to see if I can disable running saucelabs for external pull requests in the meantime.

@bluong
Copy link
Contributor

bluong commented Aug 14, 2014

Looking into this slightly I see this

Travis CI: Configuring your build
docs.travis-ci.com/user/build-configuration/
One ENV variable is always set during your builds, TRAVIS . .... Please note that secure env variables are not available for pull requests from forks. This is done ...

Which would confirm @lewin 's guess if our environment variable are secure. If this is the case, I'm perfectly fine with letting this go through.

@bluong
Copy link
Contributor

bluong commented Aug 14, 2014

To specify for QEs, please QE this. If it gets a QE+1, we can merge it in and Travis should theoretically not crash on us

@bluong
Copy link
Contributor

bluong commented Aug 15, 2014

@fent Hey, after #827 , I think your build should be ok now, try merging back with master and your build should pass now. However, QEs will still need to review this. Just a reminder that it should be able to be reviewed as of now before @fent merges.

Conflicts:
	plottable.d.ts
	plottable.js
	test/tests.js
@bluong
Copy link
Contributor

bluong commented Aug 15, 2014

Yay it passed

public callbackToCall: (dragInfo: any) => any;
public ondragstart: (startLocation: Point) => void;
public ondrag: (startLocation: Point, endLocation: Point) => void;
public ondragend: (startLocation: Point, endLocation: Point) => void;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry to keep extending this pr, but can you doc these variables?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an example somewhere on how they should be documented?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, a choice that's more consistent with our codebase would be to privatize/protect these variables. there's no need for them to be public/package exported since there is already a function point for getting/setting these. if the variables were referenced from other Plottable classes, then the appropriate action would be to _name them, however since they seem to be used only in this class we should mark them private. then there is no need to document them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, good catch.

@bluong
Copy link
Contributor

bluong commented Aug 15, 2014

-1 until doced. I'll +1 after doc

This still can be QE-reviewed. Please review it when you can.

@bluong bluong added -1 and removed +1 labels Aug 15, 2014
@bluong
Copy link
Contributor

bluong commented Aug 15, 2014

Removing -1 for clarity. Will readd +1 after documentation is added

@bluong bluong removed the -1 label Aug 15, 2014
@bluong
Copy link
Contributor

bluong commented Aug 15, 2014

I take back what I said above. QE should review this anyways, but I don't want the lack of -1 to mean that it should be +1'ed above or that there should be no more code submitted.

@simoneschaffer
Copy link

-1: When you go here: http://jsfiddle.net/v4vrN/1/ and change the second script line to: , this example no longer works. Maybe I'm just doing something wrong here, but I'm not positive that there isn't a bug involving window.onload.

@teamdandelion
Copy link
Contributor

@simoneschaffer, this PR contains breaking changes to the API, so it's expected that the old jsfiddle will break. here is a JSFiddle that uses the new API and verifies that it functions correctly:
http://jsfiddle.net/93ogt3ca/

@bluong bluong added +1 and removed -1 labels Aug 18, 2014
Conflicts:
	plottable.d.ts
@simoneschaffer
Copy link

Ah, yes, this looks awesome -- thanks for clearing my confusion, too, @danmane! GIL.

@bluong
Copy link
Contributor

bluong commented Aug 18, 2014

Merge on build pass

@jtlan
Copy link
Contributor

jtlan commented Aug 18, 2014

Merge conflict again :(

Conflicts:
	plottable.js
jtlan added a commit that referenced this pull request Aug 19, 2014
DragInteraction callbacks for dragstart, drag, and dragend
@jtlan jtlan merged commit ade81f3 into palantir:master Aug 19, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants