Skip to content

Commit

Permalink
feat: scale bar for zoom (SCE-26, SCE-25, SCE-27) (#1125)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaloster authored Oct 8, 2024
1 parent 1f0048f commit 49e8d14
Show file tree
Hide file tree
Showing 15 changed files with 802 additions and 80 deletions.
2 changes: 1 addition & 1 deletion .infra/rdev/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ stack:
services:
explorer:
image:
tag: sha-e352565b
tag: sha-f9dbb3ff
replicaCount: 1
env:
# env vars common to all deployment stages
Expand Down
42 changes: 24 additions & 18 deletions client/__tests__/util/stateManager/colorHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ describe("categorical color helpers", () => {
});

const catColCategories = schema.annotations.obs.columns[2].categories;
const isSpatial = false;
const obsDataframe = new Dataframe.Dataframe(
[schema.dataframe.nObs, 2],
[
Expand All @@ -88,12 +89,14 @@ describe("categorical color helpers", () => {
);

test("default category order", () => {
const ct = createColorTable(
"color by categorical metadata",
"categoricalColumn",
obsDataframe,
schema
);
const ct = createColorTable({
colorMode: "color by categorical metadata",
colorByAccessor: "categoricalColumn",
colorByData: obsDataframe,
schema,
userColors: null,
isSpatial,
});
expect(ct).toBeDefined();
const data = obsDataframe.col("categoricalColumn").asArray();
const cats = schema.annotations.obsByName.categoricalColumn.categories;
Expand All @@ -105,12 +108,14 @@ describe("categorical color helpers", () => {
test("shuffle category order", () => {
const schemaClone = indexSchema(JSON.parse(JSON.stringify(schema)));
shuffle(schemaClone.annotations.obsByName.categoricalColumn.categories);
const ct = createColorTable(
"color by categorical metadata",
"categoricalColumn",
obsDataframe,
schemaClone
);
const ct = createColorTable({
colorMode: "color by categorical metadata",
colorByAccessor: "categoricalColumn",
colorByData: obsDataframe,
schema: schemaClone,
userColors: null,
isSpatial,
});
expect(ct).toBeDefined();
const data = obsDataframe.col("categoricalColumn").asArray();
const cats = schemaClone.annotations.obsByName.categoricalColumn.categories;
Expand Down Expand Up @@ -139,13 +144,14 @@ describe("categorical color helpers", () => {
const userColors = loadUserColorConfig(userDefinedColorTable);
expect(userColors).toBeDefined();

const ct = createColorTable(
"color by categorical metadata",
"categoricalColumn",
obsDataframe,
const ct = createColorTable({
colorMode: "color by categorical metadata",
colorByAccessor: "categoricalColumn",
colorByData: obsDataframe,
schema,
userColors
);
userColors,
isSpatial,
});
expect(ct).toBeDefined();
const data = obsDataframe.col("categoricalColumn").asArray();
for (let i = 0; i < schema.dataframe.nObs; i += 1) {
Expand Down
20 changes: 20 additions & 0 deletions client/configuration/eslint/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,26 @@ module.exports = {
"@typescript-eslint/no-var-requires": "off",
},
},
{
files: ["src/components/Graph/openseadragon-scalebar.js"],
rules: {
"func-names": "off",
"@typescript-eslint/no-redeclare": "off",
"global-require": "off",
"no-var": "off",
"vars-on-top": "off",
"block-scoped-var": "off",
"@typescript-eslint/no-this-alias": "off",
"consistent-return": "off",
"no-restricted-properties": [
"off",
{
object: "Math",
property: "pow",
},
],
},
},
],
};
/* eslint-enable @blueprintjs/classes-constants -- we don't import blueprint here */
49 changes: 35 additions & 14 deletions client/src/components/Graph/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import memoize from "memoize-one";
import Async, { AsyncProps } from "react-async";
import { Button, Icon } from "@blueprintjs/core";
import Openseadragon, { Viewer } from "openseadragon";
import "./openseadragon-scalebar";
import { throttle } from "lodash";
import { IconNames } from "@blueprintjs/icons";
import _camera, { Camera } from "util/camera";
Expand All @@ -23,7 +24,7 @@ import { Dataframe } from "util/dataframe";
import { RootState } from "reducers";
import { Field } from "common/types/schema";
import { Query } from "annoMatrix/query";
import { THROTTLE_MS } from "util/constants";
import { SLIDE_SIZE, THROTTLE_MS } from "util/constants";
import { isSpatialMode, shouldShowOpenseadragon } from "common/selectors";
import { fetchDeepZoomImageFailed } from "actions/config";
import { track } from "analytics";
Expand Down Expand Up @@ -846,7 +847,11 @@ class Graph extends React.Component<GraphProps, GraphState> {
const Y = layoutDf.col(currentDimNames[1]).asArray();

const positions = this.computePointPositions(X, Y, modelTF);
const colorTable = this.updateColorTable(colorsProp, colorDf);
const colorTable = this.updateColorTable(
colorsProp,
colorDf,
isSpatialMode(this.props)
);
const colorByData = colorDf?.icol(0)?.asArray();

const {
Expand Down Expand Up @@ -1120,28 +1125,28 @@ class Graph extends React.Component<GraphProps, GraphState> {

updateColorTable(
colors: RootState["colors"],
colorDf: Dataframe | null
colorDf: Dataframe | null,
isSpatial: boolean
): ColorTable {
const { annoMatrix } = this.props;
const { schema } = annoMatrix;

/* update color table state */
if (!colors || !colorDf) {
return createColorTable(
null, // default mode
null,
null,
return createColorTable({
schema,
null
);
isSpatial,
});
}
const { colorAccessor, userColors, colorMode } = colors;
return createColorTable(
return createColorTable({
colorMode,
colorAccessor,
colorDf,
colorByAccessor: colorAccessor,
colorByData: colorDf,
schema,
userColors
);
userColors,
isSpatial,
});
}

createColorByQuery(colors: RootState["colors"]): [Field, Query] | null {
Expand All @@ -1162,6 +1167,7 @@ class Graph extends React.Component<GraphProps, GraphState> {
isSidePanel = false,
imageUnderlay,
imageOpacity,
unsMetadata,
} = this.props;

if (
Expand All @@ -1187,6 +1193,21 @@ class Graph extends React.Component<GraphProps, GraphState> {
opacity: imageOpacity / 100,
});

const { imageHeight } = unsMetadata;

const calculatedPixelsPerMeter = imageHeight / SLIDE_SIZE;

this.openseadragon.scalebar({
type: Openseadragon.ScalebarType.MICROSCOPY,
pixelsPerMeter: calculatedPixelsPerMeter,
minWidth: "75px",
location: Openseadragon.ScalebarLocation.BOTTOM_LEFT,
color: "black",
fontColor: "black",
backgroundColor: "rgba(255, 255, 255, 0.5)",
barThickness: 2,
});

/**
* (thuang): Remove the openseadragon element when the image fails to load,
* likely because the image is not found in the S3 bucket.
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Graph/drawPointsRegl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default function drawPointsRegl(regl: Regl) {
getFlags(flag, isBackground, isSelected, isHighlight);
if (isSpatial) {
size = pointSizeSpatial(nPoints, minViewportDimension, isSelected, isHighlight, distance, imageHeight, scaleref, spotDiameterFullres);
size = pointSizeSpatial(minViewportDimension, isSelected, isHighlight, distance, imageHeight, scaleref, spotDiameterFullres);
} else {
size = pointSize(nPoints, minViewportDimension, isSelected, isHighlight);
}
Expand Down
Loading

0 comments on commit 49e8d14

Please sign in to comment.