-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
parcoords #1256
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
parcoords #1256
Conversation
01c52f4
to
e1498e4
Compare
@@ -62,6 +62,8 @@ function menuDefaults(menuIn, menuOut, layoutOut) { | |||
coerce('borderwidth'); | |||
} | |||
|
|||
// todo consider unifying it with other similar array coercions | |||
// - though `Array.isArray(buttonIn.args)` is quite spedific... |
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.
🔪
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.
🔪'd
src/traces/parcoords/attributes.js
Outdated
role: 'info', | ||
description: 'The shown name of the dimension.' | ||
}, | ||
integer: { |
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.
what is this?
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.
For integer
variables, there's
- No fractional ticks (e.g. there's no
1.5
tick between1
and2
- Brushing snaps to the integer value (see below)
The reason is that, as per client discussion, in the 1st iteration we'll have no support for ordinal
and nominal
dimensions, i.e. such user dimensions will map to integers. But going forward, we should do it with some unified (full-featured Plotly) axis
approach, with proper ordinal
, nominal
, date
etc. support.
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.
OK. But a boolean integer
can't possibly cover the ordinal
/ nominal
and date
axis type?
Something like x
or position
if you tell that vertical parcood is a thing (which would default to 0,1,2,....) sounds like the way to go here?
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.
Correct, a boolean integer
won't cover these axis types. I believe we shouldn't keep it in the API - it's just a placeholder for a preview of the functionality, not a final API element. I'll try to change it such that it follows established denotation of the alternative axis types.
Re x
or position
: I don't know how it's related to axis type, we don't currently have support for vertical parcoord (i.e. all of our parcoords
axes are currently vertical, and the panels are laid out horizontally). The integer
thing is merely an indication if the axis is integer (see that on Cylinder material
and Block material
there are no fractional ticks though there would be room for it; and that the magenta axis brushing bar 'snaps' to the integer values).
src/traces/parcoords/attributes.js
Outdated
} | ||
), | ||
|
||
lines: { |
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.
a line
and lines
attribute container? No thanks.
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.
lines
is the old stuff, I'm just not fully clear on whether you want to keep some of what's in there, which is why I haven't yet removed it.
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.
Please suggest if I should unexpose lines
, padding
and filterbar
for the time being, or if not, I'll put attributes still in lines
into line
, or resolve it some other way you deem best.
src/traces/parcoords/defaults.js
Outdated
dimensionIn = dimensionsIn[i]; | ||
dimensionOut = {}; | ||
|
||
if(!Lib.isPlainObject(dimensionIn) || !Array.isArray(dimensionIn.values)) { |
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.
probably best to keep data[i].dimensions.length === fullData[i].dimenstions.length
for restyle purposes.
Non plain-object dimensions items and items with values.length === 0
, should be skipped during the plot only.
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.
++ I'd vote for adding a dimenstions[i].visible
boolean to easily toggle dimensions visibility.
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.
++ I'd vote for adding a dimensions[i].visible boolean to easily toggle dimensions visibility.
How would this work in the UI? ie how would you get a dimension back after hiding it? Some dropdown with hidden dimensions in it?
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.
@alexcjohnson having caught up on this item with Étienne, the addition of a UI interaction was deferred for now. I created a visible
attribute in the meantime to have API control.
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.
Just summing up the current status of this feedback item - as code is right now -, which fell this way in part due to preexisting code regularity, but I'm glad to iterate, as there are some mismatches to the feedback, I just want to make sure work toward it is deemed valuable:
-
The
dimensions[i].visible
attribute has been added. -
Each
dimension
has anid
(defaults to thelabel
if unsupplied) - onPlotly.restyle
, dimensions of matchingid
are updated; dimensions with a newid
are added. My pre-feedback assumption was that the user can add dimensions incrementally. -
Currently, there's no special handling for
values.length === 0
however the line count is determined as the minimum ofvalues.length
across dimensions, so in this case, no line gets rendered. I like the idea to handlevalues.length === 0
as a special case, to implicitly mean that the dimension be removed. Also, the code already skips non-isPlainObject
dimensions and dimensions whosevalues
isn't an array which I think is what you meant; I'll reify both with a test case shortly.
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.
Each dimension has an id (defaults to the label if unsupplied) - on Plotly.restyle, dimensions of matching id are updated; dimensions with a new id are added. My pre-feedback assumption was that the user can add dimensions incrementally
No need to use id
if data[i].dimensions.length === fullData[i].dimenstions.length
, visible: false
means that particular dimension is hidden (not deleted).
Currently, there's no special handling for values.length === 0
dimensions with values.length === 0
should be set to have visible: false
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
'use strict'; | ||
var jet = [[0, 0, 255], [0, 8, 255], [0, 35, 255], [0, 77, 255], [0, 126, 255], [0, 175, 255], [0, 217, 255], [0, 245, 255], [0, 254, 255], [0, 255, 245], [0, 255, 218], [0, 255, 176], [0, 255, 128], [0, 255, 78], [0, 255, 36], [0, 255, 8], [0, 255, 0], [8, 255, 0], [36, 255, 0], [77, 255, 0], [127, 255, 0], [176, 255, 0], [217, 255, 0], [245, 255, 0], [254, 255, 0], [255, 245, 0], [255, 217, 0], [255, 176, 0], [255, 127, 0], [255, 77, 0], [255, 36, 0], [255, 8, 0], [255, 0, 0] |
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.
what's wrong with our colorscales in https://github.com/plotly/plotly.js/blob/master/src/components/colorscale/scales.js ?
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.
This is in the devtesting
directory. It's not used and the entire directory will be deleted. Our example uses "Jet"
or whichever colorscale
you want, as usual with other plots. This was one of your main feedback items. The reason for devtesting
is that it avoided me spending 10-15 seconds on each rebuild, letting me get a refreshed view in 1-2 seconds. I'm locally using budo
for this.
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.
Wait. You've been dev'ing in plotly.js w/o npm start
or npm run watch
?
Ok, sure. But next time, don't commit local-development only files.
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.
Got it! Glad to remove it ASAP, together with several other changes you asked. FWIW I continuously had a watch
as well, and refreshed the plotly
generated test plot, but slightly less frequently. BIG time saver.
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.
Done: removed devtesting
altogether!
src/traces/parcoords/index.js
Outdated
Parcoords.moduleType = 'trace'; | ||
Parcoords.name = 'parcoords'; | ||
Parcoords.basePlotModule = require('./base_plot'); | ||
Parcoords.categories = ['parcoords', 'lineColorscale']; |
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.
should be
Parcoords.categories = ['gl'];
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.
Done
src/traces/parcoords/lines.js
Outdated
resolution: [canvasWidth, canvasHeight], | ||
viewBoxPosition: [x + overdrag, 0], | ||
viewBoxSize: [panelSizeX, canvasPanelSizeY], | ||
var1A: utils.range(16).map(function(d) {return d === i ? 1 : 0;}), |
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.
a good old for-loop here should be faster.
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.
Yes, see the code comments above this piece.
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.
... now the 16 map calls are replaced with one common loop.
|
||
varying vec4 fragColor; | ||
|
||
void main() { |
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.
all glsl
files should be in a new folder src/traces/parcoords/shaders/
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.
Done
src/traces/parcoords/utils.js
Outdated
@@ -0,0 +1,137 @@ | |||
/** |
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.
naming modules like these helpers.js
would be more inline with the rest of the repo.
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.
Phasing out this file altogether is on my task list (see todo code comment on top of the file) - it was merely put in to have no plotly
utils dependency while iterative development went on locally with budo
(for above mentioned fast refreshes).
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.
Done - utils.js
is now removed!
@etpinard thanks for your fantastic, timely feedback! Just pushed the low hanging fruit items. Working on the rest one by one. There are only a couple items above where I could use some direction. |
package.json
Outdated
@@ -103,6 +104,7 @@ | |||
"fs-extra": "^1.0.0", | |||
"fuse.js": "^2.2.0", | |||
"glob": "^7.0.0", | |||
"glslify": "^4.0.0", |
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.
we'll need to add a transforms
field to the package.json so users can bundle plotly.js w/o having to worry about -t glslify
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.
@etpinard UPDATE: I added this to package.json
to permit npm install
with glslify
present:
"browserify": {
"transform": ["glslify"]
}
=============================================================
I made a custom build with npm run build
for testing purposes (http://codepen.io/monfera/pen/ObrRGP) and it worked fine, the transforms were added here and here. Please let me know if it's insufficient, and in this case, how should I go about testing whether the package.json
change was successful or not, because the build seems good as it is.
Perhaps you're referring to users who just put plotly.js
in as one of their dependencies in their package.json
and install their system with npm install
, instead of using a bundle? Should I test for this?
@monfera this is looking really slick! Just a comment about the interactions: I didn't find resetting a single constraint (click in the unselected portion of its axis) to be particularly discoverable. I notice there's a "zoom out" cursor that most browsers support, can we use that when it's available? And perhaps also reset that axis when you double-click on the selection bar, akin to how our cartesian interaction works? Also for parity with cartesian, can we make the cursor on the bottom |
@alexcjohnson yes there's plans to add a Reset All interaction to the mode bar, and perhaps per-dimension Reset interactions near the axis titles. What do you mean by the use of the zoom out cursor? That this cursor gets activated if the filter is active and the user hovers over the non-filtered part, on which a click removes the filter? Btw. this part serves not only a reset function but also a 'start new selection' interaction. I'll look into the cursor changes you've suggested. Also, there hasn't been work toward unifying with Cartesian axes, so a bunch of things may become closer in API and behavior as well. |
yes, that's what I had in mind. But...
Ah, I hadn't discovered that at all, but it makes sense. That complicates it a little though... might be even harder to discover that you can start a new selection this way if the cursor becomes "zoom-out". Alright, so perhaps lets leave this cursor as it is at least for now. I suppose if we do add a reset button to each axis we might get rid of reset on an off-selection click... though there's something nice about having it all together as you have now if we can make it intuitive enough.
Cool, I think the other ones I suggested still stand.
Your call to what extent to do this - as this comes together it's seeming to me that the interactions and drawing are sufficiently different that you shouldn't try to reuse cartesian for these parts, just mimic its feel to the extent you can. But there are likely still benefits to using the cartesian code and attributes for tick selection & formatting and using cartesian attributes for some other style aspects. |
@etpinard could you please offer feedback on the planned |
188d7db
to
f350521
Compare
@etpinard may I just update I dismissed the string based
Then I tried the object form of
Simply reinvoking
|
It's important for extensibility that the
Not quite sure what's going on here, but one thing to be aware of is that restyling with an array argument you need to wrap it in another (length-1) array to distinguish from the case of restyling multiple traces with different values. |
@alexcjohnson thanks for answering!
In this case, the above In line with your input, I'm planning to pursue two separate tracks:
|
3e192e0
to
edc2710
Compare
@etpinard regarding a not yet discussed part of a comment above, maybe you've seen it before: I'm running into an issue with the So I expect that Glad to investigate if it doesn't ring a bell. |
src/traces/parcoords/plot.js
Outdated
}; | ||
} | ||
|
||
var orig = sorter(gdDimensionsOriginalOrder[i].filter(function(d) {return d.visible === void(0) || d.visible;})); |
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.
I believe the logic is a little off here when visible: false
traces are present.
For example:
- Plot the
gl2d_parcoords
mock - call
Plotly.restyle(gd, 'dimenstion[0].visible', false)
- swap the Cylinder material dimension and Block width dimensions
- then
gd.data[0].dimensions[0]
is the Cylinder material dimension and the originalgd.data[0].dimensions[0]
container (with id Block height) is now (strangely 😕 ) indimensions[9]
. - so then if a user tries to toggle the Block height dimension back in with
Plotly.restyle(gd, 'dimensions[0].visible', true)
, the graph remain unchanged.
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.
Yes this is how it works. It's hard to interpret the location of something that isn't visible, esp. after sorting the (visible) axes. For this reason, everything that's invisible gets sorted to the end by the axis drag&drop logic. I believe it shouldn't pose a problem because there's a generated Plotly.restyle
upon axis drag&drop and the dimensions are on gd.data
in a sorted manner. It was discussed it with a client at the time, motivated by the above challenges (i.e. what's the location of an invisible dimension after other dimensions get manually repositioned in the neighborhood).
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.
I disagree. I think visible: false
dimensions should not be moved when other dimensions are swapped on drag.
In the above example, I'd expect the original dimensions[0]
to remain there after the drag event and that the Cylinder material dimension and Block width dimensions get swapped between dimensions[1]
and dimensions[2]
.
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.
I'm glad to change it, so the new logic would be such that whatever is invisible always retains its place, e.g. if we have [dim[0], dim[1], dim[2]]
and dim[1] is invisible, and the user moves dim[0] to the right, then the new state is [dim[2], dim[1], dim[0]]
.
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.
Correct. In other words, visible: false
dimensions cannot be moved on drag events.
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.
Looking good now ✅
src/traces/parcoords/parcoords.js
Outdated
.append('canvas') | ||
.attr('class', function(d) {return 'parcoords-lines ' + (d.context ? 'context' : d.pick ? 'pick' : 'focus');}) | ||
.style('box-sizing', 'content-box') | ||
.style('transform', 'translate(' + (-c.overdrag) + 'px, 0)') |
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.
This here is incompatible with the current master
since commit 4aa1a45 where @alexcjohnson made the test dashboard catch negative translate
values which can cause issues in some browsers (e.g. I.E.)
Trying to plot any of the gl2d_parcoords_*
mock in the test dashboards leads to:
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.
(Neglect deleted comment in case notification shows up. Missed that this was an html element vs. an svg element)
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.
Thanks @etpinard I now rebased, and even the mock baseline failed until the transform got redone to avoid the negative value.
0c8953d
to
b44dcca
Compare
@etienne with these pushed commits above, the outstanding PR feedback items have been addressed. |
src/traces/parcoords/defaults.js
Outdated
|
||
if(actuallyVisible) { | ||
var values = coerce('values'); | ||
var visible = coerce('visible', values.length > 0); |
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.
Thanks!
src/traces/parcoords/base_plot.js
Outdated
|
||
function canvasToImage() { | ||
var canvas = this; | ||
var rect = canvas.getBoundingClientRect(); |
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.
We should try to remove these expensive getBoundingClientRect
calls and replace them with the appropriate domain
+ layout.width
/ layout.height
formulae.
I believe these might be the reason behind the issues with autosize: true
image exports.
@monfera This is now the last remaining 🚫 item. 🎉 🎉 🎉
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.
Yikes. There are probably a lot of those hiding here: https://github.com/plotly/plotly.js/blob/master/src/components/drawing/index.js#L528
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.
This is a good point: we should definitely minimize our use of getBoundingClientRect
, and it might be worthwhile to look through the places we use it and see which ones we can remove and which others we may need to alter.
The one you point to in drawing
@rreusser is a case we really do need it - there's no other way AFAIK to get the dimensions and positioning of text, but it's important HOW it's invoked: on a test element attached directly to <body>
, ie not part of gd
. That way we can guarantee that it's attached to the DOM and displayed, which is not always the case with gd
itself when the plot is first rendered - imagine creating a bunch of plots in different tabs of your app, most of which are hidden initially.
I think we can say that during interactions getBoundingClientRect
is safe on elements within gd
(it has to be visible to be interacted with, right? I guess in principle not if an app developer triggers something like a hover effect manually...) but a quick search shows we're probably using it in unsafe ways during initial rendering.
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.
There is canvas.measureText
that I think might measure without forcing a draw (which I think is the reason getBoundingClientRect
is slow right? It's one of those getters that triggers a draw?).
Aaaaand survey says: wrong? Looking at some references, I see reference to a jsperf that indicates they're about the same speed (unfortunately jsperf seems not to exist anymore, so… no link). So probably nothing to do here for now beyond being aware of generally minimizing usage.
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.
Just to be clear: I was making more than a performance point. getBoundingClientRect
will actually fail if an element is not displayed, so it can actually be an error, not just potentially slow.
gd.style.display='none'
gd.getBoundingClientRect()
> ClientRect {top: 0, right: 0, bottom: 0, left: 0, width: 0…}
gd.style.display=''
gd.getBoundingClientRect()
> ClientRect {top: 80, right: 1100, bottom: 580, left: 0, width: 1100…}
@etpinard Got the root cause for the outstanding snapshot bug: to_image sets Looking at the screen printing behavior on other plots I guess that the intention is to generate a fixed, e.g. 700px wide snapshot even if the user exploits the full width of the browser window, for example, by specifying If the above is correct, then the WebGL layers (line layers) must be rerendered in I'm going ahead with the latter approach unless you have some other preference. |
Not quite. As I was trying to explain in #1256 (comment), base plot |
|
||
}); | ||
|
||
it('Should emit a \'plotly_hover\' event', function(done) { |
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.
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.
This one still fails on my machine. Not sure what's up.
I'll try to debug this tomorrow morning.
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.
Maybe somebody else could pull down this branch and run npm run test-jasmine -- tests/parcoords_test.js
to check?
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.
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.
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.
Yes I'll try, thanks! Stepping out now in the evening, will check later. Re the question, mouseover
fires on the entire surface of the canvas; it's after reading out the pick pixels when there's a decision if a line was found
or not.
src/traces/parcoords/index.js
Outdated
Parcoords.meta = { | ||
description: [ | ||
'Parallel coordinates for multidimensional exploratory data analysis.', | ||
'The samples are in `data`.', |
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.
should be 'The samples are in dimensions
.', no?
test/image/mocks/gl2d_parcoords.json
Outdated
|
||
"dimensions": [ | ||
{ | ||
"id": "Block height", |
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.
🔪 no need for all those id
fields in the mocks!
b63ef4e
to
7005671
Compare
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.
Amazing work 💃
@monfera I'll let the honours of merging this 💪 PR.
Thanks @etpinard for the thorough and patient review process, and thanks @alexcjohnson and @rreusser for your comments as well! |
function makeItem(i, ii, x, y, panelSizeX, canvasPanelSizeY, crossfilterDimensionIndex, scatter, I, leftmost, rightmost) { | ||
var loHi, abcd, d, index; | ||
var leftRight = [i, ii]; | ||
var filterEpsilon = verticalPadding / canvasPanelSizeY; |
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.
It doesn't look like this was ever discussed during the original PR. In order to make it so constraint ranges are honored as precisely as possible I'm planning to remove this epsilon. Or at least make it very small so it only catches floating point rounding errors, though provisionally it doesn't even look like I need to do that, if we're careful about transforming data and constraints identically. @monfera @etpinard any concerns if I do that? It doesn't really matter if you're setting these ranges interactively and just exploring the data, but if you set constraintrange: [901, 999]
we really should exclude 900 and 1000. Multiselect cannot be as precise of course, I'm just talking about single-range selections here.
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.
any concerns if I do that?
None from me 👍
Introduces
parcoords
with panel trellising, GPU based crossfilter, hybrid SVG + GPU and foundations for multivariate plots such as SPLOM (scatterplot matrices), slope diagrams, strip plots and small multiple plots.#1071
Examples:
A collection of todo items:
Essential / short term:
map
calls in uniforms setting (PR feedback: Étienne)dimension.constraintrange
attributes that represent initial interval constraints (PR feedback: Étienne)dimension.range
(PR feedback: Étienne)parcoords
rows if called with multipledata
items orPlotly.plot
is called again (PR feedback: Étienne)parcoords.js
andlayout.js
restyle
/relayout
dimension.visible
parcoords #1256 (comment)restyle
on filter brushmouseup
, rather than the current event type (PR feedback: Étienne)integer
attribute in favor of a Plotly axis style attribute (PR feedback: Étienne, Alex)defaults.js
logicdimension.values
lengths to uniform lengthdimension.values
are handled properly*range
arrays only contain finite numbersline
orline.colorscale
attributedevtesting
directory before mergetoSVG
method like this (PR feedback: Étienne)Plotly.plot
callsIn subsequent PRs (general expectations or gathered during PR discussion):
parcoords
supports up to 64 dimensions and dimension names can be of arbitrary length, so not as trivial as it sounds (also a PR feedback by Étienne)Discussed future steps:
Reset
interaction hot spot near the dimension axislabel
on top (PR feedback: Alex)pixelRatio
configurabilitycrossfilter
-ability; write up thoughts (asked by Jack)