Skip to content
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
4 changes: 3 additions & 1 deletion src/components/fields/Field.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class Field extends Component {
children,
label,
multiValued,
suppressMultiValuedMessage,
units,
extraComponent,
} = this.props;
Expand Down Expand Up @@ -68,7 +69,7 @@ class Field extends Component {
) : null}
<div className={fieldClass}>
{children}
{multiValued ? (
{multiValued && !suppressMultiValuedMessage ? (
<MenuPanel label={getMultiValueText('title', _)} ownline question>
<div className="info__title">{getMultiValueText('title', _)}</div>
<div className="info__text">{getMultiValueText('text', _)}</div>
Expand All @@ -94,6 +95,7 @@ Field.propTypes = {
label: PropTypes.any,
units: PropTypes.string,
multiValued: PropTypes.bool,
suppressMultiValuedMessage: PropTypes.bool,
children: PropTypes.node,
extraComponent: PropTypes.any,
};
Expand Down
43 changes: 33 additions & 10 deletions src/components/fields/MarkerSize.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,27 @@ import {connectToContainer} from 'lib';
import RadioBlocks from '../widgets/RadioBlocks';
import Numeric from './Numeric';
import DataSelector from './DataSelector';

const getType = value => (Array.isArray(value) ? 'variable' : 'constant');
import {MULTI_VALUED} from 'lib/constants';

class UnconnectedMarkerSize extends Component {
constructor(props, context) {
super(props, context);

const type = getType(props.fullValue);
let type = null;
if (
!props.container.marker ||
(props.container.marker && !props.container.marker.sizesrc)
) {
type = 'constant';
} else if (
props.container.marker &&
Array.isArray(props.container.marker.size) &&
props.fullContainer.marker &&
Array.isArray(props.fullContainer.marker.size)
) {
type = 'variable';
}

this.state = {
type,
value: {
Expand All @@ -30,6 +43,11 @@ class UnconnectedMarkerSize extends Component {
this.props.updatePlot(this.state.value[type]);
if (type === 'constant') {
this.context.updateContainer({['marker.sizesrc']: null});
} else {
this.context.updateContainer({
['marker.size']: null,
['marker.sizesrc']: null,
});
}
}

Expand All @@ -45,32 +63,37 @@ class UnconnectedMarkerSize extends Component {
}

render() {
const {attr} = this.props;
const {attr, fullValue} = this.props;
const {localize: _} = this.context;
const {type, value} = this.state;
const options = [
{label: _('Constant'), value: 'constant'},
{label: _('Variable'), value: 'variable'},
];
const multiValued =
this.props.multiValued ||
(Array.isArray(fullValue) && fullValue.includes(MULTI_VALUED));

return (
<div>
<Field {...this.props} attr={attr}>
<Field {...this.props} multiValued={multiValued} attr={attr}>
<RadioBlocks
options={options}
activeOption={this.state.type}
activeOption={type}
onOptionChange={this.setType}
/>
{this.state.type === 'constant' ? (
{type === 'constant' ? (
<Numeric
suppressMultiValuedMessage
attr="marker.size"
updatePlot={this.setValue}
fullValue={this.state.value.constant}
fullValue={value.constant}
/>
) : (
) : multiValued ? null : (
<DataSelector
suppressMultiValuedMessage
attr="marker.size"
updatePlot={this.setValue}
fullValue={this.state.value.variable}
/>
)}
</Field>
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/EditableText.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ EditableText.propTypes = {
text: PropTypes.any,

// Input properties
placeholder: PropTypes.string,
placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
className: PropTypes.string,
disable: PropTypes.bool,
autoFocus: PropTypes.bool,
Expand Down
8 changes: 4 additions & 4 deletions src/components/widgets/NumericInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ export default class NumericInput extends Component {
let valueUpdate;
if (isNumeric(value)) {
if (direction === 'increase') {
valueUpdate = value + step;
valueUpdate = parseFloat(value) + step;
Copy link
Contributor

Choose a reason for hiding this comment

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

man, can't believe we didn't have worse bugs before

} else {
valueUpdate = value - step;
valueUpdate = parseFloat(value) - step;
}
} else {
// if we are multi-valued and the user is incrementing or decrementing
Expand Down Expand Up @@ -138,7 +138,7 @@ export default class NumericInput extends Component {
min={this.props.min}
max={this.props.max}
step={this.props.step}
value={this.state.value}
value={parseFloat(this.state.value)}
onChange={this.updateValue}
tooltip={false}
/>
Expand Down Expand Up @@ -172,7 +172,7 @@ NumericInput.propTypes = {
max: PropTypes.number,
min: PropTypes.number,
onUpdate: PropTypes.func.isRequired,
placeholder: PropTypes.string,
placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
showArrows: PropTypes.bool,
showSlider: PropTypes.bool,
step: PropTypes.number,
Expand Down
14 changes: 11 additions & 3 deletions src/lib/connectTraceToPlot.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,25 @@ export default function connectTraceToPlot(WrappedComponent) {
};

if (traceIndexes.length > 1) {
const multiValuedContainer = deepCopyPublic(fullTrace);
const multiValuedFullContainer = deepCopyPublic(fullTrace);
fullData.forEach(t =>
Object.keys(t).forEach(key =>
setMultiValuedContainer(multiValuedFullContainer, t, key, {
searchArrays: true,
})
)
);
const multiValuedContainer = deepCopyPublic(trace);
data.forEach(t =>
Object.keys(t).forEach(key =>
setMultiValuedContainer(multiValuedContainer, t, key, {
searchArrays: true,
})
)
);
this.childContext.fullContainer = multiValuedContainer;
this.childContext.fullContainer = multiValuedFullContainer;
this.childContext.defaultContainer = fullTrace;
this.childContext.container = {};
this.childContext.container = multiValuedContainer;
}

if (trace && fullTrace) {
Expand Down
20 changes: 11 additions & 9 deletions src/lib/multiValues.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ function deepCopyPublic(value) {
}

function setMultiValuedContainer(intoObj, fromObj, key, config = {}) {
var intoVal = intoObj[key],
fromVal = fromObj[key];

var searchArrays = config.searchArrays;
const intoVal = intoObj[key];
Copy link
Contributor

Choose a reason for hiding this comment

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

nice fixes in this file.

const fromVal = fromObj[key];

// don't merge private attrs
if (
Expand Down Expand Up @@ -51,20 +49,24 @@ function setMultiValuedContainer(intoObj, fromObj, key, config = {}) {
} else if (Array.isArray(intoVal)) {
// in data, other arrays are data, which we don't care about
// for styling purposes
if (!searchArrays) {
if (!config.searchArrays) {
return;
}
// in layout though, we need to recurse into arrays
for (var i = 0; i < fromVal.length; i++) {
setMultiValuedContainer(intoVal, fromVal, i, searchArrays);
if (!Array.isArray(fromVal)) {
intoObj[key] = MULTI_VALUED;
} else {
// in layout though, we need to recurse into arrays
for (let i = 0; i < fromVal.length; i++) {
setMultiValuedContainer(intoVal, fromVal, i, config);
}
}
} else if (isPlainObject(fromVal)) {
// recurse into objects
if (!isPlainObject(intoVal)) {
throw new Error('tried to merge object into non-object: ' + key);
}
Object.keys(fromVal).forEach(function(key2) {
setMultiValuedContainer(intoVal, fromVal, key2, searchArrays);
setMultiValuedContainer(intoVal, fromVal, key2, config);
});
} else if (isPlainObject(intoVal)) {
throw new Error('tried to merge non-object into object: ' + key);
Expand Down