-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Dropdown legend items #207
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
Comments
After some more time working on this, there's some new challenges/discoveries.
So far for the scrolling, I've done it all in SVG to get around the first issue of a tainted canvas, but dropdowns will be a bit substantially more complex to create in SVG. Etienne and I had discussed how best to implement "filtering" as actions that can be in the legend box - because we want to keep python support strong, we'll need to do it declaratively, which is obviously not quite as nice as if we could just pass lambdas to a layout property.
@chriddyp what are the requirements on your end for features/appearance/interface in the workspace? Maybe a mockup for the style/interaction of it will be helpful too if @delekru can whip something up. |
I'm not familiar enough with the limitation SVG imposes, but maybe it will be easier to implement paginated legend rather than drop down? |
Filtering in the workspace has reference to a greater data model than what is just present inside the plotly chart. Folks can filter on columns that they aren't actually visualizing. We've kept the UI for this entirely outside of the plot with the chart creation and exploration controls. I don't have a strong vision for what this might look like inside the plot and how we'll unify the two interfaces. My first impression is that the filtering that we provide inside the workspace is "exportable" to the chart. These controls would be in the form of dropdown selects, search boxes, and numerical input boxes. The JSON might look something like:
|
Thanks @chriddyp. I'm thinking, to start, that we should allow only one filter per plot, similar to legends. Moreover, should we support trace filters? Or should the filter steps loop over all traces? And most importantly, we'll need to find a way make the coupling between Here's my (a little-more plotly.js-eque) version of the specs: layout: {
filter: {
type: 'buttons' // or 'dropdown'
orientation: 'h', // or 'v' or merge into type e.g 'horiz buttons' / 'vert butons'
items: [{
visible: true,
mode: 'eq', // 'lt', 'gt', 'contains', 'range'
value: 20 // numeric for 'eq', 'lt and 'gt' ,
// 2-item array for 'range' ,
// array or string for 'contains',
label: 'my filter' // string to be display on button
}, {
/* ... */
}],
// some positioning options
x: 1, // always on a 'paper'
y: 0,
xanchor: 'left',
yanchor: 'bottom',
// some style options
len: 0.4 // length in normalized coordinates
// the button width would be len / 0-1 to px / items.length
borderwidth: 1,
bordercolor: '#fff'
}
} |
The dropdown filtering use-case that @cldougl and I hear most from dashboard users and Plotly customers is simply showing one trace while hiding all the other traces. Here's a demo using the postMessage API: (From: http://help.plot.ly/documentation/dashboards/sales/) Just want to vote for this basic use case to get covered! |
Some observationsMost filtering operations will come in two forms:
Trace filtersFor example, the dashboard in @jackparmer ⏫ comment would be described as: layout.tracefilter = {
mode: 'dropdown', // or 'buttons'
labels: [], // list of button labels to optionally override the filter group values
includeall: false, // or true - include button that shows all filter groups
includereset: false, // or true - include button that reset to first view
multiplegroups: false // or true - can multiple group be selected at the same time?
// ++ common filter style and positioning attributes
}; where there would as many buttons as distinct Range filtersFor example, the range selectors as in the top-left corner of: would be described as: layout.rangefilter = {
mode: 'buttons', // or 'dropdown'
orientation: 'h' // or 'v'
updatemode: 'base', // or 'current' - i.e. is slicing performed on the base state or current one?
arrayattribute: 'x' // about which array attribute is the slicing performed? could be 'marker.color'
items: [{
label: 'all',
range: [null, null] // null in range[0] means -Infinity , in range[1] means Infinity
}, {
label: 'last month',
range: [ (new Date(2016, 1).getTime(), null ]
}]
// ++ common filter style and positioning attributes
}; Custom filtersDown the road, we could easily add a fully-custom filter type where sequences of operations could be declared. For example: {
mode: 'buttons',
items: [{
label: 'x > 30 and y < 50',
updatemode: 'base',
operations: [{
type: 'range',
arrayattribute: 'x',
range: [30, null]
}, {
type: 'range',
arrayattribute: 'y',
range: [null, 50]
}]
}, {
label: 'group1',
updatetype: 'current',
operations: [{
type: 'filtergroup',
group: 'group1'
}]
}, {
label: '10 < x < 30 and group1',
updatetype: 'base',
operations: [{
type: 'range',
arrayattribute: 'x',
range: [10, 30]
}, {
type: 'filtergroup',
group: 'group1'
}]
}];
} |
This looks like a good interface, but we still won't be able to do any conditional range/filtering - i.e. the One way we could get around this could be to use range: [ -30, null ] could indicate using the last 30 datapoints on the axis, and range: [-30, Infinity] would indicate using from -30 to infinity. Perhaps that's a bit more convoluted than necessary, but it would allow for proper "moving" ranges depending on the data provided. |
Some initial work on branch |
There has been some demand for dropdown selection of legend items and custom filtering, useful in cases where there are lots of traces and data to be toggled.
This issue will come in two parts:
legend.type
with eithervertical
ordropdown
(later on,horizontal
)The text was updated successfully, but these errors were encountered: