Skip to content

Commit 747be93

Browse files
authored
Merge pull request #4653 from plotly/change-rangebreak-pattern-flags
Revise flags of rangebreak pattern
2 parents 9a75ef0 + a333acb commit 747be93

9 files changed

+256
-94
lines changed

src/plots/cartesian/constants.js

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ module.exports = {
3131
// and for 2D subplots
3232
SUBPLOT_PATTERN: /^x([0-9]*)y([0-9]*)$/,
3333

34+
HOUR_PATTERN: 'hour',
35+
WEEKDAY_PATTERN: 'day of week',
36+
3437
// pixels to move mouse before you stop clamping to starting point
3538
MINDRAG: 8,
3639

src/plots/cartesian/layout_attributes.js

+7-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ var FORMAT_LINK = require('../../constants/docs').FORMAT_LINK;
1818
var DATE_FORMAT_LINK = require('../../constants/docs').DATE_FORMAT_LINK;
1919
var ONEDAY = require('../../constants/numerical').ONEDAY;
2020
var constants = require('./constants');
21+
var HOUR = constants.HOUR_PATTERN;
22+
var DAY_OF_WEEK = constants.WEEKDAY_PATTERN;
2123

2224
module.exports = {
2325
visible: {
@@ -278,22 +280,19 @@ module.exports = {
278280

279281
pattern: {
280282
valType: 'enumerated',
281-
// TODO could add '%H:%M:%S'
282-
values: ['%w', '%H', ''],
283+
values: [DAY_OF_WEEK, HOUR, ''],
283284
dflt: '',
284285
role: 'info',
285286
editType: 'calc',
286287
description: [
287288
'Determines a pattern on the time line that generates breaks.',
288-
'If *%w* - Sunday-based weekday as a decimal number [0, 6].',
289-
'If *%H* - hour (24-hour clock) as a decimal number [0, 23].',
290-
'These are the same directive as in `tickformat`, see',
291-
'https://github.com/d3/d3-time-format#locale_format',
289+
'If *' + DAY_OF_WEEK + '* - Sunday-based weekday as a decimal number [0, 6].',
290+
'If *' + HOUR + '* - hour (24-hour clock) as decimal numbers between 0 and 24.',
292291
'for more info.',
293292
'Examples:',
294-
'- { pattern: \'%w\', bounds: [6, 0], operation: \'[]\' }',
293+
'- { pattern: \'' + DAY_OF_WEEK + '\', bounds: [6, 0] }',
295294
' breaks from Saturday to Monday (i.e. skips the weekends).',
296-
'- { pattern: \'%H\', bounds: [17, 8] }',
295+
'- { pattern: \'' + HOUR + '\', bounds: [17, 8], operation: \'()\' }', // TODO: simplify after revise defaults
297296
' breaks from 5pm to 8am (i.e. skips non-work hours).'
298297
].join(' ')
299298
},

src/plots/cartesian/set_convert.js

+48-44
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ var ONEHOUR = numConstants.ONEHOUR;
2727
var ONEMIN = numConstants.ONEMIN;
2828
var ONESEC = numConstants.ONESEC;
2929

30-
var constants = require('./constants');
3130
var axisIds = require('./axis_ids');
3231

32+
var constants = require('./constants');
33+
var HOUR_PATTERN = constants.HOUR_PATTERN;
34+
var WEEKDAY_PATTERN = constants.WEEKDAY_PATTERN;
35+
3336
function fromLog(v) {
3437
return Math.pow(10, v);
3538
}
@@ -611,7 +614,7 @@ module.exports = function setConvert(ax, fullLayout) {
611614

612615
ax.maskBreaks = function(v) {
613616
var rangebreaksIn = ax.rangebreaks || [];
614-
var bnds, b0, b1, vb;
617+
var bnds, b0, b1, vb, vDate;
615618

616619
for(var i = 0; i < rangebreaksIn.length; i++) {
617620
var brk = rangebreaksIn[i];
@@ -622,55 +625,56 @@ module.exports = function setConvert(ax, fullLayout) {
622625
var op1 = op.charAt(1);
623626

624627
if(brk.bounds) {
625-
var doesCrossPeriod = false;
628+
var pattern = brk.pattern;
629+
bnds = Lib.simpleMap(brk.bounds, pattern ?
630+
cleanNumber :
631+
ax.d2c // case of pattern: ''
632+
);
633+
b0 = bnds[0];
634+
b1 = bnds[1];
635+
636+
switch(pattern) {
637+
case WEEKDAY_PATTERN:
638+
vDate = new Date(v);
639+
vb = vDate.getUTCDay();
640+
641+
if(b0 > b1) {
642+
b1 += 7;
643+
if(vb < b0) vb += 7;
644+
}
626645

627-
switch(brk.pattern) {
628-
case '%w':
629-
bnds = Lib.simpleMap(brk.bounds, cleanNumber);
630-
b0 = bnds[0];
631-
b1 = bnds[1];
632-
vb = (new Date(v)).getUTCDay();
633-
if(bnds[0] > bnds[1]) doesCrossPeriod = true;
634646
break;
635-
case '%H':
636-
bnds = Lib.simpleMap(brk.bounds, cleanNumber);
637-
b0 = bnds[0];
638-
b1 = bnds[1];
639-
var vDate = new Date(v);
640-
vb = vDate.getUTCHours() + (
641-
vDate.getUTCMinutes() * ONEMIN +
642-
vDate.getUTCSeconds() * ONESEC +
643-
vDate.getUTCMilliseconds()
644-
) / ONEDAY;
645-
if(bnds[0] > bnds[1]) doesCrossPeriod = true;
647+
case HOUR_PATTERN:
648+
vDate = new Date(v);
649+
var hours = vDate.getUTCHours();
650+
var minutes = vDate.getUTCMinutes();
651+
var seconds = vDate.getUTCSeconds();
652+
var milliseconds = vDate.getUTCMilliseconds();
653+
654+
vb = hours + (
655+
minutes / 60 +
656+
seconds / 3600 +
657+
milliseconds / 3600000
658+
);
659+
660+
if(b0 > b1) {
661+
b1 += 24;
662+
if(vb < b0) vb += 24;
663+
}
664+
646665
break;
647666
case '':
648667
// N.B. should work on date axes as well!
649668
// e.g. { bounds: ['2020-01-04', '2020-01-05 23:59'] }
650-
bnds = Lib.simpleMap(brk.bounds, ax.d2c);
651-
if(bnds[0] <= bnds[1]) {
652-
b0 = bnds[0];
653-
b1 = bnds[1];
654-
} else {
655-
b0 = bnds[1];
656-
b1 = bnds[0];
657-
}
658669
// TODO should work with reversed-range axes
659670
vb = v;
660671
break;
661672
}
662673

663-
if(doesCrossPeriod) {
664-
if(
665-
(op0 === '(' ? vb > b0 : vb >= b0) ||
666-
(op1 === ')' ? vb < b1 : vb <= b1)
667-
) return BADNUM;
668-
} else {
669-
if(
670-
(op0 === '(' ? vb > b0 : vb >= b0) &&
671-
(op1 === ')' ? vb < b1 : vb <= b1)
672-
) return BADNUM;
673-
}
674+
if(
675+
(op0 === '(' ? vb > b0 : vb >= b0) &&
676+
(op1 === ')' ? vb < b1 : vb <= b1)
677+
) return BADNUM;
674678
} else {
675679
var vals = Lib.simpleMap(brk.values, ax.d2c).sort(Lib.sorterAsc);
676680
var onOpenBound = false;
@@ -699,8 +703,8 @@ module.exports = function setConvert(ax, fullLayout) {
699703
if(!ax.rangebreaks) return rangebreaksOut;
700704

701705
var rangebreaksIn = ax.rangebreaks.slice().sort(function(a, b) {
702-
if(a.pattern === '%w' && b.pattern === '%H') return -1;
703-
else if(b.pattern === '%w' && a.pattern === '%H') return 1;
706+
if(a.pattern === WEEKDAY_PATTERN && b.pattern === HOUR_PATTERN) return -1;
707+
if(b.pattern === WEEKDAY_PATTERN && a.pattern === HOUR_PATTERN) return 1;
704708
return 0;
705709
});
706710

@@ -756,7 +760,7 @@ module.exports = function setConvert(ax, fullLayout) {
756760
var t;
757761

758762
switch(brk.pattern) {
759-
case '%w':
763+
case WEEKDAY_PATTERN:
760764
b0 = bnds[0] + (op0 === '(' ? 1 : 0);
761765
b1 = bnds[1];
762766
r0Pattern = r0Date.getUTCDay();
@@ -771,7 +775,7 @@ module.exports = function setConvert(ax, fullLayout) {
771775
r0Date.getUTCSeconds() * ONESEC -
772776
r0Date.getUTCMilliseconds();
773777
break;
774-
case '%H':
778+
case HOUR_PATTERN:
775779
b0 = bnds[0];
776780
b1 = bnds[1];
777781
r0Pattern = r0Date.getUTCHours();

test/image/mocks/axes_breaks-finance.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@
363363
"rangeslider": { "visible": true },
364364
"rangebreaks": [
365365
{
366-
"pattern": "%w",
366+
"pattern": "day of week",
367367
"bounds": [ 6, 0 ]
368368
},
369369
{
@@ -376,7 +376,7 @@
376376
"rangeslider": { "visible": true },
377377
"rangebreaks": [
378378
{
379-
"pattern": "%w",
379+
"pattern": "day of week",
380380
"bounds": [ 6, 0 ]
381381
},
382382
{

test/image/mocks/axes_breaks-night_autorange-reversed.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@
192192
"xaxis": {
193193
"rangebreaks": [
194194
{
195-
"pattern": "%H",
195+
"pattern": "hour",
196196
"bounds": [
197197
18,
198198
6
@@ -208,7 +208,7 @@
208208
"xaxis2": {
209209
"rangebreaks": [
210210
{
211-
"pattern": "%H",
211+
"pattern": "hour",
212212
"bounds": [
213213
18,
214214
6
@@ -253,7 +253,7 @@
253253
"yaxis3": {
254254
"rangebreaks": [
255255
{
256-
"pattern": "%H",
256+
"pattern": "hour",
257257
"bounds": [
258258
18,
259259
6
@@ -270,7 +270,7 @@
270270
"yaxis4": {
271271
"rangebreaks": [
272272
{
273-
"pattern": "%H",
273+
"pattern": "hour",
274274
"bounds": [
275275
18,
276276
6

test/image/mocks/axes_breaks-rangeslider.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -2654,22 +2654,22 @@
26542654
"tickfont": {"size": 8},
26552655
"rangebreaks": [
26562656
{
2657-
"pattern": "%w",
2657+
"pattern": "day of week",
26582658
"bounds": [6, 0],
26592659
"operation": "[]"
26602660
},
26612661
{
2662-
"pattern": "%H",
2662+
"pattern": "hour",
26632663
"bounds": [0, 9],
26642664
"operation": "()"
26652665
},
26662666
{
2667-
"pattern": "%H",
2667+
"pattern": "hour",
26682668
"bounds": [12, 13],
26692669
"operation": "()"
26702670
},
26712671
{
2672-
"pattern": "%H",
2672+
"pattern": "hour",
26732673
"bounds": [15, 21],
26742674
"operation": "()"
26752675
}

test/image/mocks/axes_breaks-weekends-weeknights.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
"xaxis": {
1616
"rangebreaks": [
1717
{
18-
"pattern": "%w",
18+
"pattern": "day of week",
1919
"bounds": [ 6, 0 ],
2020
"operation": "[]"
2121
},
2222
{
23-
"pattern": "%H",
23+
"pattern": "hour",
2424
"bounds": [ 16, 8 ],
2525
"operation": "()"
2626
}

test/image/mocks/axes_breaks-weekends_autorange-reversed.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"xaxis": {
8989
"rangebreaks": [
9090
{
91-
"pattern": "%w",
91+
"pattern": "day of week",
9292
"bounds": [
9393
6,
9494
0
@@ -104,7 +104,7 @@
104104
"xaxis2": {
105105
"rangebreaks": [
106106
{
107-
"pattern": "%w",
107+
"pattern": "day of week",
108108
"bounds": [
109109
6,
110110
0
@@ -149,7 +149,7 @@
149149
"yaxis3": {
150150
"rangebreaks": [
151151
{
152-
"pattern": "%w",
152+
"pattern": "day of week",
153153
"bounds": [
154154
6,
155155
0
@@ -166,7 +166,7 @@
166166
"yaxis4": {
167167
"rangebreaks": [
168168
{
169-
"pattern": "%w",
169+
"pattern": "day of week",
170170
"bounds": [
171171
6,
172172
0

0 commit comments

Comments
 (0)