-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Feature: Range selectors #373
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
Changes from all commits
36968ad
ab6c109
19d81d4
aa84cf0
b5e8301
80c75c7
f25213d
ef64e20
26494cf
da47cd4
da71911
ab27021
de5e6b3
e976877
3fde2f8
121231b
8c839a1
48b5c50
4c7c99d
b198529
17c8377
0d20931
b9e388f
a5e6aaa
86331c7
c9f76ab
574a6b3
beb239b
ec0771a
dd4880b
2264bdd
f11aef9
8b4340e
053be81
f49dd51
fb056b1
b2988b4
3a812c9
1ca424a
a671683
1042f4f
46f4a20
616d77d
86a3167
4318f45
f025dc6
ade535e
49507be
c95b45a
6a68155
1275935
6c3a9d7
6da24e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/** | ||
* Copyright 2012-2016, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
var fontAttrs = require('../../plots/font_attributes'); | ||
var colorAttrs = require('../color/attributes'); | ||
var extendFlat = require('../../lib/extend').extendFlat; | ||
var buttonAttrs = require('./button_attributes'); | ||
|
||
buttonAttrs = extendFlat(buttonAttrs, { | ||
_isLinkedToArray: true, | ||
description: [ | ||
'Sets the specifications for each buttons.', | ||
'By default, a range selector comes with no buttons.' | ||
].join(' ') | ||
}); | ||
|
||
module.exports = { | ||
visible: { | ||
valType: 'boolean', | ||
role: 'info', | ||
description: [ | ||
'Determines whether or not this range selector is visible.', | ||
'Note that range selectors are only available for x axes of', | ||
'`type` set to or auto-typed to *date*.' | ||
].join(' ') | ||
}, | ||
|
||
buttons: buttonAttrs, | ||
|
||
x: { | ||
valType: 'number', | ||
min: -2, | ||
max: 3, | ||
role: 'style', | ||
description: 'Sets the x position (in normalized coordinates) of the range selector.' | ||
}, | ||
xanchor: { | ||
valType: 'enumerated', | ||
values: ['auto', 'left', 'center', 'right'], | ||
dflt: 'left', | ||
role: 'info', | ||
description: [ | ||
'Sets the range selector\'s horizontal position anchor.', | ||
'This anchor binds the `x` position to the *left*, *center*', | ||
'or *right* of the range selector.' | ||
].join(' ') | ||
}, | ||
y: { | ||
valType: 'number', | ||
min: -2, | ||
max: 3, | ||
role: 'style', | ||
description: 'Sets the y position (in normalized coordinates) of the range selector.' | ||
}, | ||
yanchor: { | ||
valType: 'enumerated', | ||
values: ['auto', 'top', 'middle', 'bottom'], | ||
dflt: 'bottom', | ||
role: 'info', | ||
description: [ | ||
'Sets the range selector\'s vertical position anchor', | ||
'This anchor binds the `y` position to the *top*, *middle*', | ||
'or *bottom* of the range selector.' | ||
].join(' ') | ||
}, | ||
|
||
font: extendFlat({}, fontAttrs, { | ||
description: 'Sets the font of the range selector button text.' | ||
}), | ||
|
||
bgcolor: { | ||
valType: 'color', | ||
dflt: colorAttrs.lightLine, | ||
role: 'style', | ||
description: 'Sets the background color of the range selector buttons.' | ||
}, | ||
bordercolor: { | ||
valType: 'color', | ||
dflt: colorAttrs.defaultLine, | ||
role: 'style', | ||
description: 'Sets the color of the border enclosing the range selector.' | ||
}, | ||
borderwidth: { | ||
valType: 'number', | ||
min: 0, | ||
dflt: 0, | ||
role: 'style', | ||
description: 'Sets the width (in px) of the border enclosing the range selector.' | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
* Copyright 2012-2016, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
|
||
module.exports = { | ||
step: { | ||
valType: 'enumerated', | ||
role: 'info', | ||
values: ['month', 'year', 'day', 'hour', 'minute', 'second', 'all'], | ||
dflt: 'month', | ||
description: [ | ||
'The unit of measurement that the `count` value will set the range by.' | ||
].join(' ') | ||
}, | ||
stepmode: { | ||
valType: 'enumerated', | ||
role: 'info', | ||
values: ['backward', 'todate'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be a forwards mode? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe. HighCharts doesn't support it, so I didn't put it in the first iteration. |
||
dflt: 'backward', | ||
description: [ | ||
'Sets the range update mode.', | ||
'If *backward*, the range update shifts the start of range', | ||
'back *count* times *step* milliseconds.', | ||
'If *todate*, the range update shifts the start of range', | ||
'back to the first timestamp from *count* times', | ||
'*step* milliseconds back.', | ||
'For example, with `step` set to *year* and `count` set to *1*', | ||
'the range update shifts the start of the range back to', | ||
'January 01 of the current year.' | ||
].join(' ') | ||
}, | ||
count: { | ||
valType: 'number', | ||
role: 'info', | ||
min: 0, | ||
dflt: 1, | ||
description: [ | ||
'Sets the number of steps to take to update the range.', | ||
'Use with `step` to specify the update interval.' | ||
].join(' ') | ||
}, | ||
label: { | ||
valType: 'string', | ||
role: 'info', | ||
description: 'Sets the text label to appear on the button.' | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* Copyright 2012-2016, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
|
||
module.exports = { | ||
|
||
// 'y' position pad above counter axis domain | ||
yPad: 0.02, | ||
|
||
// minimum button width (regardless of text size) | ||
minButtonWidth: 30, | ||
|
||
// buttons rect radii | ||
rx: 3, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we plan to make this configurable later (and if people ask)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. When enough people ask. |
||
ry: 3, | ||
|
||
// color given to active and hovered buttons | ||
activeColor: '#d3d3d3' | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* Copyright 2012-2016, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
var Lib = require('../../lib'); | ||
|
||
var attributes = require('./attributes'); | ||
var buttonAttrs = require('./button_attributes'); | ||
var constants = require('./constants'); | ||
|
||
|
||
module.exports = function rangeSelectorDefaults(containerIn, containerOut, layout, counterAxes) { | ||
var selectorIn = containerIn.rangeselector || {}, | ||
selectorOut = containerOut.rangeselector = {}; | ||
|
||
function coerce(attr, dflt) { | ||
return Lib.coerce(selectorIn, selectorOut, attributes, attr, dflt); | ||
} | ||
|
||
var buttons = buttonsDefaults(selectorIn, selectorOut); | ||
|
||
var visible = coerce('visible', buttons.length > 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the moment, range selector don't ship with any default buttons. Shipping default buttons would require adding some logic based on the range of the time series, which wouldn't be too hard, but might be too magical. Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kinda like the do-it-yourself nature of this. It's not any more complex than other configurations in plotly.js and allows far greater flexibility (especially if we allow arbitrary HTML). |
||
if(!visible) return; | ||
|
||
var posDflt = getPosDflt(containerOut, layout, counterAxes); | ||
coerce('x', posDflt[0]); | ||
coerce('y', posDflt[1]); | ||
Lib.noneOrAll(containerIn, containerOut, ['x', 'y']); | ||
|
||
coerce('xanchor'); | ||
coerce('yanchor'); | ||
|
||
Lib.coerceFont(coerce, 'font', layout.font); | ||
|
||
coerce('bgcolor'); | ||
coerce('bordercolor'); | ||
coerce('borderwidth'); | ||
}; | ||
|
||
function buttonsDefaults(containerIn, containerOut) { | ||
var buttonsIn = containerIn.buttons || [], | ||
buttonsOut = containerOut.buttons = []; | ||
|
||
var buttonIn, buttonOut; | ||
|
||
function coerce(attr, dflt) { | ||
return Lib.coerce(buttonIn, buttonOut, buttonAttrs, attr, dflt); | ||
} | ||
|
||
for(var i = 0; i < buttonsIn.length; i++) { | ||
buttonIn = buttonsIn[i]; | ||
buttonOut = {}; | ||
|
||
var step = coerce('step'); | ||
if(step !== 'all') { | ||
coerce('stepmode'); | ||
coerce('count'); | ||
} | ||
|
||
coerce('label'); | ||
|
||
buttonsOut.push(buttonOut); | ||
} | ||
|
||
return buttonsOut; | ||
} | ||
|
||
function getPosDflt(containerOut, layout, counterAxes) { | ||
var anchoredList = counterAxes.filter(function(ax) { | ||
return layout[ax].anchor === containerOut._id; | ||
}); | ||
|
||
var posY = 0; | ||
for(var i = 0; i < anchoredList.length; i++) { | ||
posY = Math.max(layout[anchoredList[i]].domain[1], posY); | ||
} | ||
|
||
return [containerOut.domain[0], posY + constants.yPad]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you're using
eslint
you can use$ eslint --fix
to fix all of the whitespace issues across the codebase automatically