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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polar 2.0 #2200

Merged
merged 73 commits into from Jan 16, 2018

Conversation

Projects
None yet
5 participants
@etpinard
Copy link
Member

commented Dec 12, 2017

should close everything listed under the on-par polar milestone 馃帀


I'm making a PR at this stage to:

  • hopefully get a few 馃憤 s about the attributes came up with. I would appreciate if @alexcjohnson @cldougl @chriddyp could take a 馃憖 at commits 3c8ae5b and 853581e,
  • pin down the last open items, and
  • set a firm base branch for @dfcreative 's upcoming scatterpolargl work.

Working features so for:

  • scatterpolar is on-par with scattertenary e.g. lines, markers, text, some fills options and line shapes as well as point selections are supported.
  • scatterpolar accepts input angles in both degrees and radians using a polar-only thetaunit attribute
  • polar subplots have fully configurable radial and angular axes styling.
  • users can set the direction and starting angle of each polar subplots. (see polar_direction)
  • polar subplots can be carve into sectors (see polar_sector)
  • polar subplots can display angular tick labels in degrees or in fractions of pi.
  • polar subplots accepts category as angles (see polar_categories)

Quick demo:

peek 2017-12-12 09-40

Biggest open item: zoombox interactions

What should zoom interactions look like? At first, me and @alexcjohnson thought that a viewbox-based zoom system would suffice. In details, we thought about exposing a set of scalar attributes e.g. polar.x, polar.y and polar.zoom that determine the location and zoom-level of the polar subplots with respect to their polar.domain bounding-box. But there's a problem with such system: for some sets of x/y/zoom values, viewers won't see the subplot radial and/or angular axes - making data point only discernible via hover.

