diff --git a/dev/App.js b/dev/App.js index d35a2ed8f..9267ac632 100644 --- a/dev/App.js +++ b/dev/App.js @@ -65,6 +65,41 @@ const traceTypesConfig = { complex: true, }; +const chartHelp = { + area: { + helpDoc: 'https://help.plot.ly/make-an-area-graph/', + examplePlot: () => { + console.log('example bar plot!'); + }, + }, + bar: { + helpDoc: 'https://help.plot.ly/stacked-bar-chart/', + examplePlot: () => { + console.log('example bar plot!'); + }, + }, + box: {helpDoc: 'https://help.plot.ly/make-a-box-plot/'}, + candlestick: {helpDoc: 'https://help.plot.ly/make-a-candlestick/'}, + choropleth: {helpDoc: 'https://help.plot.ly/make-a-choropleth-map/'}, + contour: {helpDoc: 'https://help.plot.ly/make-a-contour-plot/'}, + heatmap: {helpDoc: 'https://help.plot.ly/make-a-heatmap/'}, + histogram2d: {helpDoc: 'https://help.plot.ly/make-a-2d-histogram-heatmap/'}, + histogram2dcontour: {helpDoc: 'https://help.plot.ly/make-a-histogram/'}, + line: {helpDoc: 'https://help.plot.ly/make-a-line-graph/'}, + mesh3d: {helpDoc: null}, + ohlc: {helpDoc: 'https://help.plot.ly/make-a-ohlc/'}, + pie: {helpDoc: 'https://help.plot.ly/make-a-pie-chart/'}, + scatter3d: {helpDoc: 'https://help.plot.ly/make-a-3d-scatter-plot/'}, + line3d: {helpDoc: null}, + scatter: {helpDoc: 'https://help.plot.ly/how-to-make-a-scatter-plot/'}, + scattergeo: {helpDoc: 'https://help.plot.ly/make-scatter-map/'}, + scattermapbox: {helpDoc: 'https://help.plot.ly/make-a-mapbox-map/'}, + scatterternary: {helpDoc: 'https://help.plot.ly/ternary-scatter-plot/'}, + surface: {helpDoc: 'https://help.plot.ly/make-a-3d-surface-plot/'}, + table: {helpDoc: null}, + timeseries: {helpDoc: 'https://help.plot.ly/range-slider/'}, +}; + class App extends Component { constructor() { super(); @@ -148,6 +183,7 @@ class App extends Component { // traceTypesConfig={traceTypesConfig} // makeDefaultTrace={() => ({type: 'scattergl', mode: 'markers'})} // fontOptions={[{label:'Arial', value: 'arial'}]} + // chartHelp={chartHelp} > @@ -211,11 +247,7 @@ class App extends Component { Refresh
- +
diff --git a/package.json b/package.json index b94274e19..af31df603 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,8 @@ "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.24.1", "babel-traverse": "^6.26.0", - "css-loader": "^1.0.0", - "cssnano": "^4.1.0", + "css-loader": "^0.28.11", + "cssnano": "^3.10.0", "enzyme": "^3.1.0", "enzyme-adapter-react-16": "^1.0.4", "eslint": "^5.4.0", @@ -59,9 +59,9 @@ "jest-cli": "^23.5.0", "mkdirp": "^0.5.1", "node-sass": "^4.7.2", - "postcss": "^7.0.2", + "postcss": "^6.0.23", "postcss-combine-duplicated-selectors": "^6.0.2", - "postcss-custom-properties": "^7.0.0", + "postcss-custom-properties": "^6.3.1", "postcss-remove-root": "^0.0.2", "prettier": "1.14.2", "react": "^16.0.0", diff --git a/src/EditorControls.js b/src/EditorControls.js index 620eb15c7..8ddad4e5a 100644 --- a/src/EditorControls.js +++ b/src/EditorControls.js @@ -57,6 +57,7 @@ class EditorControls extends Component { glByDefault: this.props.glByDefault, mapBoxAccess: this.props.mapBoxAccess, fontOptions: this.props.fontOptions, + chartHelp: this.props.chartHelp, }; } @@ -335,6 +336,7 @@ EditorControls.propTypes = { glByDefault: PropTypes.bool, mapBoxAccess: PropTypes.bool, fontOptions: PropTypes.array, + chartHelp: PropTypes.object, }; EditorControls.defaultProps = { @@ -376,6 +378,7 @@ EditorControls.childContextTypes = { glByDefault: PropTypes.bool, mapBoxAccess: PropTypes.bool, fontOptions: PropTypes.array, + chartHelp: PropTypes.object, }; export default EditorControls; diff --git a/src/PlotlyEditor.js b/src/PlotlyEditor.js index 5be6f6524..a867e76e1 100644 --- a/src/PlotlyEditor.js +++ b/src/PlotlyEditor.js @@ -31,6 +31,7 @@ class PlotlyEditor extends Component { glByDefault={this.props.glByDefault} mapBoxAccess={Boolean(this.props.config && this.props.config.mapboxAccessToken)} fontOptions={this.props.fontOptions} + chartHelp={this.props.chartHelp} > {this.props.children} @@ -80,6 +81,7 @@ PlotlyEditor.propTypes = { makeDefaultTrace: PropTypes.func, glByDefault: PropTypes.bool, fontOptions: PropTypes.array, + chartHelp: PropTypes.object, }; PlotlyEditor.defaultProps = { diff --git a/src/components/widgets/TraceTypeSelector.js b/src/components/widgets/TraceTypeSelector.js index 6f13a3e01..c5b45ac6a 100644 --- a/src/components/widgets/TraceTypeSelector.js +++ b/src/components/widgets/TraceTypeSelector.js @@ -7,19 +7,22 @@ import {traceTypeToPlotlyInitFigure, renderTraceIcon, plotlyTraceToCustomTrace} const renderActionItems = (actionItems, item) => actionItems - ? actionItems(item).map((action, i) => ( - - {action.icon} - - )) + ? actionItems(item).map( + (action, i) => + !action.onClick ? null : ( + + {action.icon} + + ) + ) : null; const Item = ({item, active, handleClick, actions, showActions, complex}) => { @@ -28,10 +31,7 @@ const Item = ({item, active, handleClick, actions, showActions, complex}) => { const ComplexIcon = renderTraceIcon(icon ? icon : value, 'TraceType'); return ( -
handleClick()} - > +
{actions && showActions ? renderActionItems(actions, item) : null}
@@ -52,7 +52,29 @@ const Item = ({item, active, handleClick, actions, showActions, complex}) => { ); }; +Item.propTypes = { + item: PropTypes.object, + active: PropTypes.bool, + complex: PropTypes.bool, + handleClick: PropTypes.func, + actions: PropTypes.func, + showActions: PropTypes.bool, +}; +Item.contextTypes = { + localize: PropTypes.func, +}; + class TraceTypeSelector extends Component { + constructor(props) { + super(props); + + this.selectAndClose = this.selectAndClose.bind(this); + this.actions = this.actions.bind(this); + this.renderCategories = this.renderCategories.bind(this); + this.renderGrid = this.renderGrid.bind(this); + this.renderSingleBlock = this.renderSingleBlock.bind(this); + } + selectAndClose(value) { const { updateContainer, @@ -72,21 +94,38 @@ class TraceTypeSelector extends Component { } actions({value}) { - const {localize: _} = this.context; + const {localize: _, chartHelp} = this.context; + + const onClick = (e, func) => { + e.stopPropagation(); + func(); + this.context.handleClose(); + }; + return [ { label: _('Charts like this by Plotly users.'), - href: `https://plot.ly/feed/?q=plottype:${value}`, + onClick: + chartHelp[value] && + (e => + onClick(e, () => + window.open( + `https://plot.ly/feed/?q=${chartHelp[value] ? chartHelp[value].feedQuery : value}`, + '_blank' + ) + )), icon: , }, { label: _('View tutorials on this chart type.'), - href: '#', + onClick: + chartHelp[value] && + (e => onClick(e, () => window.open(chartHelp[value].helpDoc, '_blank'))), icon: , }, { label: _('See a basic example.'), - href: '#', + onClick: chartHelp[value] && (e => onClick(e, chartHelp[value].examplePlot)), icon: , }, ]; @@ -98,6 +137,7 @@ class TraceTypeSelector extends Component { traceTypesConfig: {traces, categories, complex}, mapBoxAccess, localize: _, + chartHelp, } = this.context; return categories(_).map((category, i) => { @@ -131,8 +171,8 @@ class TraceTypeSelector extends Component { active={fullValue === item.value} item={item} actions={this.actions} - showActions={false} handleClick={() => this.selectAndClose(item.value)} + showActions={Boolean(chartHelp)} /> ))}
@@ -193,6 +233,20 @@ class TraceTypeSelector extends Component { } } +TraceTypeSelector.propTypes = { + updateContainer: PropTypes.func, + fullValue: PropTypes.string, + fullContainer: PropTypes.object, + glByDefault: PropTypes.bool, +}; +TraceTypeSelector.contextTypes = { + traceTypesConfig: PropTypes.object, + handleClose: PropTypes.func, + localize: PropTypes.func, + mapBoxAccess: PropTypes.bool, + chartHelp: PropTypes.object, +}; + export class TraceTypeSelectorButton extends Component { render() { const { @@ -209,7 +263,7 @@ export class TraceTypeSelectorButton extends Component { const Icon = renderTraceIcon(icon ? icon : value); return ( -
handleClick() : null}> +
@@ -219,18 +273,6 @@ export class TraceTypeSelectorButton extends Component { } } -TraceTypeSelector.propTypes = { - updateContainer: PropTypes.func, - fullValue: PropTypes.string, - fullContainer: PropTypes.object, - glByDefault: PropTypes.bool, -}; -TraceTypeSelector.contextTypes = { - traceTypesConfig: PropTypes.object, - handleClose: PropTypes.func, - localize: PropTypes.func, - mapBoxAccess: PropTypes.bool, -}; TraceTypeSelectorButton.propTypes = { handleClick: PropTypes.func.isRequired, container: PropTypes.object, @@ -239,16 +281,5 @@ TraceTypeSelectorButton.propTypes = { TraceTypeSelectorButton.contextTypes = { localize: PropTypes.func, }; -Item.propTypes = { - item: PropTypes.object, - active: PropTypes.bool, - complex: PropTypes.bool, - handleClick: PropTypes.func, - actions: PropTypes.func, - showActions: PropTypes.bool, -}; -Item.contextTypes = { - localize: PropTypes.func, -}; export default TraceTypeSelector; diff --git a/src/styles/components/widgets/_trace-type-selector.scss b/src/styles/components/widgets/_trace-type-selector.scss index 6382d0b33..d9eece1de 100644 --- a/src/styles/components/widgets/_trace-type-selector.scss +++ b/src/styles/components/widgets/_trace-type-selector.scss @@ -121,6 +121,7 @@ $item-size: 90px; display: block; width: 16px; height: 16px; + fill: currentColor; } } }