-
Notifications
You must be signed in to change notification settings - Fork 186
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
vector + symbol #649
vector + symbol #649
Conversation
(I really wanted to use radians here, but I wanted to be consistent with Plot.text’s rotate option.) |
Maybe anchor should default to middle instead? |
I tried implementing vx and vy channels as alternatives to length and rotate, but it’s awkward because vx and vy would likely need to be in pixel space, rather than data space as x and y are. So I’m going to punt on that idea. |
Yes I imagine vx, vy to be working in data space; maybe it needs a "time resolution" factor t, so if x and y are in kilometers, and vx, vy in km/h, the actual length of a vector represents t hours of driving? |
I’m not planning on implementing vx and vy channels for now. |
A few thoughts as I'm playing with this branch: Should we filter on positive lengths? Or do we keep it generalized to negative lengths being "reversed"? Do we want a way to personalize the arrows' shapes? (In #39 there is some demand for arrowheads symbols, and in https://observablehq.com/@fil/plot-arrow I've experimented with a variable arrowhead angle and length.) If we wanted to generalize, Plot.vector could be an instance of Plot.symbol (#41), with an arrow symbol and a linear size. In that case, we wouldn't compute the rotated path's d, but only a scaled path, and we would leave the rotation to a svg transform. (Also, it needs a bit of documentation.) |
I originally filtered on positive lengths, but I think it’s preferable to support inverted vectors for negative lengths. You can always filter if you don’t want this behavior.
I think we want this eventually, but I don’t think it’s a blocker for now. I also think there is a difference between Plot.symbol having an r channel with default sqrt scale (or area channel with linear scale) versus Plot.vector’s length channel. Having magnitude and direction feels most natural for a vector field, but for a symbol I would expect an areal encoding (and rarely need rotate).
I originally implemented Plot.vector with a transform attribute such that the d attribute always pointed up with the given length. But I suspected that the performance would be better to bake everything into the path string, or at least, it felt more concise to do it in one place. But, I’m happy to change it. I don’t see it as being necessary, though, since it’s just an implementation detail of the mark. I could certainly take a crack at Plot.symbol as a PR to this PR so that we can feel confident that we’re designing holistically.
Yep! |
b720e62
to
f2eda5b
Compare
This is ready for review, @Fil. 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two small remarks in the README
|
||
If the **x** channel is not specified, vectors will be horizontally centered in the plot (or facet). Likewise if the **y** channel is not specified, vectors will vertically centered in the plot (or facet). Typically either *x*, *y*, or both are specified. | ||
|
||
The **rotate** and **length** options can be specified as either channels or constants. When specified as a number, it is interpreted as a constant; otherwise it is interpreted as a channel. The length defaults to 12 pixels, and the rotate defaults to 0 degrees (pointing up↑). Vectors with a negative length will be drawn inverted. Positive angles proceed clockwise from noon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The **rotate** and **length** options can be specified as either channels or constants. When specified as a number, it is interpreted as a constant; otherwise it is interpreted as a channel. The length defaults to 12 pixels, and the rotate defaults to 0 degrees (pointing up↑). Vectors with a negative length will be drawn inverted. Positive angles proceed clockwise from noon. | |
The **rotate** and **length** options can be specified as either channels or constants. When specified as a number, it is interpreted as a constant; otherwise it is interpreted as a channel. The length defaults to 12 pixels, and the rotate defaults to 0 degrees (pointing up↑). Vectors with a negative length will be drawn inverted. Vectors of length 0 will show as a single pixel; use NaN to remove. Positive angles proceed clockwise from noon. |
(not sure about this wording)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don’t think saying a single pixel is correct… since it depends on the strokeWidth? Or possibly you see nothing? In any case, probably better to elaborate in the Marks section above, near here:
Plot.dot will not generate circles with null, undefined or negative radius, or null or undefined coordinates.
Co-authored-by: Philippe Rivière <fil@rezo.net>
Adds a new Plot.vector mark, similar to Plot.dot, for drawing little arrows. In addition to x and y, it exposes length (magnitude) and rotate (direction, in degrees) channels. The anchor option (start, middle, or end) controls where the arrow is anchored to x and y; it defaults to start.
TODO
Fixes #407.