diff --git a/src/components/containers/SubplotAccordion.js b/src/components/containers/SubplotAccordion.js index 4612e4448..f357dcbb4 100644 --- a/src/components/containers/SubplotAccordion.js +++ b/src/components/containers/SubplotAccordion.js @@ -6,6 +6,7 @@ import { connectTraceToPlot, connectCartesianSubplotToLayout, connectNonCartesianSubplotToLayout, + getSubplotTitle, } from 'lib'; import {TRACE_TO_AXIS, SUBPLOT_TO_ATTR} from 'lib/constants'; @@ -15,7 +16,7 @@ const CartesianSubplotFold = connectCartesianSubplotToLayout(PlotlyFold); class SubplotAccordion extends Component { render() { - const {data = [], layout = {}} = this.context; + const {data = [], layout = {}, localize: _} = this.context; const {children, messageIfEmptyFold} = this.props; const subplotFolds = []; @@ -31,8 +32,12 @@ class SubplotAccordion extends Component { acc.push({ xaxis: xaxis, yaxis: yaxis, - xaxisName: curVal.xaxis || 'x1', - yaxisName: curVal.yaxis || 'y1', + xaxisName: curVal.xaxis + ? getSubplotTitle(curVal.xaxis, 'x', _) + : 'X 1', + yaxisName: curVal.yaxis + ? getSubplotTitle(curVal.yaxis, 'y', _) + : 'Y 1', index: [inx], }); } else { @@ -52,7 +57,7 @@ class SubplotAccordion extends Component { messageIfEmpty={messageIfEmptyFold} xaxis={d.xaxis} yaxis={d.yaxis} - name={`${d.xaxisName} ${d.yaxisName}`} + name={`${d.xaxisName} | ${d.yaxisName}`} > {children} @@ -87,8 +92,10 @@ class SubplotAccordion extends Component { Object.keys(layout).forEach(layoutKey => { const traceIndexes = []; + let subplotName; if ( ['geo', 'mapbox', 'polar', 'gl3d', 'ternary'].some(subplotType => { + subplotName = getSubplotTitle(layoutKey, subplotType, _); const trIndex = SUBPLOT_TO_ATTR[subplotType].layout === layoutKey ? data.findIndex(trace => @@ -111,7 +118,7 @@ class SubplotAccordion extends Component { canDelete={false} messageIfEmpty={messageIfEmptyFold} subplot={layoutKey} - name={layoutKey} + name={subplotName} > {children} @@ -119,15 +126,26 @@ class SubplotAccordion extends Component { } }); + let pieCounter = 0; + let tableCounter = 0; data.forEach((d, i) => { if ((d.type === 'pie' && d.values) || d.type === 'table') { + if (d.type === 'pie') { + pieCounter++; + } else if (d.type === 'table') { + tableCounter++; + } subplotFolds[i] = ( 1 ? pieCounter : ''}` + : `${_('Table')} ${tableCounter > 1 ? tableCounter : ''}` + } > {children} diff --git a/src/components/fields/SubplotCreator.js b/src/components/fields/SubplotCreator.js index d69f7bd80..156503c0f 100644 --- a/src/components/fields/SubplotCreator.js +++ b/src/components/fields/SubplotCreator.js @@ -131,7 +131,7 @@ class UnconnectedSubplotCreator extends Component { function getOptions(subplotType) { return fullLayout._subplots[subplotType].map(subplotId => ({ - label: getSubplotTitle(subplotId, subplotType), + label: getSubplotTitle(subplotId, subplotType, _), value: subplotId, })); } diff --git a/src/lib/constants.js b/src/lib/constants.js index 85324a3e7..e8da52aa5 100644 --- a/src/lib/constants.js +++ b/src/lib/constants.js @@ -79,8 +79,10 @@ export const TRACE_TO_AXIS = { // Note: scene, and xaxis/yaxis were added for convenience sake even though they're not subplot types export const SUBPLOT_TO_ATTR = { cartesian: {data: ['xaxis', 'yaxis'], layout: ['x', 'y']}, - xaxis: {data: ['xaxis', 'yaxis'], layout: ['x', 'y']}, - yaxis: {data: ['xaxis', 'yaxis'], layout: ['x', 'y']}, + xaxis: {data: 'xaxis', layout: 'x'}, + yaxis: {data: 'yaxis', layout: 'y'}, + x: {data: 'xaxis', layout: 'x'}, + y: {data: 'yaxis', layout: 'y'}, ternary: {data: 'subplot', layout: 'ternary'}, gl3d: {data: 'scene', layout: 'scene'}, scene: {data: 'scene', layout: 'scene'}, @@ -89,6 +91,18 @@ export const SUBPLOT_TO_ATTR = { polar: {data: 'subplot', layout: 'polar'}, }; +export const subplotName = (type, _) => + ({ + x: _('X'), + y: _('Y'), + ternary: _('Ternary'), + gl3d: _('Scene'), + scene: _('Scene'), + geo: _('Geo'), + mapbox: _('Mapbox'), + polar: _('Polar'), + }[type]); + export const TRANSFORMS_LIST = ['filter', 'groupby', 'aggregate']; export const COLORS = { diff --git a/src/lib/getAllAxes.js b/src/lib/getAllAxes.js index d9eb0f45e..2c446814f 100644 --- a/src/lib/getAllAxes.js +++ b/src/lib/getAllAxes.js @@ -1,4 +1,4 @@ -import {TRACE_TO_AXIS} from 'lib/constants'; +import {TRACE_TO_AXIS, SUBPLOT_TO_ATTR, subplotName} from 'lib/constants'; import {capitalize, striptags} from 'lib'; export default function getAllAxes(fullLayout) { @@ -72,7 +72,7 @@ export function axisIdToAxisName(id) { return id.charAt(0) + 'axis' + id.slice(1); } -function getSubplotNumber(axis) { +function getAxisNumber(axis) { const splitSubplot = axis._subplot ? axis._subplot.split(axis._axisGroup) : []; @@ -83,9 +83,21 @@ function getSubplotNumber(axis) { export function getAxisTitle(axis) { const axisType = capitalize(axis._name.split('axis')[0]); - const subplotNumber = getSubplotNumber(axis) || 1; + const subplotNumber = getAxisNumber(axis) || 1; return axis._input && axis._input.title ? striptags(`${axisType}: ${axis._input.title}`) : striptags(`${axisType} ${subplotNumber}`); } + +function getSubplotNumber(subplot, type) { + return Number(subplot.split(type)[1]); +} + +export function getSubplotTitle(subplot, type, _) { + const axisName = subplotName(type, _); + const subplotNumber = + getSubplotNumber(subplot, SUBPLOT_TO_ATTR[type].layout) || ''; + + return `${axisName} ${subplotNumber}`; +} diff --git a/src/lib/getAllSubplots.js b/src/lib/getAllSubplots.js deleted file mode 100644 index 4383d3668..000000000 --- a/src/lib/getAllSubplots.js +++ /dev/null @@ -1,81 +0,0 @@ -import {TRACE_TO_AXIS} from 'lib/constants'; -import {capitalize} from 'lib'; - -export default function getAllSubplots(fullLayout) { - const axes = []; - // Plotly.js should really have a helper function for this, but until it does.. - if (fullLayout && fullLayout._subplots) { - Object.keys(fullLayout._subplots) - .filter( - // xaxis and yaxis already included separately in _fullLayout._subplots - type => type !== 'cartesian' && fullLayout._subplots[type].length !== 0 - ) - .forEach(type => { - 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 - subplot.length > 1 - ? subplot.slice(0, 1) + 'axis' + subplot.slice(1) - : subplot + 'axis'; - - fullLayout[subplot]._subplot = subplot; - fullLayout[subplot]._axisGroup = type; - axes.push(fullLayout[subplot]); - } else { - Object.keys(fullLayout[subplot]) - .filter(key => key.includes('axis')) - .forEach(axis => { - fullLayout[subplot][axis]._subplot = subplot; - fullLayout[subplot][axis]._axisGroup = type; - - // it should be in plotly.js, but it's not there for geo axes.. - if (!fullLayout[subplot][axis]._name) { - fullLayout[subplot][axis]._name = axis; - } - axes.push(fullLayout[subplot][axis]); - }); - } - }); - }); - } - - return axes; -} - -export function traceTypeToSubplotType(traceType, subplot = false) { - let category = null; - const traceToAxis = TRACE_TO_AXIS; - if (subplot) { - Object.assign(traceToAxis, TRACE_TO_AXIS, {scene: TRACE_TO_AXIS.gl3d}); - delete traceToAxis.gl3d; - } - - Object.keys(traceToAxis).forEach(c => { - if (traceToAxis[c].includes(traceType)) { - category = c; - } - }); - - if (category) { - return category; - } - - if (traceType === 'pie' || traceType === 'table') { - return null; - } - - throw new Error(`Sorry, could not find ${traceType} in any category.`); -} - -function getSubplotNumber(subplot, type) { - return Number(subplot.split(type)[1]); -} - -export function getSubplotTitle(subplot, type) { - const axisType = capitalize(type === 'gl3d' ? 'scene' : type); - const subplotNumber = - getSubplotNumber(subplot, type === 'gl3d' ? 'scene' : type) || ''; - - return `${axisType} ${subplotNumber}`; -} diff --git a/src/lib/index.js b/src/lib/index.js index a97668d4d..87a776c16 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -21,11 +21,8 @@ import getAllAxes, { axisIdToAxisName, traceTypeToAxisType, getAxisTitle, -} from './getAllAxes'; -import getAllSubplots, { - traceTypeToSubplotType, getSubplotTitle, -} from './getAllSubplots'; +} from './getAllAxes'; import localize, {localizeString} from './localize'; import tinyColor from 'tinycolor2'; import unpackPlotProps from './unpackPlotProps'; @@ -66,9 +63,18 @@ function renderTraceIcon(trace, prefix = 'Plot') { return null; } const gl = 'gl'; + + let tempTrace = trace; + if (tempTrace === 'cone') { + tempTrace = 'scatter3d'; + } else if (tempTrace === 'streamtube') { + tempTrace = 'line3d'; + } + const componentName = `${prefix}${pascalCase( - trace.endsWith(gl) ? trace.slice(0, -gl.length) : trace + tempTrace.endsWith(gl) ? tempTrace.slice(0, -gl.length) : tempTrace )}Icon`; + return PlotlyIcons[componentName] ? PlotlyIcons[componentName] : PlotlyIcons.PlotLineIcon; @@ -242,8 +248,6 @@ export { dereference, getAllAxes, getAxisTitle, - getAllSubplots, - traceTypeToSubplotType, getSubplotTitle, getDisplayName, isPlainObject,