feat: Add measurement tracking user guide

This commit is contained in:
Alireza 2021-07-01 23:24:03 -04:00
parent 39ff15aeaf
commit 3fc56f373c
4 changed files with 806 additions and 810 deletions

View File

@ -5,12 +5,15 @@ sidebar_position: 4
# Measurement Tracking
## Introduction
OHIF-V3's `Basic Viewer` implements a `Measurement Tracking` workflow. Measurement
tracking allows you to:
- Draw annotations and have them shown in the measurement panel
- Create a report from the tracked measurement and export them as DICOM SR
- Use already exported DICOM SR to re-hydrate the measurements in the viewer
### Tracked Icon
## Status Icon
Each viewport has a left icon indicating whether the series within the viewport
contains:
@ -19,39 +22,74 @@ contains:
- Structured Report OR
- Locked (uneditable) Structured Report
In the following, we will discuss each category.
### Tracked vs Untracked Measurements
`OHIF-v3` implements a workflow for measurement tracking that can be seen below.
![user-measurement-panel-modal](../../assets/img/tracking-workflow1.png)
In summary, when you create an annotation, a prompt will be shown whether to start tracking or not. If you start the tracking, the annotation style will change to a solid line, and annotation details get displayed on the measurement panel.
On the other hand, if you decline the tracking pormpt, the measurement will be considered "temporary," and annotation style remains as a dashed line and not shown on the right panel, and cannot be exported.
Below, you can see different icons that appear for a tracked vs. untracked series in
`OHIF-v3`.
![tracked-not-tracked](../../assets/img/tracked-not-tracked.png)
when you export an SR you will see, and also draggin and dropping SR inside viewer
Overview video for starting the tracking for measurements:
<!-- trackedMeasurements -->
TEMP
Overview video for not starting tracking for measurements:
<!-- untrackedMeasurements -->
TEMP
### Reading and Writing DICOM SR
`OHIF-v3` provides full support for reading, writing and mapping the DICOM Structured
Report (SR) to interactable `Cornerstone Tools`. When you load an already exported
DICOM SR into the viewer, you will be prompted whether to track the measurements
for the series or not.
![SR-exported](../../assets/img/SR-exported.png)
If you say no and later decide to say yes, click on the SR button the prompt will come again
click to restore measurements
If you click Yes, DICOM SR measurements gets re-hydrated into the viewer and
the series become a tracked series. However, If you say no and later decide to say track the measurements, you can always click on the SR button that will prompt you
with the same message again.
![restore-exported-sr](../../assets/img/restore-exported-sr.png)
The full workflow for saving measurements to SR and loading SR into the viewer is shown below.
![user-measurement-panel-modal](../../assets/img/tracking-workflow2.png)
![user-measurement-panel-modal](../../assets/img/tracking-workflow3.png)
Overview video for loading DICOM SR and making a tracked sereis:
<!-- SR Restore and Yes -->
TEMP
Overview video for loading DICOM SR and not making a tracked series:
<!-- SR Restore and No -->
<!-- SR Export and measurement restore -->
TEMP
### Loading DICOM SR into an Already Tracked Series
If you have an already tracked series and try to load a DICOM SR measurements,
you will be shown the following lock icon. This means that, you can review the
DICOM SR measurement, manipulate image and draw "temporary" measurements; however,
you cannot edit the DICOM SR measurement.
Locked SR
![locked-sr](../../assets/img/locked-sr.png)
Workflow for tracking can be found below. You can click on the image to have a zoomed in
version pop up or you can also right click on the image
and click `Open image in new tab` to have a better experience reading the details.
![user-measurement-panel-modal](../../assets/img/tracking-workflow1.png)
![user-measurement-panel-modal](../../assets/img/tracking-workflow2.png)
![user-measurement-panel-modal](../../assets/img/tracking-workflow3.png)
Overview video for loading DICOM SR inside an already tracked sereis:
<!-- DICOMSRLockedTracked -->
TEMP

View File

@ -15,13 +15,13 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "2.0.0-beta.0",
"@docusaurus/plugin-client-redirects": "2.0.0-beta.0",
"@docusaurus/plugin-ideal-image": "2.0.0-beta.0",
"@docusaurus/plugin-pwa": "2.0.0-beta.0",
"@docusaurus/preset-classic": "2.0.0-beta.0",
"@docusaurus/remark-plugin-npm2yarn": "2.0.0-beta.0",
"@docusaurus/theme-live-codeblock": "2.0.0-beta.0",
"@docusaurus/core": "2.0.0-beta.3",
"@docusaurus/plugin-client-redirects": "2.0.0-beta.3",
"@docusaurus/plugin-ideal-image": "2.0.0-beta.3",
"@docusaurus/plugin-pwa": "2.0.0-beta.3",
"@docusaurus/preset-classic": "2.0.0-beta.3",
"@docusaurus/remark-plugin-npm2yarn": "2.0.0-beta.3",
"@docusaurus/theme-live-codeblock": "2.0.0-beta.3",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"clsx": "^1.1.1",

