diff --git a/src/components/fields/AxesCreator.js b/src/components/fields/AxesCreator.js index febe736d1..13e19d816 100644 --- a/src/components/fields/AxesCreator.js +++ b/src/components/fields/AxesCreator.js @@ -99,7 +99,6 @@ UnconnectedAxisCreator.propTypes = { attr: PropTypes.string, label: PropTypes.string, options: PropTypes.array, - canAddAxis: PropTypes.bool, container: PropTypes.object, fullContainer: PropTypes.object, updateContainer: PropTypes.func, diff --git a/src/components/fields/Field.js b/src/components/fields/Field.js index a91bec8bb..399d4c6ff 100644 --- a/src/components/fields/Field.js +++ b/src/components/fields/Field.js @@ -73,6 +73,7 @@ class Field extends Component { ) : null}
{children} + {extraComponent ? extraComponent : null} {multiValued && !suppressMultiValuedMessage ? (
{getMultiValueText('title', _)}
@@ -80,7 +81,6 @@ class Field extends Component {
{getMultiValueText('subText', _)}
) : null} - {extraComponent ? extraComponent : null}
{units ? (
diff --git a/src/components/fields/GroupCreator.js b/src/components/fields/GroupCreator.js new file mode 100644 index 000000000..e7fb7ff25 --- /dev/null +++ b/src/components/fields/GroupCreator.js @@ -0,0 +1,84 @@ +import React, {Component} from 'react'; +import {connectToContainer} from 'lib'; +import Field from './Field'; +import Dropdown from './Dropdown'; +import PropTypes from 'prop-types'; +import Button from '../widgets/Button'; +import {PlusIcon} from 'plotly-icons'; +import {MULTI_VALUED} from 'lib/constants'; + +class UnconnectedGroupCreator extends Component { + getAllGroups() { + return [...new Set(this.context.data.map(t => t[this.props.attr]))].filter(g => Boolean(g)); + } + + canAddGroup() { + const {fullContainer, attr} = this.props; + const currentGroup = fullContainer[attr]; + const currentTraceIndex = fullContainer.index; + + if (fullContainer.index === MULTI_VALUED) { + return this.getAllGroups().length === 0; + } + + return ( + !currentGroup || + this.context.fullData.some(d => d.index !== currentTraceIndex && d[attr] === currentGroup) + ); + } + + addAndUpdateGroup() { + const allGroups = this.context.fullData + .map(t => parseInt(t[this.props.attr], 10)) + .filter(n => Number.isInteger(n)); + // don't want to pass empty array to max + allGroups.push(0); + + const lastGroupNumber = Math.max.apply(Math, allGroups); + + this.props.updatePlot(lastGroupNumber + 1); + } + + render() { + const {localize: _} = this.context; + const {attr, label, prefix, updatePlot} = this.props; + + const options = [{label: _('None'), value: ''}]; + const allGroups = this.getAllGroups(); + allGroups.forEach(g => options.push({label: `${prefix} ${g}`, value: g})); + options.sort((a, b) => a.value - b.value); + + const icon = ; + const addButton = this.canAddGroup() ? ( +