Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: React Examples Components (DT-7024) #49

Merged
merged 10 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions examples/dzi.html

This file was deleted.

12 changes: 5 additions & 7 deletions examples/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<!doctype html>
<html>
<body>
EXAMPLES
<br />
<ul>
<li><a href="/dzi">Deep Zoom Image</a><br /></li>
<li><a href="/omezarr">OMEZARR</a><br /></li>
<li><a href="/layers">Layers</a><br /></li>
</ul>
<div id="app"></div>
<script
type="module"
src="/src/index.tsx"
></script>
</body>
</html>
17 changes: 0 additions & 17 deletions examples/omezarr.html

This file was deleted.

5 changes: 3 additions & 2 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
"vite": "^5.3.5"
},
"dependencies": {
"@alleninstitute/vis-geometry": "workspace:*",
"@alleninstitute/vis-scatterbrain": "workspace:*",
"@alleninstitute/vis-dzi": "workspace:*",
"@alleninstitute/vis-geometry": "workspace:*",
"@alleninstitute/vis-omezarr": "workspace:*",
"@alleninstitute/vis-scatterbrain": "workspace:*",
"@czi-sds/components": "^20.0.1",
"@emotion/css": "^11.11.2",
"@emotion/react": "^11.11.4",
Expand All @@ -61,6 +61,7 @@
"lodash": "^4.17.21",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-router": "^7.0.2",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are a handful of static, independant pages worth pulling in this dependency?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it does let us delete the kinda gross repetetative {demo-name.html} files....

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets keep it, seems fine

"regl": "^2.1.0",
"zarrita": "0.4.0-next.14"
}
Expand Down
17 changes: 0 additions & 17 deletions examples/public/layers.html

This file was deleted.

75 changes: 22 additions & 53 deletions examples/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,27 @@
import React from 'react';
import { SliceViewLayer } from './ui/slice-ui';
import type { Demo } from './layers';
import { AnnotationGrid } from './ui/annotation-grid';
import { ContactSheetUI } from './ui/contact-sheet';
import { ScatterplotUI } from './ui/scatterplot-ui';
import { Button } from '@czi-sds/components';
import { BrowserRouter, Route, Routes } from 'react-router';
import { Home } from './home';
import { OmezarrDemo } from './omezarr/omezarr-demo';
import { DziDemo } from './dzi/dzi-demo';

