Skip to content

frames support + slider styling controls #405

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

Merged
merged 8 commits into from
Mar 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,721 changes: 2,718 additions & 3 deletions dev/App.js

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion examples/custom/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class App extends Component {
},
],
layout: {},
frames: [],
};
}

Expand All @@ -39,10 +40,13 @@ class App extends Component {
data={this.state.data}
layout={this.state.layout}
config={config}
frames={this.state.frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
onUpdate={(data, layout) => this.setState({data, layout})}
onUpdate={(data, layout, frames) =>
this.setState({data, layout, frames})
}
useResizeHandler
debug
advancedTraceTypeSelector
Expand Down
7 changes: 6 additions & 1 deletion examples/demo/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class App extends Component {
this.state = {
data: [],
layout: {},
frames: [],
currentMockIndex: -1,
mocks: [],
};
Expand All @@ -52,6 +53,7 @@ class App extends Component {
currentMockIndex: mockIndex,
data: figure.data,
layout: figure.layout,
frames: figure.frames,
});
});
}
Expand All @@ -63,10 +65,13 @@ class App extends Component {
data={this.state.data}
layout={this.state.layout}
config={config}
frames={this.state.frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
onUpdate={(data, layout) => this.setState({data, layout})}
onUpdate={(data, layout, frames) =>
this.setState({data, layout, frames})
}
useResizeHandler
debug
advancedTraceTypeSelector
Expand Down
12 changes: 11 additions & 1 deletion examples/redux/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,22 @@ class App extends Component {
}

render() {
const {actions, dataSources, dataSourceOptions, data, layout} = this.props;
const {
actions,
dataSources,
dataSourceOptions,
data,
layout,
frames,
} = this.props;

return (
<div className="app">
<PlotlyEditor
data={data}
layout={layout}
config={config}
frames={frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
Expand All @@ -56,13 +64,15 @@ App.propTypes = {
dataSources: PropTypes.object,
data: PropTypes.array,
layout: PropTypes.object,
frames: PropTypes.array,
};

const mapStateToProps = state => ({
dataSourceOptions: state.dataSourceOptions,
dataSources: state.dataSources,
data: state.data,
layout: state.layout,
frames: state.frames,
});

const mapDispatchToProps = dispatch => ({
Expand Down
4 changes: 2 additions & 2 deletions examples/redux/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export function dataSourceOptionsUpdate(payload) {
};
}

export function editorUpdate(data, layout) {
export function editorUpdate(data, layout, frames) {
return {
type: ACTIONS.EDITOR_UPDATE,
payload: {data, layout},
payload: {data, layout, frames},
};
}
2 changes: 2 additions & 0 deletions examples/redux/src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const initialState = {
dataSourceOptions: [],
data: [],
layout: {},
frames: [],
};

export default (state = initialState, action) => {
Expand All @@ -18,6 +19,7 @@ export default (state = initialState, action) => {
...state,
data: action.payload.data,
layout: action.payload.layout,
frames: action.payload.frames,
};
default:
return state;
Expand Down
7 changes: 5 additions & 2 deletions examples/simple/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const config = {editable: true};
class App extends Component {
constructor() {
super();
this.state = {data: [], layout: {}};
this.state = {data: [], layout: {}, frames: []};
}

render() {
Expand All @@ -29,10 +29,13 @@ class App extends Component {
data={this.state.data}
layout={this.state.layout}
config={config}
frames={this.state.frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
onUpdate={(data, layout) => this.setState({data, layout})}
onUpdate={(data, layout, frames) =>
this.setState({data, layout, frames})
}
useResizeHandler
debug
advancedTraceTypeSelector
Expand Down
105 changes: 59 additions & 46 deletions scripts/translationKeys/combined-translation-keys.txt

Large diffs are not rendered by default.

31 changes: 22 additions & 9 deletions scripts/translationKeys/translation-keys.txt

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/DefaultEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import {
StyleLegendPanel,
StyleNotesPanel,
StyleShapesPanel,
StyleSlidersPanel,
StyleImagesPanel,
StyleTracesPanel,
StyleColorbarsPanel,
StyleUpdateMenusPanel,
} from './default_panels';

const DefaultEditor = ({localize: _}) => (
Expand All @@ -26,6 +28,8 @@ const DefaultEditor = ({localize: _}) => (
<StyleColorbarsPanel group={_('Style')} name={_('Color Bars')} />
<StyleShapesPanel group={_('Style')} name={_('Shapes')} />
<StyleImagesPanel group={_('Style')} name={_('Images')} />
<StyleSlidersPanel group={_('Style')} name={_('Sliders')} />
<StyleUpdateMenusPanel group={_('Style')} name={_('Update Menus')} />
</PanelMenuWrapper>
</Fragment>
);
Expand Down
8 changes: 7 additions & 1 deletion src/EditorControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class EditorControls extends Component {
dataSourceValueRenderer: this.props.dataSourceValueRenderer,
dataSourceOptionRenderer: this.props.dataSourceOptionRenderer,
dictionaries: this.props.dictionaries || {},
frames: gd._transitionData ? gd._transitionData._frames : [],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

although here I've noticed it's a little odd that my gd doesn't always get _transitionData, sometimes it's undefined..
it's a little odd because it seems to me like this key is always on gd, even if there's no frames...

like here:https://codepen.io/veraz/pen/zRRONV

fullData: gd._fullData,
fullLayout: gd._fullLayout,
graphDiv: gd,
Expand Down Expand Up @@ -98,7 +99,11 @@ class EditorControls extends Component {
this.props.afterUpdateTraces(payload);
}
if (this.props.onUpdate) {
this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout);
this.props.onUpdate(
graphDiv.data.slice(),
graphDiv.layout,
graphDiv._transitionData._frames
);
}
break;

Expand Down Expand Up @@ -278,6 +283,7 @@ EditorControls.childContextTypes = {
dataSources: PropTypes.object,
dataSourceValueRenderer: PropTypes.func,
dictionaries: PropTypes.object,
frames: PropTypes.array,
fullData: PropTypes.array,
fullLayout: PropTypes.object,
graphDiv: PropTypes.any,
Expand Down
2 changes: 2 additions & 0 deletions src/PlotlyEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class PlotlyEditor extends Component {
<this.PlotComponent
data={this.props.data}
layout={this.props.layout}
frames={this.props.frames}
config={this.props.config}
useResizeHandler={this.props.useResizeHandler}
debug={this.props.debug}
Expand All @@ -53,6 +54,7 @@ PlotlyEditor.propTypes = {
config: PropTypes.object,
dataSourceOptions: PropTypes.array,
dataSources: PropTypes.object,
frames: PropTypes.array,
onUpdate: PropTypes.func,
plotly: PropTypes.object,
useResizeHandler: PropTypes.bool,
Expand Down
47 changes: 47 additions & 0 deletions src/components/containers/SliderAccordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Fold from './Fold';
import TraceRequiredPanel from './TraceRequiredPanel';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {connectSliderToLayout, localize} from 'lib';

const SliderFold = connectSliderToLayout(Fold);

class SliderAccordion extends Component {
render() {
const {layout: {sliders = []}} = this.context;
const {children, localize: _} = this.props;

const content =
sliders.length > 0 &&
sliders.map((sli, i) => (
<SliderFold key={i} sliderIndex={i} name={_('Slider') + ` ${i + 1}`}>
{children}
</SliderFold>
));

return (
<TraceRequiredPanel
extraConditions={[() => sliders.length > 0]}
extraEmptyPanelMessages={[
{
heading: _('There are no sliders to style in your plot'),
message: '',
},
]}
>
{content ? content : null}
</TraceRequiredPanel>
);
}
}

SliderAccordion.contextTypes = {
layout: PropTypes.object,
};

SliderAccordion.propTypes = {
children: PropTypes.node,
localize: PropTypes.func,
};

export default localize(SliderAccordion);
58 changes: 58 additions & 0 deletions src/components/containers/UpdateMenuAccordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Fold from './Fold';
import TraceRequiredPanel from './TraceRequiredPanel';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {connectUpdateMenuToLayout, localize, capitalize} from 'lib';

const UpdateMenuFold = connectUpdateMenuToLayout(Fold);

class UpdateMenuAccordion extends Component {
render() {
const {layout: {updatemenus = []}} = this.context;
const {children, localize: _} = this.props;

const content =
updatemenus.length > 0 &&
updatemenus.map((upd, i) => {
const updateMenuType = capitalize(upd.type) || 'Dropdown';
const activeElementLabel = upd.buttons.filter(
b => b.index === upd.active
)[0].label;

return (
<UpdateMenuFold
key={i}
updateMenuIndex={i}
name={updateMenuType + ': ' + activeElementLabel}
>
{children}
</UpdateMenuFold>
);
});

return (
<TraceRequiredPanel
extraConditions={[() => updatemenus.length > 0]}
extraEmptyPanelMessages={[
{
heading: _('There are no update menus to style in your plot'),
message: '',
},
]}
>
{content ? content : null}
</TraceRequiredPanel>
);
}
}

UpdateMenuAccordion.contextTypes = {
layout: PropTypes.object,
};

UpdateMenuAccordion.propTypes = {
children: PropTypes.node,
localize: PropTypes.func,
};

export default localize(UpdateMenuAccordion);
4 changes: 4 additions & 0 deletions src/components/containers/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import AnnotationAccordion from './AnnotationAccordion';
import ShapeAccordion from './ShapeAccordion';
import SliderAccordion from './SliderAccordion';
import ImageAccordion from './ImageAccordion';
import UpdateMenuAccordion from './UpdateMenuAccordion';
import AxesFold from './AxesFold';
import Fold from './Fold';
import MenuPanel from './MenuPanel';
Expand All @@ -18,7 +20,9 @@ import SectionHeader from './SectionHeader';
export {
AnnotationAccordion,
ShapeAccordion,
SliderAccordion,
ImageAccordion,
UpdateMenuAccordion,
MenuPanel,
Fold,
Panel,
Expand Down
52 changes: 52 additions & 0 deletions src/components/fields/UpdateMenuButtons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {Dropdown, TextEditor} from '../index';
import Field from './Field';
import {connectToContainer, localize} from 'lib';

class UpdateMenuButtons extends Component {
constructor(props, context) {
super(props, context);
this.state = {
currentButtonIndex: 0,
};
}

renderDropdown() {
const _ = this.props.localize;
const options = this.props.fullValue.map((button, index) => {
return {label: _('Button') + ` ${index + 1}`, value: index};
});
return (
<Dropdown
attr="buttons"
label={_('Button')}
options={options}
updatePlot={index => this.setState({currentButtonIndex: index})}
clearable={false}
fullValue={this.state.currentButtonIndex}
/>
);
}

render() {
return (
<Field>
{this.renderDropdown()}
<TextEditor
attr={`buttons[${this.state.currentButtonIndex}].label`}
richTextOnly
/>
</Field>
);
}
}

UpdateMenuButtons.propTypes = {
attr: PropTypes.string,
localize: PropTypes.func,
fullValue: PropTypes.array,
updatePlot: PropTypes.func,
};

export default connectToContainer(localize(UpdateMenuButtons));
Loading