Skip to content

Commit 83b22a0

Browse files
committed
apply AlexJ's suggestion to use Lib.incrementMonth and simplify case of milliseconds
1 parent 5ae9e1e commit 83b22a0

10 files changed

+136
-76
lines changed

src/plots/cartesian/align_period.js

+35-37
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
var isNumeric = require('fast-isnumeric');
1212
var Lib = require('../../lib');
13-
var ms2DateTime = Lib.ms2DateTime;
1413
var dateTime2ms = Lib.dateTime2ms;
1514
var incrementMonth = Lib.incrementMonth;
16-
var ONEDAY = require('../../constants/numerical').ONEDAY;
15+
var constants = require('../../constants/numerical');
16+
var ONEAVGMONTH = constants.ONEAVGMONTH;
1717

1818
module.exports = function alignPeriod(trace, ax, axLetter, vals) {
1919
if(ax.type !== 'date') return vals;
@@ -22,12 +22,10 @@ module.exports = function alignPeriod(trace, ax, axLetter, vals) {
2222
if(!alignment) return vals;
2323

2424
var period = trace[axLetter + 'period'];
25-
var mPeriod, dPeriod;
25+
var mPeriod;
2626
if(isNumeric(period)) {
27-
dPeriod = +period;
28-
dPeriod /= ONEDAY; // convert milliseconds to days
29-
dPeriod = Math.round(dPeriod);
30-
if(dPeriod <= 0) return vals;
27+
period = +period;
28+
if(period <= 0) return vals;
3129
} else if(typeof period === 'string' && period.charAt(0) === 'M') {
3230
var n = +(period.substring(1));
3331
if(n > 0 && Math.round(n) === n) {
@@ -47,46 +45,46 @@ module.exports = function alignPeriod(trace, ax, axLetter, vals) {
4745
var newVals = [];
4846
var len = vals.length;
4947
for(var i = 0; i < len; i++) {
50-
var v = vals[i] - base;
51-
52-
var dateStr = ms2DateTime(v, 0, calendar);
53-
var d = new Date(dateStr);
54-
var year = d.getUTCFullYear();
55-
var month = d.getUTCMonth();
56-
var day = d.getUTCDate();
57-
58-
var startTime, endTime;
59-
if(dPeriod) {
60-
startTime = Date.UTC(year, month, day);
61-
endTime = startTime + dPeriod * ONEDAY;
62-
}
48+
var v = vals[i];
6349

50+
var nEstimated, startTime, endTime;
6451
if(mPeriod) {
65-
var nYears = Math.floor(mPeriod / 12);
66-
var nMonths = mPeriod % 12;
52+
// guess at how many periods away from base we are
53+
nEstimated = Math.round((v - base) / (mPeriod * ONEAVGMONTH));
54+
endTime = incrementMonth(base, mPeriod * nEstimated, calendar);
55+
56+
// iterate to get the exact bounds before and after v
57+
// there may be ways to make this faster, but most of the time
58+
// we'll only execute each loop zero or one time.
59+
while(endTime > v) {
60+
endTime = incrementMonth(endTime, -mPeriod, calendar);
61+
}
62+
while(endTime <= v) {
63+
endTime = incrementMonth(endTime, mPeriod, calendar);
64+
}
65+
66+
// now we know endTime is the boundary immediately after v
67+
// so startTime is obtained by incrementing backward one period.
68+
startTime = incrementMonth(endTime, -mPeriod, calendar);
69+
} else { // case of ms
70+
nEstimated = Math.round((v - base) / period);
71+
endTime = base + nEstimated * period;
6772

68-
if(nMonths) {
69-
startTime = Date.UTC(year, nYears ? month : roundMonth(month, nMonths));
70-
endTime = incrementMonth(startTime, mPeriod, calendar);
71-
} else {
72-
startTime = Date.UTC(year, 0);
73-
endTime = Date.UTC(year + nYears, 0);
73+
while(endTime > v) {
74+
endTime -= period;
7475
}
76+
while(endTime <= v) {
77+
endTime += period;
78+
}
79+
80+
startTime = endTime - period;
7581
}
7682

77-
var newD = new Date(
83+
newVals[i] = (
7884
isStart ? startTime :
7985
isEnd ? endTime :
8086
(startTime + endTime) / 2
8187
);
82-
83-
newVals[i] = newD.getTime() + base;
8488
}
8589
return newVals;
8690
};
87-
88-
var monthSteps = [2, 3, 4, 6];
89-
90-
function roundMonth(month, step) {
91-
return (monthSteps.indexOf(step) === -1) ? month : Math.floor(month / step) * step;
92-
}

src/traces/scatter/attributes.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ function axisPeriod(axis) {
2929
'Only relevant when the axis `type` is *date*.',
3030
'Sets the period positioning in milliseconds or *M<n>* on the ' + axis + ' axis.',
3131
'Special values in the form of *M<n>* could be used to declare',
32-
'the number of "average" months. In this case `n` must be a positive integer.',
33-
'When using milliseconds the period is rounded and applied as the number of days.'
32+
'the number of "average" months. In this case `n` must be a positive integer.'
3433
].join(' ')
3534
};
3635
}
-2.02 KB
Loading
11.5 KB
Loading
452 Bytes
Loading
269 Bytes
Loading

test/image/mocks/period_positioning3.json

+15-9
Original file line numberDiff line numberDiff line change
@@ -158,31 +158,34 @@
158158
{
159159
"xaxis": "x6",
160160
"yaxis": "y6",
161-
"xperiod": 31557600000,
162-
"name": "start (AVG-YEAR)",
161+
"xperiod": 604800000,
162+
"name": "start (W1)",
163163
"type": "scatter",
164164
"y": [1, 2, 3, 4, 5, 6],
165-
"x": ["2001-01-01", "2002-01-01", "2003-01-01", "2004-01-01", "2005-01-01", "2006-01-01"],
165+
"x": ["2001-01-01", "2001-01-08", "2001-01-15", "2001-01-22", "2001-01-29", "2001-02-05"],
166+
"xperiod0": "2001-01-01",
166167
"xperiodalignment": "start"
167168
},
168169
{
169170
"xaxis": "x6",
170171
"yaxis": "y6",
171-
"xperiod": 31557600000,
172-
"name": "middle (AVG-YEAR)",
172+
"xperiod": 604800000,
173+
"name": "bar (W1)",
173174
"type": "bar",
174175
"y": [1, 2, 3, 4, 5, 6],
175-
"x": ["2001-01-01", "2002-01-01", "2003-01-01", "2004-01-01", "2005-01-01", "2006-01-01"],
176+
"x": ["2001-01-01", "2001-01-08", "2001-01-15", "2001-01-22", "2001-01-29", "2001-02-05"],
177+
"xperiod0": "2001-01-01",
176178
"xperiodalignment": "middle"
177179
},
178180
{
179181
"xaxis": "x6",
180182
"yaxis": "y6",
181-
"xperiod": 31557600000,
182-
"name": "end (AVG-YEAR)",
183+
"xperiod": 604800000,
184+
"name": "start (W1)",
183185
"type": "scatter",
184186
"y": [1, 2, 3, 4, 5, 6],
185-
"x": ["2001-01-01", "2002-01-01", "2003-01-01", "2004-01-01", "2005-01-01", "2006-01-01"],
187+
"x": ["2001-01-01", "2001-01-08", "2001-01-15", "2001-01-22", "2001-01-29", "2001-02-05"],
188+
"xperiod0": "2001-01-01",
186189
"xperiodalignment": "end"
187190
}
188191
],
@@ -248,7 +251,10 @@
248251
]
249252
},
250253
"xaxis6": {
254+
"dtick": 604800000,
255+
"tick0": "2001-01-01",
251256
"ticklabelmode": "period",
257+
"tickformat": "W%V",
252258
"tickcolor": "black",
253259
"anchor": "y6",
254260
"domain": [

test/image/mocks/period_positioning4.json

+23-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"marker": { "opacity": 0.5 }, "type": "bar",
1919
"y": [1, 2, 3, 4, 5, 6],
2020
"x": ["2001-01-01", "2001-01-15", "2001-02-01", "2001-02-15", "2001-03-01", "2001-03-15"],
21+
"textposition": "inside", "textangle": 0, "texttemplate": "%{x|%b-%e}",
2122
"xperiodalignment": "middle"
2223
},
2324
{
@@ -49,6 +50,7 @@
4950
"marker": { "opacity": 0.5 }, "type": "bar",
5051
"y": [1, 2, 3, 4, 5, 6],
5152
"x": ["2001-01-01", "2001-02-01", "2001-03-01", "2001-04-01", "2001-05-01", "2001-06-01"],
53+
"textposition": "inside", "textangle": 0, "texttemplate": "%{x|%b-%e}",
5254
"xperiodalignment": "middle"
5355
},
5456
{
@@ -80,6 +82,7 @@
8082
"marker": { "opacity": 0.5 }, "type": "bar",
8183
"y": [1, 2, 3, 4, 5, 6],
8284
"x": ["2001-01-01", "2001-02-15", "2001-04-01", "2001-05-15", "2001-07-01", "2001-08-15"],
85+
"textposition": "inside", "textangle": 0, "texttemplate": "%{x|%b-%e}",
8386
"xperiodalignment": "middle"
8487
},
8588
{
@@ -111,6 +114,7 @@
111114
"marker": { "opacity": 0.5 }, "type": "bar",
112115
"y": [1, 2, 3, 4, 5, 6],
113116
"x": ["2001-01-01", "2001-04-01", "2001-07-01", "2001-10-01", "2002-01-01", "2002-04-01"],
117+
"textposition": "inside", "textangle": 0, "texttemplate": "%{x|%b-%e}",
114118
"xperiodalignment": "middle"
115119
},
116120
{
@@ -142,6 +146,7 @@
142146
"marker": { "opacity": 0.5 }, "type": "bar",
143147
"y": [1, 2, 3, 4, 5, 6],
144148
"x": ["2001-01-01", "2001-07-01", "2002-01-01", "2002-07-01", "2003-01-01", "2003-07-01"],
149+
"textposition": "inside", "textangle": 0, "texttemplate": "%{x|%b-%e}",
145150
"xperiodalignment": "middle"
146151
},
147152
{
@@ -158,31 +163,37 @@
158163
{
159164
"xaxis": "x6",
160165
"yaxis": "y6",
161-
"xperiod": 31557600000,
162-
"name": "start (AVG-YEAR)",
166+
"xperiod": 604800000,
167+
"name": "start (W1)",
163168
"marker": { "opacity": 0.5 }, "type": "scatter",
164169
"y": [1, 2, 3, 4, 5, 6],
165-
"x": ["2001-01-01", "2001-07-01", "2002-01-01", "2002-07-01", "2003-01-01", "2003-07-01"],
170+
"x": ["2001-01-01", "2001-01-05", "2001-01-08", "2001-01-12", "2001-01-15", "2001-01-19"],
171+
"xperiod0": "2001-01-01",
166172
"xperiodalignment": "start"
167173
},
168174
{
169175
"xaxis": "x6",
170176
"yaxis": "y6",
171-
"xperiod": 31557600000,
172-
"name": "middle (AVG-YEAR)",
177+
"xperiod": 604800000,
178+
"name": "middle (W1)",
173179
"marker": { "opacity": 0.5 }, "type": "bar",
174180
"y": [1, 2, 3, 4, 5, 6],
175-
"x": ["2001-01-01", "2001-07-01", "2002-01-01", "2002-07-01", "2003-01-01", "2003-07-01"],
181+
"x": ["2001-01-01", "2001-01-05", "2001-01-08", "2001-01-12", "2001-01-15", "2001-01-19"],
182+
"textposition": "inside", "textangle": 0,
183+
"texttemplate": "%{x|%A}",
184+
"hovertemplate": "%{x|%A}, %{y}",
185+
"xperiod0": "2001-01-01",
176186
"xperiodalignment": "middle"
177187
},
178188
{
179189
"xaxis": "x6",
180190
"yaxis": "y6",
181-
"xperiod": 31557600000,
182-
"name": "end (AVG-YEAR)",
191+
"xperiod": 604800000,
192+
"name": "end (W1)",
183193
"marker": { "opacity": 0.5 }, "type": "scatter",
184194
"y": [1, 2, 3, 4, 5, 6],
185-
"x": ["2001-01-01", "2001-07-01", "2002-01-01", "2002-07-01", "2003-01-01", "2003-07-01"],
195+
"x": ["2001-01-01", "2001-01-05", "2001-01-08", "2001-01-12", "2001-01-15", "2001-01-19"],
196+
"xperiod0": "2001-01-01",
186197
"xperiodalignment": "end"
187198
}
188199
],
@@ -249,7 +260,10 @@
249260
]
250261
},
251262
"xaxis6": {
263+
"dtick": 604800000,
264+
"tick0": "2001-01-01",
252265
"ticklabelmode": "period",
266+
"tickformat": "W%V",
253267
"tickcolor": "black",
254268
"anchor": "y6",
255269
"domain": [

test/image/mocks/period_positioning5.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"name": "start (M9)",
88
"type": "scatter",
99
"y": [1, 2, 3, 4, 5, 6],
10-
"x": ["2001-01", "2001-10", "2002-07", "2003-04", "2004-01", "2004-09"],
10+
"x": ["2001-01", "2001-10", "2002-07", "2003-04", "2004-01", "2004-10"],
1111
"xperiod0": "2001-01-01",
1212
"xperiodalignment": "start"
1313
},
@@ -18,7 +18,7 @@
1818
"name": "middle (M9)",
1919
"type": "bar",
2020
"y": [1, 2, 3, 4, 5, 6],
21-
"x": ["2001-01", "2001-10", "2002-07", "2003-04", "2004-01", "2004-09"],
21+
"x": ["2001-01", "2001-10", "2002-07", "2003-04", "2004-01", "2004-10"],
2222
"xperiod0": "2001-01-01",
2323
"xperiodalignment": "middle"
2424
},
@@ -29,7 +29,7 @@
2929
"name": "end (M9)",
3030
"type": "scatter",
3131
"y": [1, 2, 3, 4, 5, 6],
32-
"x": ["2001-01", "2001-10", "2002-07", "2003-04", "2004-01", "2004-09"],
32+
"x": ["2001-01", "2001-10", "2002-07", "2003-04", "2004-01", "2004-10"],
3333
"xperiod0": "2001-01-01",
3434
"xperiodalignment": "end"
3535
},
@@ -75,7 +75,7 @@
7575
"name": "start (Y1.5)",
7676
"type": "scatter",
7777
"y": [1, 2, 3, 4, 5, 6],
78-
"x": ["2001-01", "2002-06", "2004-01", "2005-06", "2007-01", "2008-06"],
78+
"x": ["2001-01", "2002-07", "2004-01", "2005-07", "2007-01", "2008-07"],
7979
"xperiod0": "2001-01-01",
8080
"xperiodalignment": "start"
8181
},
@@ -86,7 +86,7 @@
8686
"name": "middle (Y1.5)",
8787
"type": "bar",
8888
"y": [1, 2, 3, 4, 5, 6],
89-
"x": ["2001-01", "2002-06", "2004-01", "2005-06", "2007-01", "2008-06"],
89+
"x": ["2001-01", "2002-07", "2004-01", "2005-07", "2007-01", "2008-07"],
9090
"xperiod0": "2001-01-01",
9191
"xperiodalignment": "middle"
9292
},
@@ -97,7 +97,7 @@
9797
"name": "end (Y1.5)",
9898
"type": "scatter",
9999
"y": [1, 2, 3, 4, 5, 6],
100-
"x": ["2001-01", "2002-06", "2004-01", "2005-06", "2007-01", "2008-06"],
100+
"x": ["2001-01", "2002-07", "2004-01", "2005-07", "2007-01", "2008-07"],
101101
"xperiod0": "2001-01-01",
102102
"xperiodalignment": "end"
103103
},

0 commit comments

Comments
 (0)