7df99a27a400ec5627663c3a0692e9ab7d04796c
max
Fri May 9 09:25:54 2025 -0700
fix: null on recent genes, split screen titles, scroll bar coming up without reason, zooming on split screen, checkbox on both sides updating on change event, hide checkbox when not in split screen mode
diff --git src/cbPyLib/cellbrowser/cbWeb/js/cellBrowser.js src/cbPyLib/cellbrowser/cbWeb/js/cellBrowser.js
index 6276394..c543433 100644
--- src/cbPyLib/cellbrowser/cbWeb/js/cellBrowser.js
+++ src/cbPyLib/cellbrowser/cbWeb/js/cellBrowser.js
@@ -3419,82 +3419,87 @@
function colorByNothing() {
/* color by nothing, rarely needed */
renderer.setColors([cNullColor]);
var cellCount = db.conf.sampleCount;
renderer.setColorArr(new Uint8Array(cellCount));
gLegend.rows = [];
gLegend.title = "Nothing selected";
gLegend.subTitle = "";
gLegend.rows.push( {
color:cNullColor, defColor:null, label:"No Value",
count:cellCount, intKey:0, strKey:null
} );
buildLegendBar();
}
- function buildWatermark(myRend) {
+ function buildWatermark(myRend, showWatermark) {
/* update the watermark behind the image */
if (myRend===undefined)
myRend = renderer;
- if (!myRend.isSplit()) {
+ if (!myRend.isSplit() && !showWatermark) {
myRend.setWatermark("");
return;
}
let prefix = "";
if (db.conf.coords.length!==1)
- prefix = renderer.coords.coordInfo.shortLabel+": ";
+ prefix = myRend.coords.coordInfo.shortLabel+": ";
let labelStr;
if (gLegend.type==="expr")
labelStr = prefix+gLegend.geneSym;
else
labelStr = prefix+gLegend.metaInfo.label;
let waterLabel;
if (db.isAtacMode())
waterLabel= labelStr.split("|").length + " peak(s)";
else
waterLabel = labelStr;
myRend.setWatermark(waterLabel);
}
function colorByLocus(locusStr, onDone, locusLabel) {
- /* color by a gene or peak, load the array into the renderer and call onDone or just redraw
+ /* colorByGene: color by a gene or peak, load the array into the renderer and call onDone or just redraw
* peak can be in format: +chr1:1-1000
* gene can be in format: geneSym or geneSym=geneId
* */
if (onDone===undefined || onDone===null)
onDone = function() { renderer.drawDots(); };
function gotGeneVec(exprArr, decArr, locusStr, geneDesc, binInfo) {
/* called when the expression vector has been loaded and binning is done */
if (decArr===null)
return;
console.log("Received expression vector, for "+locusStr+", desc: "+geneDesc);
// update the URL and possibly the gene combo box
if (locusStr.indexOf("|") > -1) {
if (locusStr.length < 600)
// this is rare, so just completely skip this URL change now
changeUrl({"locus":locusStr, "meta":null});
} else
changeUrl({"gene":locusStr, "meta":null});
makeLegendExpr(locusStr, geneDesc, binInfo, exprArr, decArr);
renderer.setColors(legendGetColors(gLegend.rows));
renderer.setColorArr(decArr);
+ if (renderer.childPlot && document.getElementById("splitJoinBox").checked) {
+ renderer.childPlot.setColors(legendGetColors(gLegend.rows));
+ renderer.childPlot.setColorArr(decArr);
+ buildWatermark(renderer.childPlot);
+ }
buildWatermark(renderer);
buildLegendBar();
onDone();
// update the "recent genes" div
for (var i = 0; i < gRecentGenes.length; i++) {
// remove previous gene entry with the same symbol
if (gRecentGenes[i][0]===locusStr || gRecentGenes[i][1]===locusStr) { // match symbol or ID
gRecentGenes.splice(i, 1);
break;
}
}
// make sure that recent genes table has symbol and Id
@@ -3555,30 +3560,31 @@
for (var i = 0; i < clusterMids.length; i++) {
origLabels.push(clusterMids[i][2]);
}
renderer.origLabels = origLabels;
}
if (clusterInfo && clusterInfo.lines) {
opts["lines"] = clusterInfo.lines;
opts["lineWidth"] = db.conf.lineWidth;
opts["lineColor"] = db.conf.lineColor;
opts["lineAlpha"] = db.conf.lineAlpha;
}
renderer.setCoords(coords, clusterMids, info, opts);
+ buildWatermark(renderer);
}
function computeAndSetLabels(values, metaInfo) {
/* recompute the label positions and redraw everything. Updates the dropdown. */
var labelCoords;
var coords = renderer.coords.orig;
var names = null;
if (metaInfo.type !== "float" && metaInfo.type !== "int") {
var names = metaInfo.ui.shortLabels;
}
console.time("cluster centers");
var calc = renderer.calcMedian(coords, values, names, metaInfo.origVals);
@@ -3843,36 +3849,41 @@
else
renderer.drawDots();
// this requires coordinates to be loaded
if (getVar("cell")!==undefined) {
selectCellsById([getVar("cell")], false, null)
}
//if (db.conf.multiModal && db.conf.multiModal.splitPrefix)
//renderer.split();
if (db.conf.split) {
let splitOpts = db.conf.split;
//configureRenderer(splitOpts[0]);
//renderer.drawDots();
//buildWatermark();
+ //buildWatermark();
activateSplit();
configureRenderer(splitOpts);
+ $("#splitJoinDiv").show();
+ $("#splitJoinBox").prop("checked", true);
//buildWatermark();
//renderer.drawDots();
changeUrl({"layout":null, "meta":null, "gene":null});
renderer.drawDots();
+ } else {
+ $("#splitJoinDiv").hide();
}
}
}
function guessRadiusAlpha(dotCount) {
/* return reasonable radius and alpha values for a number of dots */
if (dotCount<3000)
return [4, 0.7];
if (dotCount<6000)
return [4, 0.6];
if (dotCount<10000)
return [3, 0.5];
if (dotCount<35000)
return [2, 0.3];
if (dotCount<80000)
@@ -4722,31 +4733,31 @@
htmls.push('
");
if (geneInfos===undefined || geneInfos===null || geneInfos.length===0) {
- if (noteStr!==undefined)
+ if (noteStr!==undefined && noteStr!==null)
htmls.push("
"+noteStr+"
");
htmls.push("
");
return;
}
var i = 0;
while (i < geneInfos.length) {
var geneInfo = geneInfos[i];
var geneIdOrSym = geneInfo[0];
var mouseOver = geneInfo[1];
// geneIdOrSym can be just the symbol (if we all we have is symbols) or geneId|symbol
var internalId;
var label;
if (geneIdOrSym.indexOf("|")!==-1) {
@@ -5511,31 +5522,31 @@
var field = metaFieldInfo[i];
var fieldName = field.label;
var isNumeric = (field.type==="int" || field.type==="float");
var hasTooManyVals = (field.diffValCount>MAXCOLORCOUNT);
if ((optStr==="noNums" && isNumeric) ||
(optStr=='doLabels' && (isNumeric || hasTooManyVals))) {
continue;
}
entries.push( ["tpMetaVal_"+i, fieldName] );
if (selectedField == fieldName) {
selIdx = i-1; // -1 because the first element was skipped
}
}
- buildComboBox(htmls, id, entries, selIdx, "select a field...", metaBarWidth+50);
+ buildComboBox(htmls, id, entries, selIdx, "select a field...", 50);
htmls.push('');
}
function getGeneLabel() {
/* some datasets have data not on genes, but on other things e.g. "lipids". The config can
* define a label for the rows in the expression matrix */
var geneLabel = "Gene";
if (db.conf.atacSearch)
geneLabel = "Range";
if (db.conf.geneLabel)
geneLabel = db.conf.geneLabel;
return geneLabel;
}
function splitButtonLabel(state) {
@@ -7375,71 +7386,73 @@
buildMetaFieldCombo(htmls, "tpLabelComboBox", "tpLabelCombo", 0, db.conf.labelField, "doLabels");
htmls.push('
");
buildGeneCombo(htmls, "tpGeneCombo", 0, metaBarWidth-10);
- if (db.conf.split)
- htmls.push(' ');
- // var myGenes = loadMyGenes();
+ htmls.push('
');
if (db.conf.atacSearch)
buildPeakList(htmls);
var geneLabel = getGeneLabel();
var recentHelp = "Shown below are the 10 most recently searched genes. Click any gene to color the plot on the right-hand side by the gene.";
buildGeneTable(htmls, "tpRecentGenes", "Recent "+geneLabel+"s",
"Hover or select cells to update colors here Click to color by gene", gRecentGenes, null, recentHelp);
-
- var noteStr = "No genes or peaks defined. Use the setting quickGenesFile in "
- "cellbrowser.conf to add a file with gene symbols or peaks that will be shown here";
+ var noteStr = "No genes or peaks defined: Use quickGenesFile in cellbrowser.conf.";
var geneHelp = "The dataset genes were defined by the dataset submitter, publication author or data wrangler at UCSC. " +
"Click any of them to color the plot on the right hand side by the gene.";
buildGeneTable(htmls, "tpGenes", "Dataset "+geneLabel+"s", null, db.conf.quickGenes, noteStr, geneHelp);
htmls.push("
');
htmls.push("");
htmls.push("");
htmls.push("");
htmls.push("");
- let buttonText = "Color only checked";
+ let buttonText = "Recolor only checked";
if (gLegend.isColorOnlyChecked===true) {
buttonText = "Reset colors";
}
htmls.push("");
htmls.push(""); // title
htmls.push('
');
htmls.push('
');
// get the sum of all, to calculate frequency
var sum = 0;
for (var i = 0; i < rows.length; i++) {
let count = rows[i].count;
sum += count;
@@ -8910,39 +8923,40 @@
if (!renderer.childPlot && !renderer.parentPlot)
return;
if (!renderer.isMain) {
// make sure the left renderer is the active one
renderer = renderer.childPlot;
renderer.activatePlot();
}
renderer.unsplit();
$("#tpSplitMenuEntry").text("Split Screen");
renderer.drawDots();
$("#tpSplitOnGene").text(splitButtonLabel(true));
}
function activateSplit() {
// nothing is split yet -> start the split
- buildWatermark(renderer);
+ $("#splitJoinDiv").show();
+ buildWatermark(renderer, true);
renderer.onActiveChange = onActRendChange;
var currCoordIdx = $("#tpLayoutCombo").val();
renderer.legend = gLegend;
renderer.isMain = true;
let rend2 = renderer.split();
- buildWatermark(rend2);
+ buildWatermark(rend2, true);
renderer.childPlot.legend = gLegend;
$("#tpSplitMenuEntry").text("Unsplit Screen");
$("#mpCloseButton").click( function() { removeSplit(renderer);} );
$("#tpSplitOnGene").text(splitButtonLabel(false));
}
function onSplitClick() {
/* user clicked on View > Split Screen */
if (!renderer.childPlot && !renderer.parentPlot) {
activateSplit();
} else {
removeSplit(renderer);