From 0e3006fb1eb9683eddfc7dfcb3cba71d43a450d0 Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Tue, 2 Mar 2021 18:26:37 -0500 Subject: [PATCH 1/8] Expose model matrix as query param and to imjoy API --- src/io.ts | 7 ++++++- src/ome.ts | 5 ++++- src/state.ts | 5 ++++- src/utils.ts | 41 +++++++++++++++++++++++++++++++++++++++++ types/viv.d.ts | 2 ++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/io.ts b/src/io.ts index 0bc16347..d57ceaf5 100644 --- a/src/io.ts +++ b/src/io.ts @@ -19,6 +19,7 @@ import { MAGENTA_GREEN, MAX_CHANNELS, open, + parseMatrix, range, RGB, } from './utils'; @@ -45,6 +46,7 @@ function loadSingleChannel(config: SingleChannelConfig, data: ZarrPixelSource[], max: number): SourceData { - const { names, channel_axis, name, opacity = 1, colormap = '' } = config; + const { names, channel_axis, name, model_matrix, opacity = 1, colormap = '' } = config; let { contrast_limits, visibilities, colors } = config; const n = data[0].shape[channel_axis as number]; @@ -104,6 +106,7 @@ function loadMultiChannel(config: MultichannelConfig, data: ZarrPixelSource `channel_${i}`), contrast_limits: contrast_limits ?? Array(n).fill([0, max]), visibilities, + model_matrix: parseMatrix(config.model_matrix), defaults: { selection: Array(data[0].shape.length).fill(0), colormap, @@ -181,6 +184,7 @@ export function initLayerStateFromSource(sourceData: SourceData, layerId: string colors, visibilities, contrast_limits, + model_matrix, defaults, // Grid loaders, @@ -231,6 +235,7 @@ export function initLayerStateFromSource(sourceData: SourceData, layerId: string channelIsOn, opacity, colormap, + modelMatrix: model_matrix, onClick, }, on: true, diff --git a/src/ome.ts b/src/ome.ts index 4b73162b..4d3c9846 100644 --- a/src/ome.ts +++ b/src/ome.ts @@ -2,7 +2,7 @@ import { ZarrPixelSource } from '@hms-dbmi/viv'; import pMap from 'p-map'; import { Group as ZarrGroup, HTTPStore, openGroup, ZarrArray } from 'zarr'; import type { ImageLayerConfig, SourceData } from './state'; -import { join, loadMultiscales, guessTileSize, range } from './utils'; +import { join, loadMultiscales, guessTileSize, range, parseMatrix } from './utils'; export async function loadWell(config: ImageLayerConfig, grp: ZarrGroup, wellAttrs: Ome.Well): Promise { // Can filter Well fields by URL query ?acquisition=ID @@ -64,6 +64,7 @@ export async function loadWell(config: ImageLayerConfig, grp: ZarrGroup, wellAtt loaders, ...meta, loader: [loaders[0].loader], + model_matrix: parseMatrix(config.model_matrix), defaults: { selection: meta.defaultSelection, colormap: config.colormap ?? '', @@ -154,6 +155,7 @@ export async function loadPlate(config: ImageLayerConfig, grp: ZarrGroup, plateA loaders, ...meta, loader: [loaders[0].loader], + model_matrix: parseMatrix(config.model_matrix), defaults: { selection: meta.defaultSelection, colormap: config.colormap ?? '', @@ -199,6 +201,7 @@ export async function loadOmeroMultiscales( return { loader: loader, name: meta.name ?? name, + model_matrix: parseMatrix(config.model_matrix), defaults: { selection: meta.defaultSelection, colormap, diff --git a/src/state.ts b/src/state.ts index 9c7e4efb..0defcddd 100644 --- a/src/state.ts +++ b/src/state.ts @@ -3,6 +3,7 @@ import type { ZarrArray } from 'zarr'; import type { ImageLayer, MultiscaleImageLayer, ZarrPixelSource } from '@hms-dbmi/viv'; import type { VivLayerProps } from 'viv-layers'; import type GridLayer from './gridLayer'; +import { Matrix4 } from 'math.gl'; export const DEFAULT_VIEW_STATE = { zoom: 0, target: [0, 0, 0], default: true }; export const DEFAULT_LAYER_PROPS = { @@ -24,6 +25,7 @@ interface BaseConfig { colormap?: string; opacity?: number; acquisition?: string; + model_matrix?: string | number[]; onClick?: (e: any) => void; } @@ -68,6 +70,7 @@ export type SourceData = { colormap: string; opacity: number; }; + model_matrix: Matrix4; axis_labels: string[]; onClick?: (e: any) => void; }; @@ -105,7 +108,7 @@ export const layerStateFamily = atomFamily({ key: 'layerStateFamily', default: (id: string): LayerState => ({ Layer: null, - layerProps: { id, ...DEFAULT_LAYER_PROPS }, + layerProps: { id, modelMatrix: new Matrix4(), ...DEFAULT_LAYER_PROPS }, on: false, }), }); diff --git a/src/utils.ts b/src/utils.ts index cd8d4873..ef30fe36 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,6 @@ import { ContainsArrayError, HTTPStore, openArray, openGroup, ZarrArray } from 'zarr'; import type { Group as ZarrGroup } from 'zarr'; +import { Matrix4 } from 'math.gl'; export const MAX_CHANNELS = 6; @@ -105,3 +106,43 @@ export function fitBounds( const zoom = Math.min(maxZoom, Math.log2(Math.min(scaleX, scaleY))); return { zoom, target: [width / 2, height / 2, 0] }; } + +type Array16 = [ + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number +]; + +function isArray16(o: unknown): o is Array16 { + if (!Array.isArray(o)) return false; + return o.length === 16 && o.every((i) => typeof i === 'number'); +} + +export function parseMatrix(model_matrix?: string | number[]): Matrix4 { + if (!model_matrix) return new Matrix4(); + const matrix = new Matrix4(); + try { + const arr = typeof model_matrix === 'string' ? JSON.parse(model_matrix) : model_matrix; + if (!isArray16(arr)) { + throw Error('Invalid modelMatrix size. Must be 16.'); + } + matrix.set(...arr); + } catch { + const msg = `Failed to parse modelMatrix. Got ${JSON.stringify(model_matrix)}, using identity.`; + console.warn(msg); + } + return matrix; +} diff --git a/types/viv.d.ts b/types/viv.d.ts index d004f381..b0ff012a 100644 --- a/types/viv.d.ts +++ b/types/viv.d.ts @@ -1,5 +1,6 @@ declare module 'viv-layers' { import type { Layer } from '@deck.gl/core'; + import type { Matrix4 } from 'math.gl'; import type { LayerProps } from '@deck.gl/core/lib/layer'; import type { PixelSource } from '@hms-dbmi/viv'; @@ -9,5 +10,6 @@ declare module 'viv-layers' { sliderValues: number[][]; channelIsOn: boolean[]; colormap: null | string; + modelMatrix: Matrix4; }; } From 57a8879abb36c6e64efffdd28374bccc135404ee Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Tue, 2 Mar 2021 18:38:49 -0500 Subject: [PATCH 2/8] disable prettier for multiline type --- src/utils.ts | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index ef30fe36..1b80dfb1 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -107,24 +107,8 @@ export function fitBounds( return { zoom, target: [width / 2, height / 2, 0] }; } -type Array16 = [ - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number -]; +// prettier-ignore +type Array16 = [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]; function isArray16(o: unknown): o is Array16 { if (!Array.isArray(o)) return false; From 3098e20b3017bd4d6881ee57e68e0b011e4747bf Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Tue, 2 Mar 2021 21:21:01 -0500 Subject: [PATCH 3/8] Reuse array metadata --- src/ome.ts | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/ome.ts b/src/ome.ts index 4d3c9846..92327a14 100644 --- a/src/ome.ts +++ b/src/ome.ts @@ -1,8 +1,7 @@ import { ZarrPixelSource } from '@hms-dbmi/viv'; -import pMap from 'p-map'; -import { Group as ZarrGroup, HTTPStore, openGroup, ZarrArray } from 'zarr'; +import { Group as ZarrGroup, HTTPStore, openGroup, ZarrArray, openArray } from 'zarr'; import type { ImageLayerConfig, SourceData } from './state'; -import { join, loadMultiscales, guessTileSize, range, parseMatrix } from './utils'; +import { join, loadMultiscales, guessTileSize, parseMatrix } from './utils'; export async function loadWell(config: ImageLayerConfig, grp: ZarrGroup, wellAttrs: Ome.Well): Promise { // Can filter Well fields by URL query ?acquisition=ID @@ -42,22 +41,25 @@ export async function loadWell(config: ImageLayerConfig, grp: ZarrGroup, wellAtt const rows = Math.ceil(imgPaths.length / cols); // Use first image for rendering settings, resolutions etc. - const imgAttrs = (await grp.getItem(imgPaths[0]).then((g) => g.attrs.asObject())) as Ome.Attrs; + const img = await grp.getItem(imgPaths[0]); + const imgAttrs = (await img.attrs.asObject()) as Ome.Attrs; if (!('omero' in imgAttrs)) { throw Error('Path for image is not valid.'); } - let resolution = imgAttrs.multiscales[0].datasets[0].path; + const { datasets } = imgAttrs.multiscales[0]; + const resolutions = datasets.map((d) => d.path); // Create loader for every Image. - const promises = imgPaths.map((p) => grp.getItem(join(p, resolution))); + const pyramid = resolutions.map((p) => grp.getItem(join(imgPaths[0], p))); const meta = parseOmeroMeta(imgAttrs.omero); - const data = (await Promise.all(promises)) as ZarrArray[]; + const data = (await Promise.all(pyramid)) as ZarrArray[]; const tileSize = guessTileSize(data[0]); - const loaders = range(rows).flatMap((row) => { - return range(cols).map((col) => { - const offset = col + row * cols; - return { name: String(offset), row, col, loader: new ZarrPixelSource(data[offset], meta.axis_labels, tileSize) }; + const loaders = imgPaths.map((p, i) => { + const loader = resolutions.map((res, level) => { + const arr: ZarrArray = new (ZarrArray as any)(grp.store, join(grp.path, p, res), data[level].meta); + return new ZarrPixelSource(arr, meta.axis_labels, tileSize); }); + return { name: String(i), row: Math.floor(i / cols), col: i % cols, loader: loader[loader.length - 1] }; }); const sourceData: SourceData = { @@ -128,25 +130,26 @@ export async function loadPlate(config: ImageLayerConfig, grp: ZarrGroup, plateA } // Lowest resolution is the 'path' of the last 'dataset' from the first multiscales const { datasets } = imgAttrs.multiscales[0]; - const resolution = datasets[datasets.length - 1].path; + const resolutions = datasets.map((d) => d.path); // Create loader for every Well. Some loaders may be undefined if Wells are missing. - const mapper = ([key, path]: string[]) => grp.getItem(path).then((arr) => [key, arr]) as Promise<[string, ZarrArray]>; - const promises = await pMap( - wellPaths.map((p) => [p, join(p, imgPath, resolution)]), - mapper, - { concurrency: 10 } + const promises = resolutions.map((res) => + openArray({ store: grp.store, path: join(grp.path, wellPaths[0], imgPath, res) }) ); - const meta = parseOmeroMeta(imgAttrs.omero); const data = await Promise.all(promises); - const tileSize = guessTileSize(data[0][1]); - const loaders = data.map((d) => { - const [row, col] = d[0].split('/'); + const meta = parseOmeroMeta(imgAttrs.omero); + const tileSize = guessTileSize(data[0]); + const loaders = wellPaths.map((d) => { + const [row, col] = d.split('/'); + const loader = resolutions.map((res, i) => { + const arr = new (ZarrArray as any)(grp.store, join(grp.path, d, imgPath, res), data[i].meta); + return new ZarrPixelSource(arr, meta.axis_labels, tileSize); + }); return { name: `${row}${col}`, row: rows.indexOf(row), col: columns.indexOf(col), - loader: new ZarrPixelSource(d[1], meta.axis_labels, tileSize), + loader: loader[loader.length - 1], }; }); From 57d29277eed6d7e28e4963063264616637644853 Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Tue, 2 Mar 2021 22:08:42 -0500 Subject: [PATCH 4/8] WIP multiscale grid --- src/gridLayer.ts | 89 +++++++----------------------------------------- src/ome.ts | 8 ++--- src/state.ts | 2 +- 3 files changed, 17 insertions(+), 82 deletions(-) diff --git a/src/gridLayer.ts b/src/gridLayer.ts index 3d1087c4..433d6ffe 100644 --- a/src/gridLayer.ts +++ b/src/gridLayer.ts @@ -1,9 +1,8 @@ import { CompositeLayer } from '@deck.gl/core'; import { SolidPolygonLayer, TextLayer } from '@deck.gl/layers'; import type { CompositeLayerProps } from '@deck.gl/core/lib/composite-layer'; -import pMap from 'p-map'; - -import { XRLayer } from '@hms-dbmi/viv'; +import { Matrix4 } from 'math.gl'; +import { MultiscaleImageLayer } from '@hms-dbmi/viv'; import type { GridLoader } from './state'; export interface GridLayerProps extends CompositeLayerProps { @@ -21,82 +20,20 @@ export interface GridLayerProps extends CompositeLayerProps { } const defaultProps = { - ...XRLayer.defaultProps, + ...MultiscaleImageLayer.defaultProps, // Special grid props loaders: { type: 'array', value: [], compare: true }, spacer: { type: 'number', value: 5, compare: true }, rows: { type: 'number', value: 0, compare: true }, columns: { type: 'number', value: 0, compare: true }, concurrency: { type: 'number', value: 10, compare: false }, // set concurrency for queue - text: { type: 'boolean', value: false, compare: true }, + text: { type: 'boolean', value: true, compare: true }, // Deck.gl onClick: { type: 'function', value: null, compare: true }, onHover: { type: 'function', value: null, compare: true }, }; -function scaleBounds(width: number, height: number, translate = [0, 0], scale = 1) { - const [left, top] = translate; - const right = width * scale + left; - const bottom = height * scale + top; - return [left, bottom, right, top]; -} - -function validateWidthHeight(d: { data: { width: number; height: number } }[]) { - const [first] = d; - // Return early if no grid data. Maybe throw an error? - const { width, height } = first.data; - // Verify that all grid data is same shape (ignoring undefined) - d.forEach(({ data }) => { - if (data?.width !== width || data?.height !== height) { - throw new Error('Grid data is not same shape.'); - } - }); - return { width, height }; -} - -function refreshGridData(props: { loaders: GridLoader[]; concurrency?: number; loaderSelection: number[][] }) { - const { loaders, loaderSelection = [] } = props; - let { concurrency } = props; - if (concurrency && loaderSelection.length > 0) { - // There are `loaderSelection.length` requests per loader. This block scales - // the provided concurrency to map to the number of actual requests. - concurrency = Math.ceil(concurrency / loaderSelection.length); - } - const mapper = async (d: GridLoader) => { - const promises = loaderSelection.map((selection) => d.loader.getRaster({ selection })); - const tiles = await Promise.all(promises); - return { - ...d, - data: { - data: tiles.map((d) => d.data), - width: tiles[0].width, - height: tiles[0].height, - }, - }; - }; - return pMap(loaders, mapper, { concurrency }); -} - export default class GridLayer

extends CompositeLayer { - initializeState() { - this.state = { gridData: [], width: 0, height: 0 }; - refreshGridData(this.props).then((gridData) => { - const { width, height } = validateWidthHeight(gridData); - this.setState({ gridData, width, height }); - }); - } - - updateState({ props, oldProps, changeFlags }: { props: GridLayerProps; oldProps: GridLayerProps; changeFlags: any }) { - const { propsChanged } = changeFlags; - const loaderChanged = typeof propsChanged === 'string' && propsChanged.includes('props.loaders'); - const loaderSelectionChanged = props.loaderSelection !== oldProps.loaderSelection; - if (loaderChanged || loaderSelectionChanged) { - // Only fetch new data to render if loader has changed - refreshGridData(this.props).then((gridData) => { - this.setState({ gridData }); - }); - } - } getPickingInfo({ info }: { info: any }) { // provide Grid row and column info for mouse events (hover & click) @@ -104,7 +41,7 @@ export default class GridLayer

extend return info; } const spacer = this.props.spacer || 0; - const { width, height } = this.state; + const [height, width] = this.props.loaders[0].loader[0].shape.slice(-2); const [x, y] = info.coordinate; const row = Math.floor(y / (height + spacer)); const column = Math.floor(x / (width + spacer)); @@ -113,21 +50,19 @@ export default class GridLayer

extend } renderLayers() { - const { gridData, width, height } = this.state; - if (width === 0 || height === 0) return null; // early return if no data - + if (this.props.loaders.length === 0) return null; + const [height, width] = this.props.loaders[0].loader[0].shape.slice(-2); const { rows, columns, spacer = 0, id = '' } = this.props; - const layers = gridData.map((d: any) => { + const layers = this.props.loaders.map((d: any) => { const y = d.row * (height + spacer); const x = d.col * (width + spacer); const layerProps = { - channelData: d.data, // coerce to null if no data - bounds: scaleBounds(width, height, [x, y]), + loader: d.loader, + modelMatrix: (new Matrix4()).translate([x, y, 0]), id: `${id}-GridLayer-${d.row}-${d.col}`, - dtype: d.loader.dtype || 'Uint16', // fallback if missing, pickable: false, }; - return new (XRLayer as any)({ ...this.props, ...layerProps }); + return new (MultiscaleImageLayer as any)({ ...this.props, ...layerProps }); }); if (this.props.pickable) { @@ -155,7 +90,7 @@ export default class GridLayer

extend if (this.props.text) { const textLayer = new TextLayer({ id: `${id}-GridLayer-text`, - data: gridData, + data: this.props.loaders, getPosition: (d: any) => [d.col * (width + spacer), d.row * (height + spacer)], getText: (d: any) => d.name, getColor: [255, 255, 255, 255], diff --git a/src/ome.ts b/src/ome.ts index 92327a14..93ded80b 100644 --- a/src/ome.ts +++ b/src/ome.ts @@ -59,13 +59,13 @@ export async function loadWell(config: ImageLayerConfig, grp: ZarrGroup, wellAtt const arr: ZarrArray = new (ZarrArray as any)(grp.store, join(grp.path, p, res), data[level].meta); return new ZarrPixelSource(arr, meta.axis_labels, tileSize); }); - return { name: String(i), row: Math.floor(i / cols), col: i % cols, loader: loader[loader.length - 1] }; + return { name: String(i), row: Math.floor(i / cols), col: i % cols, loader }; }); const sourceData: SourceData = { loaders, ...meta, - loader: [loaders[0].loader], + loader: loaders[0].loader, model_matrix: parseMatrix(config.model_matrix), defaults: { selection: meta.defaultSelection, @@ -149,7 +149,7 @@ export async function loadPlate(config: ImageLayerConfig, grp: ZarrGroup, plateA name: `${row}${col}`, row: rows.indexOf(row), col: columns.indexOf(col), - loader: loader[loader.length - 1], + loader: loader, }; }); @@ -157,7 +157,7 @@ export async function loadPlate(config: ImageLayerConfig, grp: ZarrGroup, plateA const sourceData: SourceData = { loaders, ...meta, - loader: [loaders[0].loader], + loader: loaders[0].loader, model_matrix: parseMatrix(config.model_matrix), defaults: { selection: meta.defaultSelection, diff --git a/src/state.ts b/src/state.ts index 0defcddd..d126498b 100644 --- a/src/state.ts +++ b/src/state.ts @@ -46,7 +46,7 @@ export interface SingleChannelConfig extends BaseConfig { export type ImageLayerConfig = MultichannelConfig | SingleChannelConfig; export interface GridLoader { - loader: ZarrPixelSource; + loader: ZarrPixelSource[]; row: number; col: number; name: string; From 18253f2149cbb5cb99ce7415fc86bb3b94b09b8d Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Tue, 2 Mar 2021 22:31:19 -0500 Subject: [PATCH 5/8] prettier' --- src/gridLayer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gridLayer.ts b/src/gridLayer.ts index 433d6ffe..5629f074 100644 --- a/src/gridLayer.ts +++ b/src/gridLayer.ts @@ -34,7 +34,6 @@ const defaultProps = { }; export default class GridLayer

extends CompositeLayer { - getPickingInfo({ info }: { info: any }) { // provide Grid row and column info for mouse events (hover & click) if (!info.coordinate) { @@ -58,7 +57,7 @@ export default class GridLayer

extend const x = d.col * (width + spacer); const layerProps = { loader: d.loader, - modelMatrix: (new Matrix4()).translate([x, y, 0]), + modelMatrix: new Matrix4().translate([x, y, 0]), id: `${id}-GridLayer-${d.row}-${d.col}`, pickable: false, }; From e85c96d1ae42553a783ec3bd2f02d8f7384ae44f Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Mon, 8 Mar 2021 18:33:20 -0500 Subject: [PATCH 6/8] Fix math.gl import --- src/state.ts | 2 +- src/utils.ts | 2 +- types/viv.d.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/state.ts b/src/state.ts index 0defcddd..3f1b1054 100644 --- a/src/state.ts +++ b/src/state.ts @@ -3,7 +3,7 @@ import type { ZarrArray } from 'zarr'; import type { ImageLayer, MultiscaleImageLayer, ZarrPixelSource } from '@hms-dbmi/viv'; import type { VivLayerProps } from 'viv-layers'; import type GridLayer from './gridLayer'; -import { Matrix4 } from 'math.gl'; +import { Matrix4 } from '@math.gl/core/dist/esm';; export const DEFAULT_VIEW_STATE = { zoom: 0, target: [0, 0, 0], default: true }; export const DEFAULT_LAYER_PROPS = { diff --git a/src/utils.ts b/src/utils.ts index afe9e864..fe99f220 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import { ContainsArrayError, HTTPStore, openArray, openGroup, ZarrArray } from 'zarr'; import type { Group as ZarrGroup } from 'zarr'; -import { Matrix4 } from 'math.gl'; +import { Matrix4 } from '@math.gl/core/dist/esm'; export const MAX_CHANNELS = 6; diff --git a/types/viv.d.ts b/types/viv.d.ts index b0ff012a..28e4c8e9 100644 --- a/types/viv.d.ts +++ b/types/viv.d.ts @@ -1,6 +1,6 @@ declare module 'viv-layers' { import type { Layer } from '@deck.gl/core'; - import type { Matrix4 } from 'math.gl'; + import type { Matrix4 } from '@math.gl/core/dist/esm'; import type { LayerProps } from '@deck.gl/core/lib/layer'; import type { PixelSource } from '@hms-dbmi/viv'; From ca3679ec3454cc036040f0809945601c28496d17 Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Mon, 8 Mar 2021 18:40:59 -0500 Subject: [PATCH 7/8] format with prettier --- src/state.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state.ts b/src/state.ts index 310b0f99..256fad9a 100644 --- a/src/state.ts +++ b/src/state.ts @@ -3,7 +3,7 @@ import type { ZarrArray } from 'zarr'; import type { ImageLayer, MultiscaleImageLayer, ZarrPixelSource } from '@hms-dbmi/viv'; import type { VivLayerProps } from 'viv-layers'; import type GridLayer from './gridLayer'; -import { Matrix4 } from '@math.gl/core/dist/esm';; +import { Matrix4 } from '@math.gl/core/dist/esm'; export const DEFAULT_VIEW_STATE = { zoom: 0, target: [0, 0, 0], default: true }; export const DEFAULT_LAYER_PROPS = { From db54860771745d020b0e393917d27d079bcde354 Mon Sep 17 00:00:00 2001 From: Trevor Manz Date: Mon, 8 Mar 2021 18:43:37 -0500 Subject: [PATCH 8/8] fix import for matrix in gridlayer --- src/gridLayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gridLayer.ts b/src/gridLayer.ts index 5629f074..c8323e74 100644 --- a/src/gridLayer.ts +++ b/src/gridLayer.ts @@ -1,7 +1,7 @@ import { CompositeLayer } from '@deck.gl/core'; import { SolidPolygonLayer, TextLayer } from '@deck.gl/layers'; import type { CompositeLayerProps } from '@deck.gl/core/lib/composite-layer'; -import { Matrix4 } from 'math.gl'; +import { Matrix4 } from '@math.gl/core/dist/esm'; import { MultiscaleImageLayer } from '@hms-dbmi/viv'; import type { GridLoader } from './state';