From 3534d5f17b106dae6fba1c8d2ed9c8ccf896e636 Mon Sep 17 00:00:00 2001
From: Matus Talcik <matus.talcik@outlook.com>
Date: Wed, 17 Aug 2022 00:49:34 +0200
Subject: [PATCH] fix bugs here and there

---
 .../ChromatinViewportConfigurationPanel.tsx   |  34 ++--
 .../components/RightPanel/SelectionsPart.tsx  |  14 +-
 app/src/components/Tools/ToolOptions.tsx      |   2 +-
 .../viewports/ChromatinViewport.tsx           | 189 +++++++++---------
 .../storage/models/viewports/chromatin.ts     |   2 +-
 .../src/viewports/chromatin_viewport.ts       |   2 +-
 6 files changed, 116 insertions(+), 127 deletions(-)

diff --git a/app/src/components/RightPanel/ChromatinViewportConfigurationPanel.tsx b/app/src/components/RightPanel/ChromatinViewportConfigurationPanel.tsx
index 0ca17e0..2c34a1b 100644
--- a/app/src/components/RightPanel/ChromatinViewportConfigurationPanel.tsx
+++ b/app/src/components/RightPanel/ChromatinViewportConfigurationPanel.tsx
@@ -38,6 +38,7 @@ export function ChromatinViewportConfigurationPanel(props: {
         }
     > = [
             { key: 'single-color', id: 'none', text: 'Single color' },
+            { key: 'selections', id: 'none', text: 'Selections' },
             {
                 key: 'centromers',
                 id: 'centromers',
@@ -281,7 +282,7 @@ export function ChromatinViewportConfigurationPanel(props: {
 
             representation: ChromatinRepresentation.Spheres,
 
-            color: getColorFromRGBA({ r: 255, g: 255, b: 255, a: 100}),
+            color: getColorFromRGBA({ r: 255, g: 255, b: 255, a: 100 }),
 
             radius,
             radiusRange,
@@ -608,7 +609,7 @@ export function ChromatinViewportConfigurationPanel(props: {
         (<div className={"treeViewListItem " + (configuration.selectedDatum == index ? 'selected' : '')} key={index} onClick={() => setSelectedDatum(index)}>
             <span style={{ display: 'block', width: '4px' }}></span>
             <Text className="text" nowrap>{datum.id}</Text>
-            <Delete16Regular primaryFill={'white'} className='icon iconHoverRed' onClick={(e) => { e.stopPropagation(); removeData3D(index); } }></Delete16Regular>
+            <Delete16Regular primaryFill={'white'} className='icon iconHoverRed' onClick={(e) => { e.stopPropagation(); removeData3D(index); }}></Delete16Regular>
         </div>)
         )}
 
@@ -663,7 +664,7 @@ export function ChromatinViewportConfigurationPanel(props: {
             <DefaultButton id="singleColorButton" styles={{
                 root: { width: 'calc(100% - 8px)', margin: '0px 4px 0px 4px' }
             }} key="singleColorButton" onClick={() => setIsSingleColorCalloutVisible(true)}>
-                <span style={{ color: '#' + configuration.data[configuration.selectedDatum].color.hex}}>{configuration.data[configuration.selectedDatum].color.hex}</span>
+                <span style={{ color: '#' + configuration.data[configuration.selectedDatum].color.hex }}>{configuration.data[configuration.selectedDatum].color.hex}</span>
             </DefaultButton>
             {isSingleColorCalloutVisible && (
                 <Callout
@@ -685,6 +686,20 @@ export function ChromatinViewportConfigurationPanel(props: {
             )}
         </>}
 
+        {configuration.selectedDatum != null && configuration.data.length > configuration.selectedDatum && configuration.data[configuration.selectedDatum].colorMappingMode == 'selections' && <>
+            <div style={{ display: 'block', width: '100%', marginTop: '8px' }}></div>
+
+            {configuration.selectedDatum != null && (
+                <SelectionsPart
+                    selections={selections}
+                    configurationReducer={configurationReducer}
+                    dataReducer={props.dataReducer}
+                    selectionsReducer={props.selectionsReducer}
+                    selectedDataIndex={configuration.selectedDatum}
+                ></SelectionsPart>
+            )}
+        </>}
+
         {configuration.selectedDatum != null && configuration.data.length > configuration.selectedDatum && configuration.data[configuration.selectedDatum].colorMappingMode == 'centromers' && <>
             {centromerDataOptions.length <= 0 && ("No more data available.")}
             {
@@ -860,19 +875,6 @@ export function ChromatinViewportConfigurationPanel(props: {
             }
         </>}
 
-        {/* SELECTIONS */}
-        <div style={{ display: 'block', width: '100%', marginTop: '16px' }}></div>
-        <Separator></Separator>
-        {configuration.selectedDatum != null && (
-            <SelectionsPart
-                selections={selections}
-                configurationReducer={configurationReducer}
-                dataReducer={props.dataReducer}
-                selectionsReducer={props.selectionsReducer}
-                selectedDataIndex={configuration.selectedDatum}
-            ></SelectionsPart>
-        )}
-
         {/* <Separator></Separator>
         <Text nowrap block variant='large'>Labeling</Text>
         <Checkbox label="Show labels" checked={configuration.labeling.showLabelingOverlay} onChange={handleShowLabelingOverlayChange} />
diff --git a/app/src/components/RightPanel/SelectionsPart.tsx b/app/src/components/RightPanel/SelectionsPart.tsx
index f68358b..d3cb6fa 100644
--- a/app/src/components/RightPanel/SelectionsPart.tsx
+++ b/app/src/components/RightPanel/SelectionsPart.tsx
@@ -56,10 +56,10 @@ export function SelectionsPart<T extends ConfigurationsWithSelections>(props: Pr
     }
 
     const selectSelection = (selectionID: SelectionID) => {
-        if (configuration.type === ViewportConfigurationType.Chromatin && configuration.selectedDatum != null) {
+        if (configuration.type === ViewportConfigurationType.Chromatin && props.selectedDataIndex != null) {
             const newData = [...configuration.data];
-            newData[configuration.selectedDatum] = {
-                ...newData[configuration.selectedDatum],
+            newData[props.selectedDataIndex] = {
+                ...newData[props.selectedDataIndex],
                 selectedSelectionID: selectionID,
             };
 
@@ -147,8 +147,6 @@ export function SelectionsPart<T extends ConfigurationsWithSelections>(props: Pr
     }
 
     function changeSelectionColor(selectionID: SelectionID, color: IColor) {
-        console.log(color);
-
         globalSelectionsDispatch({
             type: SelectionActionKind.UPDATE,
             id: selectionID,
@@ -162,13 +160,11 @@ export function SelectionsPart<T extends ConfigurationsWithSelections>(props: Pr
     }
 
     const isSelected = (id: SelectionID) => {
-        if (configuration.type === ViewportConfigurationType.Chromatin && configuration.selectedDatum && configuration.data[configuration.selectedDatum]) {
-            return configuration.data[configuration.selectedDatum].selectedSelectionID == id;
+        if (configuration.type === ViewportConfigurationType.Chromatin) {
+            return configuration.data[props.selectedDataIndex].selectedSelectionID == id;
         } else {
             return configuration.selectedSelectionID == id;
         }
-
-        return false;
     }
 
     return <>
diff --git a/app/src/components/Tools/ToolOptions.tsx b/app/src/components/Tools/ToolOptions.tsx
index 63c95a8..34fe859 100644
--- a/app/src/components/Tools/ToolOptions.tsx
+++ b/app/src/components/Tools/ToolOptions.tsx
@@ -19,7 +19,7 @@ export function ToolOptions(props: {
     
     let hasSelectedSelection = configuration.selectedSelectionID != null;
 
-    if (configuration.type == ViewportConfigurationType.Chromatin && configuration.selectedDatum && configuration.data[configuration.selectedDatum]) {
+    if (configuration.type == ViewportConfigurationType.Chromatin && configuration.selectedDatum != null && configuration.data[configuration.selectedDatum]) {
         hasSelectedSelection = configuration.data[configuration.selectedDatum].selectedSelectionID != null;
     }
 
diff --git a/app/src/components/viewports/ChromatinViewport.tsx b/app/src/components/viewports/ChromatinViewport.tsx
index f9aac25..5336da7 100644
--- a/app/src/components/viewports/ChromatinViewport.tsx
+++ b/app/src/components/viewports/ChromatinViewport.tsx
@@ -117,29 +117,29 @@ export function ChromatinViewport(props: {
     }, [layoutGenerator, viewport, viewport.width, viewport.height]);
 
     // Camera Update
-    // useDeepCompareEffect(() => {
-    //     viewport.cameraConfiguration = configuration.camera;
-    // }, [configuration.camera]);
+    useDeepCompareEffect(() => {
+        viewport.cameraConfiguration = configuration.camera;
+    }, [configuration.camera]);
 
-    // useDeepCompareEffect(() => {
-    //     if (!viewport.camera || !viewport.canvas) return;
+    useDeepCompareEffect(() => {
+        if (!viewport.camera || !viewport.canvas) return;
 
-    //     const timer = setTimeout(() => {
-    //         updateConfiguration({
-    //             ...configuration,
-    //             camera: viewport.cameraConfiguration
-    //         });
-    //     }, 500)
+        const timer = setTimeout(() => {
+            updateConfiguration({
+                ...configuration,
+                camera: viewport.cameraConfiguration
+            });
+        }, 500)
 
-    //     return () => clearTimeout(timer);
-    // }, [viewport.cameraConfiguration]);
+        return () => clearTimeout(timer);
+    }, [viewport.cameraConfiguration]);
 
     // Disable camera if control is pressed
     useEffect(() => {
         if (!viewport || !viewport.camera) return;
 
         viewport.camera.ignoreEvents = isPrimaryModPressed;
-    }, [isPrimaryModPressed]);
+    }, [viewport, isPrimaryModPressed]);
 
     // remove data removed from data tab 
     // useEffect(() => {
@@ -152,7 +152,7 @@ export function ChromatinViewport(props: {
     // }, [data, globalSelections]);
 
     useEffect(() => {
-        if (!viewport.canvas || !configuration.data) return;
+        if (!viewport.canvas) return;
 
         viewport.clearChromatin();
 
@@ -244,6 +244,8 @@ export function ChromatinViewport(props: {
                     configurationDatum.color.b / 255.0,
                     1.0
                 )));
+            } else if (configurationDatum.colorMappingMode == "selections") {
+                newColors[configurationDatumIndex] = data3D.cacheColorArray(new Array(binsAmount).fill(vec4.fromValues(1.0, 1.0, 1.0, 1.0)));
             }
         }
 
@@ -569,7 +571,7 @@ export function ChromatinViewport(props: {
 
     // Color bins
     useEffect(() => {
-        if (!viewport.canvas || !configuration.data) {
+        if (!viewport.canvas) {
             return;
         }
 
@@ -611,14 +613,8 @@ export function ChromatinViewport(props: {
             return;
         }
 
-        let intersectionBin = closestIntersection.binIndex;
-        if (interesctionSecondaryData) {
-            // intersectionBin = ;
-        }
-
-
         if (closestIntersection != null && tool.type == ChromatinViewportToolType.PointSelection) {
-            closestIntersection.chromatinPart.setBinColor(intersectionBin, { r: selection.color.r, g: selection.color.g, b: selection.color.b, a: 1.0 });
+            closestIntersection.chromatinPart.setBinColor(closestIntersection.binIndex, { r: selection.color.r, g: selection.color.g, b: selection.color.b, a: 1.0 });
         } else if (closestIntersection != null && tool.type == ChromatinViewportToolType.SphereSelection && configuration.data[selectedDatum].selectedSelectionID) {
             // Only find position in space where the ray intersects
             const intersectionExactPosition = vec3.add(vec3.create(), closestIntersection.ray.origin, vec3.scale(vec3.create(), closestIntersection.ray.direction, closestIntersection.distance));
@@ -710,7 +706,7 @@ export function ChromatinViewport(props: {
         }
         // console.timeEnd('colorBins::intersection');
         // console.timeEnd('colorBins');
-    }, [viewport, closestIntersection, colors, configuration.data, configuration.tool, configuration.selectedSelectionID, configuration.chromosomes, data.data, globalSelections.selections, isShiftPressed]);
+    }, [viewport, closestIntersection, colors, configuration.data, configuration.selectedDatum, configuration.tool, configuration.selectedSelectionID, configuration.chromosomes, data.data, globalSelections.selections, isShiftPressed]);
 
     useEffect(() => {
         if (viewport && configuration.backgroundColor) {
@@ -781,112 +777,107 @@ export function ChromatinViewport(props: {
 
 
     const onClick = () => {
-        if (!viewport || !configuration.data || !closestIntersection || !isPrimaryModPressed || !configuration.tool || !configuration.selectedSelectionID) {
+        if (!viewport || !configuration.data || !closestIntersection || !isPrimaryModPressed || !configuration.tool || configuration.selectedDatum == null || !configuration.data[configuration.selectedDatum]) {
             return;
         }
 
-        /*
-
+        const datum = configuration.data[configuration.selectedDatum];
         const tool = configuration.tool;
-        const selectionId = configuration.selectedSelectionID;
 
-        const selectedChromatinPart = viewport.getChromatinPartByChromosomeIndex(closestIntersection.chromatinPart.chromosomeIndex);
-        if (!selectedChromatinPart) {
+        const selectionId = datum.selectedSelectionID;
+        if (selectionId == null) {
             return;
         }
 
+        const selectedChromatinPart = closestIntersection.chromatinPart;
+
         const selection = globalSelections.selections.find(s => s.id == selectionId);
         if (!selection) {
             throw "No global selection found with local selection ID " + selectionId;
         }
 
-        const datum = configuration.data;
         const binPositions = data.data.filter(d => d.id == datum.id)[0] as BinPositionsData;
-        const chromosomeSlices = binPositions.chromosomes;
-        const selectedChromosomeIndex = selectedChromatinPart.chromosomeIndex;
-        const selectedChromosomeOffset = binPositions.chromosomes[selectedChromosomeIndex].from;
 
         const newBins: Uint16Array = selection.bins.slice();
         if (tool.type == ChromatinViewportToolType.PointSelection) {
-            newBins[selectedChromosomeOffset + closestIntersection.binIndex] = isSecondaryModPressed ? 0 : 1;
+            newBins[closestIntersection.binIndex] = isSecondaryModPressed ? 0 : 1;
         } else if (tool.type == ChromatinViewportToolType.SphereSelection) {
-            const sphereCenter = vec3.add(vec3.create(), closestIntersection.ray.origin, vec3.scale(vec3.create(), closestIntersection.ray.direction, closestIntersection.distance));
-            const sphereRadius = tool.radius;
-            const value = isSecondaryModPressed ? 0 : 1;
+            // const sphereCenter = vec3.add(vec3.create(), closestIntersection.ray.origin, vec3.scale(vec3.create(), closestIntersection.ray.direction, closestIntersection.distance));
+            // const sphereRadius = tool.radius;
+            // const value = isSecondaryModPressed ? 0 : 1;
 
-            for (let chromosomeIndex = 0; chromosomeIndex < configuration.chromosomes.length; chromosomeIndex++) {
-                const chromatinPart = viewport.getChromatinPartByChromosomeIndex(chromosomeIndex);
-                if (!chromatinPart || !configuration.chromosomes[chromosomeIndex]) continue;
+            // for (let chromosomeIndex = 0; chromosomeIndex < configuration.chromosomes.length; chromosomeIndex++) {
+            //     const chromatinPart = viewport.getChromatinPartByChromosomeIndex(chromosomeIndex);
+            //     if (!chromatinPart || !configuration.chromosomes[chromosomeIndex]) continue;
 
-                const binsPositions = chromatinPart.getBinsPositions();
-                const offset = binPositions.chromosomes[chromosomeIndex].from;
-                for (let binIndex = 0; binIndex < binsPositions.length; binIndex++) {
-                    const binPosition = binsPositions[binIndex];
+            //     const binsPositions = chromatinPart.getBinsPositions();
+            //     const offset = binPositions.chromosomes[chromosomeIndex].from;
+            //     for (let binIndex = 0; binIndex < binsPositions.length; binIndex++) {
+            //         const binPosition = binsPositions[binIndex];
 
-                    if (vec3.distance(binPosition, sphereCenter) < sphereRadius) {
-                        newBins[offset + binIndex] = value;
-                    }
-                }
-            }
+            //         if (vec3.distance(binPosition, sphereCenter) < sphereRadius) {
+            //             newBins[offset + binIndex] = value;
+            //         }
+            //     }
+            // }
         } else if (tool.type == ChromatinViewportToolType.JoinSelection) {
-            if (tool.from == null) {
-                updateConfiguration({
-                    ...configuration,
-                    tool: {
-                        ...tool,
-                        from: selectedChromosomeOffset + closestIntersection.binIndex
-                    }
-                });
-            } else {
-                const closestIntersectionChromosomeOffset = chromosomeSlices[closestIntersection.chromatinPart.chromosomeIndex].from;
+            // if (tool.from == null) {
+            //     updateConfiguration({
+            //         ...configuration,
+            //         tool: {
+            //             ...tool,
+            //             from: selectedChromosomeOffset + closestIntersection.binIndex
+            //         }
+            //     });
+            // } else {
+            //     const closestIntersectionChromosomeOffset = chromosomeSlices[closestIntersection.chromatinPart.chromosomeIndex].from;
 
-                const startBinIndex = Math.min(closestIntersectionChromosomeOffset + closestIntersection.binIndex, tool.from);
-                const endBinIndex = Math.max(closestIntersectionChromosomeOffset + closestIntersection.binIndex, tool.from);
+            //     const startBinIndex = Math.min(closestIntersectionChromosomeOffset + closestIntersection.binIndex, tool.from);
+            //     const endBinIndex = Math.max(closestIntersectionChromosomeOffset + closestIntersection.binIndex, tool.from);
 
-                const value = isSecondaryModPressed ? 0 : 1;
-                for (let chromosomeIndex = 0; chromosomeIndex < configuration.chromosomes.length; chromosomeIndex++) {
-                    const chromatinPart = viewport.getChromatinPartByChromosomeIndex(chromosomeIndex);
-                    if (!chromatinPart) continue;
-
-                    const binsPositions = chromatinPart.getBinsPositions();
-                    const binOffset = chromosomeSlices[chromosomeIndex].from;
-                    for (let binIndex = 0; binIndex < binsPositions.length; binIndex++) {
-                        if (startBinIndex <= (binOffset + binIndex) && (binOffset + binIndex) <= endBinIndex) {
-                            newBins[binOffset + binIndex] = value;
-                        }
-                    }
-                }
+            //     const value = isSecondaryModPressed ? 0 : 1;
+            //     for (let chromosomeIndex = 0; chromosomeIndex < configuration.chromosomes.length; chromosomeIndex++) {
+            //         const chromatinPart = viewport.getChromatinPartByChromosomeIndex(chromosomeIndex);
+            //         if (!chromatinPart) continue;
 
-                updateConfiguration({
-                    ...configuration,
-                    tool: {
-                        ...tool,
-                        from: null,
-                        to: null
-                    }
-                });
-            }
-        } else if (tool.type == ChromatinViewportToolType.Ruler) {
-            const ruler = { ...tool };
+            //         const binsPositions = chromatinPart.getBinsPositions();
+            //         const binOffset = chromosomeSlices[chromosomeIndex].from;
+            //         for (let binIndex = 0; binIndex < binsPositions.length; binIndex++) {
+            //             if (startBinIndex <= (binOffset + binIndex) && (binOffset + binIndex) <= endBinIndex) {
+            //                 newBins[binOffset + binIndex] = value;
+            //             }
+            //         }
+            //     }
 
-            if (!isSecondaryModPressed) {
-                ruler.from = {
-                    bin: closestIntersection.binIndex,
-                    chrom: closestIntersection.chromatinPart.name,
-                };
-            } else {
-                ruler.from = null;
-            }
+            //     updateConfiguration({
+            //         ...configuration,
+            //         tool: {
+            //             ...tool,
+            //             from: null,
+            //             to: null
+            //         }
+            //     });
+            // }
+        } else if (tool.type == ChromatinViewportToolType.Ruler) {
+            // const ruler = { ...tool };
+
+            // if (!isSecondaryModPressed) {
+            //     ruler.from = {
+            //         bin: closestIntersection.binIndex,
+            //         chrom: closestIntersection.chromatinPart.name,
+            //     };
+            // } else {
+            //     ruler.from = null;
+            // }
 
 
-            updateConfiguration({
-                ...configuration,
-                tool: ruler
-            });
+            // updateConfiguration({
+            //     ...configuration,
+            //     tool: ruler
+            // });
         }
 
         globalSelectionsDispatch({ type: SelectionActionKind.UPDATE, id: selectionId, bins: newBins });
-        */
     };
 
     return (<div style={{ width: '100%', height: '100%', overflow: 'hidden', position: 'relative' }}>
diff --git a/app/src/modules/storage/models/viewports/chromatin.ts b/app/src/modules/storage/models/viewports/chromatin.ts
index 67c62c5..4b6e871 100644
--- a/app/src/modules/storage/models/viewports/chromatin.ts
+++ b/app/src/modules/storage/models/viewports/chromatin.ts
@@ -95,7 +95,7 @@ export interface IChromatinDataConfiguration extends IDataConfiguration {
 }
 
 export type ChromatinViewportAggregationFunction = "min" | "max" | "median" | "mean" | 'sum';
-export type ChromatinViewportColorMappingMode = 'single-color' | 'centromers' | '1d-numerical' | '1d-density' | 'linear-order' | 'sasa' | '3d-density';
+export type ChromatinViewportColorMappingMode = 'single-color' | 'selections' | 'centromers' | '1d-numerical' | '1d-density' | 'linear-order' | 'sasa' | '3d-density';
 export type TooltipTextAggregation = 'none' | 'count';
 export type TooltipNumericAggregation = 'none' | 'min' | 'max' | 'median' | 'mean' | 'sum';
 export type LabelingDebugTexture = 'id' | 'contours' | 'dt';
diff --git a/libs/graphics/src/viewports/chromatin_viewport.ts b/libs/graphics/src/viewports/chromatin_viewport.ts
index 4c705d9..f808796 100644
--- a/libs/graphics/src/viewports/chromatin_viewport.ts
+++ b/libs/graphics/src/viewports/chromatin_viewport.ts
@@ -149,7 +149,7 @@ export class ChromatinPart {
   }
 
   public setBinColorVec4(binIndex: number, color: vec4): void {
-    this._binsColor[binIndex] = color;
+    this._binsColor[binIndex] = vec4.clone(color);
 
     if (this._structure instanceof ContinuousTube) {
       if (binIndex == 0) {
-- 
GitLab