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

Subplots2 #357

Merged
merged 23 commits into from
Mar 1, 2018
Merged

Subplots2 #357

merged 23 commits into from
Mar 1, 2018

Conversation

VeraZab
Copy link
Contributor

@VeraZab VeraZab commented Feb 23, 2018

No description provided.

@VeraZab VeraZab changed the title Subplots2 [WIP] Subplots2 Feb 23, 2018
@VeraZab VeraZab force-pushed the subplots2 branch 3 times, most recently from 0e8d9be to 21ad5b0 Compare February 25, 2018 23:56
@VeraZab VeraZab changed the title [WIP] Subplots2 Subplots2 Feb 26, 2018
@VeraZab
Copy link
Contributor Author

VeraZab commented Feb 26, 2018

@nicolaskruchten ready for review

@@ -58,6 +61,14 @@ class Field extends Component {
</MenuPanel>
) : null}
</div>
{action ? (
Copy link
Contributor

Choose a reason for hiding this comment

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

does this really belong in Field? Is it a generic enough thing that we'll want it in multiple fields?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well, it may :) if you don't mind too much I'd like to keep it in here for the moment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or looking at it again, yeah, I may change this, it's a bit ugly

Copy link
Contributor

Choose a reason for hiding this comment

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

well, it's likely not worth going through the effort of moving it now, but in future I'd be more comfortable adding in this kind of thing higher up in the stack, not in the base-level components like Field :)

supplyLayoutPlotProps,
striptags,
} from 'lib';

export const AxisAnchorDropdown = connectToContainer(UnconnectedDropdown, {
Copy link
Contributor

Choose a reason for hiding this comment

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

general comment: we should start breaking up this file... it's long and getting longer as we add more and more derived types. Doesn't have to be done in this PR but soon. Maybe create an issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

plotly.Axes.list(graphDiv, props.attr.charAt(1))
),
];
if (props.attr === 'axref') {
Copy link
Contributor

Choose a reason for hiding this comment

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

for this and the cases below, we should DRY it up :) Something like a map over {x: "axref", y: "ayref"}

@@ -7,7 +7,7 @@ import {connectLayoutToPlot, connectAxesToLayout} from '..';
import {mount} from 'enzyme';

