@@ -15,6 +15,8 @@ var makeColorScaleFuncFromTrace = require('../../components/colorscale').makeCol
1515var xmlnsNamespaces = require ( '../../constants/xmlns_namespaces' ) ;
1616var alignmentConstants = require ( '../../constants/alignment' ) ;
1717var LINE_SPACING = alignmentConstants . LINE_SPACING ;
18+ var supportsPixelatedImage = require ( '../../lib/supports_pixelated_image' ) ;
19+ var PIXELATED_IMAGE_STYLE = require ( '../../constants/pixelated_image' ) . STYLE ;
1820
1921var labelClass = 'heatmap-label' ;
2022
@@ -109,11 +111,18 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
109111 y = cd0 . yfill ;
110112 }
111113
114+ var drawingMethod = 'default' ;
115+ if ( zsmooth ) {
116+ drawingMethod = zsmooth === 'best' ? 'smooth' : 'fast' ;
117+ } else if ( trace . _islinear && xGap === 0 && yGap === 0 && supportsPixelatedImage ( ) ) {
118+ drawingMethod = 'fast' ;
119+ }
120+
112121 // make an image that goes at most half a screen off either side, to keep
113- // time reasonable when you zoom in. if zsmooth is true/ fast, don't worry
122+ // time reasonable when you zoom in. if drawingMethod is fast, don't worry
114123 // about this, because zooming doesn't increase number of pixels
115124 // if zsmooth is best, don't include anything off screen because it takes too long
116- if ( zsmooth !== 'fast' ) {
125+ if ( drawingMethod !== 'fast' ) {
117126 var extra = zsmooth === 'best' ? 0 : 0.5 ;
118127 left = Math . max ( - extra * xa . _length , left ) ;
119128 right = Math . min ( ( 1 + extra ) * xa . _length , right ) ;
@@ -127,7 +136,9 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
127136 // setup image nodes
128137
129138 // if image is entirely off-screen, don't even draw it
130- var isOffScreen = ( imageWidth <= 0 || imageHeight <= 0 ) ;
139+ var isOffScreen = (
140+ left >= xa . _length || right <= 0 || top >= ya . _length || bottom <= 0
141+ ) ;
131142
132143 if ( isOffScreen ) {
133144 var noImage = plotGroup . selectAll ( 'image' ) . data ( [ ] ) ;
@@ -140,7 +151,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
140151 // generate image data
141152
142153 var canvasW , canvasH ;
143- if ( zsmooth === 'fast' ) {
154+ if ( drawingMethod === 'fast' ) {
144155 canvasW = n ;
145156 canvasH = m ;
146157 } else {
@@ -158,7 +169,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
158169 // map brick boundaries to image pixels
159170 var xpx ,
160171 ypx ;
161- if ( zsmooth === 'fast' ) {
172+ if ( drawingMethod === 'fast' ) {
162173 xpx = xrev ?
163174 function ( index ) { return n - 1 - index ; } :
164175 Lib . identity ;
@@ -235,7 +246,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
235246 return setColor ( z00 + xinterp . frac * dx + yinterp . frac * ( dy + xinterp . frac * dxy ) ) ;
236247 }
237248
238- if ( zsmooth ) { // best or fast, works fastest with imageData
249+ if ( drawingMethod !== 'default' ) { // works fastest with imageData
239250 var pxIndex = 0 ;
240251 var pixels ;
241252
@@ -245,7 +256,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
245256 pixels = new Array ( canvasW * canvasH * 4 ) ;
246257 }
247258
248- if ( zsmooth === 'best ' ) {
259+ if ( drawingMethod === 'smooth ' ) { // zsmooth="best"
249260 var xForPx = xc || x ;
250261 var yForPx = yc || y ;
251262 var xPixArray = new Array ( xForPx . length ) ;
@@ -273,7 +284,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
273284 putColor ( pixels , pxIndex , c ) ;
274285 }
275286 }
276- } else { // zsmooth = fast
287+ } else { // drawingMethod = "fast" ( zsmooth = " fast"|false)
277288 for ( j = 0 ; j < m ; j ++ ) {
278289 row = z [ j ] ;
279290 yb = ypx ( j ) ;
@@ -297,7 +308,8 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
297308 }
298309
299310 context . putImageData ( imageData , 0 , 0 ) ;
300- } else { // zsmooth = false -> filling potentially large bricks works fastest with fillRect
311+ } else { // rawingMethod = "default" (zsmooth = false)
312+ // filling potentially large bricks works fastest with fillRect
301313 // gaps do not need to be exact integers, but if they *are* we will get
302314 // cleaner edges by rounding at least one edge
303315 var xGapLeft = Math . floor ( xGap / 2 ) ;
@@ -353,6 +365,10 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
353365 'xlink:href' : canvas . toDataURL ( 'image/png' )
354366 } ) ;
355367
368+ if ( drawingMethod === 'fast' && ! zsmooth ) {
369+ image3 . attr ( 'style' , PIXELATED_IMAGE_STYLE ) ;
370+ }
371+
356372 removeLabels ( plotGroup ) ;
357373
358374 var texttemplate = trace . texttemplate ;
0 commit comments