export function AppUi(props: { demo: Demo }) {
const { demo } = props;
export function App() {
return (
<div>
<Button
onClick={() => {
demo.requestSnapshot(3000);
}}
>
{'📸'}
</Button>
<label>{`Layer ${demo.selectedLayer}`}</label>
<Button
onClick={() => {
demo.selectLayer(demo.selectedLayer - 1);
}}
>
{'<-'}
</Button>
<Button
onClick={() => {
demo.selectLayer(demo.selectedLayer + 1);
}}
>
{'->'}
</Button>
<LayerUi demo={demo} />
</div>
<BrowserRouter>
<Routes>
<Route
index
element={<Home />}
/>
<Route
path="/dzi"
element={<DziDemo />}
/>
<Route
path="/omezarr"
element={<OmezarrDemo />}
/>
<Route path="/layers" />
</Routes>
</BrowserRouter>
);
}
function LayerUi(props: { demo: Demo }) {
const { demo } = props;
const layer = demo.layers[demo.selectedLayer];
if (layer) {
switch (layer.type) {
case 'annotationGrid':
return <AnnotationGrid demo={demo} />;
case 'volumeGrid':
return <ContactSheetUI demo={demo} />;
case 'volumeSlice':
return <SliceViewLayer demo={demo} />;
case 'scatterplot':
case 'scatterplotGrid':
return <ScatterplotUI demo={demo} />;
default:
return null;
}
}
return <SliceViewLayer demo={props.demo} />;
}
6 changes: 0 additions & 6 deletions examples/src/dzi/app.tsx

This file was deleted.

61 changes: 34 additions & 27 deletions examples/src/dzi/double.tsx → examples/src/dzi/dzi-demo.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { RenderServerProvider } from '../common/react/render-server-provider';
import React from 'react';
import { DziView } from './dziView';
import type { DziImage, DziRenderSettings } from '@alleninstitute/vis-dzi';
import { Box2D, Vec2, type box2D } from '@alleninstitute/vis-geometry';
import { Box2D, Vec2, type box2D, type vec2 } from '@alleninstitute/vis-geometry';
import { DziViewer } from './dzi-viewer';

const example: DziImage = {
// We know the sizes and formats ahead of time for these examples,
// if you'd like to see how to get this data from an endpoint with a dzi file check out use-dzi-image.ts
const exampleA: DziImage = {
format: 'jpeg',
imagesUrl:
'https://idk-etl-prod-download-bucket.s3.amazonaws.com/idf-23-10-pathology-images/pat_images_HPW332DMO29NC92JPWA/H20.33.029-A12-I6-primary/H20.33.029-A12-I6-primary_files/',
Expand All @@ -16,7 +18,8 @@ const example: DziImage = {
},
tileSize: 512,
};
const exampleDzi: DziImage = {

const exampleB: DziImage = {
imagesUrl: 'https://openseadragon.github.io/example-images/highsmith/highsmith_files/',
format: 'jpg',
overlap: 2,
Expand All @@ -26,12 +29,11 @@ const exampleDzi: DziImage = {
},
tileSize: 256,
};
const exampleSettings: DziRenderSettings = {
camera: {
screenSize: [500, 500],
view: Box2D.create([0, 0], [1, 1]),
},
};

const screenSize: vec2 = [500, 500];

const images = [exampleA, exampleB];

/**
* HEY!!!
* this is an example React Component for rendering two DZI images which share a camera.
Expand All @@ -42,40 +44,45 @@ const exampleSettings: DziRenderSettings = {
* SVG overlays, etc may all be different!
*
*/
export function TwoClientsPOC() {
export function DziDemo() {
// the DZI renderer expects a "relative" camera - that means a box, from 0 to 1. 0 is the bottom or left of the image,
// and 1 is the top or right of the image, regardless of the aspect ratio of that image.
const [view, setView] = useState<box2D>(Box2D.create([0, 0], [1, 1]));
const zoom = (e: React.WheelEvent<HTMLCanvasElement>) => {
const zoom = (e: WheelEvent) => {
e.preventDefault();
const scale = e.deltaY > 0 ? 1.1 : 0.9;
const m = Box2D.midpoint(view);
const v = Box2D.translate(Box2D.scale(Box2D.translate(view, Vec2.scale(m, -1)), [scale, scale]), m);
setView(v);
};
const overlay = useRef<HTMLImageElement>(new Image());

const camera: DziRenderSettings['camera'] = useMemo(() => ({ screenSize, view }), [view]);

useEffect(() => {
overlay.current.onload = () => {
console.log('loaded svg!');
};
overlay.current.src =
'https://idk-etl-prod-download-bucket.s3.amazonaws.com/idf-22-07-pathology-image-move/pat_images_JGCXWER774NLNWX2NNR/7179-A6-I6-MTG-classified/annotation.svg';
}, []);

return (
<RenderServerProvider>
<DziView
id="left"
svgOverlay={overlay.current}
dzi={example}
camera={{ ...exampleSettings.camera, view }}
wheel={zoom}
/>
<DziView
id="right"
dzi={exampleDzi}
svgOverlay={overlay.current}
camera={{ ...exampleSettings.camera, view }}
wheel={zoom}
/>
<p>Scroll below to view image</p>
<div style={{ display: 'flex', flexDirection: 'row' }}>
{images.map((v) => (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add some text to the page encouraging users to scroll to get the demos to appear? Alternatively, we figure out why it takes interaction to make these show up properly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In bkp we solve that problem with an "onComplete" callback with a hook, but lets wait to look into this deeper in another ticket

<div style={{ width: screenSize[0], height: screenSize[1] }}>
<DziViewer
id={v.imagesUrl}
dzi={v}
camera={camera}
svgOverlay={overlay.current}
onWheel={zoom}
/>
</div>
))}
</div>
</RenderServerProvider>
);
}
Loading
Loading