-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Polar 2.0 #2200
Merged
Polar 2.0 #2200
Changes from 1 commit
Commits
Show all changes
73 commits
Select commit
Hold shift + click to select a range
58d53e8
move (old) polar code to legacy/ folder
etpinard 853581e
introduce scatterpolar attributes
etpinard 3c8ae5b
introduce polar subplot attributes
etpinard ca8081b
introduce angles helper module
etpinard 46fe066
first cut polar subplot defaults and draw routines
etpinard 0826ee7
first cut scatterpolar calc/defaults/plot/style/hover
etpinard 9770f2c
misc things to get scatterpolar traces to show up
etpinard 0b85af2
init categories stashes for polar axes
etpinard cbf19c1
allow ticksuffix dflt to be passed via option
etpinard 86204a6
get polar axis updates to work
etpinard 0027f53
add legacy deprecation warnings
etpinard 4cdc301
remove obsolete check for polar in registry
etpinard a5a719c
get snapshot redraw function right for (new) polar
etpinard da720aa
improve scatterpolar hover
etpinard 04a886b
use subplot ref in scatterternary hover pointData
etpinard 22cf4ba
expose a few things out of cartesian dragbox for :recycle:
etpinard 122dd0b
uber wip polar main drag interaction
etpinard 689414c
add radial axis drag interactions
etpinard 543b615
first cut polar mocks!
etpinard 54b3f1c
Merge branch 'master' into polar
etpinard 17503cb
make scatter{ternary,polar,carpet} Scatter.style reuse straight-up
etpinard 7b0f718
add test for commit 86204a6 (ternary ax tickfont relayouts)
etpinard fbea869
:palm_tree: domain attributes
etpinard 1e769f0
make non-zero radialaxis.range[0] work
etpinard f53495e
make radial/angular axis visible: false cases work
etpinard c5a3a72
1st pass isPtWithinSector algo
etpinard 61e155c
warn -> log for polar deprecation
etpinard 258600d
:hocho: special polygon logic from scatterpolar/plot
etpinard 0a41da5
implement {angular,radial}axis.layer
etpinard f3a2379
:palm_tree: make filter-visible work for calcdata containers
etpinard 3f5e77b
first cut radial axis drag intractions
etpinard 65b717d
get `polar.sector` working on category angular axes
etpinard 13568a3
fixup isPtWithinSector
etpinard 797fec1
add support for 'log' radial axes
etpinard 0a9278c
fixup axis autotype logic for visible: false traces
etpinard 07a3af7
make sure that angular setting relayout call propagate to tick labels
etpinard a263c1c
solid zoombox try + some pan work and radial drag fixups
etpinard 765d2b7
pretty solid zoom/pan interactions
etpinard 909d134
make polar ticks relayout more robust
etpinard 3e1e4dd
:palm_tree: calcMarkerSize logic
etpinard a96131d
fix hoveron fill hover label placement edge case
etpinard b35d7ec
update ticks when panning sectors using new wrap180 routine
etpinard 5751de5
make marker.size bump radial autorange results
etpinard 86067a6
:palm_tree: cartesian/ternary/polar line/grid default logic
etpinard 5422da9
coerce 'cliponaxis' only when markers and/or text are present
etpinard b4af46f
clear ternary axis titles when ternary subplots are removed
etpinard 20b17e5
set radialaxis.rangemode dflt to 'tozero' + add support for -ve r ranges
etpinard cb78d19
implement radialaxis.title
etpinard 25b4e7b
even more robust relayout
etpinard 1e81039
large commit of attribute name & dflt changes
etpinard e5d238d
remove crispEdges for all polar subplot paths
etpinard 0146c2f
Merge branch 'master' into polar
etpinard c94423b
adapt polar to clean-subplots improvements
etpinard 4d5a1bd
fixups for domain attrs
etpinard d4c7d2c
default *rotation* to 90 for clockwise *direction*
etpinard 8b4c2b5
do not implement 'date' angular axes (for now)
etpinard 5357501
clear polar radial range viewInitial during log <-> linear relayout
etpinard 9a71ba3
set limit of 100 for num2frac denominator
etpinard f714449
extend line & fills to polar center when pts < radialaxis.range[0]
etpinard cde7369
fixup radial axis drag rotate logic
etpinard 9c4c9bf
Merge branch 'master' into polar
etpinard b365374
more strict check for polar subplot existence
etpinard a72ce55
adapt polar main drag to dragElement updates (+ tests)
etpinard 473643c
AJ-proof latest additions
etpinard c2da23e
replace dragmode: 'pan' with annulus-shaped dragger
etpinard 974740b
improve zoom dragbox behavior
etpinard e8aec86
un-rotate markers and text pts during angular drag
etpinard e8865bc
add scatterpolar hover label tests
etpinard 8a33b89
add scatterpolar select test
etpinard c7a7f59
add polar drag interaction tests
etpinard 7f7193d
a few small tweaks
etpinard 816be51
misc. polar fixup after AJ's review:
etpinard 18a3a0d
add clampFn option to dragElement & use it for radial drag box
etpinard File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,327 @@ | ||
/** | ||
* Copyright 2012-2017, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
var colorAttrs = require('../../components/color/attributes'); | ||
var axesAttrs = require('../cartesian/layout_attributes'); | ||
var extendFlat = require('../../lib').extendFlat; | ||
var overrideAll = require('../../plot_api/edit_types').overrideAll; | ||
|
||
var domainItem = { | ||
valType: 'info_array', | ||
role: 'info', | ||
editType: 'plot', | ||
items: [ | ||
{valType: 'number', min: 0, max: 1}, | ||
{valType: 'number', min: 0, max: 1} | ||
], | ||
dflt: [0, 1] | ||
}; | ||
|
||
var axisLineGridAttr = overrideAll({ | ||
color: axesAttrs.color, | ||
showline: extendFlat({}, axesAttrs.showline, {dflt: true}), | ||
linecolor: axesAttrs.linecolor, | ||
linewidth: axesAttrs.linewidth, | ||
showgrid: extendFlat({}, axesAttrs.showgrid, {dflt: true}), | ||
gridcolor: axesAttrs.gridcolor, | ||
gridwidth: axesAttrs.gridwidth | ||
|
||
// should we add zeroline* attributes? | ||
// might be useful on radial axes where range is negative and positive | ||
|
||
// we could add spike* attributes down the road | ||
}, 'plot', 'from-root'); | ||
|
||
var axisTickAttr = overrideAll({ | ||
tickmode: axesAttrs.tickmode, | ||
nticks: axesAttrs.nticks, | ||
tick0: axesAttrs.tick0, | ||
dtick: axesAttrs.dtick, | ||
tickvals: axesAttrs.tickvals, | ||
ticktext: axesAttrs.ticktext, | ||
ticks: axesAttrs.ticks, | ||
ticklen: axesAttrs.ticklen, | ||
tickwidth: axesAttrs.tickwidth, | ||
tickcolor: axesAttrs.tickcolor, | ||
showticklabels: axesAttrs.showticklabels, | ||
showtickprefix: axesAttrs.showtickprefix, | ||
tickprefix: axesAttrs.tickprefix, | ||
showticksuffix: axesAttrs.showticksuffix, | ||
ticksuffix: axesAttrs.ticksuffix, | ||
showexponent: axesAttrs.showexponent, | ||
exponentformat: axesAttrs.exponentformat, | ||
separatethousands: axesAttrs.separatethousands, | ||
tickfont: axesAttrs.tickfont, | ||
tickangle: axesAttrs.tickangle, | ||
tickformat: axesAttrs.tickformat, | ||
tickformatstops: axesAttrs.tickformatstops, | ||
}, 'plot', 'from-root'); | ||
|
||
var radialAxisAttrs = { | ||
visible: extendFlat({}, axesAttrs.visible, {dflt: true}), | ||
type: axesAttrs.type, | ||
|
||
// You thought maybe that range should only be a 'max' instead | ||
// 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 | ||
autorange: axesAttrs.autorange, | ||
// might make 'nonnegative' the default, | ||
// or add a special polar algo. | ||
rangemode: axesAttrs.rangemode, | ||
range: axesAttrs.range, | ||
|
||
categoryorder: axesAttrs.categoryorder, | ||
categoryarray: axesAttrs.categoryarray, | ||
|
||
// position (name analogous to xaxis.position), | ||
// or maybe something more specific e.g. angle angleoffset? | ||
// | ||
// (should this support any data coordinate system?) | ||
// I think it is more intuitive to set this as just an angle! | ||
// Thoughts? | ||
position: { | ||
valType: 'angle', | ||
editType: 'plot', | ||
role: 'info', | ||
description: [ | ||
'Sets the angle (in degrees) from which the radial axis is drawn.', | ||
'Note that by default, radial axis line on the theta=0 line', | ||
'corresponds to a line pointing right (like what mathematicians prefer).', | ||
'Defaults to the first `polar.sector` angle.' | ||
].join(' ') | ||
}, | ||
|
||
side: { | ||
valType: 'enumerated', | ||
// maybe 'clockwise' and 'counterclockwise' would be best here | ||
values: ['left', 'right'], | ||
dflt: 'right', | ||
editType: 'plot', | ||
role: 'info', | ||
description: [ | ||
'Determines on which side of radial axis line', | ||
'the tick and tick labels appear.' | ||
].join(' ') | ||
}, | ||
|
||
// not sure about these | ||
// maybe just for radialaxis ?? | ||
title: axesAttrs.title, | ||
titlefont: axesAttrs.titlefont, | ||
|
||
// only applies to radial axis for now (i.e. for cliponaxis: false traces) | ||
// but angular.layer could be a thing later | ||
layer: axesAttrs.layer, | ||
|
||
hoverformat: axesAttrs.hoverformat, | ||
|
||
// More attributes: | ||
|
||
// We'll need some attribute that determines the span | ||
// to draw donut-like charts | ||
// e.g. https://github.com/matplotlib/matplotlib/issues/4217 | ||
// | ||
// maybe something like 'span' or 'hole' (like pie, but pie set it in data coords?) | ||
// span: {}, | ||
// hole: 1 | ||
|
||
// maybe should add a boolean to enable square grid lines | ||
// and square axis lines | ||
// (most common in radar-like charts) | ||
// e.g. squareline/squaregrid or showline/showgrid: 'square' (on-top of true) | ||
|
||
editType: 'calc' | ||
}; | ||
|
||
extendFlat( | ||
radialAxisAttrs, | ||
|
||
// N.B. the radialaxis grid lines are circular, | ||
// but radialaxis lines are straight from circle center to outer bound | ||
axisLineGridAttr, | ||
axisTickAttr | ||
); | ||
|
||
var angularAxisAttrs = { | ||
visible: extendFlat({}, axesAttrs.visible, {dflt: true}), | ||
type: { | ||
valType: 'enumerated', | ||
// 'linear' should maybe be called 'angle' or 'angular' here | ||
// to make clear that axis here is periodic and more tightly match | ||
// `thetaunit`? | ||
// | ||
// no 'log' for now | ||
values: ['-', 'linear', 'date', 'category'], | ||
dflt: '-', | ||
role: 'info', | ||
editType: 'calc', | ||
description: [ | ||
'Sets the angular axis type.', | ||
'If *linear*, set `thetaunit` to determine the unit in which axis value are shown.', | ||
'If *date*, set `period` to determine the wrap around period.', | ||
'If *category, set `period` to determine the number of integer coordinates around polar axis.' | ||
].join(' ') | ||
}, | ||
|
||
categoryorder: axesAttrs.categoryorder, | ||
categoryarray: axesAttrs.categoryarray, | ||
|
||
thetaunit: { | ||
valType: 'enumerated', | ||
values: ['radians', 'degrees'], | ||
dflt: 'degrees', | ||
role: 'info', | ||
editType: 'calc', | ||
description: [ | ||
'Sets the format unit of the formatted *theta* values.', | ||
'Has an effect only when `angularaxis.type` is *linear*.' | ||
].join(' ') | ||
}, | ||
|
||
period: { | ||
valType: 'any', | ||
editType: 'calc', | ||
role: 'info', | ||
description: '' | ||
|
||
// 360 / 2*pi for linear (might not need to set it) | ||
// and to full range for other types | ||
|
||
// 'period' is the angular equivalent to 'range' | ||
|
||
// similar to dtick, one way to achieve e.g.: | ||
// - period that equals the timeseries length | ||
// http://flowingdata.com/2017/01/24/one-dataset-visualized-25-ways/18-polar-coordinates/ | ||
// - and 1-year periods (focusing on seasonal change0 | ||
// http://otexts.org/fpp2/seasonal-plots.html | ||
// https://blogs.scientificamerican.com/sa-visual/why-are-so-many-babies-born-around-8-00-a-m/ | ||
// 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/ | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great feature !! Can you please include the code (layout config attributes) for the above example screenshots? |
||
|
||
direction: { | ||
valType: 'enumerated', | ||
values: ['counterclockwise', 'clockwise'], | ||
// we could make the default 'clockwise' for date axes ... | ||
dflt: 'counterclockwise', | ||
role: 'info', | ||
editType: 'calc', | ||
description: [ | ||
'Sets the direction corresponding to positive angles.' | ||
].join(' ') | ||
}, | ||
|
||
// matlab uses thetaZeroLocation: 'North', 'West', 'East', 'South' | ||
// mpl uses set_theta_zero_location('W', offset=10) | ||
// | ||
// position is analogous to yaxis.position, but as an angle (going | ||
// counterclockwise about cartesian y=0. | ||
position: { | ||
valType: 'angle', | ||
// we could maybe make `position: 90` by default for category and date angular axes. | ||
dflt: 0, | ||
editType: 'calc', | ||
role: 'info', | ||
description: [ | ||
'Sets that start position (in degrees) of the angular axis', | ||
'Note that by default, polar subplots are orientation such that the theta=0', | ||
'corresponds to a line pointing right (like what mathematicians prefer).', | ||
'For example to make the angular axis start from the North (like on a compass),', | ||
'set `angularaxis.position` to *90*.' | ||
].join(' ') | ||
}, | ||
|
||
hoverformat: axesAttrs.hoverformat, | ||
|
||
editType: 'calc' | ||
}; | ||
|
||
extendFlat( | ||
angularAxisAttrs, | ||
|
||
// N.B. the angular grid lines are straight lines from circle center to outer bound | ||
// the angular line is circular bounding the polar plot area. | ||
axisLineGridAttr, | ||
// Note that ticksuffix defaults to '°' for angular axes with `thetaunit: 'degrees'` | ||
axisTickAttr | ||
); | ||
|
||
module.exports = { | ||
// AJ and I first thought about a x/y/zoom system for paper-based zooming | ||
// but I came to think that sector span + radial axis range | ||
// zooming will be better | ||
// | ||
// TODO confirm with team. | ||
// x: {}, | ||
// y: {}, | ||
// zoom: {}, | ||
|
||
domain: { | ||
x: extendFlat({}, domainItem, { | ||
description: [ | ||
'Sets the horizontal domain of this subplot', | ||
'(in plot fraction).' | ||
].join(' ') | ||
}), | ||
y: extendFlat({}, domainItem, { | ||
description: [ | ||
'Sets the vertical domain of this subplot', | ||
'(in plot fraction).' | ||
].join(' ') | ||
}), | ||
editType: 'plot' | ||
}, | ||
|
||
// Maybe this should angularaxis.range correspond to | ||
// angular span of the drawing area? | ||
// | ||
// matlab's angular equivalent to 'range' bounds the drawing area | ||
// (partial circles as they call it) | ||
// https://www.mathworks.com/help/matlab/ref/thetalim.html | ||
// | ||
// as this attribute would be best set in (absolute) angles, | ||
// I think this should be set outside of angularaxis e.g | ||
// as polar.sector: [0, 180] | ||
sector: { | ||
valType: 'info_array', | ||
items: [ | ||
// or be more strict -> `valType: 'angle' with `dflt: [0, 360]` | ||
{valType: 'number', editType: 'plot'}, | ||
{valType: 'number', editType: 'plot'} | ||
], | ||
dflt: [0, 360], | ||
role: 'info', | ||
editType: 'plot', | ||
description: [ | ||
'Sets angular span of this polar subplot with two angles (in degrees).', | ||
'Sector are assumed to be spanned in the counterclockwise direction', | ||
'with *0* corresponding to rightmost limit of the polar subplot.' | ||
].join(' ') | ||
}, | ||
|
||
bgcolor: { | ||
valType: 'color', | ||
role: 'style', | ||
editType: 'plot', | ||
dflt: colorAttrs.background, | ||
description: 'Set the background color of the subplot' | ||
}, | ||
|
||
radialaxis: radialAxisAttrs, | ||
angularaxis: angularAxisAttrs, | ||
|
||
// TODO maybe? | ||
// annotations: | ||
|
||
editType: 'calc' | ||
}; |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
e.g. in matlab: