Skip to content

Commit 572ac69

Browse files
Numeric sliders (#346)
1 parent d298cb7 commit 572ac69

File tree

16 files changed

+354
-105
lines changed

16 files changed

+354
-105
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"react-color": "^2.13.8",
2222
"react-colorscales": "^0.4.2",
2323
"react-dom": "^16.2.0",
24+
"react-rangeslider": "^2.2.0",
2425
"react-select": "^1.0.0-rc.10",
2526
"react-tabs": "^2.2.1",
2627
"tinycolor2": "^1.4.1"

src/components/fields/Numeric.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class UnconnectedNumeric extends Component {
2525
onChange={this.props.updatePlot}
2626
onUpdate={this.props.updatePlot}
2727
showArrows={!this.props.hideArrows}
28+
showSlider={this.props.showSlider}
2829
/>
2930
</Field>
3031
);
@@ -38,6 +39,7 @@ UnconnectedNumeric.propTypes = {
3839
max: PropTypes.number,
3940
multiValued: PropTypes.bool,
4041
hideArrows: PropTypes.bool,
42+
showSlider: PropTypes.bool,
4143
step: PropTypes.number,
4244
updatePlot: PropTypes.func,
4345
...Field.propTypes,

src/components/fields/derived.js

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,45 @@ export const AxesRange = connectToContainer(UnconnectedNumeric, {
105105
},
106106
});
107107

108-
class NumericFraction extends UnconnectedNumeric {}
109-
NumericFraction.propTypes = UnconnectedNumeric.propTypes;
110-
NumericFraction.defaultProps = {
108+
class UnconnectedNumericFraction extends UnconnectedNumeric {}
109+
UnconnectedNumericFraction.propTypes = UnconnectedNumeric.propTypes;
110+
UnconnectedNumericFraction.defaultProps = {
111111
units: '%',
112+
showSlider: true,
112113
};
113114

115+
const numericFractionModifyPlotProps = (props, context, plotProps) => {
116+
const {attrMeta, fullValue, updatePlot} = plotProps;
117+
const min = attrMeta.min || 0;
118+
const max = attrMeta.max || 1;
119+
if (isNumeric(fullValue)) {
120+
plotProps.fullValue = Math.round(100 * (fullValue - min) / (max - min));
121+
}
122+
123+
plotProps.updatePlot = v => {
124+
if (isNumeric(v)) {
125+
updatePlot(v / 100 * (max - min) + min);
126+
} else {
127+
updatePlot(v);
128+
}
129+
};
130+
plotProps.max = 100;
131+
plotProps.min = 0;
132+
};
133+
134+
export const NumericFraction = connectToContainer(UnconnectedNumericFraction, {
135+
modifyPlotProps: numericFractionModifyPlotProps,
136+
});
137+
138+
export const LayoutNumericFraction = connectLayoutToPlot(
139+
connectToContainer(UnconnectedNumericFraction, {
140+
supplyPlotProps: supplyLayoutPlotProps,
141+
modifyPlotProps: numericFractionModifyPlotProps,
142+
})
143+
);
144+
114145
export const LayoutNumericFractionInverse = connectLayoutToPlot(
115-
connectToContainer(NumericFraction, {
146+
connectToContainer(UnconnectedNumericFraction, {
116147
supplyPlotProps: supplyLayoutPlotProps,
117148
modifyPlotProps: (props, context, plotProps) => {
118149
const {attrMeta, fullValue, updatePlot} = plotProps;
@@ -142,36 +173,6 @@ export const LayoutNumericFractionInverse = connectLayoutToPlot(
142173
})
143174
);
144175

145-
export const LayoutNumericFraction = connectLayoutToPlot(
146-
connectToContainer(NumericFraction, {
147-
supplyPlotProps: supplyLayoutPlotProps,
148-
modifyPlotProps: (props, context, plotProps) => {
149-
const {attrMeta, fullValue, updatePlot} = plotProps;
150-
if (isNumeric(fullValue)) {
151-
plotProps.fullValue = fullValue * 100;
152-
}
153-
154-
plotProps.updatePlot = v => {
155-
if (isNumeric(v)) {
156-
updatePlot(v / 100);
157-
} else {
158-
updatePlot(v);
159-
}
160-
};
161-
162-
if (attrMeta) {
163-
if (isNumeric(attrMeta.max)) {
164-
plotProps.max = attrMeta.max * 100;
165-
}
166-
167-
if (isNumeric(attrMeta.min)) {
168-
plotProps.min = attrMeta.min * 100;
169-
}
170-
}
171-
},
172-
})
173-
);
174-
175176
export const AnnotationArrowRef = connectToContainer(UnconnectedDropdown, {
176177
modifyPlotProps: (props, context, plotProps) => {
177178
const {fullContainer: {xref, yref}, plotly, graphDiv} = context;
@@ -271,6 +272,34 @@ export const PositioningRef = connectToContainer(UnconnectedDropdown, {
271272
},
272273
});
273274

275+
export const PositioningNumeric = connectToContainer(UnconnectedNumeric, {
276+
modifyPlotProps: (props, context, plotProps) => {
277+
const {fullContainer, fullValue, updatePlot} = plotProps;
278+
if (
279+
fullContainer &&
280+
(fullContainer[props.attr[0] + 'ref'] === 'paper' ||
281+
fullContainer[props.attr[props.attr.length - 1] + 'ref'] === 'paper')
282+
) {
283+
plotProps.units = '%';
284+
plotProps.showSlider = true;
285+
plotProps.max = 100;
286+
plotProps.min = 0;
287+
plotProps.step = 1;
288+
if (isNumeric(fullValue)) {
289+
plotProps.fullValue = Math.round(100 * fullValue);
290+
}
291+
292+
plotProps.updatePlot = v => {
293+
if (isNumeric(v)) {
294+
updatePlot(v / 100);
295+
} else {
296+
updatePlot(v);
297+
}
298+
};
299+
}
300+
},
301+
});
302+
274303
function computeAxesRefOptions(axes) {
275304
const options = [];
276305
for (let i = 0; i < axes.length; i++) {

src/components/fields/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ import {
2424
GeoProjections,
2525
GeoScope,
2626
HoverInfo,
27+
NumericFraction,
28+
PositioningNumeric,
29+
NumericFractionInverse,
2730
LayoutNumericFraction,
2831
LayoutNumericFractionInverse,
2932
TraceOrientation,
@@ -53,6 +56,9 @@ export {
5356
Info,
5457
LayoutNumericFraction,
5558
LayoutNumericFractionInverse,
59+
NumericFraction,
60+
NumericFractionInverse,
61+
PositioningNumeric,
5662
LineDashSelector,
5763
LineShapeSelector,
5864
Numeric,

src/components/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import {
2121
Info,
2222
LayoutNumericFraction,
2323
LayoutNumericFractionInverse,
24+
NumericFraction,
25+
PositioningNumeric,
26+
NumericFractionInverse,
2427
LineDashSelector,
2528
LineShapeSelector,
2629
Numeric,
@@ -81,6 +84,9 @@ export {
8184
GeoScope,
8285
HoverInfo,
8386
Info,
87+
NumericFraction,
88+
PositioningNumeric,
89+
NumericFractionInverse,
8490
LayoutNumericFraction,
8591
LayoutNumericFractionInverse,
8692
LayoutPanel,

src/components/widgets/NumericInput.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import EditableText from './EditableText';
22
import React, {Component} from 'react';
33
import PropTypes from 'prop-types';
44
import isNumeric from 'fast-isnumeric';
5+
import Slider from 'react-rangeslider';
56
import {CarretDownIcon, CarretUpIcon} from 'plotly-icons';
67

78
export const UP_ARROW = 38;
@@ -94,7 +95,7 @@ export default class NumericInput extends Component {
9495
}
9596

9697
renderArrows() {
97-
if (!this.props.showArrows) {
98+
if (!this.props.showArrows || this.props.showSlider) {
9899
return null;
99100
}
100101

@@ -116,6 +117,23 @@ export default class NumericInput extends Component {
116117
);
117118
}
118119

120+
renderSlider() {
121+
if (!this.props.showSlider) {
122+
return null;
123+
}
124+
125+
return (
126+
<Slider
127+
min={this.props.min}
128+
max={this.props.max}
129+
step={this.props.step}
130+
value={this.state.value}
131+
onChange={this.updateValue}
132+
tooltip={false}
133+
/>
134+
);
135+
}
136+
119137
render() {
120138
return (
121139
<div className="numeric-input__wrapper">
@@ -129,6 +147,7 @@ export default class NumericInput extends Component {
129147
onKeyDown={this.onKeyDown}
130148
/>
131149
{this.renderArrows()}
150+
{this.renderSlider()}
132151
</div>
133152
);
134153
}
@@ -143,6 +162,7 @@ NumericInput.propTypes = {
143162
onUpdate: PropTypes.func.isRequired,
144163
placeholder: PropTypes.string,
145164
showArrows: PropTypes.bool,
165+
showSlider: PropTypes.bool,
146166
step: PropTypes.number,
147167
value: PropTypes.any,
148168
};

src/default_panels/StyleAxesPanel.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
Dropdown,
77
FontSelector,
88
Numeric,
9+
NumericFraction,
910
Radio,
1011
TextEditor,
1112
MenuPanel,
@@ -292,18 +293,8 @@ const StyleAxesPanel = ({localize: _}) => (
292293
</AxesFold>
293294
<AxesFold name={_('Layout')}>
294295
<Section name={_('Axis Width')} attr="domain[0]">
295-
<Numeric
296-
label={_('Start Position')}
297-
attr="domain[0]"
298-
units="%"
299-
step={0.1}
300-
/>
301-
<Numeric
302-
label={_('End Position')}
303-
attr="domain[1]"
304-
units="%"
305-
step={0.1}
306-
/>
296+
<NumericFraction label={_('Start Position')} attr="domain[0]" />
297+
<NumericFraction label={_('End Position')} attr="domain[1]" />
307298
</Section>
308299
<Section name={_('Positioning')}>
309300
<Radio

src/default_panels/StyleImagesPanel.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
ImageAccordion,
55
Radio,
66
TextEditor,
7-
Numeric,
7+
PositioningNumeric,
88
Section,
99
PositioningRef,
1010
Dropdown,
@@ -33,8 +33,8 @@ const StyleImagesPanel = ({localize: _}) => (
3333
{label: _('Stretch'), value: 'stretch'},
3434
]}
3535
/>
36-
<Numeric attr="sizex" label={_('Width')} />
37-
<Numeric attr="sizey" label={_('Height')} />
36+
<PositioningNumeric attr="sizex" label={_('Width')} />
37+
<PositioningNumeric attr="sizey" label={_('Height')} />
3838
<Section name={_('Horizontal Positioning')}>
3939
<MenuPanel>
4040
<Section name={_('Anchor Point')}>
@@ -49,7 +49,7 @@ const StyleImagesPanel = ({localize: _}) => (
4949
</Section>
5050
</MenuPanel>
5151
<PositioningRef label={_('Relative To')} attr="xref" />
52-
<Numeric label={_('Position')} attr="x" hideArrows />
52+
<PositioningNumeric label={_('Position')} attr="x" />
5353
</Section>
5454

5555
<Section name={_('Vertical Positioning')}>
@@ -66,7 +66,7 @@ const StyleImagesPanel = ({localize: _}) => (
6666
</Section>
6767
</MenuPanel>
6868
<PositioningRef label={_('Relative To')} attr="yref" />
69-
<Numeric label={_('Position')} attr="y" hideArrows />
69+
<PositioningNumeric label={_('Position')} attr="y" />
7070
</Section>
7171
</ImageAccordion>
7272
);

src/default_panels/StyleNotesPanel.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
FontSelector,
1010
Info,
1111
Numeric,
12+
PositioningNumeric,
1213
Radio,
1314
TextEditor,
1415
Section,
@@ -40,8 +41,8 @@ const StyleNotesPanel = ({localize: _}) => (
4041
<Numeric label={_('Scale')} step={0.1} attr="arrowsize" units="px" />
4142
<AnnotationArrowRef label="X Offset" attr="axref" />
4243
<AnnotationArrowRef label="Y Offset" attr="ayref" />
43-
<Numeric label={_('X Vector')} attr="ax" hideArrows />
44-
<Numeric label={_('Y Vector')} attr="ay" hideArrows />
44+
<Numeric label={_('X Vector')} attr="ax" />
45+
<Numeric label={_('Y Vector')} attr="ay" />
4546
</Section>
4647
<Section name={_('Horizontal Positioning')}>
4748
<MenuPanel>
@@ -64,7 +65,7 @@ const StyleNotesPanel = ({localize: _}) => (
6465
</Section>
6566
</MenuPanel>
6667
<AnnotationRef label={_('Relative To')} attr="xref" />
67-
<Numeric label={_('Position')} attr="x" hideArrows />
68+
<PositioningNumeric label={_('Position')} attr="x" />
6869
</Section>
6970
<Section name={_('Vertical Positioning')}>
7071
<MenuPanel>
@@ -87,7 +88,7 @@ const StyleNotesPanel = ({localize: _}) => (
8788
</Section>
8889
</MenuPanel>
8990
<AnnotationRef label={_('Relative To')} attr="yref" />
90-
<Numeric label={_('Position')} attr="y" hideArrows />
91+
<PositioningNumeric label={_('Position')} attr="y" />
9192
</Section>
9293
</AnnotationAccordion>
9394
);

src/default_panels/StyleShapesPanel.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Radio,
66
Section,
77
PositioningRef,
8+
PositioningNumeric,
89
Numeric,
910
ColorPicker,
1011
LineDashSelector,
@@ -32,14 +33,14 @@ const StyleShapesPanel = ({localize: _}) => (
3233

3334
<Section name={_('Horizontal Boundaries')}>
3435
<PositioningRef label={_('Relative to')} attr="xref" />
35-
<Numeric label={_('Start Point')} attr="x0" />
36-
<Numeric label={_('End Point')} attr="x1" />
36+
<PositioningNumeric label={_('Start Point')} attr="x0" />
37+
<PositioningNumeric label={_('End Point')} attr="x1" />
3738
</Section>
3839

3940
<Section name={_('Vertical Boundaries')}>
4041
<PositioningRef label={_('Relative to')} attr="yref" />
41-
<Numeric label={_('Start Point')} attr="y0" />
42-
<Numeric label={_('End Point')} attr="y1" />
42+
<PositioningNumeric label={_('Start Point')} attr="y0" />
43+
<PositioningNumeric label={_('End Point')} attr="y1" />
4344
</Section>
4445
<Section name={_('Lines')}>
4546
<Numeric label={_('Width')} attr="line.width" />

0 commit comments

Comments
 (0)