View File

@ -8,21 +8,17 @@ import React from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Link from '@docusaurus/Link';
import Translate from '@docusaurus/Translate';
import {
useActivePlugin,
useActiveVersion,
useDocVersionSuggestions,
} from '@theme/hooks/useDocs';
import { useActivePlugin, useDocVersionSuggestions } from '@theme/hooks/useDocs';
import { useDocsPreferredVersion } from '@docusaurus/theme-common';
function UnreleasedVersionLabel({ siteTitle, versionLabel }) {
function UnreleasedVersionLabel({ siteTitle, versionMetadata }) {
return (
<Translate
id="theme.docs.versions.unreleasedVersionLabel"
description="The label used to tell the user that he's browsing an unreleased doc version"
values={{
siteTitle,
versionLabel: <strong>{versionLabel}</strong>,
versionLabel: <b>{versionMetadata.label}</b>,
latestVersionLink: (
<strong>
<Link to={"/"}>
@ -42,14 +38,14 @@ function UnreleasedVersionLabel({ siteTitle, versionLabel }) {
);
}
function UnmaintainedVersionLabel({ siteTitle, versionLabel }) {
function UnmaintainedVersionLabel({ siteTitle, versionMetadata }) {
return (
<Translate
id="theme.docs.versions.unmaintainedVersionLabel"
description="The label used to tell the user that he's browsing an unmaintained doc version"
values={{
siteTitle,
versionLabel: <strong>{versionLabel}</strong>,
versionLabel: <b>{versionMetadata.label}</b>,
}}>
{
'This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.'
@ -58,15 +54,26 @@ function UnmaintainedVersionLabel({ siteTitle, versionLabel }) {
);
}
const BannerLabelComponents = {
unreleased: UnreleasedVersionLabel,
unmaintained: UnmaintainedVersionLabel,
};
function BannerLabel(props) {
const BannerLabelComponent =
BannerLabelComponents[props.versionMetadata.banner];
return <BannerLabelComponent {...props} />;
}
function LatestVersionSuggestionLabel({ versionLabel, to, onClick }) {
return (
<Translate
id="theme.docs.versions.latestVersionSuggestionLabel"
description="The label userd to tell the user that he's browsing an unmaintained doc version"
description="The label used to tell the user to check the latest version"
values={{
versionLabel,
latestVersionLink: (
<strong>
<b>
<Link to={to} onClick={onClick}>
<Translate
id="theme.docs.versions.latestVersionLinkLabel"
@ -74,7 +81,7 @@ function LatestVersionSuggestionLabel({ versionLabel, to, onClick }) {
latest version
</Translate>
</Link>
</strong>
</b>
),
}}>
{
@ -84,26 +91,22 @@ function LatestVersionSuggestionLabel({ versionLabel, to, onClick }) {
);
}
const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId);
function DocVersionSuggestions() {
function DocVersionBannerEnabled({ versionMetadata }) {
const {
siteConfig: { title: siteTitle },
} = useDocusaurusContext();
const { pluginId } = useActivePlugin({
failfast: true,
});
const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId);
const { savePreferredVersionName } = useDocsPreferredVersion(pluginId);
const activeVersion = useActiveVersion(pluginId);
const {
latestDocSuggestion,
latestVersionSuggestion,
} = useDocVersionSuggestions(pluginId); // No suggestion to be made
if (!latestVersionSuggestion) {
return <></>;
} // try to link to same doc in latest version (not always possible)
} = useDocVersionSuggestions(pluginId); // try to link to same doc in latest version (not always possible)
// fallback to main doc of latest version
const latestVersionSuggestedDoc =
@ -111,21 +114,25 @@ function DocVersionSuggestions() {
return (
<div className="alert alert--warning margin-bottom--md" role="alert">
<div>
{activeVersion.name === 'current' ? (
<UnreleasedVersionLabel
siteTitle={siteTitle}
versionLabel={activeVersion.label}
/>
) : (
<UnmaintainedVersionLabel
siteTitle={siteTitle}
versionLabel={activeVersion.label}
/>
)}
<BannerLabel siteTitle={siteTitle} versionMetadata={versionMetadata} />
</div>
{/* <div className="margin-top--md">
<LatestVersionSuggestionLabel
versionLabel={latestVersionSuggestion.label}
to={latestVersionSuggestedDoc.path}
onClick={() => savePreferredVersionName(latestVersionSuggestion.name)}
/>
</div> */}
</div>
);
}
export default DocVersionSuggestions;
function DocVersionBanner({ versionMetadata }) {
if (versionMetadata.banner === 'none') {
return <></>;
} else {
return <DocVersionBannerEnabled versionMetadata={versionMetadata} />;
}
}
export default DocVersionBanner;

1439
yarn.lock

File diff suppressed because it is too large Load Diff