describe('multiValued Numeric', () => {
it.only('uses placeholder and empty string value', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

should this be looked-for and flagged in the syntax.js test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is just a test I uncommented, because my previous merge was messing up this behaviour and I knew I'd fix it by introducing subplots..

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, I meant that this kind of it.only should never be allowed right? like we don't allow fit and xit etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah it should not be allowed..

Copy link
Contributor

Choose a reason for hiding this comment

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

#362 will prevent you from trying this trick again ;)

import {connectToContainer, localize, traceTypeToAxisType} from 'lib';
import {EDITOR_ACTIONS} from 'lib/constants';
import {PlusIcon} from 'plotly-icons';

Copy link
Contributor

Choose a reason for hiding this comment

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

this component should show the axis title, not just the x, x2, y2 axis IDs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's done, as per below gif

Copy link
Contributor

Choose a reason for hiding this comment

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

It's done in the AxesSelector but not the AxisCreator right?

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..

@nicolaskruchten
Copy link
Contributor

This looks pretty good! A couple of my comments need addressing... I've also noticed some odd behaviour in the UI itself but nothing specific I can point to as a bug just yet. Mostly it seems hard or impossible to build a basic dual-Y-axis chart with this UI unfortunately. Maybe I'm missing something I'll try to do some more systematic review after lunch. Sorry to be out of sync today.

@VeraZab
Copy link
Contributor Author

VeraZab commented Feb 27, 2018

hmm, i did set the y2 axis to be easy to make..
ex

and i made axes name reflect the names they're given by the user:
ex

@nicolaskruchten
Copy link
Contributor

So if I create two traces and then set one of them to the second Y-axis, I only ever see 1 trace displayed, I'm not sure where the other one goes!

@VeraZab
Copy link
Contributor Author

VeraZab commented Feb 27, 2018

I only ever see 1 trace displayed, I'm not sure where the other one goes!

are you talking about the example in my gif, or some that you've tried?

@nicolaskruchten
Copy link
Contributor

I'm trying it locally. If I set up trace 0 with x=col1, y=col1, then trace1 with x=col3, y=col3, then I set trace1's y-axis to a new axis, I see the following... where are the blue points for trace0?

image

@VeraZab
Copy link
Contributor Author

VeraZab commented Feb 27, 2018

hmm, you're right, ok, will investigate more of this tomorrow.. right now.. I'm not sure

@nicolaskruchten
Copy link
Contributor

Yeah, it's weird, and not necessarily related to this PR, but worth investigating!

@nicolaskruchten
Copy link
Contributor

Ah ok, it looks like yaxis2.overlaying = 'y' is needed... Not sure if forcing that on creation makes sense or not. We're already moving it to the right side right?

@VeraZab
Copy link
Contributor Author

VeraZab commented Feb 27, 2018

@alexcjohnson would you take a look at this pr for me? see if the logic makes sense.

Also, about creating a second y axis, I haven't noticed that part of my data disappears when I assign yaxis: 'y2' to a trace..
https://codepen.io/plotly/pen/648434b7b06688fc6b00067592d616b0
As Nicolas points out above, it seems like an overlaying: 'y' is needed for both traces to show up. Is this something that maybe plotly.js should be handling by default?

If it's not something to be handled by default by plotly.js, what's the best update that I need to send to plotly.js for all my traces to continue to show up after I've created new axes?

@alexcjohnson
Copy link
Collaborator

it seems like an overlaying: 'y' is needed for both traces to show up. Is this something that maybe plotly.js should be handling by default?

That would be tricky for plotly.js to figure out - we'd have to infer that you intend the two y axes to have not only the same domain but to actually be used within the same subplot (as opposed to just side-by-side plots). Theoretically possible, but I feel like it would be hard to make robust. Whereas here when you're making the second axis, you know whether the intent is overlaid, side-by-side, stacked, or whatever, and you can send yaxis2.overlaying='y' if that's the intent.

@nicolaskruchten
Copy link
Contributor

@alexcjohnson I'm having trouble understanding the overlay: free behaviour... if y and y2 are both anchored to x, and both are overlay: free (the default) then why don't both traces show up on the plot?

images.map((ann, i) => (
<ImageFold key={i} imageIndex={i} name={ann.text} canDelete={canAdd}>
images.map((img, i) => (
<ImageFold key={i} imageIndex={i} name={img.text} canDelete={canAdd}>
Copy link
Collaborator

Choose a reason for hiding this comment

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

images don't have .text do they? Perhaps make a name from .source? Not sure what to do about shapes... index and type perhaps?

Copy link
Contributor

Choose a reason for hiding this comment

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

hehe so this change is @VeraZab cleaning up my copy-paste work from a previous PR... When I created the Images panel I'd based it off of the Notes panel but not renamed ann to img (and ditto Shapes). So any issues with this code should probably go in a separate issue that I can handle ;)

@alexcjohnson
Copy link
Collaborator

I'm having trouble understanding the overlay: free behaviour...

Heh that's because there isn't any free behavior. That's a mistake in the attribute definition, I'll fix it. If you look at _fullLayout the only options you should actually see are an axis id, undefined (there are no possible axes to overlay) or false (you declined to overlay another axis).

overlaying does two related but things when you enable it: 1) it forces the axis to copy the domain of the axis it's overlaying, and 2) it draws its data (when sharing an x axis too) on top of the data for the axis it's overlaying, without first covering the lower subplot in an opaque background.

It's helpful to remember the case you DO want one subplot to block another: inset plots. You do not want data from the main plot to show up behind the inset. I'm sure there could be smarter ways to handle this kind of case, since it's admittedly rare... but hopefully that at least makes it clear how we arrived at the situation we have now.

@nicolaskruchten
Copy link
Contributor

Ahh, thanks for the explainer, it makes sense now :)

? subplot.slice(0, 1) + 'axis' + subplot.slice(1)
: subplot + 'axis';

fullLayout[subplot].subplot = subplot;
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you're adding something to fullLayout that's not a real attribute, can you make it private, ie _subplot?

@@ -2,14 +2,19 @@ import React, {Component} from 'react';
import PropTypes from 'prop-types';
import nestedProperty from 'plotly.js/src/lib/nested_property';
import {deepCopyPublic, setMultiValuedContainer} from './multiValues';
import {getDisplayName, localize, capitalize} from '../lib';
import {capitalize, getAllAxes, getDisplayName, localize} from '../lib';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also not new in this PR, but Isn't this from '.'? Actually, wouldn't it be better to import from the individual files anyway rather than lib/index, since this way is a circular import? It obviously doesn't break, but makes me uneasy...

gl3d: ['scatter3d', 'surface', 'mesh3d'],
geo: ['scattergeo', 'choropleth'],
mapbox: ['scattermapbox'],
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

This feels fragile to me - an alternative that wouldn't require any hardcoding here would be to look at fullTrace._module.basePlotModule.name. Traces that don't have a subplot, like pie, will define their own basePlotModule, so then you can filter on names in the list of known subplot types.

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'll add this to our list of refactorings in fit n' finish.. thanks..

export const AxisOverlayDropdown = connectToContainer(UnconnectedDropdown, {
modifyPlotProps: (props, context, plotProps) => {
let options = [];
if (plotProps.fullContainer.subplot.includes('xaxis')) {
Copy link
Contributor

Choose a reason for hiding this comment

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

could this be DRYed up with a map on xaxis, yaxis ?

@VeraZab
Copy link
Contributor Author

VeraZab commented Feb 27, 2018

@nicolaskruchten would you checkout this branch once more and see if it looks ok to you..?

fullLayout._subplots[type].forEach(subplot => {
if (['xaxis', 'yaxis'].includes(type)) {
// subplot will look like x2, x45, convert it to xaxis2, xaxis45
subplot = // eslint-disable-line no-param-reassign
Copy link
Contributor

Choose a reason for hiding this comment

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

why disable eslint here as opposed to just creating a new variable?

@nicolaskruchten
Copy link
Contributor

💃 💃 ! thanks for putting up with my million comments on this one :)

@VeraZab VeraZab merged commit be01eb4 into master Mar 1, 2018
@VeraZab VeraZab deleted the subplots2 branch March 1, 2018 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants