@@ -3,14 +3,19 @@ var Plots = require('@src/plots/plots');
3
3
var Lib = require ( '@src/lib' ) ;
4
4
5
5
var d3Select = require ( '../../strict-d3' ) . select ;
6
+ var d3SelectAll = require ( '../../strict-d3' ) . selectAll ;
6
7
var supplyAllDefaults = require ( '../assets/supply_defaults' ) ;
7
8
var createGraphDiv = require ( '../assets/create_graph_div' ) ;
8
9
var destroyGraphDiv = require ( '../assets/destroy_graph_div' ) ;
9
10
var mouseEvent = require ( '../assets/mouse_event' ) ;
11
+ var delay = require ( '../assets/delay' ) ;
10
12
11
13
var customAssertions = require ( '../assets/custom_assertions' ) ;
12
14
var assertHoverLabelStyle = customAssertions . assertHoverLabelStyle ;
13
15
var assertHoverLabelContent = customAssertions . assertHoverLabelContent ;
16
+ var checkTextTemplate = require ( '../assets/check_texttemplate' ) ;
17
+
18
+ var SLICES_SELECTOR = '.iciclelayer path.surface' ;
14
19
15
20
function _mouseEvent ( type , gd , v ) {
16
21
return function ( ) {
@@ -30,6 +35,10 @@ function hover(gd, v) {
30
35
return _mouseEvent ( 'mouseover' , gd , v ) ;
31
36
}
32
37
38
+ function click ( gd , v ) {
39
+ return _mouseEvent ( 'click' , gd , v ) ;
40
+ }
41
+
33
42
describe ( 'Test icicle defaults:' , function ( ) {
34
43
var gd ;
35
44
var fullData ;
@@ -680,3 +689,239 @@ describe('Test icicle hover:', function() {
680
689
} ) ;
681
690
} ) ;
682
691
} ) ;
692
+
693
+ describe ( 'Test icicle restyle:' , function ( ) {
694
+ var gd ;
695
+
696
+ beforeEach ( function ( ) { gd = createGraphDiv ( ) ; } ) ;
697
+
698
+ afterEach ( destroyGraphDiv ) ;
699
+
700
+ function _restyle ( updateObj ) {
701
+ return function ( ) { return Plotly . restyle ( gd , updateObj ) ; } ;
702
+ }
703
+
704
+ it ( 'should be able to toggle visibility' , function ( done ) {
705
+ var mock = Lib . extendDeep ( { } , require ( '@mocks/icicle_first.json' ) ) ;
706
+
707
+ function _assert ( msg , exp ) {
708
+ return function ( ) {
709
+ var layer = d3Select ( gd ) . select ( '.iciclelayer' ) ;
710
+ expect ( layer . selectAll ( '.trace' ) . size ( ) ) . toBe ( exp , msg ) ;
711
+ } ;
712
+ }
713
+
714
+ Plotly . newPlot ( gd , mock )
715
+ . then ( _assert ( 'base' , 2 ) )
716
+ . then ( _restyle ( { 'visible' : false } ) )
717
+ . then ( _assert ( 'both visible:false' , 0 ) )
718
+ . then ( _restyle ( { 'visible' : true } ) )
719
+ . then ( _assert ( 'back to visible:true' , 2 ) )
720
+ . then ( done , done . fail ) ;
721
+ } ) ;
722
+
723
+ it ( 'should be able to restyle *maxdepth* and *level* w/o recomputing the hierarchy' , function ( done ) {
724
+ var mock = Lib . extendDeep ( { } , require ( '@mocks/icicle_coffee.json' ) ) ;
725
+
726
+ function _assert ( msg , exp ) {
727
+ return function ( ) {
728
+ var layer = d3Select ( gd ) . select ( '.iciclelayer' ) ;
729
+
730
+ expect ( layer . selectAll ( '.slice' ) . size ( ) ) . toBe ( exp , msg ) ;
731
+
732
+ // editType:plot
733
+ if ( msg !== 'base' ) {
734
+ expect ( Plots . doCalcdata ) . toHaveBeenCalledTimes ( 0 ) ;
735
+ }
736
+ } ;
737
+ }
738
+
739
+ Plotly . newPlot ( gd , mock )
740
+ . then ( _assert ( 'base' , 97 ) )
741
+ . then ( function ( ) {
742
+ spyOn ( Plots , 'doCalcdata' ) . and . callThrough ( ) ;
743
+ } )
744
+ . then ( _restyle ( { maxdepth : 3 } ) )
745
+ . then ( _assert ( 'with maxdepth:3' , 97 ) )
746
+ . then ( _restyle ( { level : 'Aromas' } ) )
747
+ . then ( _assert ( 'with non-root level' , 67 ) )
748
+ . then ( _restyle ( { maxdepth : null , level : null } ) )
749
+ . then ( _assert ( 'back to first view' , 97 ) )
750
+ . then ( done , done . fail ) ;
751
+ } ) ;
752
+
753
+ it ( 'should be able to restyle *leaf.opacity*' , function ( done ) {
754
+ var mock = {
755
+ data : [ {
756
+ type : 'icicle' ,
757
+ labels : [ 'Root' , 'A' , 'B' , 'b' ] ,
758
+ parents : [ '' , 'Root' , 'Root' , 'B' ]
759
+ } ]
760
+ } ;
761
+
762
+ function _assert ( msg , exp ) {
763
+ return function ( ) {
764
+ var layer = d3Select ( gd ) . select ( '.iciclelayer' ) ;
765
+
766
+ var opacities = [ ] ;
767
+ layer . selectAll ( 'path.surface' ) . each ( function ( ) {
768
+ opacities . push ( this . style . opacity ) ;
769
+ } ) ;
770
+
771
+ expect ( opacities ) . toEqual ( exp , msg ) ;
772
+
773
+ // editType:style
774
+ if ( msg !== 'base' ) {
775
+ expect ( Plots . doCalcdata ) . toHaveBeenCalledTimes ( 0 ) ;
776
+ expect ( gd . _fullData [ 0 ] . _module . plot ) . toHaveBeenCalledTimes ( 0 ) ;
777
+ }
778
+ } ;
779
+ }
780
+
781
+ Plotly . newPlot ( gd , mock )
782
+ . then ( _assert ( 'base' , [ '' , '0.7' , '' , '0.7' ] ) )
783
+ . then ( function ( ) {
784
+ spyOn ( Plots , 'doCalcdata' ) . and . callThrough ( ) ;
785
+ spyOn ( gd . _fullData [ 0 ] . _module , 'plot' ) . and . callThrough ( ) ;
786
+ } )
787
+ . then ( _restyle ( { 'leaf.opacity' : 0.3 } ) )
788
+ . then ( _assert ( 'lower leaf.opacity' , [ '' , '0.3' , '' , '0.3' ] ) )
789
+ . then ( _restyle ( { 'leaf.opacity' : 1 } ) )
790
+ . then ( _assert ( 'raise leaf.opacity' , [ '' , '1' , '' , '1' ] ) )
791
+ . then ( _restyle ( { 'leaf.opacity' : null } ) )
792
+ . then ( _assert ( 'back to dflt' , [ '' , '0.7' , '' , '0.7' ] ) )
793
+ . then ( done , done . fail ) ;
794
+ } ) ;
795
+ } ) ;
796
+
797
+ describe ( 'Test icicle texttemplate without `values` should work at root level:' , function ( ) {
798
+ checkTextTemplate ( [ {
799
+ type : 'icicle' ,
800
+ labels : [ 'Eve' , 'Cain' , 'Seth' , 'Enos' , 'Noam' , 'Abel' , 'Awan' , 'Enoch' , 'Azura' ] ,
801
+ parents : [ '' , 'Eve' , 'Eve' , 'Seth' , 'Seth' , 'Eve' , 'Eve' , 'Awan' , 'Eve' ] ,
802
+ text : [ 'sixty-five' , 'fourteen' , 'twelve' , 'ten' , 'two' , 'six' , 'six' , 'one' , 'four' ]
803
+ } ] , 'g.slicetext' , [
804
+ [ 'color: %{color}' , [ 'color: rgba(0,0,0,0)' , 'color: #1f77b4' , 'color: #ff7f0e' , 'color: #2ca02c' , 'color: #d62728' , 'color: #9467bd' , 'color: #ff7f0e' , 'color: #ff7f0e' , 'color: #d62728' ] ] ,
805
+ [ 'label: %{label}' , [ 'label: Eve' , 'label: Cain' , 'label: Seth' , 'label: Enos' , 'label: Noam' , 'label: Abel' , 'label: Awan' , 'label: Enoch' , 'label: Azura' ] ] ,
806
+ [ 'text: %{text}' , [ 'text: sixty-five' , 'text: fourteen' , 'text: twelve' , 'text: ten' , 'text: two' , 'text: six' , 'text: six' , 'text: one' , 'text: four' ] ] ,
807
+ [ 'path: %{currentPath}' , [ 'path: /' , 'path: Eve/' , 'path: Eve/' , 'path: Eve/' , 'path: Eve/' , 'path: Eve' , 'path: Eve/Seth' , 'path: Eve/Seth/' , 'path: Eve/Awan/' ] ] ,
808
+ [ '%{percentRoot} of %{root}' , [ '100% of Eve' , '33% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' ] ] ,
809
+ [ '%{percentEntry} of %{entry}' , [ '100% of Eve' , '33% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' ] ] ,
810
+ [ '%{percentParent} of %{parent}' , [ '%{percentParent} of %{parent}' , '100% of Seth' , '33% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '17% of Eve' , '50% of Seth' , '100% of Awan' ] ] ,
811
+ [
812
+ [
813
+ 'label: %{label}' ,
814
+ 'text: %{text}' ,
815
+ 'value: %{value}' ,
816
+ '%{percentRoot} of %{root}' ,
817
+ '%{percentEntry} of %{entry}' ,
818
+ '%{percentParent} of %{parent}' ,
819
+ '%{percentParent} of %{parent}' ,
820
+ '%{percentParent} of %{parent}' ,
821
+ 'color: %{color}'
822
+ ] ,
823
+ [
824
+ 'label: Eve' ,
825
+ 'text: fourteen' ,
826
+ 'value: %{value}' , // N.B. there is no `values` array
827
+ '17% of Eve' ,
828
+ '17% of Eve' ,
829
+ '17% of Eve' ,
830
+ '17% of Eve' ,
831
+ '100% of Awan' ,
832
+ 'color: #9467bd'
833
+ ]
834
+ ]
835
+ ] ) ;
836
+ } ) ;
837
+
838
+ describe ( 'Test icicle texttemplate with *total* `values` should work at root level:' , function ( ) {
839
+ checkTextTemplate ( [ {
840
+ type : 'icicle' ,
841
+ branchvalues : 'total' ,
842
+ labels : [ 'Eve' , 'Cain' , 'Seth' , 'Enos' , 'Noam' , 'Abel' , 'Awan' , 'Enoch' , 'Azura' ] ,
843
+ parents : [ '' , 'Eve' , 'Eve' , 'Seth' , 'Seth' , 'Eve' , 'Eve' , 'Awan' , 'Eve' ] ,
844
+ values : [ 65 , 14 , 12 , 10 , 2 , 6 , 6 , 1 , 4 ] ,
845
+ text : [ 'sixty-five' , 'fourteen' , 'twelve' , 'ten' , 'two' , 'six' , 'six' , 'one' , 'four' ]
846
+ } ] , 'g.slicetext' , [
847
+ [ 'color: %{color}' , [ 'color: rgba(0,0,0,0)' , 'color: #1f77b4' , 'color: #ff7f0e' , 'color: #2ca02c' , 'color: #d62728' , 'color: #9467bd' , 'color: #ff7f0e' , 'color: #ff7f0e' , 'color: #d62728' ] ] ,
848
+ [ 'label: %{label}' , [ 'label: Eve' , 'label: Cain' , 'label: Seth' , 'label: Enos' , 'label: Noam' , 'label: Abel' , 'label: Awan' , 'label: Enoch' , 'label: Azura' ] ] ,
849
+ [ 'value: %{value}' , [ 'value: 65' , 'value: 14' , 'value: 12' , 'value: 10' , 'value: 2' , 'value: 6' , 'value: 6' , 'value: 1' , 'value: 4' ] ] ,
850
+ [ 'text: %{text}' , [ 'text: sixty-five' , 'text: fourteen' , 'text: twelve' , 'text: ten' , 'text: two' , 'text: six' , 'text: six' , 'text: one' , 'text: four' ] ] ,
851
+ [ 'path: %{currentPath}' , [ 'path: /' , 'path: Eve/' , 'path: Eve/' , 'path: Eve/' , 'path: Eve/' , 'path: Eve' , 'path: Eve/Seth' , 'path: Eve/Seth/' , 'path: Eve/Awan/' ] ] ,
852
+ [ '%{percentRoot} of %{root}' , [ '100% of Eve' , '22% of Eve' , '18% of Eve' , '9% of Eve' , '9% of Eve' , '6% of Eve' , '15% of Eve' , '3% of Eve' , '2% of Eve' ] ] ,
853
+ [ '%{percentEntry} of %{entry}' , [ '100% of Eve' , '22% of Eve' , '18% of Eve' , '9% of Eve' , '9% of Eve' , '6% of Eve' , '15% of Eve' , '3% of Eve' , '2% of Eve' ] ] ,
854
+ [ '%{percentParent} of %{parent}' , [ '%{percentParent} of %{parent}' , '22% of Eve' , '18% of Eve' , '9% of Eve' , '9% of Eve' , '6% of Eve' , '83% of Seth' , '17% of Seth' , '17% of Awan' ] ] ,
855
+ [
856
+ [
857
+ 'label: %{label}' ,
858
+ 'text: %{text}' ,
859
+ 'value: %{value}' ,
860
+ '%{percentRoot} of %{root}' ,
861
+ '%{percentEntry} of %{entry}' ,
862
+ '%{percentParent} of %{parent}' ,
863
+ '%{percentParent} of %{parent}' ,
864
+ '%{percentParent} of %{parent}' ,
865
+ 'color: %{color}'
866
+ ] ,
867
+ [
868
+ 'label: Eve' ,
869
+ 'text: fourteen' ,
870
+ 'value: 12' ,
871
+ '9% of Eve' ,
872
+ '15% of Eve' ,
873
+ '3% of Eve' ,
874
+ '6% of Eve' ,
875
+ '17% of Awan' ,
876
+ 'color: #9467bd'
877
+ ]
878
+ ]
879
+ ] ) ;
880
+ } ) ;
881
+
882
+ describe ( 'icicle pathbar react' , function ( ) {
883
+ 'use strict' ;
884
+
885
+ var gd ;
886
+
887
+ beforeEach ( function ( ) {
888
+ gd = createGraphDiv ( ) ;
889
+ } ) ;
890
+
891
+ afterEach ( destroyGraphDiv ) ;
892
+
893
+ it ( 'should show and hide pathbar' , function ( done ) {
894
+ var fig = {
895
+ data : [ {
896
+ type : 'icicle' ,
897
+ parents : [ '' , 'A' , 'B' , 'C' ] ,
898
+ labels : [ 'A' , 'B' , 'C' , 'D' ] ,
899
+ level : 'C'
900
+ } ] ,
901
+ layout : { }
902
+ } ;
903
+
904
+ function _assert ( msg , exp ) {
905
+ return function ( ) {
906
+ var selection = d3SelectAll ( SLICES_SELECTOR ) ;
907
+ var size = selection . size ( ) ;
908
+
909
+ expect ( size ) . toBe ( exp , msg ) ;
910
+ } ;
911
+ }
912
+
913
+ Plotly . newPlot ( gd , fig )
914
+ . then ( _assert ( 'default pathbar.visible: true' , 4 ) )
915
+ . then ( function ( ) {
916
+ fig . data [ 0 ] . pathbar = { visible : false } ;
917
+ return Plotly . react ( gd , fig ) ;
918
+ } )
919
+ . then ( _assert ( 'disable pathbar' , 2 ) )
920
+ . then ( function ( ) {
921
+ fig . data [ 0 ] . pathbar = { visible : true } ;
922
+ return Plotly . react ( gd , fig ) ;
923
+ } )
924
+ . then ( _assert ( 'enable pathbar' , 4 ) )
925
+ . then ( done , done . fail ) ;
926
+ } ) ;
927
+ } ) ;
0 commit comments