From b7f4b27c6c649f758c387d39197f7672f4c7ca41 Mon Sep 17 00:00:00 2001 From: VeraZab Date: Tue, 13 Feb 2018 16:14:17 -0500 Subject: [PATCH 1/7] Remove plotly.Axes.list(graphDiv) // doesn't work everywhere --- src/lib/connectAxesToLayout.js | 49 ++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/lib/connectAxesToLayout.js b/src/lib/connectAxesToLayout.js index a002535d8..3d5dfcd91 100644 --- a/src/lib/connectAxesToLayout.js +++ b/src/lib/connectAxesToLayout.js @@ -8,10 +8,12 @@ function computeAxesOptions(axes, _) { const options = [{label: _('All'), value: 'allaxes'}]; for (let i = 0; i < axes.length; i++) { const ax = axes[i]; - const axesPrefix = ax._id.length > 1 ? ' ' + ax._id.substr(1) : ''; - const label = `${ax._id.charAt(0).toUpperCase()}${axesPrefix}`; - const value = - (axesPrefix.length > 0 ? axesPrefix + '.' : '').trim() + ax._name; + const label = ax._name + .split('axis')[0] + .charAt(0) + .toUpperCase(); + + const value = (ax.prefix ? ax.prefix + '.' : '').trim() + ax._name; options[i + 1] = {label, value}; } @@ -35,18 +37,37 @@ export default function connectAxesToLayout(WrappedComponent) { this.setLocals(nextProps, nextState, nextContext); } - // This function should be optimized. We can compare a list of - // axesNames to nextAxesNames and check gd.layout[axesN] for shallow - // equality. Unfortunately we are currently mutating gd.layout so the - // shallow check is not possible. setLocals(nextProps, nextState, nextContext) { - const {plotly, graphDiv, container, fullContainer} = nextContext; + const {container, fullContainer} = nextContext; const {axesTarget} = nextState; - if (plotly) { - this.axes = plotly.Axes.list(graphDiv); - } else { - this.axes = []; - } + + this.axes = []; + + // Plotly.js should really have a helper function for this, but until it does.. + Object.keys(fullContainer._subplots) + .filter( + // cartesian types will have xaxis or yaxis directly in _fullLayout + type => + type !== 'cartesian' && fullContainer._subplots[type].length !== 0 + ) + .forEach(type => { + if (['xaxis', 'yaxis'].includes(type)) { + this.axes.push(fullContainer[type]); + } + if (!['xaxis', 'yaxis', 'cartesian'].includes(type)) { + this.axes = Object.keys( + fullContainer[fullContainer._subplots[type]] + ) + .filter(key => key.includes('axis')) + .map(axis => { + // will take care of subplots after + const prefix = fullContainer._subplots[type][0]; + fullContainer[prefix][axis].prefix = prefix; + return fullContainer[prefix][axis]; + }); + } + }); + this.axesOptions = computeAxesOptions(this.axes, nextProps.localize); if (axesTarget === 'allaxes') { From 91645c8761db77eda2f372399dd5bcfed8cb943c Mon Sep 17 00:00:00 2001 From: VeraZab Date: Wed, 14 Feb 2018 13:50:37 -0500 Subject: [PATCH 2/7] Create AxisRequiredPanel --- README.md | 1 + .../containers/AxisRequiredPanel.js | 51 ++ src/components/containers/PanelEmpty.js | 14 +- .../containers/TraceRequiredPanel.js | 15 +- src/components/containers/index.js | 2 + src/components/index.js | 2 + src/default_panels/StyleAxesPanel.js | 563 +++++++++--------- 7 files changed, 355 insertions(+), 293 deletions(-) create mode 100644 src/components/containers/AxisRequiredPanel.js diff --git a/README.md b/README.md index aed29b950..1d07f74af 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ Simple component that takes in props and renders. * ``: `` whose children are replicated into `` connected to traces via `connectTraceToPlot()`. * ``: `` whose children are connected to the `layout` figure key * ``: `` renders `` if no trace data is set +* ``: `` renders `` if no axis in `_fullLayout._subplots` * ``: `` whose children are replicated into `` connected to annotations via `connectAnnotationToLayout()`. For use in a ``. * ``: `` whose children are replicated into `` connected to shapes via `connectShapeToLayout()`. For use in a ``. * ``: `` whose children are replicated into `` connected to images via `connectImageToLayout()`. For use in a ``. diff --git a/src/components/containers/AxisRequiredPanel.js b/src/components/containers/AxisRequiredPanel.js new file mode 100644 index 000000000..e5a8a8ac3 --- /dev/null +++ b/src/components/containers/AxisRequiredPanel.js @@ -0,0 +1,51 @@ +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; +import PanelEmpty from './PanelEmpty'; +import Panel from './Panel'; + +class AxisRequiredPanel extends Component { + constructor(props) { + super(props); + this.state = { + hasAxis: true, + }; + } + + checkAxisExistence() { + const hasSubplot = + Object.keys(this.context.fullContainer._subplots).filter( + type => + !['cartesian', 'mapbox'].includes(type) && + this.context.fullContainer._subplots[type].length > 0 + ).length > 0; + if (!hasSubplot) { + this.setState({hasAxis: false}); + } + } + + componentWillReceiveProps() { + this.checkAxisExistence(); + } + + componentDidMount() { + this.checkAxisExistence(); + } + + render() { + if (this.state.hasAxis) { + return {this.props.children}; + } + return ; + } +} + +AxisRequiredPanel.propTypes = { + children: PropTypes.node, + emptyPanelHeader: PropTypes.string, +}; + +AxisRequiredPanel.contextTypes = { + fullContainer: PropTypes.object, +}; + +export default AxisRequiredPanel; diff --git a/src/components/containers/PanelEmpty.js b/src/components/containers/PanelEmpty.js index 403fadad6..30e78f5c8 100644 --- a/src/components/containers/PanelEmpty.js +++ b/src/components/containers/PanelEmpty.js @@ -1,17 +1,13 @@ import PropTypes from 'prop-types'; import React, {Component} from 'react'; import {ChartLineIcon} from 'plotly-icons'; -import {bem, localize} from 'lib'; +import {bem} from 'lib'; class PanelEmpty extends Component { render() { - const { - children, - localize: _, - heading = _("Looks like there aren't any traces defined yet."), - message = _("Go to the 'Create' tab to define traces."), - icon: Icon, - } = this.props; + const {children, icon: Icon} = this.props; + const heading = this.props.heading || ''; + const message = this.props.message || ''; return (
@@ -38,4 +34,4 @@ PanelEmpty.propTypes = { icon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), }; -export default localize(PanelEmpty); +export default PanelEmpty; diff --git a/src/components/containers/TraceRequiredPanel.js b/src/components/containers/TraceRequiredPanel.js index 31bfc0893..140b8fd69 100644 --- a/src/components/containers/TraceRequiredPanel.js +++ b/src/components/containers/TraceRequiredPanel.js @@ -1,7 +1,8 @@ -import React, {Component} from 'react'; -import PropTypes from 'prop-types'; import PanelEmpty from './PanelEmpty'; +import PropTypes from 'prop-types'; +import React, {Component} from 'react'; import {LayoutPanel} from './derived'; +import {localize} from 'lib'; class TraceRequiredPanel extends Component { constructor(props) { @@ -36,14 +37,17 @@ class TraceRequiredPanel extends Component { } render() { - const {children, ...rest} = this.props; + const {localize: _, children, ...rest} = this.props; const {hasTraces} = this.state; if (this.props.visible) { return hasTraces ? ( {children} ) : ( - + ); } return null; @@ -52,6 +56,7 @@ class TraceRequiredPanel extends Component { TraceRequiredPanel.propTypes = { children: PropTypes.node, + localize: PropTypes.func, visible: PropTypes.bool, }; @@ -63,4 +68,4 @@ TraceRequiredPanel.contextTypes = { fullData: PropTypes.array, }; -export default TraceRequiredPanel; +export default localize(TraceRequiredPanel); diff --git a/src/components/containers/index.js b/src/components/containers/index.js index 5c8937f1e..8a7c373ed 100644 --- a/src/components/containers/index.js +++ b/src/components/containers/index.js @@ -2,6 +2,7 @@ import AnnotationAccordion from './AnnotationAccordion'; import ShapeAccordion from './ShapeAccordion'; import ImageAccordion from './ImageAccordion'; import AxesFold from './AxesFold'; +import AxisRequiredPanel from './AxisRequiredPanel'; import Fold from './Fold'; import MenuPanel from './MenuPanel'; import Panel from './Panel'; @@ -14,6 +15,7 @@ import SingleSidebarItem from './SingleSidebarItem'; export { AnnotationAccordion, + AxisRequiredPanel, ShapeAccordion, ImageAccordion, MenuPanel, diff --git a/src/components/index.js b/src/components/index.js index f118eac30..1d004da59 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -36,6 +36,7 @@ import { ShapeAccordion, ImageAccordion, AxesFold, + AxisRequiredPanel, Fold, LayoutPanel, MenuPanel, @@ -63,6 +64,7 @@ export { AxesFold, AxesRange, AxesSelector, + AxisRequiredPanel, Button, CanvasSize, ColorPicker, diff --git a/src/default_panels/StyleAxesPanel.js b/src/default_panels/StyleAxesPanel.js index f8fdaac71..44ec42115 100644 --- a/src/default_panels/StyleAxesPanel.js +++ b/src/default_panels/StyleAxesPanel.js @@ -11,6 +11,7 @@ import { MenuPanel, Section, TraceRequiredPanel, + AxisRequiredPanel, AxesFold, Fold, } from '../components'; @@ -19,313 +20,317 @@ import {localize} from '../lib'; const StyleAxesPanel = ({localize: _}) => ( - - - - - - + + + + + + + - -
- - - - -
-
+ +
+ + + + +
+
- -
- - - + +
+ + + - - -
-
- - - -
-
- - - -
+ + +
+
+ + + +
+
+ + + +
-
- - -
-
+
+ + +
+ + + +
+ + + + + + - -
+ +
+ +
+ +
+ +
+
+ +
+
+ + +
+ +
+ + + + + +
+
+ +
+ + + + +
+
+ + + + + +
+
+ + - - - - - - - -
- -
- -
- -
-
- -
-
- - + -
+ + -
+ + + +
+ + +
+
+ +
+
- - - -
-
- -
+ - - - -
-
- - - - -
-
- - - - - - - - - - - - - -
- - -
-
- -
-
- - - - - - - + + + +
); From 57f7032943f440d9ee6ce08bdd0424f3e4c1ceca Mon Sep 17 00:00:00 2001 From: VeraZab Date: Wed, 14 Feb 2018 14:37:41 -0500 Subject: [PATCH 3/7] Corrected update function for all axes --- src/lib/connectAxesToLayout.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib/connectAxesToLayout.js b/src/lib/connectAxesToLayout.js index 3d5dfcd91..fded3ba50 100644 --- a/src/lib/connectAxesToLayout.js +++ b/src/lib/connectAxesToLayout.js @@ -118,12 +118,11 @@ export default function connectAxesToLayout(WrappedComponent) { const keys = Object.keys(update); for (let i = 0; i < keys.length; i++) { for (let j = 0; j < axes.length; j++) { - const scene = axes[j]._id.substr(1); + const prefix = axes[j].prefix; let axesKey = axes[j]._name; - // scenes are nested - if (scene.indexOf('scene') !== -1) { - axesKey = `${scene}.${axesKey}`; + if (prefix) { + axesKey = `${prefix}.${axesKey}`; } const newkey = `${axesKey}.${keys[i]}`; From be812479ee614e7a4c98e61d8fd75e77bede0b77 Mon Sep 17 00:00:00 2001 From: VeraZab Date: Wed, 14 Feb 2018 14:45:01 -0500 Subject: [PATCH 4/7] Not needed --- src/lib/connectAxesToLayout.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib/connectAxesToLayout.js b/src/lib/connectAxesToLayout.js index fded3ba50..543c1ac5f 100644 --- a/src/lib/connectAxesToLayout.js +++ b/src/lib/connectAxesToLayout.js @@ -154,8 +154,6 @@ export default function connectAxesToLayout(WrappedComponent) { AxesConnectedComponent.contextTypes = { container: PropTypes.object.isRequired, fullContainer: PropTypes.object.isRequired, - graphDiv: PropTypes.object.isRequired, - plotly: PropTypes.object, updateContainer: PropTypes.func, }; From db692b63af1d290eba004a6174c6f13663cfeac7 Mon Sep 17 00:00:00 2001 From: VeraZab Date: Wed, 14 Feb 2018 16:19:37 -0500 Subject: [PATCH 5/7] Fix geo axes --- src/default_panels/StyleAxesPanel.js | 11 ++++++++++- src/lib/connectAxesToLayout.js | 12 ++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/default_panels/StyleAxesPanel.js b/src/default_panels/StyleAxesPanel.js index 44ec42115..785d28478 100644 --- a/src/default_panels/StyleAxesPanel.js +++ b/src/default_panels/StyleAxesPanel.js @@ -14,6 +14,7 @@ import { AxisRequiredPanel, AxesFold, Fold, + TraceTypeSection, } from '../components'; import {localize} from '../lib'; @@ -49,6 +50,14 @@ const StyleAxesPanel = ({localize: _}) => ( ]} /> + + + + @@ -206,7 +215,7 @@ const StyleAxesPanel = ({localize: _}) => ( /> -
+
Date: Wed, 14 Feb 2018 16:27:34 -0500 Subject: [PATCH 6/7] Subplots are in next pr // will re enable tests there --- src/lib/__tests__/multiValued-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/__tests__/multiValued-test.js b/src/lib/__tests__/multiValued-test.js index d0ed601eb..55ac08230 100644 --- a/src/lib/__tests__/multiValued-test.js +++ b/src/lib/__tests__/multiValued-test.js @@ -7,7 +7,7 @@ import {connectLayoutToPlot, connectAxesToLayout} from '..'; import {mount} from 'enzyme'; describe('multiValued Numeric', () => { - it('uses placeholder and empty string value', () => { + it.only('uses placeholder and empty string value', () => { const fixtureProps = fixtures.scatter({ layout: {xaxis: {range: [0, 1]}, yaxis: {range: [-1, 1]}}, }); From 36dae8f8975782b18d630f43f67e8308bfad753d Mon Sep 17 00:00:00 2001 From: VeraZab Date: Thu, 15 Feb 2018 10:32:50 -0500 Subject: [PATCH 7/7] fixes individual axes controls display for 3d, ternary, geo --- src/lib/connectAxesToLayout.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/connectAxesToLayout.js b/src/lib/connectAxesToLayout.js index 2101ee3c1..3b17d4b25 100644 --- a/src/lib/connectAxesToLayout.js +++ b/src/lib/connectAxesToLayout.js @@ -81,11 +81,11 @@ export default function connectAxesToLayout(WrappedComponent) { ); this.fullContainer = multiValuedContainer; this.defaultContainer = this.axes[0]; - // what should this be set to? Probably doesn't matter. this.container = {}; } else { this.fullContainer = nestedProperty(fullContainer, axesTarget).get(); - this.container = nestedProperty(container, axesTarget).get(); + this.container = this.container = + nestedProperty(container, axesTarget).get() || {}; } }