Skip to content

Commit ecda2d4

Browse files
yauhen-kavaliouapalchys
authored andcommitted
add tests for tickformatstops
1 parent a13c29e commit ecda2d4

File tree

3 files changed

+342
-2
lines changed

3 files changed

+342
-2
lines changed

src/plots/cartesian/axes.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1516,8 +1516,8 @@ axes.getTickFormat = function(ax) {
15161516
var convertFn = convert || function(x) { return x;};
15171517
var leftDtick = range[0];
15181518
var rightDtick = range[1];
1519-
return (leftDtick === null || convertFn(leftDtick) <= convertFn(dtick)) &&
1520-
(rightDtick === null || convertFn(rightDtick) >= convertFn(dtick));
1519+
return ((!leftDtick && typeof leftDtick !== 'number') || convertFn(leftDtick) <= convertFn(dtick)) &&
1520+
((!rightDtick && typeof rightDtick !== 'number') || convertFn(rightDtick) >= convertFn(dtick));
15211521
}
15221522
function getRangeWidth(range, convert) {
15231523
var convertFn = convert || function(x) { return x;};

test/image/mocks/tickformatstops.json

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"data": [
3+
{
4+
"x": ["2005-01","2005-02","2005-03","2005-04","2005-05","2005-06","2005-07"],
5+
"y": [-20,10,-5,0,5,-10,20]
6+
}
7+
],
8+
"layout": {
9+
"xaxis": {
10+
"tickformatstops": [
11+
{
12+
"dtickrange": [null, 1000],
13+
"value": "%H:%M:%S.%L ms"
14+
},
15+
{
16+
"dtickrange": [1000, 60000],
17+
"value": "%H:%M:%S s"
18+
},
19+
{
20+
"dtickrange": [60000, 3600000],
21+
"value": "%H:%M m"
22+
},
23+
{
24+
"dtickrange": [3600000, 86400000],
25+
"value": "%H:%M h"
26+
},
27+
{
28+
"dtickrange": [86400000, 604800000],
29+
"value": "%e. %b d"
30+
},
31+
{
32+
"dtickrange": [604800000, "M1"],
33+
"value": "%e. %b w"
34+
},
35+
{
36+
"dtickrange": ["M1", "M12"],
37+
"value": "%b '%y M"
38+
},
39+
{
40+
"dtickrange": ["M12", null],
41+
"value": "%Y Y"
42+
}
43+
]
44+
}
45+
}
46+
}
+294
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
var Plotly = require('@lib/index');
2+
var Lib = require('@src/lib');
3+
var Axes = require('@src/plots/cartesian/axes');
4+
var Fx = require('@src/components/fx');
5+
var d3 = require('d3');
6+
var createGraphDiv = require('../assets/create_graph_div');
7+
var destroyGraphDiv = require('../assets/destroy_graph_div');
8+
var selectButton = require('../assets/modebar_button');
9+
10+
var mock = require('@mocks/tickformatstops.json');
11+
12+
function getZoomInButton(gd) {
13+
return selectButton(gd._fullLayout._modeBar, 'zoomIn2d');
14+
}
15+
16+
function getZoomOutButton(gd) {
17+
return selectButton(gd._fullLayout._modeBar, 'zoomOut2d');
18+
}
19+
20+
function getFormatter(format) {
21+
return d3.time.format.utc(format);
22+
}
23+
24+
describe('Test Axes.getTickformat', function() {
25+
it('get proper tickformatstop for linear axis', function() {
26+
var lineartickformatstops = [
27+
{
28+
dtickrange: [null, 1],
29+
value: '.f2',
30+
},
31+
{
32+
dtickrange: [1, 100],
33+
value: '.f1',
34+
},
35+
{
36+
dtickrange: [100, null],
37+
value: 'g',
38+
}
39+
];
40+
expect(Axes.getTickFormat({
41+
type: 'linear',
42+
tickformatstops: lineartickformatstops,
43+
dtick: 0.1
44+
})).toEqual(lineartickformatstops[0].value);
45+
46+
expect(Axes.getTickFormat({
47+
type: 'linear',
48+
tickformatstops: lineartickformatstops,
49+
dtick: 1
50+
})).toEqual(lineartickformatstops[1].value);
51+
52+
expect(Axes.getTickFormat({
53+
type: 'linear',
54+
tickformatstops: lineartickformatstops,
55+
dtick: 99
56+
})).toEqual(lineartickformatstops[1].value);
57+
expect(Axes.getTickFormat({
58+
type: 'linear',
59+
tickformatstops: lineartickformatstops,
60+
dtick: 99999
61+
})).toEqual(lineartickformatstops[2].value);
62+
});
63+
64+
it('get proper tickformatstop for date axis', function() {
65+
var MILLISECOND = 1;
66+
var SECOND = MILLISECOND * 1000;
67+
var MINUTE = SECOND * 60;
68+
var HOUR = MINUTE * 60;
69+
var DAY = HOUR * 24;
70+
var WEEK = DAY * 7;
71+
var MONTH = 'M1'; // or YEAR / 12;
72+
var YEAR = 'M12'; // or 365.25 * DAY;
73+
var datetickformatstops = [
74+
{
75+
dtickrange: [null, SECOND],
76+
value: '%H:%M:%S.%L ms' // millisecond
77+
},
78+
{
79+
dtickrange: [SECOND, MINUTE],
80+
value: '%H:%M:%S s' // second
81+
},
82+
{
83+
dtickrange: [MINUTE, HOUR],
84+
value: '%H:%M m' // minute
85+
},
86+
{
87+
dtickrange: [HOUR, DAY],
88+
value: '%H:%M h' // hour
89+
},
90+
{
91+
dtickrange: [DAY, WEEK],
92+
value: '%e. %b d' // day
93+
},
94+
{
95+
dtickrange: [WEEK, MONTH],
96+
value: '%e. %b w' // week
97+
},
98+
{
99+
dtickrange: [MONTH, YEAR],
100+
value: '%b \'%y M' // month
101+
},
102+
{
103+
dtickrange: [YEAR, null],
104+
value: '%Y Y' // year
105+
}
106+
];
107+
expect(Axes.getTickFormat({
108+
type: 'date',
109+
tickformatstops: datetickformatstops,
110+
dtick: 100
111+
})).toEqual(datetickformatstops[0].value); // millisecond
112+
113+
expect(Axes.getTickFormat({
114+
type: 'date',
115+
tickformatstops: datetickformatstops,
116+
dtick: 1000
117+
})).toEqual(datetickformatstops[1].value); // second
118+
119+
expect(Axes.getTickFormat({
120+
type: 'date',
121+
tickformatstops: datetickformatstops,
122+
dtick: 1000 * 60 * 60 * 3 // three hours
123+
})).toEqual(datetickformatstops[3].value); // hour
124+
125+
expect(Axes.getTickFormat({
126+
type: 'date',
127+
tickformatstops: datetickformatstops,
128+
dtick: 1000 * 60 * 60 * 24 * 7 * 2 // two weeks
129+
})).toEqual(datetickformatstops[5].value); // week
130+
131+
expect(Axes.getTickFormat({
132+
type: 'date',
133+
tickformatstops: datetickformatstops,
134+
dtick: 'M1'
135+
})).toEqual(datetickformatstops[6].value); // month
136+
137+
expect(Axes.getTickFormat({
138+
type: 'date',
139+
tickformatstops: datetickformatstops,
140+
dtick: 'M5'
141+
})).toEqual(datetickformatstops[6].value); // month
142+
143+
expect(Axes.getTickFormat({
144+
type: 'date',
145+
tickformatstops: datetickformatstops,
146+
dtick: 'M24'
147+
})).toEqual(datetickformatstops[7].value); // year
148+
});
149+
150+
it('get proper tickformatstop for log axis', function() {
151+
var logtickformatstops = [
152+
{
153+
dtickrange: [null, 'L0.01'],
154+
value: '.f3',
155+
},
156+
{
157+
dtickrange: ['L0.01', 'L1'],
158+
value: '.f2',
159+
},
160+
{
161+
dtickrange: ['D1', 'D2'],
162+
value: '.f1',
163+
},
164+
{
165+
dtickrange: [1, null],
166+
value: 'g'
167+
}
168+
];
169+
expect(Axes.getTickFormat({
170+
type: 'log',
171+
tickformatstops: logtickformatstops,
172+
dtick: 'L0.0001'
173+
})).toEqual(logtickformatstops[0].value);
174+
175+
expect(Axes.getTickFormat({
176+
type: 'log',
177+
tickformatstops: logtickformatstops,
178+
dtick: 'L0.1'
179+
})).toEqual(logtickformatstops[1].value);
180+
181+
expect(Axes.getTickFormat({
182+
type: 'log',
183+
tickformatstops: logtickformatstops,
184+
dtick: 'L2'
185+
})).toEqual(undefined);
186+
expect(Axes.getTickFormat({
187+
type: 'log',
188+
tickformatstops: logtickformatstops,
189+
dtick: 'D2'
190+
})).toEqual(logtickformatstops[2].value);
191+
expect(Axes.getTickFormat({
192+
type: 'log',
193+
tickformatstops: logtickformatstops,
194+
dtick: 1
195+
})).toEqual(logtickformatstops[3].value);
196+
});
197+
});
198+
199+
describe('Test tickformatstops:', function() {
200+
201+
var mockCopy, gd;
202+
203+
beforeEach(function() {
204+
gd = createGraphDiv();
205+
mockCopy = Lib.extendDeep({}, mock);
206+
});
207+
208+
afterEach(destroyGraphDiv);
209+
210+
describe('Zooming-in until milliseconds zoom level', function() {
211+
it('Zoom in', function(done) {
212+
var promise = Plotly.plot(gd, mockCopy.data, mockCopy.layout);
213+
var zoomIn = function() {
214+
promise = promise.then(function() {
215+
getZoomInButton(gd).click();
216+
var xLabels = Axes.calcTicks(gd._fullLayout.xaxis);
217+
var formatter = getFormatter(Axes.getTickFormat(gd._fullLayout.xaxis));
218+
var expectedLabels = xLabels.map(function(d) {return formatter(new Date(d.x));});
219+
var actualLabels = xLabels.map(function(d) {return d.text;});
220+
expect(expectedLabels).toEqual(actualLabels);
221+
if(gd._fullLayout.xaxis.dtick > 1) {
222+
zoomIn();
223+
} else {
224+
done();
225+
}
226+
});
227+
};
228+
zoomIn();
229+
});
230+
});
231+
232+
describe('Zooming-out until years zoom level', function() {
233+
it('Zoom out', function(done) {
234+
var promise = Plotly.plot(gd, mockCopy.data, mockCopy.layout);
235+
236+
var zoomOut = function() {
237+
promise = promise.then(function() {
238+
getZoomOutButton(gd).click();
239+
var xLabels = Axes.calcTicks(gd._fullLayout.xaxis);
240+
var formatter = getFormatter(Axes.getTickFormat(gd._fullLayout.xaxis));
241+
var expectedLabels = xLabels.map(function(d) {return formatter(new Date(d.x));});
242+
var actualLabels = xLabels.map(function(d) {return d.text;});
243+
expect(expectedLabels).toEqual(actualLabels);
244+
if(typeof gd._fullLayout.xaxis.dtick === 'number' ||
245+
typeof gd._fullLayout.xaxis.dtick === 'string' && parseInt(gd._fullLayout.xaxis.dtick.replace(/\D/g, '')) < 48) {
246+
zoomOut();
247+
} else {
248+
done();
249+
}
250+
});
251+
};
252+
zoomOut();
253+
});
254+
});
255+
256+
describe('Check tickformatstops for hover', function() {
257+
'use strict';
258+
259+
var evt = { xpx: 270, ypx: 10 };
260+
261+
afterEach(destroyGraphDiv);
262+
263+
beforeEach(function() {
264+
gd = createGraphDiv();
265+
mockCopy = Lib.extendDeep({}, mock);
266+
});
267+
268+
describe('hover info', function() {
269+
270+
it('responds to hover', function(done) {
271+
var mockCopy = Lib.extendDeep({}, mock);
272+
273+
Plotly.plot(gd, mockCopy.data, mockCopy.layout).then(function() {
274+
Fx.hover(gd, evt, 'xy');
275+
276+
var hoverTrace = gd._hoverdata[0];
277+
var formatter = getFormatter(Axes.getTickFormat(gd._fullLayout.xaxis));
278+
279+
expect(hoverTrace.curveNumber).toEqual(0);
280+
expect(hoverTrace.pointNumber).toEqual(3);
281+
expect(hoverTrace.x).toEqual('2005-04-01');
282+
expect(hoverTrace.y).toEqual(0);
283+
284+
expect(d3.selectAll('g.axistext').size()).toEqual(1);
285+
expect(d3.selectAll('g.hovertext').size()).toEqual(1);
286+
expect(d3.selectAll('g.axistext').select('text').html()).toEqual(formatter(new Date(hoverTrace.x)));
287+
expect(d3.selectAll('g.hovertext').select('text').html()).toEqual('0');
288+
done();
289+
});
290+
});
291+
});
292+
});
293+
294+
});

0 commit comments

Comments
 (0)