@@ -826,6 +826,123 @@ describe('heatmap plot', function() {
826826 } )
827827 . then ( done , done . fail ) ;
828828 } ) ;
829+
830+ it ( 'should set canvas dimensions according to z data shape if `zsmooth` is fast' , function ( done ) {
831+ var mock1 = require ( '../../image/mocks/zsmooth_methods.json' ) ;
832+ var mock2 = require ( '../../image/mocks/zz-heatmap_small_layout_zsmooth_fast.json' ) ;
833+
834+ var canvasStub ;
835+ var originalCreateElement = document . createElement ;
836+
837+ spyOn ( document , 'createElement' ) . and . callFake ( function ( elementType ) {
838+ var element = originalCreateElement . call ( document , elementType ) ;
839+ if ( elementType === 'canvas' ) {
840+ canvasStub = {
841+ width : spyOnProperty ( element , 'width' , 'set' ) . and . callThrough ( ) ,
842+ height : spyOnProperty ( element , 'height' , 'set' ) . and . callThrough ( )
843+ } ;
844+ }
845+ return element ;
846+ } ) ;
847+
848+ function assertCanvas ( z ) {
849+ expect ( canvasStub . width . calls . count ( ) ) . toBe ( 1 ) ;
850+ expect ( canvasStub . height . calls . count ( ) ) . toBe ( 1 ) ;
851+ var m = z . length ;
852+ var n = Lib . maxRowLength ( z ) ;
853+ var canvasW = canvasStub . width . calls . argsFor ( 0 ) [ 0 ] ;
854+ var canvasH = canvasStub . height . calls . argsFor ( 0 ) [ 0 ] ;
855+ expect ( [ canvasW , canvasH ] ) . toEqual ( [ n , m ] ) ;
856+ }
857+
858+ Plotly . newPlot ( gd , [ mock1 . data [ 1 ] ] ) . then ( function ( ) {
859+ assertCanvas ( mock1 . data [ 1 ] . z ) ;
860+ return Plotly . newPlot ( gd , mock2 . data , mock2 . layout ) ;
861+ } ) . then ( function ( ) {
862+ assertCanvas ( mock2 . data [ 0 ] . z ) ;
863+ } ) . then ( done , done . fail ) ;
864+ } ) ;
865+
866+ it ( 'should create imageData that fits the canvas dimensions if zsmooth is set' , function ( done ) {
867+ var mock1 = require ( '../../image/mocks/zsmooth_methods.json' ) ;
868+ var mock2 = require ( '../../image/mocks/zz-heatmap_small_layout_zsmooth_fast.json' ) ;
869+
870+ var imageDataStub = {
871+ data : {
872+ set : jasmine . createSpy ( )
873+ }
874+ } ;
875+
876+ var getContextStub = {
877+ createImageData : jasmine . createSpy ( ) . and . returnValue ( imageDataStub ) ,
878+ putImageData : function ( ) { } ,
879+ fillRect : function ( ) { } ,
880+ } ;
881+
882+ function checkPixels ( pixels ) {
883+ for ( var j = 0 , px , check ; j < pixels . length ; j += 4 ) {
884+ px = pixels . slice ( j , j + 4 ) ;
885+ check = px . every ( function ( c ) { return c === 0 ; } ) ;
886+ if ( check ) {
887+ return false ;
888+ }
889+ }
890+ return true ;
891+ }
892+
893+ var canvasStubs = [ ] ;
894+ var originalCreateElement = document . createElement ;
895+
896+ spyOn ( document , 'createElement' ) . and . callFake ( function ( elementType ) {
897+ var element = originalCreateElement . call ( document , elementType ) ;
898+ if ( elementType === 'canvas' ) {
899+ spyOn ( element , 'getContext' ) . and . returnValue ( getContextStub ) ;
900+ canvasStubs . push ( {
901+ width : spyOnProperty ( element , 'width' , 'set' ) . and . callThrough ( ) ,
902+ height : spyOnProperty ( element , 'height' , 'set' ) . and . callThrough ( )
903+ } ) ;
904+ }
905+ return element ;
906+ } ) ;
907+
908+ Plotly . newPlot ( gd , mock1 . data , mock1 . layout ) . then ( function ( ) {
909+ expect ( getContextStub . createImageData . calls . count ( ) ) . toBe ( 2 ) ;
910+ expect ( imageDataStub . data . set . calls . count ( ) ) . toBe ( 2 ) ;
911+
912+ [ 0 , 1 ] . forEach ( function ( i ) {
913+ var createImageDataArgs = getContextStub . createImageData . calls . argsFor ( i ) ;
914+ var setImageDataArgs = imageDataStub . data . set . calls . argsFor ( i ) ;
915+
916+ var canvasW = canvasStubs [ i ] . width . calls . argsFor ( 0 ) [ 0 ] ;
917+ var canvasH = canvasStubs [ i ] . height . calls . argsFor ( 0 ) [ 0 ] ;
918+ expect ( createImageDataArgs ) . toEqual ( [ canvasW , canvasH ] ) ;
919+
920+ var pixels = setImageDataArgs [ 0 ] ;
921+ expect ( pixels . length ) . toBe ( canvasW * canvasH * 4 ) ;
922+ expect ( checkPixels ( pixels ) ) . toBe ( true ) ;
923+ } ) ;
924+
925+ getContextStub . createImageData . calls . reset ( ) ;
926+ imageDataStub . data . set . calls . reset ( ) ;
927+ canvasStubs = [ ] ;
928+
929+ return Plotly . newPlot ( gd , mock2 . data , mock2 . layout ) ;
930+ } ) . then ( function ( ) {
931+ expect ( getContextStub . createImageData . calls . count ( ) ) . toBe ( 1 ) ;
932+ expect ( imageDataStub . data . set . calls . count ( ) ) . toBe ( 1 ) ;
933+
934+ var canvasW = canvasStubs [ 0 ] . width . calls . argsFor ( 0 ) [ 0 ] ;
935+ var canvasH = canvasStubs [ 0 ] . height . calls . argsFor ( 0 ) [ 0 ] ;
936+
937+ var createImageDataArgs = getContextStub . createImageData . calls . argsFor ( 0 ) ;
938+ expect ( createImageDataArgs ) . toEqual ( [ canvasW , canvasH ] ) ;
939+
940+ var setImageDataArgs = imageDataStub . data . set . calls . argsFor ( 0 ) ;
941+ var pixels = setImageDataArgs [ 0 ] ;
942+ expect ( pixels . length ) . toBe ( canvasW * canvasH * 4 ) ;
943+ expect ( checkPixels ( pixels ) ) . toBe ( true ) ;
944+ } ) . then ( done , done . fail ) ;
945+ } ) ;
829946} ) ;
830947
831948describe ( 'heatmap hover' , function ( ) {
0 commit comments