While adding functionality for non-full polar.sector values, I thought that perhaps we could make zoombox interactions correspond to a combination of polar sector and radial axis range relayout updates. That is, zooming in on a point would correspond to carving a sector around it and narrowing the radialaxis.range (note that radial axis ranges that don't start at 0 are common in other libraries e.g. matlab).

@nicolaskruchten pointed out that generalising polar.sector to some 4-pt polar bounding box attribute could allow for even better zooming interactions (we should probably draw that on a whiteboard and take a screenshot to make it easier to grasp).

So I ask: is x/y/zoom zooming more intuitive than some fancy sector/radial range algo?


cc'ing @jackparmer @cpsievert @monfera @bpostlethwaite who might also be interested.

// If same angle over a full circle, the last tick vals is a duplicate.
//
// TODO must do something similar for angular date axes.
if(ax._id === 'angular' && Math.abs(rng[1] - rng[0]) === 360) {

This comment has been minimized.

Copy link
@etpinard

etpinard Dec 12, 2017

Author Member

I had to hack a few things deep into axes.js to get the angular axes looking the way I wanted. I hope @alexcjohnson won't mind.

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Jan 5, 2018

Contributor

What if you use something else as the period of a linear angular axis? Also do we need to do something more flexible to handle nearly duplicate values so we don't get overlaps?

// http://www.seasonaladjustment.com/2012/09/05/clock-plot-visualising-seasonality-using-r-and-ggplot2-part-3/
// https://i.pinimg.com/736x/49/b9/72/49b972ccb3206a1a6d6f870dac543280.jpg
// https://www.climate-lab-book.ac.uk/spirals/
},

This comment has been minimized.

Copy link
@etpinard

etpinard Dec 12, 2017

Author Member

Some screenshot of date angular axes:

image

image

image

image

This comment has been minimized.

Copy link
@srpn

srpn Mar 20, 2018

Great feature !! Can you please include the code (layout config attributes) for the above example screenshots?

// as it always starts at 0? But, looks like off-zero cutout polar chart are
// a thing:
// -> mpl allow radial ranges to start off 0
// -> same for matlab: https://www.mathworks.com/help/matlab/ref/rlim.html

This comment has been minimized.

Copy link
@etpinard

etpinard Dec 12, 2017

Author Member

e.g. in matlab:

image

@@ -1905,7 +1905,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
var axLetter = axid.charAt(0),
counterLetter = axes.counterLetter(axid),
vals = axes.calcTicks(ax),
datafn = function(d) { return [d.text, d.x, ax.mirror].join('_'); },
datafn = function(d) { return [d.text, d.x, ax.mirror, d.font, d.fontSize, d.fontColor].join('_'); },

This comment has been minimized.

Copy link
@etpinard

etpinard Dec 12, 2017

Author Member

Cartesian axes use a special ticks update pathway that.

This here gets Axes.doTicks to update properly. I'm pretty sure some axis style updates are currently broken for ternary subplots. I'll lock those down in tests soon.

This comment has been minimized.

Copy link
@etpinard

etpinard Dec 21, 2017

Author Member

馃敀 in 7b0f718

@chriddyp

This comment has been minimized.

Copy link
Member

commented Dec 12, 2017

馃帀 馃弳

@alexcjohnson

This comment has been minimized.

Copy link
Contributor

commented Dec 12, 2017

Re: zooming interaction: I think we may need two different modes, eventually if not right away, because there are two very different ways polar plots get used. One is where you're drawing a real 2D space (where zero is a unique point and shapes have meaning) just in polar coordinates. That's where you would want zoombox-type interactions that I was thinking of. I notice though that none of your examples are of this type (except maybe the cardioid). Your examples all have independent R and Theta variables, just mapped onto a polar space mostly to show periodicity. Incidentally, this points to another way the behavior may want to depend on this distinction: what do you do with negative R? If you're mapping a real space, then it should show up as a positive R in the opposite direction, but if you're not it should disappear at the origin.

So how should zooming work in the independent-variable case? I still need to look at some more example plots with the question "how would I want to zoom this to explore THIS data set", but as a first cut, I feel like the most useful for people would be to independently move each of the axis ends - so min and max radius (dragging them like you drag an axis end in cartesian? @etpinard points out that this is ambiguous with interacting with data near the origin though... not sure how to handle that.), and for angle I guess initial angle (rotating the whole plot) and period (so points at the initial angle would stay put, points at initial angle + period would move with the cursor, points at initial angle + twice the period would move twice as fast as the cursor... per private discussion with @etpinard this interaction should NOT happen when the period is physically significant, like 360 degrees or 2Pi - perhaps we can have an attribute to enable/disable it, with a smart default set depending on whether an explicit period is provided or not)?

I also liked the way our old polar plots had the radial axis on top of the data, with an outline around the text in the background color. Perhaps it could be configurable whether this axis is above or below the data?

@alexcjohnson

This comment has been minimized.

Copy link
Contributor

commented on src/plots/polar/layout_attributes.js in 3c8ae5b Dec 12, 2017

This shows up all over the place... 馃尨 ?

This comment has been minimized.

Copy link
Member Author

replied Dec 21, 2017

done in fbea869

@etpinard

This comment has been minimized.

Copy link
Member Author

commented Dec 12, 2017

I also liked the way our old polar plots had the radial axis on top of the data, with an outline around the text in the background color. Perhaps it could be configurable whether this axis is above or below the data?

Absolutely. I'll add a polar.radialaxis.layer enumerated attribute. I could even make that the default if you prefer. Moreover, it's true that polar charts would benefit a lot from #1597

nums: 'r: 4.022892\n胃: 2.239991',
name: 'Trial 3'
}, {
desc: 'on work on log radial axis',

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Jan 16, 2018

Contributor

on work on log radial axis


// make a small cut on full sectors so that the
// inner region isn't filled
if(isFullCircle(sector)) s1 -= 1e-3;

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Jan 16, 2018

Contributor

FWIW pies solved this by making two arcs at each radius so the annulus really is complete.

Probably not going to cause any issues, it's just missing a fraction of a pixel, but I worry a little about numerical stability - it has to determine the center of the circle based on the very small vector from p00 to p01 and I'm not sure how much precision SVG uses.

@alexcjohnson

This comment has been minimized.

Copy link
Contributor

commented Jan 16, 2018

Two problems I just encountered with interaction effects, both while looking at the polar_direction mock:

  • Rotating the plot by dragging the angular axis: seems like this is centered on the wrong point (though dragging the radial axis around has the correct center now)
  • Dragging the radial axis around: sometimes after I've done this once, it doesn't seem to allow it anymore, I can only change the outer limit of the radius no matter which direction I start the drag. But sometimes it still works indefinitely... I can't really figure out the pattern.
_this.clipPaths.circle.select('path').attr('transform',
strTranslate(cxx, cyy) + strRotate(da)
);
// 'un-rotate' marker and text points

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Jan 16, 2018

Contributor

Oh man, that is such a satisfying effect 馃嵐

@alexcjohnson

This comment has been minimized.

Copy link
Contributor

commented Jan 16, 2018

@etpinard Fantastic work! Aside from the three quick comments above (at least I hope the interaction bugs are quick 馃槄 ) the only thing I'd like to see before merging is an issue collecting open items, so we can point people to that when questions arise, and use it to prioritize future additions.

misc. polar fixup after AJ's review:
- fixup angular drag xy -> angle calculations
- decrease min drag value for radial drag box,
  to catch smaller dx/dy
  that can determine rotateMove vs rerangeMove
- better annulus path
- typo in scatterpolar test

@etpinard etpinard referenced this pull request Jan 16, 2018

Open

Polar 2.0 open items #2255

4 of 12 tasks complete
add clampFn option to dragElement & use it for radial drag box
- by default, dragElement clamps small x,y displacement to 0
  independently
- for radial drag box, using d(x,y) to determine 'small' displacements
  to clamp prove more advantageous.
* clampFn (optional, function(dx, dy) return [dx2, dy2])
* Provide custom clamping function for small displacements.
* By default, clamping is done using `minDrag` to x and y displacements
* independently.

This comment has been minimized.

Copy link
@alexcjohnson

alexcjohnson Jan 16, 2018

Contributor

Nicely done. And it works great to solve the radial/angular drag bug! 馃幆

@alexcjohnson

This comment has been minimized.

Copy link
Contributor

commented Jan 16, 2018

A hard-fought 馃拑 - excellent work.

@etpinard

This comment has been minimized.

Copy link
Member Author

commented Jan 16, 2018

Merging.

For future development ideas and updates, please subscribe to #2255

@etpinard

This comment has been minimized.

Copy link
Member Author

commented Jan 16, 2018

Oh and please note that (r,t) legacy polar charts are now deprecated! Please switch over to scatterpolar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can鈥檛 perform that action at this time.