1
1
var Plotly = require ( '@lib/index' ) ;
2
+ var d3 = require ( 'd3' ) ;
2
3
3
4
var Plots = require ( '@src/plots/plots' ) ;
4
5
var Lib = require ( '@src/lib' ) ;
@@ -7,10 +8,12 @@ var tinycolor = require('tinycolor2');
7
8
8
9
var handleTickValueDefaults = require ( '@src/plots/cartesian/tick_value_defaults' ) ;
9
10
var Axes = require ( '@src/plots/cartesian/axes' ) ;
11
+ var Fx = require ( '@src/components/fx' ) ;
10
12
11
13
var createGraphDiv = require ( '../assets/create_graph_div' ) ;
12
14
var destroyGraphDiv = require ( '../assets/destroy_graph_div' ) ;
13
15
var failTest = require ( '../assets/fail_test' ) ;
16
+ var selectButton = require ( '../assets/modebar_button' ) ;
14
17
15
18
16
19
describe ( 'Test axes' , function ( ) {
@@ -2481,3 +2484,301 @@ describe('Test axes', function() {
2481
2484
} ) ;
2482
2485
} ) ;
2483
2486
} ) ;
2487
+
2488
+ function getZoomInButton ( gd ) {
2489
+ return selectButton ( gd . _fullLayout . _modeBar , 'zoomIn2d' ) ;
2490
+ }
2491
+
2492
+ function getZoomOutButton ( gd ) {
2493
+ return selectButton ( gd . _fullLayout . _modeBar , 'zoomOut2d' ) ;
2494
+ }
2495
+
2496
+ function getFormatter ( format ) {
2497
+ return d3 . time . format . utc ( format ) ;
2498
+ }
2499
+
2500
+ describe ( 'Test Axes.getTickformat' , function ( ) {
2501
+ 'use strict' ;
2502
+
2503
+ it ( 'get proper tickformatstop for linear axis' , function ( ) {
2504
+ var lineartickformatstops = [
2505
+ {
2506
+ dtickrange : [ null , 1 ] ,
2507
+ value : '.f2' ,
2508
+ } ,
2509
+ {
2510
+ dtickrange : [ 1 , 100 ] ,
2511
+ value : '.f1' ,
2512
+ } ,
2513
+ {
2514
+ dtickrange : [ 100 , null ] ,
2515
+ value : 'g' ,
2516
+ }
2517
+ ] ;
2518
+ expect ( Axes . getTickFormat ( {
2519
+ type : 'linear' ,
2520
+ tickformatstops : lineartickformatstops ,
2521
+ dtick : 0.1
2522
+ } ) ) . toEqual ( lineartickformatstops [ 0 ] . value ) ;
2523
+
2524
+ expect ( Axes . getTickFormat ( {
2525
+ type : 'linear' ,
2526
+ tickformatstops : lineartickformatstops ,
2527
+ dtick : 1
2528
+ } ) ) . toEqual ( lineartickformatstops [ 0 ] . value ) ;
2529
+
2530
+ expect ( Axes . getTickFormat ( {
2531
+ type : 'linear' ,
2532
+ tickformatstops : lineartickformatstops ,
2533
+ dtick : 99
2534
+ } ) ) . toEqual ( lineartickformatstops [ 1 ] . value ) ;
2535
+ expect ( Axes . getTickFormat ( {
2536
+ type : 'linear' ,
2537
+ tickformatstops : lineartickformatstops ,
2538
+ dtick : 99999
2539
+ } ) ) . toEqual ( lineartickformatstops [ 2 ] . value ) ;
2540
+ } ) ;
2541
+
2542
+ it ( 'get proper tickformatstop for date axis' , function ( ) {
2543
+ var MILLISECOND = 1 ;
2544
+ var SECOND = MILLISECOND * 1000 ;
2545
+ var MINUTE = SECOND * 60 ;
2546
+ var HOUR = MINUTE * 60 ;
2547
+ var DAY = HOUR * 24 ;
2548
+ var WEEK = DAY * 7 ;
2549
+ var MONTH = 'M1' ; // or YEAR / 12;
2550
+ var YEAR = 'M12' ; // or 365.25 * DAY;
2551
+ var datetickformatstops = [
2552
+ {
2553
+ dtickrange : [ null , SECOND ] ,
2554
+ value : '%H:%M:%S.%L ms' // millisecond
2555
+ } ,
2556
+ {
2557
+ dtickrange : [ SECOND , MINUTE ] ,
2558
+ value : '%H:%M:%S s' // second
2559
+ } ,
2560
+ {
2561
+ dtickrange : [ MINUTE , HOUR ] ,
2562
+ value : '%H:%M m' // minute
2563
+ } ,
2564
+ {
2565
+ dtickrange : [ HOUR , DAY ] ,
2566
+ value : '%H:%M h' // hour
2567
+ } ,
2568
+ {
2569
+ dtickrange : [ DAY , WEEK ] ,
2570
+ value : '%e. %b d' // day
2571
+ } ,
2572
+ {
2573
+ dtickrange : [ WEEK , MONTH ] ,
2574
+ value : '%e. %b w' // week
2575
+ } ,
2576
+ {
2577
+ dtickrange : [ MONTH , YEAR ] ,
2578
+ value : '%b \'%y M' // month
2579
+ } ,
2580
+ {
2581
+ dtickrange : [ YEAR , null ] ,
2582
+ value : '%Y Y' // year
2583
+ }
2584
+ ] ;
2585
+ expect ( Axes . getTickFormat ( {
2586
+ type : 'date' ,
2587
+ tickformatstops : datetickformatstops ,
2588
+ dtick : 100
2589
+ } ) ) . toEqual ( datetickformatstops [ 0 ] . value ) ; // millisecond
2590
+
2591
+ expect ( Axes . getTickFormat ( {
2592
+ type : 'date' ,
2593
+ tickformatstops : datetickformatstops ,
2594
+ dtick : 1000
2595
+ } ) ) . toEqual ( datetickformatstops [ 0 ] . value ) ; // millisecond
2596
+
2597
+ expect ( Axes . getTickFormat ( {
2598
+ type : 'date' ,
2599
+ tickformatstops : datetickformatstops ,
2600
+ dtick : 1000 * 60 * 60 * 3 // three hours
2601
+ } ) ) . toEqual ( datetickformatstops [ 3 ] . value ) ; // hour
2602
+
2603
+ expect ( Axes . getTickFormat ( {
2604
+ type : 'date' ,
2605
+ tickformatstops : datetickformatstops ,
2606
+ dtick : 1000 * 60 * 60 * 24 * 7 * 2 // two weeks
2607
+ } ) ) . toEqual ( datetickformatstops [ 5 ] . value ) ; // week
2608
+
2609
+ expect ( Axes . getTickFormat ( {
2610
+ type : 'date' ,
2611
+ tickformatstops : datetickformatstops ,
2612
+ dtick : 'M1'
2613
+ } ) ) . toEqual ( datetickformatstops [ 5 ] . value ) ; // week
2614
+
2615
+ expect ( Axes . getTickFormat ( {
2616
+ type : 'date' ,
2617
+ tickformatstops : datetickformatstops ,
2618
+ dtick : 'M5'
2619
+ } ) ) . toEqual ( datetickformatstops [ 6 ] . value ) ; // month
2620
+
2621
+ expect ( Axes . getTickFormat ( {
2622
+ type : 'date' ,
2623
+ tickformatstops : datetickformatstops ,
2624
+ dtick : 'M24'
2625
+ } ) ) . toEqual ( datetickformatstops [ 7 ] . value ) ; // year
2626
+ } ) ;
2627
+
2628
+ it ( 'get proper tickformatstop for log axis' , function ( ) {
2629
+ var logtickformatstops = [
2630
+ {
2631
+ dtickrange : [ null , 'L0.01' ] ,
2632
+ value : '.f3' ,
2633
+ } ,
2634
+ {
2635
+ dtickrange : [ 'L0.01' , 'L1' ] ,
2636
+ value : '.f2' ,
2637
+ } ,
2638
+ {
2639
+ dtickrange : [ 'D1' , 'D2' ] ,
2640
+ value : '.f1' ,
2641
+ } ,
2642
+ {
2643
+ dtickrange : [ 1 , null ] ,
2644
+ value : 'g'
2645
+ }
2646
+ ] ;
2647
+ expect ( Axes . getTickFormat ( {
2648
+ type : 'log' ,
2649
+ tickformatstops : logtickformatstops ,
2650
+ dtick : 'L0.0001'
2651
+ } ) ) . toEqual ( logtickformatstops [ 0 ] . value ) ;
2652
+
2653
+ expect ( Axes . getTickFormat ( {
2654
+ type : 'log' ,
2655
+ tickformatstops : logtickformatstops ,
2656
+ dtick : 'L0.1'
2657
+ } ) ) . toEqual ( logtickformatstops [ 1 ] . value ) ;
2658
+
2659
+ expect ( Axes . getTickFormat ( {
2660
+ type : 'log' ,
2661
+ tickformatstops : logtickformatstops ,
2662
+ dtick : 'L2'
2663
+ } ) ) . toEqual ( undefined ) ;
2664
+ expect ( Axes . getTickFormat ( {
2665
+ type : 'log' ,
2666
+ tickformatstops : logtickformatstops ,
2667
+ dtick : 'D2'
2668
+ } ) ) . toEqual ( logtickformatstops [ 2 ] . value ) ;
2669
+ expect ( Axes . getTickFormat ( {
2670
+ type : 'log' ,
2671
+ tickformatstops : logtickformatstops ,
2672
+ dtick : 1
2673
+ } ) ) . toEqual ( logtickformatstops [ 3 ] . value ) ;
2674
+ } ) ;
2675
+ } ) ;
2676
+
2677
+ describe ( 'Test tickformatstops:' , function ( ) {
2678
+ 'use strict' ;
2679
+
2680
+ var mock = require ( '@mocks/tickformatstops.json' ) ;
2681
+
2682
+ var mockCopy , gd ;
2683
+
2684
+ beforeEach ( function ( ) {
2685
+ gd = createGraphDiv ( ) ;
2686
+ mockCopy = Lib . extendDeep ( { } , mock ) ;
2687
+ } ) ;
2688
+
2689
+ afterEach ( destroyGraphDiv ) ;
2690
+
2691
+ it ( 'handles zooming-in until milliseconds zoom level' , function ( done ) {
2692
+ var promise = Plotly . plot ( gd , mockCopy . data , mockCopy . layout ) ;
2693
+
2694
+ var testCount = 0 ;
2695
+
2696
+ var zoomIn = function ( ) {
2697
+ promise = promise . then ( function ( ) {
2698
+ getZoomInButton ( gd ) . click ( ) ;
2699
+ var xLabels = Axes . calcTicks ( gd . _fullLayout . xaxis ) ;
2700
+ var formatter = getFormatter ( Axes . getTickFormat ( gd . _fullLayout . xaxis ) ) ;
2701
+ var expectedLabels = xLabels . map ( function ( d ) { return formatter ( new Date ( d . x ) ) ; } ) ;
2702
+ var actualLabels = xLabels . map ( function ( d ) { return d . text ; } ) ;
2703
+ expect ( expectedLabels ) . toEqual ( actualLabels ) ;
2704
+ testCount ++ ;
2705
+
2706
+ if ( gd . _fullLayout . xaxis . dtick > 1 ) {
2707
+ zoomIn ( ) ;
2708
+ } else {
2709
+ // make sure we tested as many levels as we thought we would
2710
+ expect ( testCount ) . toBe ( 32 ) ;
2711
+ done ( ) ;
2712
+ }
2713
+ } ) ;
2714
+ } ;
2715
+ zoomIn ( ) ;
2716
+ } ) ;
2717
+
2718
+ it ( 'handles zooming-out until years zoom level' , function ( done ) {
2719
+ var promise = Plotly . plot ( gd , mockCopy . data , mockCopy . layout ) ;
2720
+
2721
+ var testCount = 0 ;
2722
+
2723
+ var zoomOut = function ( ) {
2724
+ promise = promise . then ( function ( ) {
2725
+ getZoomOutButton ( gd ) . click ( ) ;
2726
+ var xLabels = Axes . calcTicks ( gd . _fullLayout . xaxis ) ;
2727
+ var formatter = getFormatter ( Axes . getTickFormat ( gd . _fullLayout . xaxis ) ) ;
2728
+ var expectedLabels = xLabels . map ( function ( d ) { return formatter ( new Date ( d . x ) ) ; } ) ;
2729
+ var actualLabels = xLabels . map ( function ( d ) { return d . text ; } ) ;
2730
+ expect ( expectedLabels ) . toEqual ( actualLabels ) ;
2731
+ testCount ++ ;
2732
+
2733
+ if ( typeof gd . _fullLayout . xaxis . dtick === 'number' ||
2734
+ typeof gd . _fullLayout . xaxis . dtick === 'string' && parseInt ( gd . _fullLayout . xaxis . dtick . replace ( / \D / g, '' ) ) < 48 ) {
2735
+ zoomOut ( ) ;
2736
+ } else {
2737
+ // make sure we tested as many levels as we thought we would
2738
+ expect ( testCount ) . toBe ( 5 ) ;
2739
+ done ( ) ;
2740
+ }
2741
+ } ) ;
2742
+ } ;
2743
+ zoomOut ( ) ;
2744
+ } ) ;
2745
+
2746
+ it ( 'responds to hover' , function ( done ) {
2747
+ var evt = { xpx : 270 , ypx : 10 } ;
2748
+
2749
+ Plotly . plot ( gd , mockCopy . data , mockCopy . layout ) . then ( function ( ) {
2750
+ Fx . hover ( gd , evt , 'xy' ) ;
2751
+
2752
+ var hoverTrace = gd . _hoverdata [ 0 ] ;
2753
+ var formatter = getFormatter ( Axes . getTickFormat ( gd . _fullLayout . xaxis ) ) ;
2754
+
2755
+ expect ( hoverTrace . curveNumber ) . toEqual ( 0 ) ;
2756
+ expect ( hoverTrace . pointNumber ) . toEqual ( 3 ) ;
2757
+ expect ( hoverTrace . x ) . toEqual ( '2005-04-01' ) ;
2758
+ expect ( hoverTrace . y ) . toEqual ( 0 ) ;
2759
+
2760
+ expect ( d3 . selectAll ( 'g.axistext' ) . size ( ) ) . toEqual ( 1 ) ;
2761
+ expect ( d3 . selectAll ( 'g.hovertext' ) . size ( ) ) . toEqual ( 1 ) ;
2762
+ expect ( d3 . selectAll ( 'g.axistext' ) . select ( 'text' ) . html ( ) ) . toEqual ( formatter ( new Date ( hoverTrace . x ) ) ) ;
2763
+ expect ( d3 . selectAll ( 'g.hovertext' ) . select ( 'text' ) . html ( ) ) . toEqual ( '0' ) ;
2764
+ } )
2765
+ . catch ( failTest )
2766
+ . then ( done ) ;
2767
+ } ) ;
2768
+
2769
+ it ( 'doesn\'t fail on bad input' , function ( done ) {
2770
+ var promise = Plotly . plot ( gd , mockCopy . data , mockCopy . layout ) ;
2771
+
2772
+ [ 1 , { a : 1 , b : 2 } , 'boo' ] . forEach ( function ( v ) {
2773
+ promise = promise . then ( function ( ) {
2774
+ return Plotly . relayout ( gd , { 'xaxis.tickformatstops' : v } ) ;
2775
+ } ) . then ( function ( ) {
2776
+ expect ( gd . _fullLayout . xaxis . tickformatstops ) . toEqual ( [ ] ) ;
2777
+ } ) ;
2778
+ } ) ;
2779
+
2780
+ promise
2781
+ . catch ( failTest )
2782
+ . then ( done ) ;
2783
+ } ) ;
2784
+ } ) ;
0 commit comments