Skip to content

Commit ce36ec3

Browse files
committed
Slider now supports range
1 parent 8f7a4e6 commit ce36ec3

File tree

5 files changed

+34
-24
lines changed

5 files changed

+34
-24
lines changed

examples/widgets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
st.write(w1)
88

99
st.subheader('Slider')
10-
w2 = st.slider('Age', 32, 0, 100, 1)
10+
w2 = st.slider('Age', [32.5, 72.5], 0, 100, 0.5)
1111
st.write(w2)
1212

1313
st.subheader('Textarea')

frontend/src/components/widgets/Slider/Slider.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import React from 'react'
77
// @ts-ignore
8-
import { Slider as UISlider } from 'baseui/slider';
8+
import { Slider as UISlider } from 'baseui/slider'
99
import { Map as ImmutableMap } from 'immutable'
1010
import { WidgetStateManager } from 'lib/WidgetStateManager'
1111
import { PureStreamlitElement, StState } from 'components/shared/StreamlitElement/'
@@ -21,6 +21,10 @@ interface State extends StState {
2121
value: number[];
2222
}
2323

24+
interface SliderValue {
25+
value: number[];
26+
}
27+
2428
class Slider extends PureStreamlitElement<Props, State> {
2529
public constructor(props: Props) {
2630
super(props)
@@ -33,9 +37,8 @@ class Slider extends PureStreamlitElement<Props, State> {
3337
this.props.widgetMgr.sendUpdateWidgetsMessage()
3438
}
3539

36-
private handleChange = (e: any) => {
40+
private handleChange = ({ value }: SliderValue) => {
3741
const widgetId = this.props.element.get('id')
38-
const value = e.value
3942

4043
this.setState({ value })
4144
this.props.widgetMgr.setFloatArrayValue(widgetId, value)

frontend/src/lib/WidgetStateManager.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import {BackMsg, IBackMsg, WidgetState, WidgetStates} from 'autogen/protobuf'
2-
1+
import {IBackMsg, BackMsg, FloatArray, WidgetState, WidgetStates} from 'autogen/protobuf'
32

43
/**
54
* Manages widget values, and sends widget update messages back to the server.
65
*/
76
export class WidgetStateManager {
8-
/** Called to deliver a message to the server */
7+
// Called to deliver a message to the server
98
private readonly sendBackMsg: (msg: IBackMsg) => void
109

1110
private readonly widgetStates: Map<string, WidgetState> = new Map<string, WidgetState>()
@@ -38,8 +37,8 @@ export class WidgetStateManager {
3837
this.getOrCreateWidgetStateProto(widgetId).stringValue = value
3938
}
4039

41-
public setFloatArrayValue(widgetId: string, value: WidgetState.IFloatArray): void {
42-
this.getOrCreateWidgetStateProto(widgetId).floatArrayValue = value
40+
public setFloatArrayValue(widgetId: string, value: number[]): void {
41+
this.getOrCreateWidgetStateProto(widgetId).floatArrayValue = FloatArray.fromObject({ value })
4342
}
4443

4544
public sendUpdateWidgetsMessage(): void {
@@ -59,7 +58,7 @@ export class WidgetStateManager {
5958
private getOrCreateWidgetStateProto(id: string): WidgetState {
6059
let state = this.getWidgetStateProto(id)
6160
if (state == null) {
62-
state = new WidgetState({id: id})
61+
state = new WidgetState({ id })
6362
this.widgetStates.set(id, state)
6463
}
6564
return state
@@ -99,5 +98,4 @@ export class WidgetStateManager {
9998
this.latestPendingMessage = undefined
10099
this.widgetThrottleTimer = undefined
101100
}
102-
103101
}

lib/streamlit/DeltaGenerator.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# Python 2/3 compatibility
66
from __future__ import print_function, division, unicode_literals, absolute_import
77
from streamlit.compatibility import setup_2_3_shims
8+
89
setup_2_3_shims(globals())
910

1011
import functools
@@ -20,8 +21,8 @@
2021

2122
# setup logging
2223
from streamlit.logger import get_logger
23-
LOGGER = get_logger(__name__)
2424

25+
LOGGER = get_logger(__name__)
2526

2627
MAX_DELTA_BYTES = 14 * 1024 * 1024 # 14MB
2728

@@ -70,9 +71,11 @@ def some_function(self, unused_element_argument, stuff):
7071
function as above, the wrapped function will be called this way:
7172
dg.some_function(None, stuff)
7273
"""
74+
7375
@_wraps_with_cleaned_sig(method)
7476
def wrapped_method(self, *args, **kwargs):
7577
return method(self, None, *args, **kwargs)
78+
7679
return wrapped_method
7780

7881

@@ -96,11 +99,13 @@ def _with_element(method):
9699
A new DeltaGenerator method with arguments (self, ...)
97100
98101
"""
102+
99103
@_wraps_with_cleaned_sig(method)
100104
def wrapped_method(self, *args, **kwargs):
101105
try:
102106
def marshall_element(element):
103107
return method(self, element, *args, **kwargs)
108+
104109
return self._enqueue_new_element_delta(marshall_element)
105110
except Exception as e:
106111
# First, write the delta to stderr.
@@ -131,6 +136,7 @@ def wrapper(dg, element, *args, **kwargs):
131136
ctx.widgets.get_widget_value(widget_id) if ctx else None
132137
)
133138
return f(dg, element, ui_value, *args, **kwargs)
139+
134140
return wrapper
135141

136142

@@ -570,6 +576,7 @@ def dataframe(self, _, data=None):
570576

571577
def set_data_frame(delta):
572578
data_frame_proto.marshall_data_frame(data, delta.data_frame)
579+
573580
return self._enqueue_new_element_delta(set_data_frame)
574581

575582
# TODO: Either remove this or make it public. This is only used in the
@@ -833,8 +840,8 @@ def graphviz_chart(self, element, figure_or_dot, width=0, height=0):
833840

834841
@_with_element
835842
def plotly_chart(
836-
self, element, figure_or_data, width=0, height=0,
837-
sharing='streamlit', **kwargs):
843+
self, element, figure_or_data, width=0, height=0,
844+
sharing='streamlit', **kwargs):
838845
"""Display an interactive Plotly chart.
839846
840847
Plotly is a charting library for Python. The arguments to this function
@@ -1029,8 +1036,8 @@ def bokeh_chart(self, element, figure):
10291036
# TODO: Make this accept files and strings/bytes as input.
10301037
@_with_element
10311038
def image(
1032-
self, element, image, caption=None, width=None,
1033-
use_column_width=False, clamp=False):
1039+
self, element, image, caption=None, width=None,
1040+
use_column_width=False, clamp=False):
10341041
"""Display an image or list of images.
10351042
10361043
Parameters
@@ -1179,11 +1186,13 @@ def slider(self, element, ui_value, label, value=0, min_value=0, max_value=100,
11791186
"""Slider doc string."""
11801187
current_value = ui_value if ui_value is not None else value
11811188
element.slider.label = label
1182-
if type(current_value) is list:
1183-
assert len(current_value) <= 2
1184-
element.slider.value[:] = current_value
1189+
if isinstance(current_value, list):
1190+
assert len(current_value) == 2
1191+
elif isinstance(current_value, (int, float)):
1192+
current_value = [current_value]
11851193
else:
1186-
element.slider.value[:] = [current_value]
1194+
current_value = getattr(current_value, 'value')
1195+
element.slider.value[:] = current_value
11871196
element.slider.min = min_value
11881197
element.slider.max = max_value
11891198
element.slider.step = step

protobuf/BackMsg.proto

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ message BackMsg {
2525
// Requests that the report's execution be stopped
2626
bool stop_report = 7;
2727

28-
// string widget_json = 8;
28+
// string widget_json = 8;
2929

3030
WidgetStates update_widgets = 9;
3131
}
@@ -55,8 +55,8 @@ message WidgetState {
5555
string string_value = 6;
5656
FloatArray float_array_value = 7;
5757
}
58+
}
5859

59-
message FloatArray {
60-
repeated float float_array_value = 8;
61-
}
60+
message FloatArray {
61+
repeated float value = 1;
6262
}

0 commit comments

Comments
 (0)