Skip to content
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

Revise flags of rangebreak pattern #4653

Merged
merged 12 commits into from
Mar 17, 2020
3 changes: 3 additions & 0 deletions src/plots/cartesian/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ module.exports = {
// and for 2D subplots
SUBPLOT_PATTERN: /^x([0-9]*)y([0-9]*)$/,

HOUR_PATTERN: 'hour',
WEEKDAY_PATTERN: 'day of week',

// pixels to move mouse before you stop clamping to starting point
MINDRAG: 8,

Expand Down
15 changes: 7 additions & 8 deletions src/plots/cartesian/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ var FORMAT_LINK = require('../../constants/docs').FORMAT_LINK;
var DATE_FORMAT_LINK = require('../../constants/docs').DATE_FORMAT_LINK;
var ONEDAY = require('../../constants/numerical').ONEDAY;
var constants = require('./constants');
var HOUR = constants.HOUR_PATTERN;
var DAY_OF_WEEK = constants.WEEKDAY_PATTERN;

module.exports = {
visible: {
Expand Down Expand Up @@ -278,22 +280,19 @@ module.exports = {

pattern: {
valType: 'enumerated',
// TODO could add '%H:%M:%S'
values: ['%w', '%H', ''],
values: [DAY_OF_WEEK, HOUR, ''],
dflt: '',
role: 'info',
editType: 'calc',
description: [
'Determines a pattern on the time line that generates breaks.',
'If *%w* - Sunday-based weekday as a decimal number [0, 6].',
'If *%H* - hour (24-hour clock) as a decimal number [0, 23].',
'These are the same directive as in `tickformat`, see',
'https://github.com/d3/d3-time-format#locale_format',
'If *' + DAY_OF_WEEK + '* - Sunday-based weekday as a decimal number [0, 6].',
'If *' + HOUR + '* - hour (24-hour clock) as decimal numbers between 0 and 24.',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh we should note here that weekday needs to be an integer but hour can be fractional.

'for more info.',
'Examples:',
'- { pattern: \'%w\', bounds: [6, 0], operation: \'[]\' }',
'- { pattern: \'' + DAY_OF_WEEK + '\', bounds: [6, 0] }',
' breaks from Saturday to Monday (i.e. skips the weekends).',
'- { pattern: \'%H\', bounds: [17, 8] }',
'- { pattern: \'' + HOUR + '\', bounds: [17, 8], operation: \'()\' }', // TODO: simplify after revise defaults
' breaks from 5pm to 8am (i.e. skips non-work hours).'
].join(' ')
},
Expand Down
92 changes: 48 additions & 44 deletions src/plots/cartesian/set_convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ var ONEHOUR = numConstants.ONEHOUR;
var ONEMIN = numConstants.ONEMIN;
var ONESEC = numConstants.ONESEC;

var constants = require('./constants');
var axisIds = require('./axis_ids');

var constants = require('./constants');
var HOUR_PATTERN = constants.HOUR_PATTERN;
var WEEKDAY_PATTERN = constants.WEEKDAY_PATTERN;

function fromLog(v) {
return Math.pow(10, v);
}
Expand Down Expand Up @@ -611,7 +614,7 @@ module.exports = function setConvert(ax, fullLayout) {

ax.maskBreaks = function(v) {
var rangebreaksIn = ax.rangebreaks || [];
var bnds, b0, b1, vb;
var bnds, b0, b1, vb, vDate;

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

if(brk.bounds) {
var doesCrossPeriod = false;
var pattern = brk.pattern;
bnds = Lib.simpleMap(brk.bounds, pattern ?
cleanNumber :
ax.d2c // case of pattern: ''
);
b0 = bnds[0];
b1 = bnds[1];

switch(pattern) {
case WEEKDAY_PATTERN:
vDate = new Date(v);
vb = vDate.getUTCDay();

if(b0 > b1) {
b1 += 7;
if(vb < b0) vb += 7;
}

switch(brk.pattern) {
case '%w':
bnds = Lib.simpleMap(brk.bounds, cleanNumber);
b0 = bnds[0];
b1 = bnds[1];
vb = (new Date(v)).getUTCDay();
if(bnds[0] > bnds[1]) doesCrossPeriod = true;
break;
case '%H':
bnds = Lib.simpleMap(brk.bounds, cleanNumber);
b0 = bnds[0];
b1 = bnds[1];
var vDate = new Date(v);
vb = vDate.getUTCHours() + (
vDate.getUTCMinutes() * ONEMIN +
vDate.getUTCSeconds() * ONESEC +
vDate.getUTCMilliseconds()
) / ONEDAY;
if(bnds[0] > bnds[1]) doesCrossPeriod = true;
case HOUR_PATTERN:
vDate = new Date(v);
var hours = vDate.getUTCHours();
var minutes = vDate.getUTCMinutes();
var seconds = vDate.getUTCSeconds();
var milliseconds = vDate.getUTCMilliseconds();

vb = hours + (
minutes / 60 +
seconds / 3600 +
milliseconds / 3600000
);

if(b0 > b1) {
b1 += 24;
if(vb < b0) vb += 24;
}

break;
case '':
// N.B. should work on date axes as well!
// e.g. { bounds: ['2020-01-04', '2020-01-05 23:59'] }
bnds = Lib.simpleMap(brk.bounds, ax.d2c);
if(bnds[0] <= bnds[1]) {
b0 = bnds[0];
b1 = bnds[1];
} else {
b0 = bnds[1];
b1 = bnds[0];
}
// TODO should work with reversed-range axes
vb = v;
break;
}

if(doesCrossPeriod) {
if(
(op0 === '(' ? vb > b0 : vb >= b0) ||
(op1 === ')' ? vb < b1 : vb <= b1)
) return BADNUM;
} else {
if(
(op0 === '(' ? vb > b0 : vb >= b0) &&
(op1 === ')' ? vb < b1 : vb <= b1)
) return BADNUM;
}
if(
(op0 === '(' ? vb > b0 : vb >= b0) &&
(op1 === ')' ? vb < b1 : vb <= b1)
) return BADNUM;
} else {
var vals = Lib.simpleMap(brk.values, ax.d2c).sort(Lib.sorterAsc);
var onOpenBound = false;
Expand Down Expand Up @@ -699,8 +703,8 @@ module.exports = function setConvert(ax, fullLayout) {
if(!ax.rangebreaks) return rangebreaksOut;

var rangebreaksIn = ax.rangebreaks.slice().sort(function(a, b) {
if(a.pattern === '%w' && b.pattern === '%H') return -1;
else if(b.pattern === '%w' && a.pattern === '%H') return 1;
if(a.pattern === WEEKDAY_PATTERN && b.pattern === HOUR_PATTERN) return -1;
if(b.pattern === WEEKDAY_PATTERN && a.pattern === HOUR_PATTERN) return 1;
return 0;
});

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

switch(brk.pattern) {
case '%w':
case WEEKDAY_PATTERN:
b0 = bnds[0] + (op0 === '(' ? 1 : 0);
b1 = bnds[1];
r0Pattern = r0Date.getUTCDay();
Expand All @@ -771,7 +775,7 @@ module.exports = function setConvert(ax, fullLayout) {
r0Date.getUTCSeconds() * ONESEC -
r0Date.getUTCMilliseconds();
break;
case '%H':
case HOUR_PATTERN:
b0 = bnds[0];
b1 = bnds[1];
r0Pattern = r0Date.getUTCHours();
Expand Down
4 changes: 2 additions & 2 deletions test/image/mocks/axes_breaks-finance.json
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@
"rangeslider": { "visible": true },
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [ 6, 0 ]
},
{
Expand All @@ -376,7 +376,7 @@
"rangeslider": { "visible": true },
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [ 6, 0 ]
},
{
Expand Down
8 changes: 4 additions & 4 deletions test/image/mocks/axes_breaks-night_autorange-reversed.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
"xaxis": {
"rangebreaks": [
{
"pattern": "%H",
"pattern": "hour",
"bounds": [
18,
6
Expand All @@ -208,7 +208,7 @@
"xaxis2": {
"rangebreaks": [
{
"pattern": "%H",
"pattern": "hour",
"bounds": [
18,
6
Expand Down Expand Up @@ -253,7 +253,7 @@
"yaxis3": {
"rangebreaks": [
{
"pattern": "%H",
"pattern": "hour",
"bounds": [
18,
6
Expand All @@ -270,7 +270,7 @@
"yaxis4": {
"rangebreaks": [
{
"pattern": "%H",
"pattern": "hour",
"bounds": [
18,
6
Expand Down
8 changes: 4 additions & 4 deletions test/image/mocks/axes_breaks-rangeslider.json
Original file line number Diff line number Diff line change
Expand Up @@ -2654,22 +2654,22 @@
"tickfont": {"size": 8},
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [6, 0],
"operation": "[]"
},
{
"pattern": "%H",
"pattern": "hour",
"bounds": [0, 9],
"operation": "()"
},
{
"pattern": "%H",
"pattern": "hour",
"bounds": [12, 13],
"operation": "()"
},
{
"pattern": "%H",
"pattern": "hour",
"bounds": [15, 21],
"operation": "()"
}
Expand Down
4 changes: 2 additions & 2 deletions test/image/mocks/axes_breaks-weekends-weeknights.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
"xaxis": {
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [ 6, 0 ],
"operation": "[]"
},
{
"pattern": "%H",
"pattern": "hour",
"bounds": [ 16, 8 ],
"operation": "()"
}
Expand Down
8 changes: 4 additions & 4 deletions test/image/mocks/axes_breaks-weekends_autorange-reversed.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"xaxis": {
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [
6,
0
Expand All @@ -104,7 +104,7 @@
"xaxis2": {
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [
6,
0
Expand Down Expand Up @@ -149,7 +149,7 @@
"yaxis3": {
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [
6,
0
Expand All @@ -166,7 +166,7 @@
"yaxis4": {
"rangebreaks": [
{
"pattern": "%w",
"pattern": "day of week",
"bounds": [
6,
0
Expand Down
Loading