fee658e200a700b6ff336bcb5d449892021e5708
max
  Fri May 2 10:08:38 2025 -0700
adding one more drawing stage so when plotting gene expression zero values will not interfere with non zero values

diff --git src/cbPyLib/cellbrowser/cbWeb/js/maxPlot.js src/cbPyLib/cellbrowser/cbWeb/js/maxPlot.js
index 942da9a..94ffd6a 100644
--- src/cbPyLib/cellbrowser/cbWeb/js/maxPlot.js
+++ src/cbPyLib/cellbrowser/cbWeb/js/maxPlot.js
@@ -854,37 +854,69 @@
 
     function drawRect(ctx, pxCoords, coordColors, colors, radius, alpha, selCells, fatIdx) {
         /* draw not circles but tiny rectangles. Maybe good enough for 2pixels sizes */
        debug("Drawing "+coordColors.length+" rectangles, with fillRect");
        ctx.save();
        ctx.globalAlpha = alpha;
        var dblSize = 2*radius;
        var count = 0;
 
        if (selCells.size!==0 || fatIdx!==null)
            //colors = makeAllGreyHex(colors.length);
            colors = hexToGrey(colors);
 
        var fatCells = [];
 
+       // first draw all the cells with value 0. Poor mans approximation of a z index. 
+       // (Should be faster than sorting by z and drawing afterwards.)
        for (var i = 0; i < pxCoords.length/2; i++) {
            var pxX = pxCoords[2*i];
            var pxY = pxCoords[2*i+1];
            if (isHidden(pxX, pxY))
                continue;
 
            var valIdx = coordColors[i];
+           // only plot color 0
+           if (valIdx!==0)
+               continue;
+
+           var col = colors[valIdx];
+           if (fatIdx!==null) {
+               if (valIdx===fatIdx) {
+                   // fattened cells must be overdrawn later, so just save their coords now
+                   fatCells.push(pxX);
+                   fatCells.push(pxY);
+                   continue
+               }
+           }
+           ctx.fillStyle="#"+col;
+           ctx.fillRect(pxX-radius, pxY-radius, dblSize, dblSize);
+           count++;
+       }
+
+       // then draw all the cells with value <> 0. 
+       for (var i = 0; i < pxCoords.length/2; i++) {
+           var pxX = pxCoords[2*i];
+           var pxY = pxCoords[2*i+1];
+           if (isHidden(pxX, pxY))
+               continue;
+
+           var valIdx = coordColors[i];
+           // only plot color != 0
+           if (valIdx===0)
+               continue;
+
            var col = colors[valIdx];
            if (fatIdx!==null) {
                if (valIdx===fatIdx) {
                    // fattened cells must be overdrawn later, so just save their coords now
                    fatCells.push(pxX);
                    fatCells.push(pxY);
                    continue
                }
                //else
                    //col = "DDDDDD";
                    //col = nonFatColorRect;
            }
 
            ctx.fillStyle="#"+col;
            ctx.fillRect(pxX-radius, pxY-radius, dblSize, dblSize);
@@ -1284,47 +1316,73 @@
 //
            //if (radius>=5)
                //ctx.drawImage(off, selImgId * tileWidth, 0, tileWidth, tileHeight, pxX - radius -1, pxY - radius-1, tileWidth, tileHeight);
        //}
        //return count;
     //}
 
     function blitAll(ctx, off, pxCoords, coordColors, tileWidth, tileHeight, radius, selCells, greyIdx, fatIdx, colors) {
    /* blit the circles onto the main canvas, using all colors */
        var count = 0;
        var hasSelection = false;
        if (selCells.size!==0)
            hasSelection = true;
 
        var col = 0;
+       // first draw all the cells of the color 0
        for (let i = 0; i < pxCoords.length/2; i++) {
            var pxX = pxCoords[2*i];
            var pxY = pxCoords[2*i+1];
            if (isHidden(pxX, pxY))
                continue;
 
            // when a selection is active, draw everything in grey. This only works because the selection is overdrawn afterwards
            // (The selection must be overdrawn later, because otherwise circles shine through the selection)
            col = coordColors[i];
+           count++;
+           // only draw the cells of entry 0 of the palette first.
+           // This is a poor approximation of a z-index, but a real z-index would take way too long.
+           // So we're just drawing twice.
+           if (col!==0)
+               continue
+           if (fatIdx===null) {
+               if (hasSelection)
+                   col = greyIdx;
+            }
+            else if (!hasSelection && !(fatIdx!=null && fatIdx===col))
+                   col = greyIdx;
+
+           ctx.drawImage(off, col * tileWidth, 0, tileWidth, tileHeight, pxX - radius - 1, pxY - radius - 1, tileWidth, tileHeight);
+       }
+
+       // then draw all the cells with the colors != 0
+       for (let i = 0; i < pxCoords.length/2; i++) {
+           var pxX = pxCoords[2*i];
+           var pxY = pxCoords[2*i+1];
+           if (isHidden(pxX, pxY))
+               continue;
+
+           col = coordColors[i];
+           if (col===0)
+               continue
            if (fatIdx===null) {
                if (hasSelection)
                    col = greyIdx;
             }
             else if (!hasSelection && !(fatIdx!=null && fatIdx===col))
                    col = greyIdx;
 
-           count++;
            ctx.drawImage(off, col * tileWidth, 0, tileWidth, tileHeight, pxX - radius - 1, pxY - radius - 1, tileWidth, tileHeight);
        }
 
        if (fatIdx!==null) {
            // do not fatten
            //radius = radius * 2;
            //let templates = makeCircleTemplates(radius, tileWidth, tileHeight, colors, fatIdx);
            //let off = templates.off;
            radius *= 1.5;
            for (let i = 0; i < pxCoords.length/2; i++) {
                col = coordColors[i];
                if (fatIdx!==col)
                    continue;
                var pxX = pxCoords[2*i];
                var pxY = pxCoords[2*i+1];