feat: react-grid尝试

This commit is contained in:
mozzie 2024-09-13 22:42:13 +08:00
parent 27f26a2af0
commit 0e7d05d9a4
6 changed files with 102 additions and 31 deletions

View File

@ -72,7 +72,9 @@
"@cornerstonejs/streaming-image-volume-loader": "1.84.4",
"dicomweb-client": "0.10.4",
"@cornerstonejs/calculate-suv": "1.1.0",
"dcmjs": "0.34.1"
"dcmjs": "0.34.1",
"react-grid-layout": "1.4.4",
"react-resizable": "3.0.5"
},
"devDependencies": {
"@radix-ui/react-icons": "^1.3.0",
@ -97,4 +99,4 @@
"@types/lodash": "4.17.7",
"vite-plugin-node-polyfills": "0.22.0"
}
}
}

View File

@ -10,7 +10,7 @@ import {
export const menuItems: MenuItem[] = [
{ to: "/", name: "自动分析", icon: <BrainCircuit /> },
{ to: "/datasource", name: "数据列表", icon: <HardDrive /> },
{ to: "/viewer", name: "MPR阅片", icon: <Rotate3DIcon size={24} /> },
// { to: "/viewer", name: "MPR阅片", icon: <Rotate3DIcon size={24} /> },
{ to: "/models", name: "模型管理", icon: <Package /> },
{ to: "/tools", name: "小工具", icon: <Wrench /> },
// { to: "/setting", name: "设置", icon: <IoSettingsOutline size={24} /> },

View File

@ -15,11 +15,10 @@ export const SideBarLeft = () => {
{menuItems.map((item) => (
<li
key={item.name}
className={`w-full flex flex-col items-center justify-center ${
location.pathname === item.to
? "active text-primary bg-primary/10 rounded-r"
: ""
}`}
className={`w-full flex flex-col items-center justify-center ${location.pathname === item.to
? "active text-primary bg-primary/10 rounded-r"
: ""
}`}
onClick={() => handleClick(item)}
>
<Link

View File

@ -1,4 +1,4 @@
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import * as cornerstoneTools from "@cornerstonejs/tools";
import { PublicViewportInput } from "@cornerstonejs/core/dist/types/types/IViewport.js";
import { createImageIdsAndCacheMetaData } from "./CornerstoneDicomLoader/createImageIdsAndCacheMetaData";
@ -20,6 +20,12 @@ import {
ViewportId,
} from "./Crosshair.config";
import GridLayout from 'react-grid-layout';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';
import { DraftingCompassIcon, MoveIcon } from "lucide-react";
import { Card } from "@/components/ui/card";
const {
ToolGroupManager,
CrosshairsTool,
@ -61,6 +67,7 @@ interface CrosshairMprProps {
}
export const CrosshairMpr = (props: CrosshairMprProps) => {
const containerRef = useRef<HTMLDivElement | null>(null);
const viewportRef_AXIAL = useRef<HTMLDivElement | null>(null);
const viewportRef_SAGITTAL = useRef<HTMLDivElement | null>(null);
const viewportRef_CORONAL = useRef<HTMLDivElement | null>(null);
@ -68,6 +75,7 @@ export const CrosshairMpr = (props: CrosshairMprProps) => {
const imageIds = useRef<string[]>();
const ts = "-" + Date.now();
useEffect(() => {
cornerstoneTools.addTool(StackScrollMouseWheelTool);
cornerstoneTools.addTool(CrosshairsTool);
@ -219,7 +227,7 @@ export const CrosshairMpr = (props: CrosshairMprProps) => {
}, [props, ts]);
useEffect(() => {
const resize = () => renderingEngine.current?.resize();
const resize = () => renderingEngine.current?.resize()
window.addEventListener("resize", resize);
return () => {
window.removeEventListener("resize", resize);
@ -231,14 +239,16 @@ export const CrosshairMpr = (props: CrosshairMprProps) => {
};
return (
<div className="h-full flex flex-col gap-y-2">
<div
onDoubleClick={() => onDBClickViewport(viewportRef_AXIAL)}
className="h-1/3 border rounded-md"
ref={viewportRef_AXIAL}
></div>
<div className="h-1/3 border rounded-md" ref={viewportRef_SAGITTAL}></div>
<div className="h-1/3 border rounded-md" ref={viewportRef_CORONAL}></div>
<div ref={containerRef} className="w-full h-full flex flex-col">
<Card className="rounded-none h-1/3">
<div className="w-full h-full" onDoubleClick={() => onDBClickViewport(viewportRef_AXIAL)} ref={viewportRef_AXIAL}></div>
</Card>
<Card className="rounded-none h-1/3">
<div className="w-full h-full" ref={viewportRef_SAGITTAL}></div>
</Card>
<Card className="rounded-none h-1/3">
<div className="w-full h-full" ref={viewportRef_CORONAL}></div>
</Card>
</div>
);
};

View File

@ -3,6 +3,7 @@ import { initCornerstone } from "./MprViewer/CornerstoneDicomLoader/init";
import { CrosshairMpr } from "./MprViewer/Crosshair";
import { useEffect, useState } from "react";
export interface CurrentDicom {
SeriesInstanceUID: string | null;
StudyInstanceUID: string | null;
@ -26,14 +27,16 @@ export const Viewer = () => {
}, [currentDicom]);
useEffect(() => {
console.log(window.location.href)
initCornerstone(() => {
setCornerstoneLoaded(true);
});
}, []);
useEffect(() => {
console.log(currentDicom, cornerstoneLoaded);
}, [cornerstoneLoaded, currentDicom]);
console.log(cornerstoneLoaded);
}, [cornerstoneLoaded]);
return (
<div className="w-full h-full flex">
@ -46,10 +49,7 @@ export const Viewer = () => {
StudyInstanceUID={currentDicom.StudyInstanceUID}
SeriesInstanceUID={currentDicom.SeriesInstanceUID}
/>
)}
</div>
{Object.values(currentDicom).some((i) => !i) && "导入dicom"}
)}</div>
</div>
);
};

View File

@ -175,12 +175,18 @@ importers:
react-dropzone:
specifier: 14.2.3
version: 14.2.3(react@18.3.1)
react-grid-layout:
specifier: 1.4.4
version: 1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-hook-form:
specifier: 7.53.0
version: 7.53.0(react@18.3.1)
react-icons:
specifier: ^5.2.1
version: 5.3.0(react@18.3.1)
react-resizable:
specifier: 3.0.5
version: 3.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-resizable-panels:
specifier: ^2.1.1
version: 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -2740,6 +2746,10 @@ packages:
clone-response@1.0.3:
resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==}
clsx@1.2.1:
resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
engines: {node: '>=6'}
clsx@2.0.0:
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
engines: {node: '>=6'}
@ -3255,6 +3265,9 @@ packages:
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
fast-equals@4.0.3:
resolution: {integrity: sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==}
fast-fifo@1.3.2:
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
@ -4632,12 +4645,24 @@ packages:
peerDependencies:
react: ^18.3.1
react-draggable@4.4.6:
resolution: {integrity: sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==}
peerDependencies:
react: '>= 16.3.0'
react-dom: '>= 16.3.0'
react-dropzone@14.2.3:
resolution: {integrity: sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==}
engines: {node: '>= 10.13'}
peerDependencies:
react: '>= 16.8 || 18.0.0'
react-grid-layout@1.4.4:
resolution: {integrity: sha512-7+Lg8E8O8HfOH5FrY80GCIR1SHTn2QnAYKh27/5spoz+OHhMmEhU/14gIkRzJOtympDPaXcVRX/nT1FjmeOUmQ==}
peerDependencies:
react: '>= 16.3.0'
react-dom: '>= 16.3.0'
react-hook-form@7.53.0:
resolution: {integrity: sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==}
engines: {node: '>=18.0.0'}
@ -4695,6 +4720,11 @@ packages:
react: ^16.14.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0
react-resizable@3.0.5:
resolution: {integrity: sha512-vKpeHhI5OZvYn82kXOs1bC8aOXktGU5AmKAgaZS4F5JPburCtbmDPqE7Pzp+1kN4+Wb81LlF33VpGwWwtXem+w==}
peerDependencies:
react: '>= 16.3'
react-router-dom@6.26.1:
resolution: {integrity: sha512-veut7m41S1fLql4pLhxeSW3jlqs+4MtjRLj0xvuCEXsxusJCbs6I8yn9BxzzDX2XDgafrccY6hwjmd/bL54tFw==}
engines: {node: '>=14.0.0'}
@ -7958,7 +7988,7 @@ snapshots:
app-builder-bin@4.0.0: {}
app-builder-lib@24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)):
app-builder-lib@24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)):
dependencies:
'@develar/schema-utils': 2.6.5
'@electron/notarize': 2.2.1
@ -7972,7 +8002,7 @@ snapshots:
builder-util-runtime: 9.2.4
chromium-pickle-js: 0.2.0
debug: 4.3.6
dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3)
ejs: 3.1.10
electron-builder-squirrel-windows: 24.13.3(dmg-builder@24.13.3)
electron-publish: 24.13.1
@ -8406,6 +8436,8 @@ snapshots:
dependencies:
mimic-response: 1.0.1
clsx@1.2.1: {}
clsx@2.0.0: {}
clsx@2.1.1: {}
@ -8686,9 +8718,9 @@ snapshots:
dlv@1.1.3: {}
dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)):
dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3):
dependencies:
app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
builder-util: 24.13.1
builder-util-runtime: 9.2.4
fs-extra: 10.1.0
@ -8758,7 +8790,7 @@ snapshots:
electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3):
dependencies:
app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
archiver: 5.3.2
builder-util: 24.13.1
fs-extra: 10.1.0
@ -8768,11 +8800,11 @@ snapshots:
electron-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)):
dependencies:
app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
builder-util: 24.13.1
builder-util-runtime: 9.2.4
chalk: 4.1.2
dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3)
fs-extra: 10.1.0
is-ci: 3.0.1
lazy-val: 1.0.5
@ -9019,6 +9051,8 @@ snapshots:
fast-deep-equal@3.1.3: {}
fast-equals@4.0.3: {}
fast-fifo@1.3.2: {}
fast-glob@3.3.2:
@ -10534,6 +10568,13 @@ snapshots:
react: 18.3.1
scheduler: 0.23.2
react-draggable@4.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
clsx: 1.2.1
prop-types: 15.8.1
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-dropzone@14.2.3(react@18.3.1):
dependencies:
attr-accept: 2.2.2
@ -10541,6 +10582,17 @@ snapshots:
prop-types: 15.8.1
react: 18.3.1
react-grid-layout@1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
clsx: 2.1.1
fast-equals: 4.0.3
prop-types: 15.8.1
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-draggable: 4.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-resizable: 3.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
resize-observer-polyfill: 1.5.1
react-hook-form@7.53.0(react@18.3.1):
dependencies:
react: 18.3.1
@ -10590,6 +10642,14 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-resizable@3.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
prop-types: 15.8.1
react: 18.3.1
react-draggable: 4.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
transitivePeerDependencies:
- react-dom
react-router-dom@6.26.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@remix-run/router': 1.19.1