Security News
Input Validation Vulnerabilities Dominate MITRE's 2024 CWE Top 25 List
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
@lunit/insight-viewer2
Advanced tools
cornerstone 등 OPT 기능을 구현하기 위한 여러 graphics layer를 구현한다.
npm install @lunit/insight-viewer2
// cornerstoneWADOImageLoader 초기화 installWADOImageLoader();
// 을 변경하면 Viewport 등 cornerstone-core 관련 속성들이 초기화 된다 const resetTime: number = Date.now();
// unload 옵션은 위에 선언된 installWADOImageLoader()와 함께 동작한다
// CornerstoneImage 객체를 unload 할때 wado image loader의 unload 동작을 하게 된다
const image: CornerstoneImage = new CornerstoneSingleImage(wadouri:samples/series/CT000010.dcm
, {unload: unloadWADOImage});
function Sample() { // addDecorator(withTestController())의 값을 받는다 const { width, height, control, wheel, invert, flip, } = useController();
const { updateCornerstoneRenderData, } = useInsightViewerSync();
return ( <InsightViewer width={width} height={height} invert={invert} flip={flip} pan={control === 'pan'} adjust={control === 'adjust'} zoom={wheel === 'zoom'} resetTime={resetTime} image={image} updateCornerstoneRenderData={updateCornerstoneRenderData}/> ); }
storiesOf('insight-viewer2', module) .addDecorator(withOptTheme) .addDecorator(withTestController({ width: [600, 400, 1000], height: [700, 400, 1000], control: ['pan', ['none', 'pan', 'adjust']], wheel: ['zoom', ['none', 'zoom']], flip: false, invert: false, })) .add('', () => );
<h3>\_\_stories\_\_/MachineHeatmapViewer.stories.tsx</h3>
```tsx
import { MachineHeatmapViewer } from '@lunit/insight-viewer2';
import { withOptTheme } from '@lunit/opt-theme';
import { storiesOf } from '@storybook/react';
import React, { useState } from 'react';
import { InsightViewer } from '../components/InsightViewer';
import { InsightViewerContainer } from '../components/InsightViewerContainer';
import { ProgressViewer } from '../components/ProgressViewer';
import { UserContourDrawer } from '../components/UserContourDrawer';
import { UserContourViewer } from '../components/UserContourViewer';
import { useInsightViewerSync } from '../hooks/useInsightViewerSync';
import { useUserContour } from '../hooks/useUserContour';
import { CornerstoneSingleImage } from '../image/CornerstoneSingleImage';
import { CornerstoneImage } from '../image/types';
import { installWADOImageLoader, unloadWADOImage } from '../installWADO';
import { useController, withTestController } from './decorators/withTestController';
import data from './posMap.sample.json';
const {engine_result: {engine_result: {pos_map: posMap}}} = data;
installWADOImageLoader();
const resetTime: number = Date.now();
const image: CornerstoneImage = new CornerstoneSingleImage(`wadouri:samples/series/CT000010.dcm`, {unload: unloadWADOImage});
function Sample() {
const {
width,
height,
control,
wheel,
invert,
flip,
} = useController();
const [interactionElement, setInteractionElement] = useState<HTMLElement | null>(null);
const {
cornerstoneRenderData,
updateCornerstoneRenderData,
} = useInsightViewerSync();
const {
contours,
focusedContour,
addContour,
removeContour,
focusContour,
} = useUserContour();
return (
<InsightViewerContainer ref={setInteractionElement} width={width} height={height}>
<InsightViewer width={width}
height={height}
invert={invert}
flip={flip}
pan={control === 'pan' && interactionElement}
adjust={control === 'adjust' && interactionElement}
zoom={wheel === 'zoom' && interactionElement}
resetTime={resetTime}
image={image}
updateCornerstoneRenderData={updateCornerstoneRenderData}/>
{/*
engineResult.posMap을 그리는 Layer
현재 Heatmap Spec (number[][])에 맞춰서 개발되었기 때문에
Spec이 다르다면 새로운 Viewer를 만들어야 한다
*/}
<MachineHeatmapViewer width={width}
height={height}
posMap={posMap}
threshold={0.1}
cornerstoneRenderData={cornerstoneRenderData}/>
{
contours &&
contours.length > 0 &&
cornerstoneRenderData &&
<UserContourViewer width={width}
height={height}
contours={contours}
focusedContour={focusedContour}
cornerstoneRenderData={cornerstoneRenderData}/>
}
{
contours &&
cornerstoneRenderData &&
control === 'pen' &&
<UserContourDrawer width={width}
height={height}
contours={contours}
draw={control === 'pen' && interactionElement}
onFocus={focusContour}
onAdd={contour => addContour(contour, 0)}
onRemove={removeContour}
cornerstoneRenderData={cornerstoneRenderData}/>
}
<ProgressViewer image={image}
width={width}
height={height}/>
</InsightViewerContainer>
);
}
storiesOf('insight-viewer2', module)
.addDecorator(withOptTheme)
.addDecorator(withTestController({
width: [600, 400, 1000],
height: [700, 400, 1000],
control: ['pan', ['none', 'pen', 'pan', 'adjust']],
wheel: ['zoom', ['none', 'zoom']],
flip: false,
invert: false,
}))
.add('<MachineHeatmapViewer>', () => <Sample/>);
installWADOImageLoader();
const resetTime: number = Date.now();
const image1: CornerstoneImage = new CornerstoneSingleImage(wadouri:samples/series/CT000010.dcm
, {unload: unloadWADOImage});
const image2: CornerstoneImage = new CornerstoneSingleImage(wadouri:samples/series/CT000020.dcm
, {unload: unloadWADOImage});
const image3: CornerstoneImage = new CornerstoneSingleImage(wadouri:samples/series/CT000030.dcm
, {unload: unloadWADOImage});
const image4: CornerstoneImage = new CornerstoneSeriesImage(series.map(p => wadouri:samples/series/${p}
), {unload: unloadWADOImage});
function Sample() { // 는 하위의 들의 상태를 수집한다 return ( ); }
function Container() { // 에서 수집한 정보를 얻을 수 있다 const progressActivity: boolean = useProgressViewersActivity(); // 혹은 가 동작중일때 비활성을 처리할 Style을 만들 수 있다 const containerDisabledStyle: CSSProperties = useContainerStyleOfProgressViewersInactivity({pointerEvents: 'none'});
return (
{ progressActivity ? '가 하나 이상 작동 중입니다!!!' : '동작중인 가 없습니다!!!' }
); }function Component({image}: {image: CornerstoneImage}) { const { width, height, control, wheel, invert, flip, } = useController();
const {updateCornerstoneRenderData} = useInsightViewerSync();
return ( <InsightViewer width={width} height={height} invert={invert} flip={flip} pan={control === 'pan'} adjust={control === 'adjust'} zoom={wheel === 'zoom'} resetTime={resetTime} image={image} updateCornerstoneRenderData={updateCornerstoneRenderData}/> {/* 이 가 에 수집된다 */} ); }
storiesOf('insight-viewer2', module) .addDecorator(withOptTheme) .addDecorator(withTestController({ width: [300, 200, 500], height: [400, 300, 600], control: ['pan', ['none', 'pen', 'pan', 'adjust']], wheel: ['zoom', ['none', 'zoom']], flip: false, invert: false, })) .add('', () => );
<h3>\_\_stories\_\_/SeriesImage.stories.tsx</h3>
```tsx
import { UserContourDrawer, UserContourViewer, useUserContour } from '@lunit/insight-viewer2';
import { withOptTheme } from '@lunit/opt-theme';
import { storiesOf } from '@storybook/react';
import React, { useState } from 'react';
import { InsightViewer } from '../components/InsightViewer';
import { InsightViewerContainer } from '../components/InsightViewerContainer';
import { ProgressViewer } from '../components/ProgressViewer';
import { useBulkImageScroll } from '../hooks/useBulkImageScroll';
import { useInsightViewerSync } from '../hooks/useInsightViewerSync';
import { CornerstoneSeriesImage } from '../image/CornerstoneSeriesImage';
import { CornerstoneBulkImage } from '../image/types';
import { installWADOImageLoader, unloadWADOImage } from '../installWADO';
import { withSeriesImageController } from './decorators/withSeriesImageController';
import { useController, withTestController } from './decorators/withTestController';
import series from './series.json';
installWADOImageLoader();
const resetTime: number = Date.now();
// CornerstoneSeriesImage는 여러장의 dcm 이미지를 받는다
const image: CornerstoneBulkImage = new CornerstoneSeriesImage(series.map(p => `wadouri:samples/series/${p}`), {unload: unloadWADOImage});
function Component() {
const {
width,
height,
control,
wheel,
invert,
flip,
} = useController();
const [interactionElement, setInteractionElement] = useState<HTMLElement | null>(null);
const {
cornerstoneRenderData,
updateCornerstoneRenderData,
} = useInsightViewerSync();
const {
contours,
focusedContour,
addContour,
removeContour,
focusContour,
} = useUserContour();
// CornerstoneBulkImage를 Wheel과 연결 시킨다
useBulkImageScroll({
image,
element: interactionElement,
enabled: wheel === 'scroll',
});
return (
<InsightViewerContainer ref={setInteractionElement} width={width} height={height}>
<InsightViewer width={width}
height={height}
invert={invert}
flip={flip}
pan={control === 'pan' && interactionElement}
adjust={control === 'adjust' && interactionElement}
zoom={wheel === 'zoom' && interactionElement}
resetTime={resetTime}
image={image}
updateCornerstoneRenderData={updateCornerstoneRenderData}/>
{
contours &&
contours.length > 0 &&
cornerstoneRenderData &&
<UserContourViewer width={width}
height={height}
contours={contours}
focusedContour={focusedContour}
cornerstoneRenderData={cornerstoneRenderData}/>
}
{
contours &&
cornerstoneRenderData &&
control === 'pen' &&
<UserContourDrawer width={width}
height={height}
contours={contours}
draw={control === 'pen' && interactionElement}
onFocus={focusContour}
onAdd={contour => addContour(contour, 0)}
onRemove={removeContour}
cornerstoneRenderData={cornerstoneRenderData}/>
}
<ProgressViewer image={image}
width={width}
height={height}/>
</InsightViewerContainer>
);
}
storiesOf('insight-viewer2', module)
.addDecorator(withOptTheme)
.addDecorator(withTestController({
width: [600, 400, 1000],
height: [700, 400, 1000],
control: ['pan', ['none', 'pen', 'pan', 'adjust']],
wheel: ['scroll', ['none', 'zoom', 'scroll']],
flip: false,
invert: false,
}))
.addDecorator(withSeriesImageController(image))
.add('Series Image', () => <Component/>);
installWADOImageLoader();
const resetTime: number = Date.now();
const image: CornerstoneImage = new CornerstoneSingleImage(wadouri:samples/series/CT000010.dcm
, {unload: unloadWADOImage});
function Sample() { const { width, height, control, wheel, invert, flip, } = useController();
// pan, adjust, zoom은 // pan={true}로 설정하면 내부 Element를 사용해서 MouseEvent를 처리하게 되고, // pan={HTMLElement}로 설정하면 해당 Element를 사용해서 MouseEvent를 처리하게 된다. // MouseEvent를 처리하는 Layer가 여러개 중첩될 때, 하위 Layer의 MouseEvent가 막히는 현상을 해결해준다. const [interactionElement, setInteractionElement] = useState<HTMLElement | null>(null);
// 내부의 Canvas Render를 외부의 다른 Component들에 동기화 시키기 위한 Hook const { cornerstoneRenderData, updateCornerstoneRenderData, } = useInsightViewerSync();
// Annotation (사용자 Contour)를 다루기 위한 Hook const { contours, focusedContour, addContour, removeContour, focusContour, } = useUserContour();
return ( <InsightViewer width={width} height={height} invert={invert} flip={flip} pan={control === 'pan' && interactionElement} adjust={control === 'adjust' && interactionElement} zoom={wheel === 'zoom' && interactionElement} resetTime={resetTime} image={image} updateCornerstoneRenderData={updateCornerstoneRenderData}/> { // 사용자가 그린 Annotation을 보여준다 // contours가 있는 경우에만 출력 contours && contours.length > 0 && cornerstoneRenderData && } { // Annotation을 그리고, 지우게 해준다 // control === 'pen' 인 경우에만 출력 contours && cornerstoneRenderData && control === 'pen' && <UserContourDrawer width={width} height={height} contours={contours} draw={control === 'pen' && interactionElement} onFocus={focusContour} onAdd={contour => addContour(contour, 0)} onRemove={removeContour} cornerstoneRenderData={cornerstoneRenderData}/> } ); }
storiesOf('insight-viewer2', module) .addDecorator(withOptTheme) .addDecorator(withTestController({ width: [600, 400, 1000], height: [700, 400, 1000], control: ['pan', ['none', 'pen', 'pan', 'adjust']], wheel: ['zoom', ['none', 'zoom']], flip: false, invert: false, })) .add('', () => );
<h3>\_\_stories\_\_/UserContourViewerCanvasStyle.stories.tsx</h3>
```tsx
import { withOptTheme } from '@lunit/opt-theme';
import { storiesOf } from '@storybook/react';
import React, { useState } from 'react';
import { InsightViewer } from '../components/InsightViewer';
import { InsightViewerContainer } from '../components/InsightViewerContainer';
import { ProgressViewer } from '../components/ProgressViewer';
import { UserContourDrawer } from '../components/UserContourDrawer';
import { UserContourViewer } from '../components/UserContourViewer';
import { useInsightViewerSync } from '../hooks/useInsightViewerSync';
import { useUserContour } from '../hooks/useUserContour';
import { CornerstoneSingleImage } from '../image/CornerstoneSingleImage';
import { CornerstoneImage } from '../image/types';
import { installWADOImageLoader, unloadWADOImage } from '../installWADO';
import { useController, withTestController } from './decorators/withTestController';
installWADOImageLoader();
const resetTime: number = Date.now();
const image: CornerstoneImage = new CornerstoneSingleImage(`wadouri:samples/series/CT000010.dcm`, {unload: unloadWADOImage});
function Sample() {
const {
width,
height,
control,
wheel,
invert,
flip,
} = useController();
const [interactionElement, setInteractionElement] = useState<HTMLElement | null>(null);
const {
cornerstoneRenderData,
updateCornerstoneRenderData,
} = useInsightViewerSync();
const {
contours,
focusedContour,
addContour,
removeContour,
focusContour,
} = useUserContour();
return (
<InsightViewerContainer ref={setInteractionElement} width={width} height={height}>
<InsightViewer width={width}
height={height}
invert={invert}
flip={flip}
pan={control === 'pan' && interactionElement}
adjust={control === 'adjust' && interactionElement}
zoom={wheel === 'zoom' && interactionElement}
resetTime={resetTime}
image={image}
updateCornerstoneRenderData={updateCornerstoneRenderData}/>
{
contours &&
contours.length > 0 &&
cornerstoneRenderData &&
// Canvas Style을 변경할 수 있다
<UserContourViewer width={width}
height={height}
contours={contours}
focusedContour={focusedContour}
cornerstoneRenderData={cornerstoneRenderData}
canvasStrokeLineWidth={10}
canvasStrokeStyle="blue"
canvasFillStyle="rgba(0, 0, 255, 0.3)"
canvasFontStyle="normal normal 600 40px proximanova"
canvasFocusedStrokeLineWidth={20}
canvasFocusedStrokeStyle="red"
canvasFocusedFillStyle="rgba(255, 0, 0, 0.3)"
canvasFocusedFontStyle="normal normal 600 50px proximanova"/>
}
{
contours &&
cornerstoneRenderData &&
control === 'pen' &&
// Canvas Style을 변경할 수 있다
<UserContourDrawer width={width}
height={height}
contours={contours}
draw={control === 'pen' && interactionElement}
onFocus={focusContour}
onAdd={contour => addContour(contour, 0)}
onRemove={removeContour}
cornerstoneRenderData={cornerstoneRenderData}
canvasStokeLineWidght={8}
canvasStokeStyle="purple"
canvasFillStyle="rgba(255, 255, 255, 0.4)"/>
}
<ProgressViewer image={image}
width={width}
height={height}/>
</InsightViewerContainer>
);
}
storiesOf('insight-viewer2', module)
.addDecorator(withOptTheme)
.addDecorator(withTestController({
width: [600, 400, 1000],
height: [700, 400, 1000],
control: ['pan', ['none', 'pen', 'pan', 'adjust']],
wheel: ['zoom', ['none', 'zoom']],
flip: false,
invert: false,
}))
.add('<UserContourViewer canvasStokeStyle="{}">', () => <Sample/>);
installWADOImageLoader();
const resetTime: number = Date.now();
const image: CornerstoneImage = new CornerstoneSingleImage(wadouri:samples/series/CT000010.dcm
, {unload: unloadWADOImage});
function Sample() { const { updateCornerstoneRenderData, } = useInsightViewerSync();
// 특정 Element의 width, height를 지속적으로 감지한다 // flex 등 layout으로 처리된
console.log('useResizeObserver.stories.tsx..Sample()', width, height);
return ( <div ref={resizeRef} style={{width: '50vw', height: '80vh'}}>
storiesOf('insight-viewer2', module) .addDecorator(withOptTheme) .add('useResizeObserver', () => );
<h3>\_\_stories\_\_/useViewportMirroring.stories.tsx</h3>
```tsx
import {
CornerstoneBulkImage,
useInsightViewerSync,
UserContourDrawer,
UserContourViewer,
useUserContour,
} from '@lunit/insight-viewer2';
import { useBulkImageScroll } from '@lunit/insight-viewer2/hooks/useBulkImageScroll';
import { useViewportMirroring } from '@lunit/insight-viewer2/hooks/useViewportMirroring';
import { withOptTheme } from '@lunit/opt-theme';
import { storiesOf } from '@storybook/react';
import React, { RefObject, useRef, useState } from 'react';
import { InsightViewer } from '../components/InsightViewer';
import { InsightViewerContainer } from '../components/InsightViewerContainer';
import { CornerstoneSeriesImage } from '../image/CornerstoneSeriesImage';
import { CornerstoneSingleImage } from '../image/CornerstoneSingleImage';
import { CornerstoneImage } from '../image/types';
import { installWADOImageLoader, unloadWADOImage } from '../installWADO';
import { useController, withTestController } from './decorators/withTestController';
import series from './series.json';
installWADOImageLoader();
const resetTime: number = Date.now();
const image1: CornerstoneImage = new CornerstoneSingleImage(`wadouri:samples/series/CT000010.dcm`, {unload: unloadWADOImage});
const image2: CornerstoneImage = new CornerstoneSingleImage(`wadouri:samples/series/CT000020.dcm`, {unload: unloadWADOImage});
const image3: CornerstoneImage = new CornerstoneSingleImage(`wadouri:samples/series/CT000030.dcm`, {unload: unloadWADOImage});
const image4: CornerstoneBulkImage = new CornerstoneSeriesImage(series.map(p => `wadouri:samples/series/${p}`), {unload: unloadWADOImage});
function Sample() {
const {
width,
height,
invert,
flip,
} = useController();
// Viewport Mirroring의 대상에게 부여할 RefObject 들을 만든다
const viewer2: RefObject<InsightViewer> = useRef(null);
const viewer3: RefObject<InsightViewer> = useRef(null);
const viewer4: RefObject<InsightViewer> = useRef(null);
// updateMasterRenderData()가 실행되면 viewer2, viewer3, viewer4에 Viewport가 Mirroring 된다
const {updateMasterRenderData} = useViewportMirroring(viewer2, viewer3, viewer4);
// 3번째 화면을 위한 처리
const [interactionElement3, setInteractionElement3] = useState<HTMLElement | null>(null);
const {
cornerstoneRenderData,
updateCornerstoneRenderData,
} = useInsightViewerSync();
const {
contours,
focusedContour,
addContour,
removeContour,
focusContour,
} = useUserContour();
// 4번째 화면을 위한 처리
const [interactionElement4, setInteractionElement4] = useState<HTMLElement | null>(null);
useBulkImageScroll({
image: image4,
element: interactionElement4,
enabled: true,
});
return (
<div style={{display: 'flex'}}>
<InsightViewerContainer width={width} height={height}>
<InsightViewer width={width}
height={height}
invert={invert}
flip={flip}
pan
adjust={false}
zoom
resetTime={resetTime}
image={image1}
updateCornerstoneRenderData={updateMasterRenderData}/>
</InsightViewerContainer>
<InsightViewerContainer width={width} height={height}>
<InsightViewer ref={viewer2}
width={width}
height={height}
invert={invert}
flip={flip}
pan={false}
adjust
zoom={false}
resetTime={resetTime}
image={image2}
updateCornerstoneRenderData={renderData => console.log('#2', renderData)}/>
</InsightViewerContainer>
<InsightViewerContainer ref={setInteractionElement3} width={width} height={height}>
<InsightViewer ref={viewer3}
width={width}
height={height}
invert={invert}
flip={flip}
pan={false}
adjust={false}
zoom={false}
resetTime={resetTime}
image={image3}
updateCornerstoneRenderData={updateCornerstoneRenderData}/>
{
contours &&
contours.length > 0 &&
cornerstoneRenderData &&
<UserContourViewer width={width}
height={height}
contours={contours}
focusedContour={focusedContour}
cornerstoneRenderData={cornerstoneRenderData}/>
}
{
contours &&
cornerstoneRenderData &&
<UserContourDrawer width={width}
height={height}
contours={contours}
draw={interactionElement3}
onFocus={focusContour}
onAdd={contour => addContour(contour, 0)}
onRemove={removeContour}
cornerstoneRenderData={cornerstoneRenderData}/>
}
</InsightViewerContainer>
<InsightViewerContainer ref={setInteractionElement4} width={width} height={height}>
<InsightViewer ref={viewer4}
width={width}
height={height}
invert={invert}
flip={flip}
pan={false}
adjust={false}
zoom={false}
resetTime={resetTime}
image={image4}
updateCornerstoneRenderData={renderData => console.log('#4', renderData)}/>
</InsightViewerContainer>
</div>
);
}
storiesOf('insight-viewer2', module)
.addDecorator(withOptTheme)
.addDecorator(withTestController({
width: [300, 200, 500],
height: [400, 300, 600],
control: ['none', ['none']],
wheel: ['none', ['none']],
flip: false,
invert: false,
}))
.add('useViewportMirroring()', () => <Sample/>);
FAQs
dcm viewer component library
The npm package @lunit/insight-viewer2 receives a total of 0 weekly downloads. As such, @lunit/insight-viewer2 popularity was classified as not popular.
We found that @lunit/insight-viewer2 demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.