diff --git a/client/component/README.md b/client/component/README.md
index 5b63baf7..9badcd71 100644
--- a/client/component/README.md
+++ b/client/component/README.md
@@ -3,6 +3,7 @@
View the frontend Typescript documentation [here](https://diamondlightsource.github.io/davidia/typedocs/index.html).
## Installation
+
### `pnpm add @diamondlightsource/davidia`
## Vite configuration
@@ -10,8 +11,8 @@ View the frontend Typescript documentation [here](https://diamondlightsource.git
Some davidia dependencies require a global object to be defined when used in Vite applications. Add the following to your vite.config.ts:
```js
-import { defineConfig } from "vite";
-import react from "@vitejs/plugin-react";
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
@@ -19,4 +20,4 @@ export default defineConfig({
global: {},
},
});
-```
\ No newline at end of file
+```
diff --git a/client/component/package.json b/client/component/package.json
index 9d3b44f6..e2c95ac8 100644
--- a/client/component/package.json
+++ b/client/component/package.json
@@ -40,6 +40,8 @@
"d3-scale": "^4.0.2",
"ndarray-concat-rows": "^1.0.1",
"ndarray-linspace": "^2.0.3",
+ "ndarray-tile": "^1.0.3",
+ "ndarray-unsqueeze": "^1.0.3",
"react-colorful": "^5.8.0",
"react-draggable": "^4.7.0",
"react-icons": "^5.7.0",
diff --git a/client/component/src/ImagePlot.tsx b/client/component/src/ImagePlot.tsx
index 54eb439d..54f4585b 100644
--- a/client/component/src/ImagePlot.tsx
+++ b/client/component/src/ImagePlot.tsx
@@ -1,4 +1,6 @@
import { Aspect, type ModifierKey, RgbVis } from '@h5web/lib';
+import unsqueeze from 'ndarray-unsqueeze';
+import tile from 'ndarray-tile';
import SelectionComponent from './SelectionComponent';
import { createInteractionsConfig, InteractionModeType } from './utils';
@@ -38,6 +40,23 @@ function getAxisOffsets(
};
}
+function makeRGB(values: NDT): NDT | null {
+ const shape = values.shape;
+
+ if (shape.length == 2) {
+ return tile(unsqueeze(values), [1, 1, 3]) as NDT;
+ } else if (shape.length == 3) {
+ const channels = shape[2];
+ if (channels == 1) {
+ return tile(values, [1, 1, 3]) as NDT;
+ } else if (channels == 3) {
+ return values;
+ }
+ }
+ console.log('Shape of array is not compatible with RGB array:', shape);
+ return null;
+}
+
export function ImageVisCanvas({ xValues, yValues, values }: Props) {
const {
title,
@@ -55,35 +74,39 @@ export function ImageVisCanvas({ xValues, yValues, values }: Props) {
} = usePlotCustomizationContext();
const interactionsConfig = createInteractionsConfig(mode);
+ const rgbValues = makeRGB(values);
+
return (
-
- {canSelect && (
-
- )}
-
+ rgbValues && (
+
+ {canSelect && (
+
+ )}
+
+ )
);
}
diff --git a/client/example/src/App.tsx b/client/example/src/App.tsx
index a7cc7986..655f432d 100644
--- a/client/example/src/App.tsx
+++ b/client/example/src/App.tsx
@@ -62,6 +62,16 @@ function generateImage(width: number, height: number) {
return ndarray(rgb, [height, width, 3]) as NDT;
}
+function generateGreyImage(width: number, height: number, threeD = false) {
+ const rgb = new Uint8Array(width * height);
+
+ for (let i = 0; i < rgb.length; i++) {
+ rgb[i] = Math.random() * 255;
+ }
+ if (threeD) return ndarray(rgb, [height, width, 1]) as NDT;
+ return ndarray(rgb, [height, width]) as NDT;
+}
+
class AppMain extends React.Component {
uuid: string;
constructor(props: AppMainProps) {
@@ -136,6 +146,10 @@ class AppMain extends React.Component {
const port = import.meta.env.VITE_WS_PORT ?? window.location.port;
console.log('host:', host, 'port:', port);
+ const portraitImage = generateImage(6, 12);
+ const landscapeImage = generateGreyImage(9, 2);
+ const squareImage = generateGreyImage(6, 6, true);
+
return (
@@ -217,7 +231,7 @@ class AppMain extends React.Component {
@@ -233,7 +247,7 @@ class AppMain extends React.Component {
@@ -245,7 +259,7 @@ class AppMain extends React.Component {
yLabel: 'Y Co-ordinate',
}}
tightAxes={this.state.tightImagePlots}
- values={generateImage(6, 6)}
+ values={squareImage}
/>
diff --git a/client/types/ndarray-tile/index.d.ts b/client/types/ndarray-tile/index.d.ts
new file mode 100644
index 00000000..04572ea9
--- /dev/null
+++ b/client/types/ndarray-tile/index.d.ts
@@ -0,0 +1,5 @@
+declare module 'ndarray-tile' {
+ import type { NdArray, TypedArray } from 'ndarray';
+ type NDT = NdArray;
+ export default function tile(array: NDT, repeats: number[]): NDT;
+}
diff --git a/client/types/ndarray-unsqueeze/index.d.ts b/client/types/ndarray-unsqueeze/index.d.ts
new file mode 100644
index 00000000..49dbec90
--- /dev/null
+++ b/client/types/ndarray-unsqueeze/index.d.ts
@@ -0,0 +1,5 @@
+declare module 'ndarray-unsqueeze' {
+ import type { NdArray, TypedArray } from 'ndarray';
+ type NDT = NdArray;
+ export default function unsqueeze(array: NDT, axis?: number): NDT;
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2cd5a1c4..e1d37322 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -105,6 +105,12 @@ importers:
ndarray-linspace:
specifier: ^2.0.3
version: 2.0.3
+ ndarray-tile:
+ specifier: ^1.0.3
+ version: 1.0.3
+ ndarray-unsqueeze:
+ specifier: ^1.0.3
+ version: 1.0.3
react-colorful:
specifier: ^5.8.0
version: 5.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -3396,6 +3402,12 @@ packages:
ndarray-scratch@1.2.0:
resolution: {integrity: sha512-a4pASwB1jQyJcKLYrwrladVfDZDUGc78qLJZbHyb1Q4rhte0URhzc6ALQpBcauwgov0sXLwZz3vYH5jKAhSMIg==}
+ ndarray-tile@1.0.3:
+ resolution: {integrity: sha512-8kTPCNwi1RHSWfZClIpTlS+edeHNdBv7YqtKznRqModPHIcqDuJIPum4+GllLBxu67+63RZJgGAcFsc0rGo32A==}
+
+ ndarray-unsqueeze@1.0.3:
+ resolution: {integrity: sha512-Gvw7eA3rlhKFrOQuNinhQyYFl6dHDix8DG3CRWQAQA4eDPHNfdRdzX80JRAmnLue623ShykszC2ru/JRyl5wig==}
+
ndarray@1.0.19:
resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==}
@@ -8261,6 +8273,15 @@ snapshots:
ndarray-ops: 1.2.2
typedarray-pool: 1.2.0
+ ndarray-tile@1.0.3:
+ dependencies:
+ ndarray-ops: 1.2.2
+ ndarray-scratch: 1.2.0
+
+ ndarray-unsqueeze@1.0.3:
+ dependencies:
+ ndarray: 1.0.19
+
ndarray@1.0.19:
dependencies:
iota-array: 1.0.0
diff --git a/tsconfig.json b/tsconfig.json
index 2e7c1ed9..4e46cc2e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,6 +13,8 @@
"typeRoots": [ "client/types" ],
"paths": {
"ndarray-concat-rows": ["./client/types/ndarray-concat-rows"],
+ "ndarray-tile": ["./client/types/ndarray-tile"],
+ "ndarray-unsqueeze": ["./client/types/ndarray-unsqueeze"],
"@diamondlightsource/davidia": [
"./client/component/src/index.ts"
],