@vitessce/heatmap 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{deflate-16770a05.js → deflate-d508d4a0.js} +1 -1
- package/dist/{index-516800f9.js → index-2a959f7f.js} +417 -708
- package/dist/index.js +1 -1
- package/dist/{jpeg-aaa6dcb6.js → jpeg-d33c98fc.js} +1 -1
- package/dist/{lerc-4c94e66f.js → lerc-10fe8c3f.js} +1 -1
- package/dist/{lzw-072df1d0.js → lzw-b482148a.js} +1 -1
- package/dist/{packbits-3dcafae7.js → packbits-09f27b8f.js} +1 -1
- package/dist/{raw-282aecb8.js → raw-0aecbbc9.js} +1 -1
- package/dist/{webimage-0d9c3bfd.js → webimage-b4a1a024.js} +1 -1
- package/dist-tsc/Heatmap.d.ts +10 -7
- package/dist-tsc/Heatmap.d.ts.map +1 -1
- package/dist-tsc/Heatmap.js +65 -62
- package/dist-tsc/Heatmap.test.js +1 -1
- package/dist-tsc/HeatmapSubscriber.d.ts.map +1 -1
- package/dist-tsc/HeatmapSubscriber.js +10 -18
- package/dist-tsc/HeatmapTooltipSubscriber.js +4 -4
- package/dist-tsc/utils.test.js +1 -0
- package/package.json +13 -13
- package/src/Heatmap.js +69 -64
- package/src/Heatmap.test.jsx +1 -1
- package/src/HeatmapSubscriber.js +17 -23
- package/src/HeatmapTooltipSubscriber.js +4 -4
- package/src/utils.test.js +1 -0
package/src/Heatmap.js
CHANGED
|
@@ -65,22 +65,22 @@ function shouldUsePaddedImplementation(dataLength) {
|
|
|
65
65
|
* for DeckGL.
|
|
66
66
|
* @param {number} props.width The width of the canvas.
|
|
67
67
|
* @param {number} props.height The height of the canvas.
|
|
68
|
-
* @param {
|
|
69
|
-
*
|
|
70
|
-
* and cols is a list of gene ID strings.
|
|
68
|
+
* @param {null|Uint8Array} props.uint8ObsFeatureMatrix A flat Uint8Array
|
|
69
|
+
* containing the expression data.
|
|
71
70
|
* @param {Map} props.cellColors Map of cell ID to color. Optional.
|
|
72
71
|
* If defined, the key ordering is used to order the cell axis of the heatmap.
|
|
73
72
|
* @param {array} props.cellColorLabels array of labels to place beside cell color
|
|
74
73
|
* tracks. Only works for transpose=true.
|
|
75
|
-
* @param {function} props.clearPleaseWait The clear please wait callback,
|
|
76
|
-
* called when the expression matrix has loaded (is not null).
|
|
77
74
|
* @param {function} props.setCellHighlight Callback function called on
|
|
78
75
|
* hover with the cell ID. Optional.
|
|
79
76
|
* @param {function} props.setGeneHighlight Callback function called on
|
|
80
77
|
* hover with the gene ID. Optional.
|
|
81
78
|
* @param {function} props.updateViewInfo Callback function that gets called with an
|
|
82
|
-
* object { uuid, project() } where
|
|
83
|
-
*
|
|
79
|
+
* object { uuid, project(), projectFromId() } where
|
|
80
|
+
* project is the DeckGL Viewport.project function, and
|
|
81
|
+
* projectFromId is a wrapper around project that
|
|
82
|
+
* takes (cellId, geneId) as parameters and returns
|
|
83
|
+
* canvas (x,y) pixel coordinates. Used to show tooltips. Optional.
|
|
84
84
|
* @param {boolean} props.transpose By default, false.
|
|
85
85
|
* @param {string} props.variablesTitle By default, 'Genes'.
|
|
86
86
|
* @param {string} props.observationsTitle By default, 'Cells'.
|
|
@@ -91,6 +91,9 @@ function shouldUsePaddedImplementation(dataLength) {
|
|
|
91
91
|
* @param {string} props.colormap The name of the colormap function to use.
|
|
92
92
|
* @param {array} props.colormapRange A tuple [lower, upper] to adjust the color scale.
|
|
93
93
|
* @param {function} props.setColormapRange The setter function for colormapRange.
|
|
94
|
+
* @param {string[]} props.obsIndex The cell ID list.
|
|
95
|
+
* @param {string[]} props.featureIndex The gene ID list.
|
|
96
|
+
* @param {null|Map<string,string>} props.featureLabelsMap A map of featureIndex to featureLabel.
|
|
94
97
|
*/
|
|
95
98
|
const Heatmap = forwardRef((props, deckRef) => {
|
|
96
99
|
const {
|
|
@@ -100,12 +103,11 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
100
103
|
setViewState,
|
|
101
104
|
width: viewWidth,
|
|
102
105
|
height: viewHeight,
|
|
103
|
-
|
|
106
|
+
uint8ObsFeatureMatrix,
|
|
104
107
|
cellColors,
|
|
105
108
|
cellColorLabels = [''],
|
|
106
109
|
colormap,
|
|
107
110
|
colormapRange,
|
|
108
|
-
clearPleaseWait,
|
|
109
111
|
setComponentHover,
|
|
110
112
|
setCellHighlight = createDefaultUpdateCellsHover('Heatmap'),
|
|
111
113
|
setGeneHighlight = createDefaultUpdateGenesHover('Heatmap'),
|
|
@@ -122,7 +124,9 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
122
124
|
hideVariableLabels = false,
|
|
123
125
|
onHeatmapClick,
|
|
124
126
|
setColorEncoding,
|
|
127
|
+
obsIndex,
|
|
125
128
|
featureIndex,
|
|
129
|
+
featureLabelsMap,
|
|
126
130
|
} = props;
|
|
127
131
|
|
|
128
132
|
const viewState = {
|
|
@@ -136,12 +140,6 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
136
140
|
|
|
137
141
|
const workerPool = useMemo(() => new HeatmapWorkerPool(), []);
|
|
138
142
|
|
|
139
|
-
useEffect(() => {
|
|
140
|
-
if (clearPleaseWait && expression) {
|
|
141
|
-
clearPleaseWait('expression-matrix');
|
|
142
|
-
}
|
|
143
|
-
}, [clearPleaseWait, expression]);
|
|
144
|
-
|
|
145
143
|
const tilesRef = useRef();
|
|
146
144
|
const dataRef = useRef();
|
|
147
145
|
const [axisLeftLabels, setAxisLeftLabels] = useState([]);
|
|
@@ -164,23 +162,23 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
164
162
|
// it back and forth from the worker thread.
|
|
165
163
|
useEffect(() => {
|
|
166
164
|
// Store the expression matrix Uint8Array in the dataRef.
|
|
167
|
-
if (
|
|
168
|
-
&& !shouldUsePaddedImplementation(
|
|
165
|
+
if (uint8ObsFeatureMatrix
|
|
166
|
+
&& !shouldUsePaddedImplementation(uint8ObsFeatureMatrix.length)
|
|
169
167
|
) {
|
|
170
|
-
dataRef.current = copyUint8Array(
|
|
168
|
+
dataRef.current = copyUint8Array(uint8ObsFeatureMatrix);
|
|
171
169
|
}
|
|
172
|
-
}, [dataRef,
|
|
170
|
+
}, [dataRef, uint8ObsFeatureMatrix]);
|
|
173
171
|
|
|
174
172
|
// Check if the ordering of axis labels needs to be changed,
|
|
175
173
|
// for example if the cells "selected" (technically just colored)
|
|
176
174
|
// have changed.
|
|
177
175
|
useEffect(() => {
|
|
178
|
-
if (!
|
|
176
|
+
if (!obsIndex) {
|
|
179
177
|
return;
|
|
180
178
|
}
|
|
181
179
|
|
|
182
180
|
const newCellOrdering = (!cellColors || cellColors.size === 0
|
|
183
|
-
?
|
|
181
|
+
? obsIndex
|
|
184
182
|
: Array.from(cellColors.keys())
|
|
185
183
|
);
|
|
186
184
|
|
|
@@ -193,41 +191,41 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
193
191
|
setAxisLeftLabels(newCellOrdering);
|
|
194
192
|
}
|
|
195
193
|
}
|
|
196
|
-
}, [
|
|
194
|
+
}, [obsIndex, cellColors, axisTopLabels, axisLeftLabels, transpose]);
|
|
197
195
|
|
|
198
196
|
// Set the genes ordering.
|
|
199
197
|
useEffect(() => {
|
|
200
|
-
if (!
|
|
198
|
+
if (!featureIndex) {
|
|
201
199
|
return;
|
|
202
200
|
}
|
|
203
201
|
if (transpose) {
|
|
204
|
-
setAxisLeftLabels(
|
|
202
|
+
setAxisLeftLabels(featureIndex);
|
|
205
203
|
} else {
|
|
206
|
-
setAxisTopLabels(
|
|
204
|
+
setAxisTopLabels(featureIndex);
|
|
207
205
|
}
|
|
208
|
-
}, [
|
|
206
|
+
}, [featureIndex, transpose]);
|
|
209
207
|
|
|
210
208
|
const [longestCellLabel, longestGeneLabel] = useMemo(() => {
|
|
211
|
-
if (!
|
|
209
|
+
if (!obsIndex || !featureIndex) {
|
|
212
210
|
return ['', ''];
|
|
213
211
|
}
|
|
214
212
|
|
|
215
213
|
return [
|
|
216
|
-
getLongestString(
|
|
217
|
-
getLongestString([...
|
|
214
|
+
getLongestString(obsIndex),
|
|
215
|
+
getLongestString([...featureIndex, ...cellColorLabels]),
|
|
218
216
|
];
|
|
219
|
-
}, [
|
|
217
|
+
}, [featureIndex, cellColorLabels, obsIndex]);
|
|
220
218
|
|
|
221
219
|
// Creating a look up dictionary once is faster than calling indexOf many times
|
|
222
220
|
// i.e when cell ordering changes.
|
|
223
221
|
const expressionRowLookUp = useMemo(() => {
|
|
224
222
|
const lookUp = new Map();
|
|
225
|
-
if (
|
|
223
|
+
if (obsIndex) {
|
|
226
224
|
// eslint-disable-next-line no-return-assign
|
|
227
|
-
|
|
225
|
+
obsIndex.forEach((cell, j) => (lookUp.set(cell, j)));
|
|
228
226
|
}
|
|
229
227
|
return lookUp;
|
|
230
|
-
}, [
|
|
228
|
+
}, [obsIndex]);
|
|
231
229
|
|
|
232
230
|
const width = axisTopLabels.length;
|
|
233
231
|
const height = axisLeftLabels.length;
|
|
@@ -274,7 +272,7 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
274
272
|
useEffect(() => {
|
|
275
273
|
updateViewInfo({
|
|
276
274
|
uuid,
|
|
277
|
-
|
|
275
|
+
projectFromId: (cellId, geneId) => {
|
|
278
276
|
const colI = transpose ? axisTopLabels.indexOf(cellId) : axisTopLabels.indexOf(geneId);
|
|
279
277
|
const rowI = transpose ? axisLeftLabels.indexOf(geneId) : axisLeftLabels.indexOf(cellId);
|
|
280
278
|
return heatmapToMousePosition(
|
|
@@ -324,7 +322,7 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
324
322
|
// then new tiles need to be generated,
|
|
325
323
|
// so add a new task to the backlog.
|
|
326
324
|
useEffect(() => {
|
|
327
|
-
if (!
|
|
325
|
+
if (!uint8ObsFeatureMatrix || uint8ObsFeatureMatrix.length < DATA_TEXTURE_SIZE ** 2) {
|
|
328
326
|
return;
|
|
329
327
|
}
|
|
330
328
|
// Use a uuid to give the task a unique ID,
|
|
@@ -336,7 +334,7 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
336
334
|
) {
|
|
337
335
|
setBacklog(prev => [...prev, uuidv4()]);
|
|
338
336
|
}
|
|
339
|
-
}, [dataRef,
|
|
337
|
+
}, [dataRef, uint8ObsFeatureMatrix, axisTopLabels, axisLeftLabels, xTiles, yTiles]);
|
|
340
338
|
|
|
341
339
|
// When the backlog has updated, a new worker job can be submitted if:
|
|
342
340
|
// - the backlog has length >= 1 (at least one job is waiting), and
|
|
@@ -349,16 +347,15 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
349
347
|
if (dataRef.current
|
|
350
348
|
&& dataRef.current.buffer.byteLength && expressionRowLookUp.size > 0
|
|
351
349
|
&& !shouldUsePaddedImplementation(dataRef.current.length)) {
|
|
352
|
-
const { cols, matrix } = expression;
|
|
353
350
|
const promises = range(yTiles).map(i => range(xTiles).map(async j => workerPool.process({
|
|
354
351
|
curr,
|
|
355
352
|
tileI: i,
|
|
356
353
|
tileJ: j,
|
|
357
354
|
tileSize: TILE_SIZE,
|
|
358
355
|
cellOrdering: transpose ? axisTopLabels : axisLeftLabels,
|
|
359
|
-
cols,
|
|
356
|
+
cols: featureIndex,
|
|
360
357
|
transpose,
|
|
361
|
-
data:
|
|
358
|
+
data: uint8ObsFeatureMatrix.buffer.slice(),
|
|
362
359
|
expressionRowLookUp,
|
|
363
360
|
})));
|
|
364
361
|
const process = async () => {
|
|
@@ -374,8 +371,8 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
374
371
|
};
|
|
375
372
|
process();
|
|
376
373
|
}
|
|
377
|
-
}, [axisLeftLabels, axisTopLabels, backlog,
|
|
378
|
-
xTiles, yTiles, workerPool, expressionRowLookUp]);
|
|
374
|
+
}, [axisLeftLabels, axisTopLabels, backlog, uint8ObsFeatureMatrix, transpose,
|
|
375
|
+
xTiles, yTiles, workerPool, expressionRowLookUp, featureIndex]);
|
|
379
376
|
|
|
380
377
|
useEffect(() => {
|
|
381
378
|
setIsRendering(backlog.length > 0);
|
|
@@ -384,8 +381,8 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
384
381
|
// Create the padded expression matrix for holding data which can then be bound to the GPU.
|
|
385
382
|
const paddedExpressions = useMemo(() => {
|
|
386
383
|
const cellOrdering = transpose ? axisTopLabels : axisLeftLabels;
|
|
387
|
-
if (
|
|
388
|
-
&& gl && shouldUsePaddedImplementation(
|
|
384
|
+
if (uint8ObsFeatureMatrix && cellOrdering.length
|
|
385
|
+
&& gl && shouldUsePaddedImplementation(uint8ObsFeatureMatrix.length)) {
|
|
389
386
|
let newIndex = 0;
|
|
390
387
|
for (
|
|
391
388
|
let cellOrderingIndex = 0;
|
|
@@ -397,13 +394,13 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
397
394
|
const cellIndex = expressionRowLookUp.get(cell);
|
|
398
395
|
for (
|
|
399
396
|
let geneIndex = 0;
|
|
400
|
-
geneIndex <
|
|
397
|
+
geneIndex < featureIndex.length;
|
|
401
398
|
geneIndex += 1
|
|
402
399
|
) {
|
|
403
|
-
const index = cellIndex *
|
|
400
|
+
const index = cellIndex * featureIndex.length + geneIndex;
|
|
404
401
|
paddedExpressionContainer[
|
|
405
402
|
newIndex % (DATA_TEXTURE_SIZE * DATA_TEXTURE_SIZE)
|
|
406
|
-
] =
|
|
403
|
+
] = uint8ObsFeatureMatrix[index];
|
|
407
404
|
newIndex = transpose ? newIndex + cellOrdering.length : newIndex + 1;
|
|
408
405
|
}
|
|
409
406
|
}
|
|
@@ -425,8 +422,9 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
425
422
|
transpose,
|
|
426
423
|
axisTopLabels,
|
|
427
424
|
axisLeftLabels,
|
|
428
|
-
|
|
425
|
+
uint8ObsFeatureMatrix,
|
|
429
426
|
expressionRowLookUp,
|
|
427
|
+
featureIndex,
|
|
430
428
|
gl,
|
|
431
429
|
]);
|
|
432
430
|
|
|
@@ -436,8 +434,8 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
436
434
|
// - the `aggSizeX` or `aggSizeY` have changed, or
|
|
437
435
|
// - the cell ordering has changed.
|
|
438
436
|
const heatmapLayers = useMemo(() => {
|
|
439
|
-
const usePaddedExpressions =
|
|
440
|
-
&& shouldUsePaddedImplementation(
|
|
437
|
+
const usePaddedExpressions = uint8ObsFeatureMatrix
|
|
438
|
+
&& shouldUsePaddedImplementation(uint8ObsFeatureMatrix.length);
|
|
441
439
|
if ((!tilesRef.current || backlog.length) && !usePaddedExpressions) {
|
|
442
440
|
return [];
|
|
443
441
|
}
|
|
@@ -445,7 +443,6 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
445
443
|
const cellOrdering = transpose ? axisTopLabels : axisLeftLabels;
|
|
446
444
|
// eslint-disable-next-line no-inner-declarations, no-shadow
|
|
447
445
|
function getLayer(i, j) {
|
|
448
|
-
const { cols } = expression;
|
|
449
446
|
return new PaddedExpressionHeatmapBitmapLayer({
|
|
450
447
|
id: `heatmapLayer-${i}-${j}`,
|
|
451
448
|
image: paddedExpressions,
|
|
@@ -460,8 +457,8 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
460
457
|
numXTiles: xTiles,
|
|
461
458
|
numYTiles: yTiles,
|
|
462
459
|
origDataSize: transpose
|
|
463
|
-
? [
|
|
464
|
-
: [cellOrdering.length,
|
|
460
|
+
? [featureIndex.length, cellOrdering.length]
|
|
461
|
+
: [cellOrdering.length, featureIndex.length],
|
|
465
462
|
aggSizeX,
|
|
466
463
|
aggSizeY,
|
|
467
464
|
colormap,
|
|
@@ -503,16 +500,24 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
503
500
|
(tile, index) => getLayer(Math.floor(index / xTiles), index % xTiles, tile),
|
|
504
501
|
);
|
|
505
502
|
return layers;
|
|
506
|
-
}, [
|
|
507
|
-
paddedExpressions, matrixLeft, tileWidth, matrixTop, tileHeight,
|
|
508
|
-
aggSizeX, aggSizeY, colormap, colormapRange, tileIteration]);
|
|
503
|
+
}, [uint8ObsFeatureMatrix, backlog.length, transpose, axisTopLabels, axisLeftLabels,
|
|
504
|
+
paddedExpressions, matrixLeft, tileWidth, matrixTop, tileHeight, yTiles, xTiles,
|
|
505
|
+
aggSizeX, aggSizeY, colormap, colormapRange, tileIteration, featureIndex]);
|
|
509
506
|
const axisLeftDashes = (transpose ? variablesDashes : observationsDashes);
|
|
510
507
|
const axisTopDashes = (transpose ? observationsDashes : variablesDashes);
|
|
511
508
|
|
|
512
509
|
// Map cell and gene names to arrays with indices,
|
|
513
510
|
// to prepare to render the names in TextLayers.
|
|
514
|
-
|
|
515
|
-
|
|
511
|
+
// We do the mapping with featureLabelsMap here at one of the final steps before rendering
|
|
512
|
+
// since it is for presentational purposes.
|
|
513
|
+
const axisTopLabelData = useMemo(() => (!transpose && featureLabelsMap
|
|
514
|
+
? axisTopLabels.map(d => featureLabelsMap.get(d) || d)
|
|
515
|
+
: axisTopLabels
|
|
516
|
+
).map((d, i) => [i, (axisTopDashes ? `- ${d}` : d)]), [axisTopLabels, axisTopDashes, transpose, featureLabelsMap]);
|
|
517
|
+
const axisLeftLabelData = useMemo(() => (transpose && featureLabelsMap
|
|
518
|
+
? axisLeftLabels.map(d => featureLabelsMap.get(d) || d)
|
|
519
|
+
: axisLeftLabels
|
|
520
|
+
).map((d, i) => [i, (axisLeftDashes ? `${d} -` : d)]), [axisLeftLabels, axisLeftDashes, transpose, featureLabelsMap]);
|
|
516
521
|
const cellColorLabelsData = useMemo(() => cellColorLabels.map((d, i) => [i, d && (transpose ? `${d} -` : `- ${d}`)]), [cellColorLabels, transpose]);
|
|
517
522
|
|
|
518
523
|
const hideTopLabels = (transpose ? hideObservationLabels : hideVariableLabels);
|
|
@@ -697,7 +702,7 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
697
702
|
|
|
698
703
|
// Set up the onHover function.
|
|
699
704
|
function onHover(info, event) {
|
|
700
|
-
if (!
|
|
705
|
+
if (!uint8ObsFeatureMatrix) {
|
|
701
706
|
return;
|
|
702
707
|
}
|
|
703
708
|
|
|
@@ -728,10 +733,10 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
728
733
|
setTrackHighlight(null);
|
|
729
734
|
setColorEncoding('geneSelection');
|
|
730
735
|
} else { // we are hovering over a cell colored track
|
|
731
|
-
const obsI =
|
|
736
|
+
const obsI = obsIndex.indexOf(transpose
|
|
732
737
|
? axisTopLabels[trackColI]
|
|
733
738
|
: axisLeftLabels[trackColI]);
|
|
734
|
-
const cellIndex =
|
|
739
|
+
const cellIndex = obsIndex[obsI];
|
|
735
740
|
setTrackHighlight([cellIndex, trackI, mouseX, mouseY]);
|
|
736
741
|
highlightedCell = cellIndex;
|
|
737
742
|
setColorEncoding('cellSelection');
|
|
@@ -749,17 +754,17 @@ const Heatmap = forwardRef((props, deckRef) => {
|
|
|
749
754
|
numCols: width,
|
|
750
755
|
});
|
|
751
756
|
|
|
752
|
-
const obsI =
|
|
757
|
+
const obsI = obsIndex.indexOf(transpose
|
|
753
758
|
? axisTopLabels[colI]
|
|
754
759
|
: axisLeftLabels[rowI]);
|
|
755
|
-
const varI =
|
|
760
|
+
const varI = featureIndex.indexOf(transpose
|
|
756
761
|
? axisLeftLabels[rowI]
|
|
757
762
|
: axisTopLabels[colI]);
|
|
758
763
|
|
|
759
|
-
const obsId =
|
|
764
|
+
const obsId = obsIndex[obsI];
|
|
760
765
|
|
|
761
766
|
// We need to use featureIndex here,
|
|
762
|
-
// because
|
|
767
|
+
// because featureIndex may be mapped to
|
|
763
768
|
// use featureLabels (if those were available in the dataset).
|
|
764
769
|
// Highlights and selections are assumed to be in terms of
|
|
765
770
|
// obsIndex/featureIndex (as opposed to obsLabels/featureLabels).
|
package/src/Heatmap.test.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable func-names */
|
|
2
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
3
|
import '@testing-library/jest-dom';
|
|
3
4
|
import { cleanup, render } from '@testing-library/react';
|
|
4
|
-
import { afterEach } from 'vitest';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
7
|
import Heatmap from './Heatmap.js';
|
package/src/HeatmapSubscriber.js
CHANGED
|
@@ -101,24 +101,25 @@ export function HeatmapSubscriber(props) {
|
|
|
101
101
|
// setObsColorEncoding with 'geneSelection' or 'cellSetSelection' upon a click.
|
|
102
102
|
const [hoveredColorEncoding, setHoveredColorEncoding] = useState('geneSelection');
|
|
103
103
|
|
|
104
|
-
const [urls, addUrl] = useUrls(loaders, dataset);
|
|
105
104
|
const [width, height, deckRef] = useDeckCanvasSize();
|
|
106
105
|
|
|
107
106
|
// Get data from loaders using the data hooks.
|
|
108
107
|
const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(
|
|
109
|
-
coordinationScopes, obsType, loaders, dataset,
|
|
108
|
+
coordinationScopes, obsType, loaders, dataset,
|
|
110
109
|
);
|
|
111
110
|
// TODO: support multiple feature labels using featureLabelsType coordination values.
|
|
112
|
-
const [{ featureLabelsMap }, featureLabelsStatus] = useFeatureLabelsData(
|
|
113
|
-
loaders, dataset,
|
|
111
|
+
const [{ featureLabelsMap }, featureLabelsStatus, featureLabelsUrls] = useFeatureLabelsData(
|
|
112
|
+
loaders, dataset, false, {}, {},
|
|
114
113
|
{ featureType },
|
|
115
114
|
);
|
|
116
|
-
const [
|
|
117
|
-
|
|
115
|
+
const [
|
|
116
|
+
{ obsIndex, featureIndex, obsFeatureMatrix }, matrixStatus, matrixUrls,
|
|
117
|
+
] = useObsFeatureMatrixData(
|
|
118
|
+
loaders, dataset, true, {}, {},
|
|
118
119
|
{ obsType, featureType, featureValueType },
|
|
119
120
|
);
|
|
120
|
-
const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus] = useObsSetsData(
|
|
121
|
-
loaders, dataset,
|
|
121
|
+
const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus, obsSetsUrls] = useObsSetsData(
|
|
122
|
+
loaders, dataset, false,
|
|
122
123
|
{ setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor },
|
|
123
124
|
{ obsSetSelection: cellSetSelection, obsSetColor: cellSetColor },
|
|
124
125
|
{ obsType },
|
|
@@ -128,6 +129,11 @@ export function HeatmapSubscriber(props) {
|
|
|
128
129
|
matrixStatus,
|
|
129
130
|
obsSetsStatus,
|
|
130
131
|
]);
|
|
132
|
+
const urls = useUrls([
|
|
133
|
+
featureLabelsUrls,
|
|
134
|
+
matrixUrls,
|
|
135
|
+
obsSetsUrls,
|
|
136
|
+
]);
|
|
131
137
|
|
|
132
138
|
const [uint8ObsFeatureMatrix, obsFeatureMatrixExtent] = useUint8ObsFeatureMatrix(
|
|
133
139
|
{ obsFeatureMatrix },
|
|
@@ -160,20 +166,6 @@ export function HeatmapSubscriber(props) {
|
|
|
160
166
|
return null;
|
|
161
167
|
}, [variablesLabel, featureLabelsMap]);
|
|
162
168
|
|
|
163
|
-
const expressionMatrix = useMemo(() => {
|
|
164
|
-
if (obsIndex && featureIndex && uint8ObsFeatureMatrix) {
|
|
165
|
-
return {
|
|
166
|
-
rows: obsIndex,
|
|
167
|
-
cols: (featureLabelsMap
|
|
168
|
-
? featureIndex.map(key => featureLabelsMap.get(key) || key)
|
|
169
|
-
: featureIndex
|
|
170
|
-
),
|
|
171
|
-
matrix: uint8ObsFeatureMatrix.data,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
return null;
|
|
175
|
-
}, [obsIndex, featureIndex, uint8ObsFeatureMatrix, featureLabelsMap]);
|
|
176
|
-
|
|
177
169
|
const cellsCount = obsIndex ? obsIndex.length : 0;
|
|
178
170
|
const genesCount = featureIndex ? featureIndex.length : 0;
|
|
179
171
|
|
|
@@ -239,12 +231,14 @@ export function HeatmapSubscriber(props) {
|
|
|
239
231
|
width={width}
|
|
240
232
|
theme={theme}
|
|
241
233
|
uuid={uuid}
|
|
242
|
-
|
|
234
|
+
uint8ObsFeatureMatrix={uint8ObsFeatureMatrix?.data}
|
|
243
235
|
cellColors={cellColors}
|
|
244
236
|
colormap={geneExpressionColormap}
|
|
245
237
|
setIsRendering={setIsRendering}
|
|
246
238
|
setCellHighlight={setCellHighlight}
|
|
247
239
|
setGeneHighlight={setGeneHighlight}
|
|
240
|
+
featureLabelsMap={featureLabelsMap}
|
|
241
|
+
obsIndex={obsIndex}
|
|
248
242
|
featureIndex={featureIndex}
|
|
249
243
|
setTrackHighlight={setTrackHighlight}
|
|
250
244
|
setComponentHover={() => {
|
|
@@ -16,8 +16,8 @@ export default function HeatmapTooltipSubscriber(props) {
|
|
|
16
16
|
const [cellInfo, cellCoord] = (obsHighlight && getObsInfo ? (
|
|
17
17
|
[
|
|
18
18
|
getObsInfo(obsHighlight),
|
|
19
|
-
(viewInfo && viewInfo.
|
|
20
|
-
? viewInfo.
|
|
19
|
+
(viewInfo && viewInfo.projectFromId
|
|
20
|
+
? viewInfo.projectFromId(obsHighlight, null)[(transpose ? 0 : 1)]
|
|
21
21
|
: null),
|
|
22
22
|
]
|
|
23
23
|
) : ([null, null]));
|
|
@@ -25,8 +25,8 @@ export default function HeatmapTooltipSubscriber(props) {
|
|
|
25
25
|
const [geneInfo, geneCoord] = (featureHighlight && getFeatureInfo ? (
|
|
26
26
|
[
|
|
27
27
|
getFeatureInfo(featureHighlight),
|
|
28
|
-
(viewInfo && viewInfo.
|
|
29
|
-
? viewInfo.
|
|
28
|
+
(viewInfo && viewInfo.projectFromId
|
|
29
|
+
? viewInfo.projectFromId(null, featureHighlight)[(transpose ? 1 : 0)]
|
|
30
30
|
: null),
|
|
31
31
|
]
|
|
32
32
|
) : ([null, null]));
|
package/src/utils.test.js
CHANGED