Skip to content

legendgroup and other legend attrs #739

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 1 commit into from
Sep 10, 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
1 change: 0 additions & 1 deletion src/components/fields/AxesCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/components/fields/Field.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ class Field extends Component {
) : null}
<div className={fieldClass}>
{children}
{extraComponent ? extraComponent : null}
{multiValued && !suppressMultiValuedMessage ? (
<MenuPanel label={getMultiValueText('title', _)} ownline question>
<div className="info__title">{getMultiValueText('title', _)}</div>
<div className="info__text">{getMultiValueText('text', _)}</div>
<div className="info__sub-text">{getMultiValueText('subText', _)}</div>
</MenuPanel>
) : null}
{extraComponent ? extraComponent : null}
</div>
{units ? (
<div className={bem('field', 'units')}>
Expand Down
84 changes: 84 additions & 0 deletions src/components/fields/GroupCreator.js
Original file line number Diff line number Diff line change
@@ -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 = <PlusIcon />;
const addButton = this.canAddGroup() ? (
<Button variant="no-text" icon={icon} onClick={() => this.addAndUpdateGroup()} />
) : (
<Button variant="no-text--disabled" icon={icon} onClick={() => {}} />
);

return (
<Dropdown
label={label}
attr={attr}
clearable={false}
options={options}
updatePlot={updatePlot}
extraComponent={addButton}
/>
);
}
}

UnconnectedGroupCreator.propTypes = {
attr: PropTypes.string,
fullContainer: PropTypes.object,
prefix: PropTypes.string,
...Field.propTypes,
};

UnconnectedGroupCreator.contextTypes = {
localize: PropTypes.func,
data: PropTypes.array,
fullData: PropTypes.array,
};

export default connectToContainer(UnconnectedGroupCreator);
7 changes: 3 additions & 4 deletions src/components/fields/SubplotCreator.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, {Component} from 'react';
import Dropdown from './Dropdown';
import Info from './Info';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {EDITOR_ACTIONS, SUBPLOT_TO_ATTR} from 'lib/constants';
import Button from '../widgets/Button';
import {PlusIcon} from 'plotly-icons';
import {connectToContainer, traceTypeToAxisType, getSubplotTitle} from 'lib';
import {PlotlySection} from 'components';

class UnconnectedSingleSubplotCreator extends Component {
canAddAxis() {
canAddSubplot() {
const currentAxisId = this.props.fullContainer[this.props.attr];
const currentTraceIndex = this.props.fullContainer.index;
return this.context.fullData.some(
Expand Down Expand Up @@ -62,7 +62,7 @@ class UnconnectedSingleSubplotCreator extends Component {

render() {
const icon = <PlusIcon />;
const extraComponent = this.canAddAxis() ? (
const extraComponent = this.canAddSubplot() ? (
<Button variant="no-text" icon={icon} onClick={() => this.addAndUpdateSubplot()} />
) : (
<Button variant="no-text--disabled" icon={icon} onClick={() => {}} />
Expand All @@ -86,7 +86,6 @@ UnconnectedSingleSubplotCreator.propTypes = {
layoutAttr: PropTypes.string,
label: PropTypes.string,
options: PropTypes.array,
canAddAxis: PropTypes.bool,
container: PropTypes.object,
fullContainer: PropTypes.object,
updateContainer: PropTypes.func,
Expand Down
2 changes: 1 addition & 1 deletion src/components/fields/derived.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export const BinningDropdown = connectToContainer(UnconnectedDropdown, {
},
});

export const ShowInLegend = connectToContainer(UnconnectedRadio, {
export const ShowInLegend = connectToContainer(UnconnectedVisibilitySelect, {
modifyPlotProps: (props, context, plotProps) => {
plotProps.isVisible = context.fullLayout.showlegend;
return plotProps;
Expand Down
2 changes: 2 additions & 0 deletions src/components/fields/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import TraceSelector from './TraceSelector';
import ErrorBars from './ErrorBars';
import AxesCreator from './AxesCreator';
import SubplotCreator from './SubplotCreator';
import GroupCreator from './GroupCreator';
import UpdateMenuButtons from './UpdateMenuButtons';
import {FilterOperation, FilterValue} from './FilterOperation';
import MarkerSize from './MarkerSize';
Expand Down Expand Up @@ -100,6 +101,7 @@ export {
TraceSelector,
AxesCreator,
SubplotCreator,
GroupCreator,
AxisOverlayDropdown,
AxisSide,
UpdateMenuButtons,
Expand Down
2 changes: 2 additions & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
RangesliderVisible,
AxesCreator,
SubplotCreator,
GroupCreator,
SymbolSelector,
TextEditor,
TraceOrientation,
Expand Down Expand Up @@ -146,6 +147,7 @@ export {
SingleSidebarItem,
AxesCreator,
SubplotCreator,
GroupCreator,
SymbolSelector,
TextEditor,
SubplotAccordion,
Expand Down
5 changes: 4 additions & 1 deletion src/default_panels/StyleLegendPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,16 @@ const StyleLegendPanel = (props, {localize: _}) => (
/>
</PlotlySection>
<PlotlySection name={_('Trace Order')}>
<Radio
<Dropdown
attr="legend.traceorder"
options={[
{label: _('Normal'), value: 'normal'},
{label: _('Reversed'), value: 'reversed'},
{label: _('Grouped'), value: 'grouped'},
{label: _('Reversed and Grouped'), value: 'reversed+grouped'},
]}
/>
<Numeric label={_('Gap Between Groups')} attr="legend.tracegroupgap" units="px" />
</PlotlySection>
</PlotlyFold>
</TraceRequiredPanel>
Expand Down
16 changes: 11 additions & 5 deletions src/default_panels/StyleTracesPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
ErrorBars,
DataSelector,
VisibilitySelect,
GroupCreator,
} from '../components';
import {
BinningNumeric,
Expand All @@ -43,12 +44,17 @@ import {
const StyleTracesPanel = (props, {localize: _}) => (
<TraceAccordion canGroup>
<TextEditor label={_('Name')} attr="name" richTextOnly />
<ShowInLegend
label={_('Show in Legend')}
attr="showlegend"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
/>
<NumericFraction label={_('Trace Opacity')} attr="opacity" />
<PlotlySection name={_('Legend')}>
<ShowInLegend
Copy link
Contributor

Choose a reason for hiding this comment

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

is the groupcreator meant to be IN the ShowInLegend? If i set it to 'hide' I still see the groupcreator

label={_('Show in Legend')}
attr="showlegend"
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
showOn={true}
>
<GroupCreator label={_('Legend Group')} prefix={_('Group')} attr="legendgroup" />
</ShowInLegend>
</PlotlySection>
<PlotlySection name={_('Cones & Streamtubes')}>
<Numeric label={_('Size')} attr="sizeref" />
<Dropdown
Expand Down