@vitessce/vit-s 3.4.12 → 3.5.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/index.js +129 -72
- package/dist-tsc/VitS.d.ts.map +1 -1
- package/dist-tsc/VitS.js +10 -5
- package/dist-tsc/contexts.d.ts +3 -1
- package/dist-tsc/contexts.d.ts.map +1 -1
- package/dist-tsc/contexts.js +27 -2
- package/dist-tsc/hooks.d.ts +14 -5
- package/dist-tsc/hooks.d.ts.map +1 -1
- package/dist-tsc/hooks.js +22 -13
- package/dist-tsc/index.d.ts +2 -2
- package/dist-tsc/index.js +2 -2
- package/dist-tsc/state/hooks.d.ts +7 -0
- package/dist-tsc/state/hooks.d.ts.map +1 -1
- package/dist-tsc/state/hooks.js +9 -0
- package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.d.ts.map +1 -1
- package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.js +16 -27
- package/package.json +9 -9
- package/src/VitS.js +15 -9
- package/src/contexts.js +30 -2
- package/src/hooks.js +24 -15
- package/src/index.js +3 -1
- package/src/state/hooks.js +11 -0
- package/src/vitessce-grid-layout/VitessceGridLayout.js +26 -31
package/dist/index.js
CHANGED
|
@@ -27921,7 +27921,8 @@ const ViewType$1 = {
|
|
|
27921
27921
|
OBS_SET_FEATURE_VALUE_DISTRIBUTION: "obsSetFeatureValueDistribution",
|
|
27922
27922
|
FEATURE_VALUE_HISTOGRAM: "featureValueHistogram",
|
|
27923
27923
|
DOT_PLOT: "dotPlot",
|
|
27924
|
-
FEATURE_BAR_PLOT: "featureBarPlot"
|
|
27924
|
+
FEATURE_BAR_PLOT: "featureBarPlot",
|
|
27925
|
+
BIOMARKER_SELECT: "biomarkerSelect"
|
|
27925
27926
|
};
|
|
27926
27927
|
const DataType$1 = {
|
|
27927
27928
|
OBS_LABELS: "obsLabels",
|
|
@@ -27960,6 +27961,9 @@ const FileType$1 = {
|
|
|
27960
27961
|
// OME-Zarr
|
|
27961
27962
|
IMAGE_OME_ZARR: "image.ome-zarr",
|
|
27962
27963
|
OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
|
|
27964
|
+
// OME-Zarr - Zipped
|
|
27965
|
+
IMAGE_OME_ZARR_ZIP: "image.ome-zarr.zip",
|
|
27966
|
+
OBS_SEGMENTATIONS_OME_ZARR_ZIP: "obsSegmentations.ome-zarr.zip",
|
|
27963
27967
|
// AnnData
|
|
27964
27968
|
OBS_FEATURE_MATRIX_ANNDATA_ZARR: "obsFeatureMatrix.anndata.zarr",
|
|
27965
27969
|
OBS_FEATURE_COLUMNS_ANNDATA_ZARR: "obsFeatureColumns.anndata.zarr",
|
|
@@ -28248,10 +28252,10 @@ const AUTO_INDEPENDENT_COORDINATION_TYPES = [
|
|
|
28248
28252
|
CoordinationType$1.EMBEDDING_OBS_OPACITY
|
|
28249
28253
|
];
|
|
28250
28254
|
const note = "This file is autogenerated by .changeset/post-changelog.mjs.";
|
|
28251
|
-
const version = "3.
|
|
28252
|
-
const date = "2024-
|
|
28255
|
+
const version = "3.5.0";
|
|
28256
|
+
const date = "2024-11-01";
|
|
28253
28257
|
const branch = "changeset-release/main";
|
|
28254
|
-
const hash = "
|
|
28258
|
+
const hash = "1eb007aa";
|
|
28255
28259
|
const META_VERSION = {
|
|
28256
28260
|
note,
|
|
28257
28261
|
version,
|
|
@@ -28631,24 +28635,29 @@ const imageOmeZarrSchema = z.object({
|
|
|
28631
28635
|
imageOmeZarrSchema.extend({
|
|
28632
28636
|
obsTypesFromChannelNames: z.boolean().optional()
|
|
28633
28637
|
});
|
|
28634
|
-
const imageSpatialdataSchema =
|
|
28635
|
-
path: z.string()
|
|
28638
|
+
const imageSpatialdataSchema = z.object({
|
|
28639
|
+
path: z.string(),
|
|
28640
|
+
coordinateSystem: z.string().optional().describe('The name of a coordinate transformation output used to transform the image. If not provided, the "global" coordinate system is assumed.')
|
|
28636
28641
|
});
|
|
28637
28642
|
const obsSegmentationsSpatialdataSchema = z.object({
|
|
28638
|
-
// TODO: should this also extend the imageOmeZarrSchema?
|
|
28639
28643
|
// TODO: should this be renamed labelsSpatialdataSchema?
|
|
28640
28644
|
// TODO: support obsTypesFromChannelNames?
|
|
28641
|
-
path: z.string()
|
|
28645
|
+
path: z.string(),
|
|
28646
|
+
tablePath: z.string().optional().describe("The path to a table which annotates the labels. If available but not specified, the spot identifiers may not be aligned with associated tabular data as expected."),
|
|
28647
|
+
coordinateSystem: z.string().optional().describe('The name of a coordinate transformation output used to transform the image. If not provided, the "global" coordinate system is assumed.')
|
|
28642
28648
|
});
|
|
28643
28649
|
z.object({
|
|
28644
|
-
path: z.string()
|
|
28650
|
+
path: z.string(),
|
|
28651
|
+
coordinateSystem: z.string().optional().describe('The name of a coordinate transformation output used to transform the coordinates. If not provided, the "global" coordinate system is assumed.')
|
|
28645
28652
|
});
|
|
28646
28653
|
const obsSpotsSpatialdataSchema = z.object({
|
|
28647
28654
|
path: z.string(),
|
|
28648
|
-
tablePath: z.string().optional().describe("The path to a table which annotates the spots. If available but not specified, the spot identifiers may not be aligned with associated tabular data as expected.")
|
|
28655
|
+
tablePath: z.string().optional().describe("The path to a table which annotates the spots. If available but not specified, the spot identifiers may not be aligned with associated tabular data as expected."),
|
|
28656
|
+
coordinateSystem: z.string().optional().describe('The name of a coordinate transformation output used to transform the coordinates and radii. If not provided, the "global" coordinate system is assumed.')
|
|
28649
28657
|
});
|
|
28650
28658
|
const obsFeatureMatrixSpatialdataSchema = annDataObsFeatureMatrix.extend({
|
|
28651
|
-
region: z.string().describe("The name of a region to use to filter instances (i.e., rows) in the table").optional()
|
|
28659
|
+
region: z.string().describe("The name of a region to use to filter instances (i.e., rows) in the table").optional(),
|
|
28660
|
+
coordinateSystem: z.string().optional().describe('The name of a coordinate transformation output used to transform the image. If not provided, the "global" coordinate system is assumed.')
|
|
28652
28661
|
});
|
|
28653
28662
|
const obsSetsSpatialdataSchema = z.object({
|
|
28654
28663
|
region: z.string().describe("The name of a region to use to filter instances (i.e., rows) in the table").optional(),
|
|
@@ -28749,15 +28758,21 @@ anndataZarrSchema.extend({
|
|
|
28749
28758
|
z.object({
|
|
28750
28759
|
// TODO: should `image` be a special schema
|
|
28751
28760
|
// to allow specifying fileUid (like for embeddingType)?
|
|
28761
|
+
// TODO: allow multiple images
|
|
28752
28762
|
image: imageSpatialdataSchema,
|
|
28753
28763
|
// TODO: should this be a special schema
|
|
28754
28764
|
// to allow specifying fileUid (like for embeddingType)?
|
|
28765
|
+
// TODO: allow multiple labels
|
|
28755
28766
|
labels: obsSegmentationsSpatialdataSchema,
|
|
28756
28767
|
obsFeatureMatrix: obsFeatureMatrixSpatialdataSchema,
|
|
28757
28768
|
obsSpots: obsSpotsSpatialdataSchema,
|
|
28758
28769
|
// TODO: obsPoints
|
|
28759
28770
|
// TODO: obsLocations
|
|
28760
|
-
obsSets: obsSetsSpatialdataSchema
|
|
28771
|
+
obsSets: obsSetsSpatialdataSchema,
|
|
28772
|
+
// TODO: obsEmbedding
|
|
28773
|
+
// TODO: obsLabels
|
|
28774
|
+
// TODO: featureLabels
|
|
28775
|
+
coordinateSystem: z.string().optional().describe("The name of a coordinate transformation output used to transform all elements which lack a per-element coordinateSystem property.")
|
|
28761
28776
|
}).partial();
|
|
28762
28777
|
z.object({
|
|
28763
28778
|
obsLabelsTypes: z.array(z.string()).optional(),
|
|
@@ -29268,7 +29283,7 @@ class VitessceConfigView {
|
|
|
29268
29283
|
* @param {number} w The width of the view in the layout.
|
|
29269
29284
|
* @param {number} h The height of the view in the layout.
|
|
29270
29285
|
*/
|
|
29271
|
-
constructor(component, coordinationScopes, x, y, w, h) {
|
|
29286
|
+
constructor(component, coordinationScopes, x, y, w, h, uid) {
|
|
29272
29287
|
this.view = {
|
|
29273
29288
|
component,
|
|
29274
29289
|
coordinationScopes,
|
|
@@ -29277,7 +29292,8 @@ class VitessceConfigView {
|
|
|
29277
29292
|
x,
|
|
29278
29293
|
y,
|
|
29279
29294
|
w,
|
|
29280
|
-
h
|
|
29295
|
+
h,
|
|
29296
|
+
uid
|
|
29281
29297
|
};
|
|
29282
29298
|
}
|
|
29283
29299
|
/**
|
|
@@ -29531,7 +29547,7 @@ class VitessceConfig {
|
|
|
29531
29547
|
* @returns {VitessceConfigView} A new view instance.
|
|
29532
29548
|
*/
|
|
29533
29549
|
addView(dataset, component, options) {
|
|
29534
|
-
const { x = 0, y = 0, w = 1, h = 1, mapping = null } = options || {};
|
|
29550
|
+
const { x = 0, y = 0, w = 1, h = 1, uid = void 0, mapping = null } = options || {};
|
|
29535
29551
|
const datasetMatches = this.config.coordinationSpace[CoordinationType$1.DATASET] ? Object.entries(this.config.coordinationSpace[CoordinationType$1.DATASET]).filter(([scopeName, datasetScope2]) => datasetScope2.cValue === dataset.dataset.uid).map(([scopeName]) => scopeName) : [];
|
|
29536
29552
|
let datasetScope;
|
|
29537
29553
|
if (datasetMatches.length === 1) {
|
|
@@ -29542,7 +29558,7 @@ class VitessceConfig {
|
|
|
29542
29558
|
const coordinationScopes = {
|
|
29543
29559
|
[CoordinationType$1.DATASET]: datasetScope
|
|
29544
29560
|
};
|
|
29545
|
-
const newView = new VitessceConfigView(component, coordinationScopes, x, y, w, h);
|
|
29561
|
+
const newView = new VitessceConfigView(component, coordinationScopes, x, y, w, h, uid);
|
|
29546
29562
|
if (mapping) {
|
|
29547
29563
|
const [etScope] = this.addCoordination(CoordinationType$1.EMBEDDING_TYPE);
|
|
29548
29564
|
etScope.setValue(mapping);
|
|
@@ -29560,9 +29576,20 @@ class VitessceConfig {
|
|
|
29560
29576
|
addCoordination(...args) {
|
|
29561
29577
|
const cTypes = args;
|
|
29562
29578
|
const result = [];
|
|
29563
|
-
cTypes.forEach((
|
|
29564
|
-
|
|
29565
|
-
|
|
29579
|
+
cTypes.forEach((cTypeOrObj) => {
|
|
29580
|
+
let cType;
|
|
29581
|
+
let cScope;
|
|
29582
|
+
let cValue;
|
|
29583
|
+
if (typeof cTypeOrObj === "string") {
|
|
29584
|
+
cType = cTypeOrObj;
|
|
29585
|
+
const prevScopes = this.config.coordinationSpace[cType] ? Object.keys(this.config.coordinationSpace[cType]) : [];
|
|
29586
|
+
cScope = this.getNextScope(prevScopes);
|
|
29587
|
+
} else {
|
|
29588
|
+
cType = cTypeOrObj.cType;
|
|
29589
|
+
cScope = cTypeOrObj.cScope;
|
|
29590
|
+
cValue = cTypeOrObj.cValue;
|
|
29591
|
+
}
|
|
29592
|
+
const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
|
|
29566
29593
|
if (!this.config.coordinationSpace[scope.cType]) {
|
|
29567
29594
|
this.config.coordinationSpace[scope.cType] = {};
|
|
29568
29595
|
}
|
|
@@ -29809,7 +29836,7 @@ class VitessceConfig {
|
|
|
29809
29836
|
}
|
|
29810
29837
|
});
|
|
29811
29838
|
config2.layout.forEach((c) => {
|
|
29812
|
-
const newView = new VitessceConfigView(c.component, c.coordinationScopes, c.x, c.y, c.w, c.h);
|
|
29839
|
+
const newView = new VitessceConfigView(c.component, c.coordinationScopes, c.x, c.y, c.w, c.h, c.uid);
|
|
29813
29840
|
vc.config.layout.push(newView);
|
|
29814
29841
|
});
|
|
29815
29842
|
return vc;
|
|
@@ -30762,6 +30789,9 @@ function useSetLoaders() {
|
|
|
30762
30789
|
function useMergeCoordination() {
|
|
30763
30790
|
return useViewConfigStore((state) => state.mergeCoordination);
|
|
30764
30791
|
}
|
|
30792
|
+
function useViewConfig() {
|
|
30793
|
+
return useViewConfigStore((state) => state.viewConfig);
|
|
30794
|
+
}
|
|
30765
30795
|
function useSetViewConfig(viewConfigStoreApi) {
|
|
30766
30796
|
const setViewConfigRef = useRef(viewConfigStoreApi.getState().setViewConfig);
|
|
30767
30797
|
const setViewConfig = setViewConfigRef.current;
|
|
@@ -36699,6 +36729,36 @@ function resolveLayout(layout2) {
|
|
|
36699
36729
|
components
|
|
36700
36730
|
};
|
|
36701
36731
|
}
|
|
36732
|
+
const AsyncFunctionsContext = createContext$1({
|
|
36733
|
+
// {
|
|
36734
|
+
// asyncFunctions: { [functionType: string]: asyncFunction },
|
|
36735
|
+
// queryClient: QueryClient from react-query
|
|
36736
|
+
// }
|
|
36737
|
+
// asyncFunctions will be an object where keys are function types
|
|
36738
|
+
// (as strings) and values are the async functions.
|
|
36739
|
+
});
|
|
36740
|
+
function useAsyncFunction(functionType2) {
|
|
36741
|
+
var _a;
|
|
36742
|
+
const context = useContext(AsyncFunctionsContext);
|
|
36743
|
+
const origFunction = (_a = context == null ? void 0 : context.asyncFunctions) == null ? void 0 : _a[functionType2];
|
|
36744
|
+
const queryClient = context == null ? void 0 : context.queryClient;
|
|
36745
|
+
const partialFunction = (...args) => origFunction({ queryClient }, ...args);
|
|
36746
|
+
return partialFunction;
|
|
36747
|
+
}
|
|
36748
|
+
const PageModeViewContext = createContext$1({
|
|
36749
|
+
// Keys are view UIDs and values are
|
|
36750
|
+
// the corresponding React components.
|
|
36751
|
+
});
|
|
36752
|
+
function ensureComponent(component) {
|
|
36753
|
+
if (!component) {
|
|
36754
|
+
return () => null;
|
|
36755
|
+
}
|
|
36756
|
+
return component;
|
|
36757
|
+
}
|
|
36758
|
+
function usePageModeView(uid) {
|
|
36759
|
+
const context = useContext(PageModeViewContext);
|
|
36760
|
+
return ensureComponent(context == null ? void 0 : context[uid]);
|
|
36761
|
+
}
|
|
36702
36762
|
const ResponsiveGridLayout = reactGridLayoutWithLodashExports.WidthProvider(reactGridLayoutWithLodashExports.Responsive);
|
|
36703
36763
|
class ResponsiveHeightGridLayout extends ResponsiveGridLayout {
|
|
36704
36764
|
componentDidUpdate(prevProps) {
|
|
@@ -36798,30 +36858,23 @@ function VitessceGridLayout(props) {
|
|
|
36798
36858
|
const saveCurrentLayouts = useCallback(() => {
|
|
36799
36859
|
setLastValidGridLayouts(gridLayouts);
|
|
36800
36860
|
}, [gridLayouts]);
|
|
36801
|
-
const layoutChildren = useMemo(() => {
|
|
36861
|
+
const [layoutChildren, pageModeViews] = useMemo(() => {
|
|
36802
36862
|
const gridComponentsValues = Object.values(gridComponents);
|
|
36803
|
-
|
|
36804
|
-
|
|
36805
|
-
|
|
36806
|
-
|
|
36807
|
-
|
|
36808
|
-
|
|
36809
|
-
|
|
36810
|
-
|
|
36811
|
-
|
|
36812
|
-
|
|
36813
|
-
|
|
36814
|
-
|
|
36815
|
-
|
|
36816
|
-
|
|
36817
|
-
|
|
36818
|
-
theme,
|
|
36819
|
-
removeGridComponent: null
|
|
36820
|
-
}
|
|
36821
|
-
) }));
|
|
36822
|
-
});
|
|
36823
|
-
}
|
|
36824
|
-
return gridComponentsValues.map((v) => {
|
|
36863
|
+
const contextValue = Object.fromEntries(gridComponentsValues.map((v) => {
|
|
36864
|
+
const Component = getComponent(v.component);
|
|
36865
|
+
return [v.uid, () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36866
|
+
Component,
|
|
36867
|
+
{
|
|
36868
|
+
...v.props,
|
|
36869
|
+
uuid: v.uid,
|
|
36870
|
+
coordinationScopes: v.coordinationScopes,
|
|
36871
|
+
coordinationScopesBy: v.coordinationScopesBy,
|
|
36872
|
+
theme,
|
|
36873
|
+
removeGridComponent: null
|
|
36874
|
+
}
|
|
36875
|
+
) }, v.uid)];
|
|
36876
|
+
}));
|
|
36877
|
+
return [gridComponentsValues.map((v) => {
|
|
36825
36878
|
const Component = getComponent(v.component);
|
|
36826
36879
|
const removeGridComponent = () => {
|
|
36827
36880
|
onRemoveComponent(v.uid);
|
|
@@ -36837,9 +36890,9 @@ function VitessceGridLayout(props) {
|
|
|
36837
36890
|
removeGridComponent
|
|
36838
36891
|
}
|
|
36839
36892
|
) }, v.uid);
|
|
36840
|
-
});
|
|
36893
|
+
}), contextValue];
|
|
36841
36894
|
}, [gridComponents, getComponent, onRemoveComponent, theme]);
|
|
36842
|
-
return pageMode ?
|
|
36895
|
+
return pageMode ? /* @__PURE__ */ jsxRuntimeExports.jsx(PageModeViewContext.Provider, { value: pageModeViews, children: children2 }) : gridLayouts && gridComponents && gridBreakpoints && gridCols && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
36843
36896
|
style,
|
|
36844
36897
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36845
36898
|
ResponsiveHeightGridLayout,
|
|
@@ -37222,18 +37275,22 @@ function useUint8ObsFeatureMatrix({ obsFeatureMatrix }) {
|
|
|
37222
37275
|
}
|
|
37223
37276
|
function useUint8FeatureSelection(expressionData) {
|
|
37224
37277
|
return useMemo(() => {
|
|
37225
|
-
if (expressionData
|
|
37226
|
-
|
|
37227
|
-
const normData = expressionData.map((arr, i) => {
|
|
37228
|
-
const [min, max] = extents[i];
|
|
37229
|
-
const ratio = 255 / (max - min);
|
|
37230
|
-
return new Uint8Array(
|
|
37231
|
-
arr.map((j) => Math.floor((j - min) * ratio))
|
|
37232
|
-
);
|
|
37233
|
-
});
|
|
37234
|
-
return [normData, extents];
|
|
37278
|
+
if ((expressionData == null ? void 0 : expressionData[0]) == null) {
|
|
37279
|
+
return { normData: null, extents: null, missing: null };
|
|
37235
37280
|
}
|
|
37236
|
-
|
|
37281
|
+
const extents = expressionData.map((arr) => extent(arr));
|
|
37282
|
+
const normData = expressionData.map((arr, i) => {
|
|
37283
|
+
const [min, max] = extents[i];
|
|
37284
|
+
const ratio = 255 / (max - min);
|
|
37285
|
+
return new Uint8Array(
|
|
37286
|
+
arr.map((j) => Math.floor((j - min) * ratio))
|
|
37287
|
+
);
|
|
37288
|
+
});
|
|
37289
|
+
const missing = expressionData.map((arr) => {
|
|
37290
|
+
const numMissing = arr.reduce((prev, curr) => Number.isNaN(curr) ? prev + 1 : prev, 0);
|
|
37291
|
+
return numMissing / arr.length;
|
|
37292
|
+
});
|
|
37293
|
+
return { normData, extents, missing };
|
|
37237
37294
|
}, [expressionData]);
|
|
37238
37295
|
}
|
|
37239
37296
|
function useExpressionValueGetter({ instanceObsIndex, matrixObsIndex, expressionData }) {
|
|
@@ -37993,14 +38050,6 @@ function createGenerateClassName(customPrefix) {
|
|
|
37993
38050
|
return `${seedPrefix}${ruleKey}`;
|
|
37994
38051
|
};
|
|
37995
38052
|
}
|
|
37996
|
-
const AsyncFunctionsContext = createContext$1({
|
|
37997
|
-
// This will be an object where keys are function types
|
|
37998
|
-
// (as strings) and values are the async functions.
|
|
37999
|
-
});
|
|
38000
|
-
function useAsyncFunction(functionType2) {
|
|
38001
|
-
const context = useContext(AsyncFunctionsContext);
|
|
38002
|
-
return context == null ? void 0 : context[functionType2];
|
|
38003
|
-
}
|
|
38004
38053
|
function VitS(props) {
|
|
38005
38054
|
const {
|
|
38006
38055
|
config: config2,
|
|
@@ -38035,14 +38084,6 @@ function VitS(props) {
|
|
|
38035
38084
|
() => coordinationTypesProp || [],
|
|
38036
38085
|
[coordinationTypesProp]
|
|
38037
38086
|
);
|
|
38038
|
-
const asyncFunctions = useMemo(
|
|
38039
|
-
() => Object.fromEntries(
|
|
38040
|
-
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
38041
|
-
// from function type strings to async functions.
|
|
38042
|
-
(asyncFunctionsProp == null ? void 0 : asyncFunctionsProp.map((p) => [p.functionType, p.asyncFunction])) || []
|
|
38043
|
-
),
|
|
38044
|
-
[asyncFunctionsProp]
|
|
38045
|
-
);
|
|
38046
38087
|
const generateClassName2 = useMemo(() => createGenerateClassName(uid), [uid]);
|
|
38047
38088
|
const configVersion = config2 == null ? void 0 : config2.version;
|
|
38048
38089
|
const configKey = useMemo(() => {
|
|
@@ -38112,7 +38153,20 @@ function VitS(props) {
|
|
|
38112
38153
|
retry: 2
|
|
38113
38154
|
}
|
|
38114
38155
|
}
|
|
38156
|
+
// TODO: should the queryClient be shared? Or have an option to be shared
|
|
38157
|
+
// (e.g., based on remountOnUidChange)?
|
|
38115
38158
|
}), [configKey]);
|
|
38159
|
+
const asyncFunctions = useMemo(
|
|
38160
|
+
() => ({
|
|
38161
|
+
queryClient,
|
|
38162
|
+
asyncFunctions: Object.fromEntries(
|
|
38163
|
+
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
38164
|
+
// from function type strings to async functions.
|
|
38165
|
+
(asyncFunctionsProp == null ? void 0 : asyncFunctionsProp.map((p) => [p.functionType, p.asyncFunction])) || []
|
|
38166
|
+
)
|
|
38167
|
+
}),
|
|
38168
|
+
[asyncFunctionsProp, queryClient]
|
|
38169
|
+
);
|
|
38116
38170
|
useEffect(() => {
|
|
38117
38171
|
if (success && !isEqual$1(configOrWarning, config2) && onConfigChange) {
|
|
38118
38172
|
onConfigChange(configOrWarning);
|
|
@@ -40221,6 +40275,7 @@ export {
|
|
|
40221
40275
|
useObsSegmentationsData,
|
|
40222
40276
|
useObsSetsData,
|
|
40223
40277
|
useObsSpotsData,
|
|
40278
|
+
usePageModeView,
|
|
40224
40279
|
useStyles as usePlotOptionsStyles,
|
|
40225
40280
|
usePointMultiObsLabels,
|
|
40226
40281
|
useReady,
|
|
@@ -40233,6 +40288,7 @@ export {
|
|
|
40233
40288
|
useSegmentationMultiObsSets,
|
|
40234
40289
|
useSetComponentHover,
|
|
40235
40290
|
useSetComponentViewInfo,
|
|
40291
|
+
useSetViewConfig,
|
|
40236
40292
|
useSetWarning,
|
|
40237
40293
|
useSpotMultiFeatureLabels,
|
|
40238
40294
|
useSpotMultiFeatureSelection,
|
|
@@ -40241,6 +40297,7 @@ export {
|
|
|
40241
40297
|
useUint8FeatureSelection,
|
|
40242
40298
|
useUint8ObsFeatureMatrix,
|
|
40243
40299
|
useUrls,
|
|
40300
|
+
useViewConfig,
|
|
40244
40301
|
useViewConfigStore,
|
|
40245
40302
|
useViewConfigStoreApi,
|
|
40246
40303
|
useVitessceContainer,
|
package/dist-tsc/VitS.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VitS.d.ts","sourceRoot":"","sources":["../src/VitS.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,4BAhCG;IAAsB,MAAM,EAApB,MAAM;IAGkB,SAAS,EAAjC,SAAS,GAAC,MAAM;IACF,MAAM,EAApB,MAAM;IACQ,KAAK,EAAnB,MAAM;IAEU,MAAM;IACN,cAAc;IAEd,cAAc;IAEf,cAAc,EAA7B,OAAO;IAIQ,sBAAsB,EAArC,OAAO;IAGY,GAAG,EAAtB,IAAI,GAAC,MAAM;IAGI,kBAAkB,EAAjC,OAAO;IAEM,SAAS,EAAtB,KAAK;IACQ,SAAS,EAAtB,KAAK;IACQ,cAAc,EAA3B,KAAK;IACQ,iBAAiB,EAA9B,KAAK;IACc,OAAO,EAA1B,IAAI,GAAC,MAAM;IACI,QAAQ,EAAvB,OAAO;CAEjB,
|
|
1
|
+
{"version":3,"file":"VitS.d.ts","sourceRoot":"","sources":["../src/VitS.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,4BAhCG;IAAsB,MAAM,EAApB,MAAM;IAGkB,SAAS,EAAjC,SAAS,GAAC,MAAM;IACF,MAAM,EAApB,MAAM;IACQ,KAAK,EAAnB,MAAM;IAEU,MAAM;IACN,cAAc;IAEd,cAAc;IAEf,cAAc,EAA7B,OAAO;IAIQ,sBAAsB,EAArC,OAAO;IAGY,GAAG,EAAtB,IAAI,GAAC,MAAM;IAGI,kBAAkB,EAAjC,OAAO;IAEM,SAAS,EAAtB,KAAK;IACQ,SAAS,EAAtB,KAAK;IACQ,cAAc,EAA3B,KAAK;IACQ,iBAAiB,EAA9B,KAAK;IACc,OAAO,EAA1B,IAAI,GAAC,MAAM;IACI,QAAQ,EAAvB,OAAO;CAEjB,eAqNA"}
|
package/dist-tsc/VitS.js
CHANGED
|
@@ -54,11 +54,6 @@ export function VitS(props) {
|
|
|
54
54
|
const fileTypes = useMemo(() => (fileTypesProp || []), [fileTypesProp]);
|
|
55
55
|
const jointFileTypes = useMemo(() => (jointFileTypesProp || []), [jointFileTypesProp]);
|
|
56
56
|
const coordinationTypes = useMemo(() => (coordinationTypesProp || []), [coordinationTypesProp]);
|
|
57
|
-
const asyncFunctions = useMemo(() => Object.fromEntries(
|
|
58
|
-
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
59
|
-
// from function type strings to async functions.
|
|
60
|
-
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
61
|
-
|| []), [asyncFunctionsProp]);
|
|
62
57
|
const generateClassName = useMemo(() => createGenerateClassName(uid), [uid]);
|
|
63
58
|
const configVersion = config?.version;
|
|
64
59
|
// If config.uid exists, then use it for hook dependencies to detect changes
|
|
@@ -132,7 +127,17 @@ export function VitS(props) {
|
|
|
132
127
|
retry: 2,
|
|
133
128
|
},
|
|
134
129
|
},
|
|
130
|
+
// TODO: should the queryClient be shared? Or have an option to be shared
|
|
131
|
+
// (e.g., based on remountOnUidChange)?
|
|
135
132
|
}), [configKey]);
|
|
133
|
+
const asyncFunctions = useMemo(() => ({
|
|
134
|
+
queryClient,
|
|
135
|
+
asyncFunctions: Object.fromEntries(
|
|
136
|
+
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
137
|
+
// from function type strings to async functions.
|
|
138
|
+
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
139
|
+
|| []),
|
|
140
|
+
}), [asyncFunctionsProp, queryClient]);
|
|
136
141
|
// Emit the upgraded/initialized view config
|
|
137
142
|
// to onConfigChange if necessary.
|
|
138
143
|
useEffect(() => {
|
package/dist-tsc/contexts.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export function useAsyncFunction(functionType: any): any;
|
|
1
|
+
export function useAsyncFunction(functionType: any): (...args: any[]) => any;
|
|
2
|
+
export function usePageModeView(uid: any): any;
|
|
2
3
|
export const AsyncFunctionsContext: any;
|
|
4
|
+
export const PageModeViewContext: any;
|
|
3
5
|
//# sourceMappingURL=contexts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../src/contexts.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../src/contexts.js"],"names":[],"mappings":"AAYA,6EAQC;AAcD,+CAKC;AApCD,wCAOG;AAYH,sCAGG"}
|
package/dist-tsc/contexts.js
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
/* eslint-disable react-refresh/only-export-components */
|
|
2
2
|
import { createContext, useContext } from 'react';
|
|
3
3
|
export const AsyncFunctionsContext = createContext({
|
|
4
|
-
//
|
|
4
|
+
// {
|
|
5
|
+
// asyncFunctions: { [functionType: string]: asyncFunction },
|
|
6
|
+
// queryClient: QueryClient from react-query
|
|
7
|
+
// }
|
|
8
|
+
// asyncFunctions will be an object where keys are function types
|
|
5
9
|
// (as strings) and values are the async functions.
|
|
6
10
|
});
|
|
7
11
|
export function useAsyncFunction(functionType) {
|
|
8
12
|
const context = useContext(AsyncFunctionsContext);
|
|
9
|
-
|
|
13
|
+
const origFunction = context?.asyncFunctions?.[functionType];
|
|
14
|
+
const queryClient = context?.queryClient;
|
|
15
|
+
// We use partial function application here, so that the caller
|
|
16
|
+
// does not need to worry about passing in the queryClient.
|
|
17
|
+
const partialFunction = (...args) => origFunction({ queryClient }, ...args);
|
|
18
|
+
return partialFunction;
|
|
19
|
+
}
|
|
20
|
+
export const PageModeViewContext = createContext({
|
|
21
|
+
// Keys are view UIDs and values are
|
|
22
|
+
// the corresponding React components.
|
|
23
|
+
});
|
|
24
|
+
function ensureComponent(component) {
|
|
25
|
+
if (!component) {
|
|
26
|
+
return () => null;
|
|
27
|
+
}
|
|
28
|
+
return component;
|
|
29
|
+
}
|
|
30
|
+
export function usePageModeView(uid) {
|
|
31
|
+
const context = useContext(PageModeViewContext);
|
|
32
|
+
// TODO: Is there any case where we would want to
|
|
33
|
+
// throw an error instead?
|
|
34
|
+
return ensureComponent(context?.[uid]);
|
|
10
35
|
}
|
package/dist-tsc/hooks.d.ts
CHANGED
|
@@ -57,15 +57,24 @@ export function useUint8ObsFeatureMatrix({ obsFeatureMatrix }: {
|
|
|
57
57
|
/**
|
|
58
58
|
* Normalize a feature selection (data for selected
|
|
59
59
|
* columns of an obsFeatureMatrix) to a Uint8Array.
|
|
60
|
-
* @param {
|
|
60
|
+
* @param {Float32Array[] | null} expressionData The expressionData
|
|
61
61
|
* returned by the useFeatureSelection hook,
|
|
62
62
|
* where each element corresponds to an
|
|
63
63
|
* array of values for a selected feature.
|
|
64
|
-
* @returns {
|
|
65
|
-
*
|
|
66
|
-
*
|
|
64
|
+
* @returns {{
|
|
65
|
+
* normData: Uint8Array[] | null,
|
|
66
|
+
* extents: [number, number][] | null,
|
|
67
|
+
* missing: number[]
|
|
68
|
+
* }} An object tuple {normData, extents, missing} where
|
|
69
|
+
* normData is an array of Uint8Arrays (or null),
|
|
70
|
+
* extents is an array of [min, max] values for each feature (or null), and
|
|
71
|
+
* missing is an array of numbers (between 0 and 1) for each feature (or null).
|
|
67
72
|
*/
|
|
68
|
-
export function useUint8FeatureSelection(expressionData:
|
|
73
|
+
export function useUint8FeatureSelection(expressionData: Float32Array[] | null): {
|
|
74
|
+
normData: Uint8Array[] | null;
|
|
75
|
+
extents: [number, number][] | null;
|
|
76
|
+
missing: number[];
|
|
77
|
+
};
|
|
69
78
|
export function useExpressionValueGetter({ instanceObsIndex, matrixObsIndex, expressionData }: {
|
|
70
79
|
instanceObsIndex: any;
|
|
71
80
|
matrixObsIndex: any;
|
package/dist-tsc/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.js"],"names":[],"mappings":"AAkBA,oDAOC;AAED;;;;GAIG;AACH,uCAHa,KAAK,CAmBjB;AAED;;;;GAIG;AACH,mCAHa,KAAK,CAoCjB;AAED;;;;;GAKG;AACH,qCAJa,KAAK,CAqCjB;AAED;;;;;;GAMG;AACH,uCAHW,MAAM,EAAE,GACN,OAAO,CAOnB;AAED;;;;GAIG;AACH,8BAHW,CAAC,IAAI,GAAC,MAAM,EAAE,CAAC,EAAE,GACf,KAAK,CAYjB;AAED;;;;;;GAMG;AACH,qDAJW,GAAG,GACD,KAAK,CA0BjB;AAED;;;;;;;;;;GAUG;AACH,+DARG;IAAuB,gBAAgB,EAA/B,MAAM;CAEd,GAAU,KAAK,CAmBjB;AAED
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.js"],"names":[],"mappings":"AAkBA,oDAOC;AAED;;;;GAIG;AACH,uCAHa,KAAK,CAmBjB;AAED;;;;GAIG;AACH,mCAHa,KAAK,CAoCjB;AAED;;;;;GAKG;AACH,qCAJa,KAAK,CAqCjB;AAED;;;;;;GAMG;AACH,uCAHW,MAAM,EAAE,GACN,OAAO,CAOnB;AAED;;;;GAIG;AACH,8BAHW,CAAC,IAAI,GAAC,MAAM,EAAE,CAAC,EAAE,GACf,KAAK,CAYjB;AAED;;;;;;GAMG;AACH,qDAJW,GAAG,GACD,KAAK,CA0BjB;AAED;;;;;;;;;;GAUG;AACH,+DARG;IAAuB,gBAAgB,EAA/B,MAAM;CAEd,GAAU,KAAK,CAmBjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,yDAbW,YAAY,EAAE,GAAG,IAAI,GAInB;IACZ,QAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACjC,OAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC;IACtC,OAAU,EAAE,MAAM,EAAE,CAAA;CACjB,CAwBH;AAED;;;;QA2BC;AAED,iEAOC;AAED,kHA4BC"}
|
package/dist-tsc/hooks.js
CHANGED
|
@@ -185,26 +185,35 @@ export function useUint8ObsFeatureMatrix({ obsFeatureMatrix }) {
|
|
|
185
185
|
/**
|
|
186
186
|
* Normalize a feature selection (data for selected
|
|
187
187
|
* columns of an obsFeatureMatrix) to a Uint8Array.
|
|
188
|
-
* @param {
|
|
188
|
+
* @param {Float32Array[] | null} expressionData The expressionData
|
|
189
189
|
* returned by the useFeatureSelection hook,
|
|
190
190
|
* where each element corresponds to an
|
|
191
191
|
* array of values for a selected feature.
|
|
192
|
-
* @returns {
|
|
193
|
-
*
|
|
194
|
-
*
|
|
192
|
+
* @returns {{
|
|
193
|
+
* normData: Uint8Array[] | null,
|
|
194
|
+
* extents: [number, number][] | null,
|
|
195
|
+
* missing: number[]
|
|
196
|
+
* }} An object tuple {normData, extents, missing} where
|
|
197
|
+
* normData is an array of Uint8Arrays (or null),
|
|
198
|
+
* extents is an array of [min, max] values for each feature (or null), and
|
|
199
|
+
* missing is an array of numbers (between 0 and 1) for each feature (or null).
|
|
195
200
|
*/
|
|
196
201
|
export function useUint8FeatureSelection(expressionData) {
|
|
197
202
|
return useMemo(() => {
|
|
198
|
-
if (expressionData
|
|
199
|
-
|
|
200
|
-
const normData = expressionData.map((arr, i) => {
|
|
201
|
-
const [min, max] = extents[i];
|
|
202
|
-
const ratio = 255 / (max - min);
|
|
203
|
-
return new Uint8Array(arr.map(j => Math.floor((j - min) * ratio)));
|
|
204
|
-
});
|
|
205
|
-
return [normData, extents];
|
|
203
|
+
if (expressionData?.[0] == null) {
|
|
204
|
+
return { normData: null, extents: null, missing: null };
|
|
206
205
|
}
|
|
207
|
-
|
|
206
|
+
const extents = expressionData.map(arr => extent(arr));
|
|
207
|
+
const normData = expressionData.map((arr, i) => {
|
|
208
|
+
const [min, max] = extents[i];
|
|
209
|
+
const ratio = 255 / (max - min);
|
|
210
|
+
return new Uint8Array(arr.map(j => Math.floor((j - min) * ratio)));
|
|
211
|
+
});
|
|
212
|
+
const missing = expressionData.map((arr) => {
|
|
213
|
+
const numMissing = arr.reduce((prev, curr) => (Number.isNaN(curr) ? prev + 1 : prev), 0);
|
|
214
|
+
return numMissing / arr.length;
|
|
215
|
+
});
|
|
216
|
+
return { normData, extents, missing };
|
|
208
217
|
}, [expressionData]);
|
|
209
218
|
}
|
|
210
219
|
export function useExpressionValueGetter({ instanceObsIndex, matrixObsIndex, expressionData }) {
|
package/dist-tsc/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ export { TitleInfo } from "./TitleInfo.js";
|
|
|
3
3
|
export { PopperMenu } from "./shared-mui/components.js";
|
|
4
4
|
export { useHasLoader } from "./data-hook-utils.js";
|
|
5
5
|
export { logConfig } from "./view-config-utils.js";
|
|
6
|
-
export { useAsyncFunction } from "./contexts.js";
|
|
7
6
|
export { useReady, useUrls, useVitessceContainer, useDeckCanvasSize, useUint8ObsFeatureMatrix, useUint8FeatureSelection, useExpressionValueGetter, useGetObsMembership, useGetObsInfo, useClosestVitessceContainerSize, useWindowDimensions, useGridItemSize } from "./hooks.js";
|
|
8
|
-
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes } from "./state/hooks.js";
|
|
7
|
+
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useViewConfig, useSetViewConfig, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes } from "./state/hooks.js";
|
|
9
8
|
export { useDescription, useImageData, useObsSetsData, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useSampleSetsData, useSampleEdgesData, useMultiObsLabels, useMultiObsSpots, useMultiObsPoints, useSpotMultiObsSets, useSpotMultiFeatureLabels, useMultiObsSegmentations, useMultiImages, useObsSpotsData, useObsPointsData, useObsLocationsData, useObsSegmentationsData, useNeighborhoodsData, useObsLabelsData, useObsFeatureMatrixData, useFeatureLabelsData, useGenomicProfilesData } from "./data-hooks.js";
|
|
10
9
|
export { usePointMultiObsLabels, useSpotMultiFeatureSelection, useSpotMultiObsFeatureMatrixIndices, useSegmentationMultiFeatureSelection, useSegmentationMultiObsFeatureMatrixIndices, useSegmentationMultiObsLocations, useSegmentationMultiObsSets } from "./data-hooks-multilevel.js";
|
|
11
10
|
export { AbstractLoader, AbstractTwoStepLoader, LoaderResult } from "./data/index.js";
|
|
12
11
|
export { AbstractLoaderError, DatasetNotFoundError, LoaderNotFoundError, LoaderValidationError, DataSourceFetchError } from "./errors/index.js";
|
|
13
12
|
export { CellColorEncodingOption, OptionsContainer, OptionSelect, usePlotOptionsStyles } from "./shared-plot-options/index.js";
|
|
13
|
+
export { useAsyncFunction, usePageModeView } from "./contexts.js";
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist-tsc/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { TitleInfo } from './TitleInfo.js';
|
|
|
3
3
|
export { PopperMenu } from './shared-mui/components.js';
|
|
4
4
|
// For plugin view types:
|
|
5
5
|
export { useReady, useUrls, useVitessceContainer, useDeckCanvasSize, useUint8ObsFeatureMatrix, useUint8FeatureSelection, useExpressionValueGetter, useGetObsMembership, useGetObsInfo, useClosestVitessceContainerSize, useWindowDimensions, useGridItemSize, } from './hooks.js';
|
|
6
|
-
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes, } from './state/hooks.js';
|
|
6
|
+
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useViewConfig, useSetViewConfig, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes, } from './state/hooks.js';
|
|
7
7
|
export { useDescription, useImageData, useObsSetsData, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useSampleSetsData, useSampleEdgesData, useMultiObsLabels, useMultiObsSpots, useMultiObsPoints, useSpotMultiObsSets, useSpotMultiFeatureLabels, useMultiObsSegmentations, useMultiImages, useObsSpotsData, useObsPointsData, useObsLocationsData, useObsSegmentationsData, useNeighborhoodsData, useObsLabelsData, useObsFeatureMatrixData, useFeatureLabelsData, useGenomicProfilesData, } from './data-hooks.js';
|
|
8
8
|
export { usePointMultiObsLabels, useSpotMultiFeatureSelection, useSpotMultiObsFeatureMatrixIndices, useSegmentationMultiFeatureSelection, useSegmentationMultiObsFeatureMatrixIndices, useSegmentationMultiObsLocations, useSegmentationMultiObsSets, } from './data-hooks-multilevel.js';
|
|
9
9
|
export { useHasLoader, } from './data-hook-utils.js';
|
|
@@ -11,4 +11,4 @@ export { AbstractLoader, AbstractTwoStepLoader, LoaderResult, } from './data/ind
|
|
|
11
11
|
export { AbstractLoaderError, DatasetNotFoundError, LoaderNotFoundError, LoaderValidationError, DataSourceFetchError, } from './errors/index.js';
|
|
12
12
|
export { CellColorEncodingOption, OptionsContainer, OptionSelect, usePlotOptionsStyles, } from './shared-plot-options/index.js';
|
|
13
13
|
export { logConfig } from './view-config-utils.js';
|
|
14
|
-
export { useAsyncFunction } from './contexts.js';
|
|
14
|
+
export { useAsyncFunction, usePageModeView } from './contexts.js';
|
|
@@ -222,6 +222,13 @@ export function useSetLoaders(): Function;
|
|
|
222
222
|
* in the `useViewConfigStore` store.
|
|
223
223
|
*/
|
|
224
224
|
export function useMergeCoordination(): Function;
|
|
225
|
+
/**
|
|
226
|
+
* Obtain the current view config object from
|
|
227
|
+
* the global app state.
|
|
228
|
+
* @returns {object} The view config object
|
|
229
|
+
* in the `useViewConfigStore` store.
|
|
230
|
+
*/
|
|
231
|
+
export function useViewConfig(): object;
|
|
225
232
|
/**
|
|
226
233
|
* Obtain the view config setter function from
|
|
227
234
|
* the global app state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/state/hooks.js"],"names":[],"mappings":"AAmCA;;;;;;GAMG;AACH,8CAJW,GAAC,mBAEC,MAAM,GAAC,SAAS,CA4B5B;AAED;;;;;;;GAOG;AACH,gDALW,GAAC,wBACD,GAAC,qBAEC,MAAM,GAAC,SAAS,CA0C5B;AAED;;;;;GAKG;AACH,6CAJW,MAAM,sBACN,GAAC,GACC,MAAM,GAAC,SAAS,CAI5B;AAED;;;;;;GAMG;AACH,+CALW,MAAM,mDACN,GAAC,wBACD,GAAC,GACC,MAAM,GAAC,SAAS,CAc5B;AA4RD;;;;;;;;;GASG;AACH,mDALW,MAAM,EAAE,sBACR,MAAM,GAEJ,MAAM,CAclB;AAED;;;;;;;;;;;;;;;GAeG;AACH,4CATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAmCjB;AAED,yFAKC;AAED,gGAqBC;AAED,0IA4BC;AAED,iJAkEC;AAED,yFAmBC;AAED;;;;GAIG;AACH,mDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;;;GAaG;AACH,mDAXW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,UAEN,MAAM,GAEJ,KAAK,CA2EjB;AAED;;;;;GAKG;AACH,0DAHW,MAAM,GACJ,MAAM,CAiBlB;AAED;;;;;;GAMG;AACH,4DAJW,MAAM,wBACN,MAAM,GACJ,MAAM,CAgBlB;AAED;;;;;;;GAOG;AACH,4DANW,MAAM,EAAE,iDACR,MAAM,eACN,MAAM,iBACN,MAAM,SAuEhB;AAGD;;;;;;;;;;;GAWG;AACH,wDATW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,GAEJ,KAAK,CAUjB;AA6BD;;;;;;;;;;;;;;;GAeG;AACH,qDATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAgCjB;AAED;;;;;GAKG;AACH,8BAHa,MAAM,CAKlB;AAGD;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAoBhB;AAED;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAShB;AAED;;;;;GAKG;AACH,6BAHa,MAAM,EAAE,CAKpB;AAED;;;;;GAKG;AACH,+CAEC;AAED;;;;;GAKG;AACH,0EAEC;AAED;;;;;GAKG;AACH,uEAEC;AAED;;;;;GAKG;AACH,4CAEC;AAED;;;;;GAKG;AACH,0CAEC;AAED;;;;;GAKG;AACH,iDAEC;AAED;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/state/hooks.js"],"names":[],"mappings":"AAmCA;;;;;;GAMG;AACH,8CAJW,GAAC,mBAEC,MAAM,GAAC,SAAS,CA4B5B;AAED;;;;;;;GAOG;AACH,gDALW,GAAC,wBACD,GAAC,qBAEC,MAAM,GAAC,SAAS,CA0C5B;AAED;;;;;GAKG;AACH,6CAJW,MAAM,sBACN,GAAC,GACC,MAAM,GAAC,SAAS,CAI5B;AAED;;;;;;GAMG;AACH,+CALW,MAAM,mDACN,GAAC,wBACD,GAAC,GACC,MAAM,GAAC,SAAS,CAc5B;AA4RD;;;;;;;;;GASG;AACH,mDALW,MAAM,EAAE,sBACR,MAAM,GAEJ,MAAM,CAclB;AAED;;;;;;;;;;;;;;;GAeG;AACH,4CATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAmCjB;AAED,yFAKC;AAED,gGAqBC;AAED,0IA4BC;AAED,iJAkEC;AAED,yFAmBC;AAED;;;;GAIG;AACH,mDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;;;GAaG;AACH,mDAXW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,UAEN,MAAM,GAEJ,KAAK,CA2EjB;AAED;;;;;GAKG;AACH,0DAHW,MAAM,GACJ,MAAM,CAiBlB;AAED;;;;;;GAMG;AACH,4DAJW,MAAM,wBACN,MAAM,GACJ,MAAM,CAgBlB;AAED;;;;;;;GAOG;AACH,4DANW,MAAM,EAAE,iDACR,MAAM,eACN,MAAM,iBACN,MAAM,SAuEhB;AAGD;;;;;;;;;;;GAWG;AACH,wDATW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,GAEJ,KAAK,CAUjB;AA6BD;;;;;;;;;;;;;;;GAeG;AACH,qDATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAgCjB;AAED;;;;;GAKG;AACH,8BAHa,MAAM,CAKlB;AAGD;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAoBhB;AAED;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAShB;AAED;;;;;GAKG;AACH,6BAHa,MAAM,EAAE,CAKpB;AAED;;;;;GAKG;AACH,+CAEC;AAED;;;;;GAKG;AACH,0EAEC;AAED;;;;;GAKG;AACH,uEAEC;AAED;;;;;GAKG;AACH,4CAEC;AAED;;;;;GAKG;AACH,0CAEC;AAED;;;;;GAKG;AACH,iDAEC;AAED;;;;;GAKG;AACH,iCAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,oEAIC;AAGD;;;;;GAKG;AACH,qCAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,iDAEC;AAED;;;;;GAKG;AACH,8BAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,0CAEC;AAED;;;;;GAKG;AACH,iDAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,6DAOC;AAED;;;;GAIG;AACH,iCAFa,MAAM,CAIlB;AAED;;;;;GAKG;AACH,8CAEC;AAvpCD;;;;aAPG,OAAO,kCAAkC,OAAO,sEAOO;AAC1D,mFAA0D;AAC1D;;;;;EAAgE;AAOhE;;;;mIAAwD;AACxD,kFAAwD;AAiIjD,yFA+KJ;AAOI,0FAFM,MAAM,CAOlB;AAcM,iDAUJ"}
|
package/dist-tsc/state/hooks.js
CHANGED
|
@@ -973,6 +973,15 @@ export function useSetLoaders() {
|
|
|
973
973
|
export function useMergeCoordination() {
|
|
974
974
|
return useViewConfigStore(state => state.mergeCoordination);
|
|
975
975
|
}
|
|
976
|
+
/**
|
|
977
|
+
* Obtain the current view config object from
|
|
978
|
+
* the global app state.
|
|
979
|
+
* @returns {object} The view config object
|
|
980
|
+
* in the `useViewConfigStore` store.
|
|
981
|
+
*/
|
|
982
|
+
export function useViewConfig() {
|
|
983
|
+
return useViewConfigStore(state => state.viewConfig);
|
|
984
|
+
}
|
|
976
985
|
/**
|
|
977
986
|
* Obtain the view config setter function from
|
|
978
987
|
* the global app state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VitessceGridLayout.d.ts","sourceRoot":"","sources":["../../src/vitessce-grid-layout/VitessceGridLayout.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VitessceGridLayout.d.ts","sourceRoot":"","sources":["../../src/vitessce-grid-layout/VitessceGridLayout.js"],"names":[],"mappings":"AAgBA,oDAwLC"}
|
|
@@ -3,6 +3,7 @@ import React, { useState, useMemo, useCallback } from 'react';
|
|
|
3
3
|
import { Responsive, WidthProvider } from 'react-grid-layout-with-lodash';
|
|
4
4
|
import { isEqual } from 'lodash-es';
|
|
5
5
|
import { getMaxRows, resolveLayout } from './layout-utils.js';
|
|
6
|
+
import { PageModeViewContext } from '../contexts.js';
|
|
6
7
|
const ResponsiveGridLayout = WidthProvider(Responsive);
|
|
7
8
|
class ResponsiveHeightGridLayout extends ResponsiveGridLayout {
|
|
8
9
|
componentDidUpdate(prevProps) {
|
|
@@ -97,38 +98,26 @@ export function VitessceGridLayout(props) {
|
|
|
97
98
|
const saveCurrentLayouts = useCallback(() => {
|
|
98
99
|
setLastValidGridLayouts(gridLayouts);
|
|
99
100
|
}, [gridLayouts]);
|
|
100
|
-
const layoutChildren = useMemo(() => {
|
|
101
|
+
const [layoutChildren, pageModeViews] = useMemo(() => {
|
|
101
102
|
const gridComponentsValues = Object.values(gridComponents);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
const v = gridComponentsValues.find(el => el.uid === childId);
|
|
107
|
-
if (!v) {
|
|
108
|
-
// The child did not map to any view in the config, so return as-is.
|
|
109
|
-
return child;
|
|
110
|
-
}
|
|
111
|
-
// The child mapped to a view in the config,
|
|
112
|
-
// so we want to render the corresponding component as a subchild.
|
|
113
|
-
const Component = getComponent(v.component);
|
|
114
|
-
return React.cloneElement(child, { key: v.uid }, (_jsx("div", { style: { display: 'flex', flexDirection: 'column', height: '100%' }, children: _jsx(Component, { ...v.props, uuid: v.uid, coordinationScopes: v.coordinationScopes, coordinationScopesBy: v.coordinationScopesBy, theme: theme, removeGridComponent: null }) })));
|
|
115
|
-
});
|
|
116
|
-
}
|
|
103
|
+
const contextValue = Object.fromEntries(gridComponentsValues.map((v) => {
|
|
104
|
+
const Component = getComponent(v.component);
|
|
105
|
+
return [v.uid, () => (_jsx("div", { style: { display: 'flex', flexDirection: 'column', height: '100%' }, children: _jsx(Component, { ...v.props, uuid: v.uid, coordinationScopes: v.coordinationScopes, coordinationScopesBy: v.coordinationScopesBy, theme: theme, removeGridComponent: null }) }, v.uid))];
|
|
106
|
+
}));
|
|
117
107
|
// Not pageMode, so no children to render.
|
|
118
108
|
// We render the grid components based on the layout information.
|
|
119
|
-
return gridComponentsValues.map((v) => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
109
|
+
return [gridComponentsValues.map((v) => {
|
|
110
|
+
const Component = getComponent(v.component);
|
|
111
|
+
const removeGridComponent = () => {
|
|
112
|
+
onRemoveComponent(v.uid);
|
|
113
|
+
};
|
|
114
|
+
return (_jsx("div", { children: _jsx(Component, { ...v.props, uuid: v.uid, coordinationScopes: v.coordinationScopes, coordinationScopesBy: v.coordinationScopesBy, theme: theme, removeGridComponent: removeGridComponent }) }, v.uid));
|
|
115
|
+
}), contextValue];
|
|
126
116
|
}, [gridComponents, getComponent, onRemoveComponent, theme]);
|
|
127
117
|
return (pageMode
|
|
128
|
-
?
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
/ maxRows), containerPadding: containerPadding, margin: margin, draggableHandle: draggableHandle, onLayoutChange: onLayoutChange, isBounded: isBounded, onResizeStart: saveCurrentLayouts, onDragStart: saveCurrentLayouts, onResize: onResize, onResizeStop: onResizeStop, children: layoutChildren })] }))));
|
|
118
|
+
? (_jsx(PageModeViewContext.Provider, { value: pageModeViews, children: children })) : ((gridLayouts && gridComponents && gridBreakpoints && gridCols) && (_jsxs(_Fragment, { children: [style, _jsx(ResponsiveHeightGridLayout, { className: "layout", cols: gridCols, layouts: tempGridLayouts || gridLayouts, breakpoints: gridBreakpoints, height: height, rowHeight: rowHeight
|
|
119
|
+
|| ((window.innerHeight - 2 * padding - (maxRows - 1) * margin)
|
|
120
|
+
/ maxRows), containerPadding: containerPadding, margin: margin, draggableHandle: draggableHandle, onLayoutChange: onLayoutChange, isBounded: isBounded, onResizeStart: saveCurrentLayouts, onDragStart: saveCurrentLayouts, onResize: onResize, onResizeStop: onResizeStop, children: layoutChildren })] }))));
|
|
132
121
|
}
|
|
133
122
|
VitessceGridLayout.defaultProps = {
|
|
134
123
|
padding: 10,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitessce/vit-s",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"author": "
|
|
3
|
+
"version": "3.5.0",
|
|
4
|
+
"author": "HIDIVE Lab at HMS",
|
|
5
5
|
"homepage": "http://vitessce.io",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"uuid": "^9.0.0",
|
|
30
30
|
"zustand": "^3.5.10",
|
|
31
31
|
"react-aria": "^3.28.0",
|
|
32
|
-
"@vitessce/constants-internal": "3.
|
|
33
|
-
"@vitessce/plugins": "3.
|
|
34
|
-
"@vitessce/schemas": "3.
|
|
35
|
-
"@vitessce/utils": "3.
|
|
36
|
-
"@vitessce/sets-utils": "3.
|
|
37
|
-
"@vitessce/config": "3.
|
|
32
|
+
"@vitessce/constants-internal": "3.5.0",
|
|
33
|
+
"@vitessce/plugins": "3.5.0",
|
|
34
|
+
"@vitessce/schemas": "3.5.0",
|
|
35
|
+
"@vitessce/utils": "3.5.0",
|
|
36
|
+
"@vitessce/sets-utils": "3.5.0",
|
|
37
|
+
"@vitessce/config": "3.5.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@testing-library/jest-dom": "^5.16.4",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"react": "^18.0.0",
|
|
43
43
|
"vite": "^4.3.0",
|
|
44
44
|
"vitest": "^0.32.2",
|
|
45
|
-
"@vitessce/types": "3.
|
|
45
|
+
"@vitessce/types": "3.5.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
package/src/VitS.js
CHANGED
|
@@ -99,15 +99,6 @@ export function VitS(props) {
|
|
|
99
99
|
() => (coordinationTypesProp || []),
|
|
100
100
|
[coordinationTypesProp],
|
|
101
101
|
);
|
|
102
|
-
const asyncFunctions = useMemo(
|
|
103
|
-
() => Object.fromEntries(
|
|
104
|
-
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
105
|
-
// from function type strings to async functions.
|
|
106
|
-
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
107
|
-
|| [],
|
|
108
|
-
),
|
|
109
|
-
[asyncFunctionsProp],
|
|
110
|
-
);
|
|
111
102
|
|
|
112
103
|
const generateClassName = useMemo(() => createGenerateClassName(uid), [uid]);
|
|
113
104
|
|
|
@@ -196,8 +187,23 @@ export function VitS(props) {
|
|
|
196
187
|
retry: 2,
|
|
197
188
|
},
|
|
198
189
|
},
|
|
190
|
+
// TODO: should the queryClient be shared? Or have an option to be shared
|
|
191
|
+
// (e.g., based on remountOnUidChange)?
|
|
199
192
|
}), [configKey]);
|
|
200
193
|
|
|
194
|
+
const asyncFunctions = useMemo(
|
|
195
|
+
() => ({
|
|
196
|
+
queryClient,
|
|
197
|
+
asyncFunctions: Object.fromEntries(
|
|
198
|
+
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
199
|
+
// from function type strings to async functions.
|
|
200
|
+
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
201
|
+
|| [],
|
|
202
|
+
),
|
|
203
|
+
}),
|
|
204
|
+
[asyncFunctionsProp, queryClient],
|
|
205
|
+
);
|
|
206
|
+
|
|
201
207
|
// Emit the upgraded/initialized view config
|
|
202
208
|
// to onConfigChange if necessary.
|
|
203
209
|
useEffect(() => {
|
package/src/contexts.js
CHANGED
|
@@ -2,11 +2,39 @@
|
|
|
2
2
|
import { createContext, useContext } from 'react';
|
|
3
3
|
|
|
4
4
|
export const AsyncFunctionsContext = createContext({
|
|
5
|
-
//
|
|
5
|
+
// {
|
|
6
|
+
// asyncFunctions: { [functionType: string]: asyncFunction },
|
|
7
|
+
// queryClient: QueryClient from react-query
|
|
8
|
+
// }
|
|
9
|
+
// asyncFunctions will be an object where keys are function types
|
|
6
10
|
// (as strings) and values are the async functions.
|
|
7
11
|
});
|
|
8
12
|
|
|
9
13
|
export function useAsyncFunction(functionType) {
|
|
10
14
|
const context = useContext(AsyncFunctionsContext);
|
|
11
|
-
|
|
15
|
+
const origFunction = context?.asyncFunctions?.[functionType];
|
|
16
|
+
const queryClient = context?.queryClient;
|
|
17
|
+
// We use partial function application here, so that the caller
|
|
18
|
+
// does not need to worry about passing in the queryClient.
|
|
19
|
+
const partialFunction = (...args) => origFunction({ queryClient }, ...args);
|
|
20
|
+
return partialFunction;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const PageModeViewContext = createContext({
|
|
24
|
+
// Keys are view UIDs and values are
|
|
25
|
+
// the corresponding React components.
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function ensureComponent(component) {
|
|
29
|
+
if (!component) {
|
|
30
|
+
return () => null;
|
|
31
|
+
}
|
|
32
|
+
return component;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function usePageModeView(uid) {
|
|
36
|
+
const context = useContext(PageModeViewContext);
|
|
37
|
+
// TODO: Is there any case where we would want to
|
|
38
|
+
// throw an error instead?
|
|
39
|
+
return ensureComponent(context?.[uid]);
|
|
12
40
|
}
|
package/src/hooks.js
CHANGED
|
@@ -221,28 +221,37 @@ export function useUint8ObsFeatureMatrix({ obsFeatureMatrix }) {
|
|
|
221
221
|
/**
|
|
222
222
|
* Normalize a feature selection (data for selected
|
|
223
223
|
* columns of an obsFeatureMatrix) to a Uint8Array.
|
|
224
|
-
* @param {
|
|
224
|
+
* @param {Float32Array[] | null} expressionData The expressionData
|
|
225
225
|
* returned by the useFeatureSelection hook,
|
|
226
226
|
* where each element corresponds to an
|
|
227
227
|
* array of values for a selected feature.
|
|
228
|
-
* @returns {
|
|
229
|
-
*
|
|
230
|
-
*
|
|
228
|
+
* @returns {{
|
|
229
|
+
* normData: Uint8Array[] | null,
|
|
230
|
+
* extents: [number, number][] | null,
|
|
231
|
+
* missing: number[]
|
|
232
|
+
* }} An object tuple {normData, extents, missing} where
|
|
233
|
+
* normData is an array of Uint8Arrays (or null),
|
|
234
|
+
* extents is an array of [min, max] values for each feature (or null), and
|
|
235
|
+
* missing is an array of numbers (between 0 and 1) for each feature (or null).
|
|
231
236
|
*/
|
|
232
237
|
export function useUint8FeatureSelection(expressionData) {
|
|
233
238
|
return useMemo(() => {
|
|
234
|
-
if (expressionData
|
|
235
|
-
|
|
236
|
-
const normData = expressionData.map((arr, i) => {
|
|
237
|
-
const [min, max] = extents[i];
|
|
238
|
-
const ratio = 255 / (max - min);
|
|
239
|
-
return new Uint8Array(
|
|
240
|
-
arr.map(j => Math.floor((j - min) * ratio)),
|
|
241
|
-
);
|
|
242
|
-
});
|
|
243
|
-
return [normData, extents];
|
|
239
|
+
if (expressionData?.[0] == null) {
|
|
240
|
+
return { normData: null, extents: null, missing: null };
|
|
244
241
|
}
|
|
245
|
-
|
|
242
|
+
const extents = expressionData.map(arr => extent(arr));
|
|
243
|
+
const normData = expressionData.map((arr, i) => {
|
|
244
|
+
const [min, max] = extents[i];
|
|
245
|
+
const ratio = 255 / (max - min);
|
|
246
|
+
return new Uint8Array(
|
|
247
|
+
arr.map(j => Math.floor((j - min) * ratio)),
|
|
248
|
+
);
|
|
249
|
+
});
|
|
250
|
+
const missing = expressionData.map((arr) => {
|
|
251
|
+
const numMissing = arr.reduce((prev, curr) => (Number.isNaN(curr) ? prev + 1 : prev), 0);
|
|
252
|
+
return numMissing / arr.length;
|
|
253
|
+
});
|
|
254
|
+
return { normData, extents, missing };
|
|
246
255
|
}, [expressionData]);
|
|
247
256
|
}
|
|
248
257
|
|
package/src/index.js
CHANGED
|
@@ -35,6 +35,8 @@ export {
|
|
|
35
35
|
useMatchingLoader,
|
|
36
36
|
useViewConfigStore,
|
|
37
37
|
useViewConfigStoreApi,
|
|
38
|
+
useViewConfig,
|
|
39
|
+
useSetViewConfig,
|
|
38
40
|
useComponentHover,
|
|
39
41
|
useSetComponentHover,
|
|
40
42
|
useComponentViewInfo,
|
|
@@ -105,4 +107,4 @@ export {
|
|
|
105
107
|
usePlotOptionsStyles,
|
|
106
108
|
} from './shared-plot-options/index.js';
|
|
107
109
|
export { logConfig } from './view-config-utils.js';
|
|
108
|
-
export { useAsyncFunction } from './contexts.js';
|
|
110
|
+
export { useAsyncFunction, usePageModeView } from './contexts.js';
|
package/src/state/hooks.js
CHANGED
|
@@ -1091,6 +1091,16 @@ export function useMergeCoordination() {
|
|
|
1091
1091
|
return useViewConfigStore(state => state.mergeCoordination);
|
|
1092
1092
|
}
|
|
1093
1093
|
|
|
1094
|
+
/**
|
|
1095
|
+
* Obtain the current view config object from
|
|
1096
|
+
* the global app state.
|
|
1097
|
+
* @returns {object} The view config object
|
|
1098
|
+
* in the `useViewConfigStore` store.
|
|
1099
|
+
*/
|
|
1100
|
+
export function useViewConfig() {
|
|
1101
|
+
return useViewConfigStore(state => state.viewConfig);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1094
1104
|
/**
|
|
1095
1105
|
* Obtain the view config setter function from
|
|
1096
1106
|
* the global app state.
|
|
@@ -1103,6 +1113,7 @@ export function useSetViewConfig(viewConfigStoreApi) {
|
|
|
1103
1113
|
return setViewConfig;
|
|
1104
1114
|
}
|
|
1105
1115
|
|
|
1116
|
+
|
|
1106
1117
|
/**
|
|
1107
1118
|
* Obtain the component hover value from
|
|
1108
1119
|
* the global app state.
|
|
@@ -2,6 +2,7 @@ import React, { useState, useMemo, useCallback } from 'react';
|
|
|
2
2
|
import { Responsive, WidthProvider } from 'react-grid-layout-with-lodash';
|
|
3
3
|
import { isEqual } from 'lodash-es';
|
|
4
4
|
import { getMaxRows, resolveLayout } from './layout-utils.js';
|
|
5
|
+
import { PageModeViewContext } from '../contexts.js';
|
|
5
6
|
|
|
6
7
|
const ResponsiveGridLayout = WidthProvider(Responsive);
|
|
7
8
|
|
|
@@ -122,37 +123,28 @@ export function VitessceGridLayout(props) {
|
|
|
122
123
|
setLastValidGridLayouts(gridLayouts);
|
|
123
124
|
}, [gridLayouts]);
|
|
124
125
|
|
|
125
|
-
const layoutChildren = useMemo(() => {
|
|
126
|
+
const [layoutChildren, pageModeViews] = useMemo(() => {
|
|
126
127
|
const gridComponentsValues = Object.values(gridComponents);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
coordinationScopes={v.coordinationScopes}
|
|
145
|
-
coordinationScopesBy={v.coordinationScopesBy}
|
|
146
|
-
theme={theme}
|
|
147
|
-
removeGridComponent={null}
|
|
148
|
-
/>
|
|
149
|
-
</div>
|
|
150
|
-
));
|
|
151
|
-
});
|
|
152
|
-
}
|
|
128
|
+
|
|
129
|
+
const contextValue = Object.fromEntries(gridComponentsValues.map((v) => {
|
|
130
|
+
const Component = getComponent(v.component);
|
|
131
|
+
return [v.uid, () => (
|
|
132
|
+
<div key={v.uid} style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
|
133
|
+
<Component
|
|
134
|
+
{... v.props}
|
|
135
|
+
uuid={v.uid}
|
|
136
|
+
coordinationScopes={v.coordinationScopes}
|
|
137
|
+
coordinationScopesBy={v.coordinationScopesBy}
|
|
138
|
+
theme={theme}
|
|
139
|
+
removeGridComponent={null}
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
)];
|
|
143
|
+
}));
|
|
144
|
+
|
|
153
145
|
// Not pageMode, so no children to render.
|
|
154
146
|
// We render the grid components based on the layout information.
|
|
155
|
-
return gridComponentsValues.map((v) => {
|
|
147
|
+
return [gridComponentsValues.map((v) => {
|
|
156
148
|
const Component = getComponent(v.component);
|
|
157
149
|
const removeGridComponent = () => {
|
|
158
150
|
onRemoveComponent(v.uid);
|
|
@@ -169,12 +161,15 @@ export function VitessceGridLayout(props) {
|
|
|
169
161
|
/>
|
|
170
162
|
</div>
|
|
171
163
|
);
|
|
172
|
-
});
|
|
164
|
+
}), contextValue];
|
|
173
165
|
}, [gridComponents, getComponent, onRemoveComponent, theme]);
|
|
174
166
|
|
|
175
167
|
return (pageMode
|
|
176
|
-
?
|
|
177
|
-
|
|
168
|
+
? (
|
|
169
|
+
<PageModeViewContext.Provider value={pageModeViews}>
|
|
170
|
+
{children}
|
|
171
|
+
</PageModeViewContext.Provider>
|
|
172
|
+
) : ((gridLayouts && gridComponents && gridBreakpoints && gridCols) && (
|
|
178
173
|
<>
|
|
179
174
|
{style}
|
|
180
175
|
<ResponsiveHeightGridLayout
|