diff --git a/app/components/Image/index.tsx b/app/components/Image/index.tsx
index 38c76ea61..66c92adb4 100644
--- a/app/components/Image/index.tsx
+++ b/app/components/Image/index.tsx
@@ -14,6 +14,7 @@ type ImageProps = {
isZoomable?: boolean;
/** Style to apply to img tag */
imgStyle?: React.ComponentPropsWithoutRef<'img'>['style'];
+ zoomStyle?: React.ComponentPropsWithoutRef<'img'>['style'];
};
const Image = ({
@@ -30,6 +31,7 @@ const Image = ({
showCaption = false,
isZoomable = true,
imgStyle = {},
+ zoomStyle = {},
}: ImageProps): JSX.Element => {
const [isZoomed, setIsZoomed] = useState(false);
@@ -85,24 +87,23 @@ const Image = ({
onClick={handleZoom}
type="button"
>
-
+
{showTitle && title && (
-
- {title}
-
+
+ {title}
+
)}

{showCaption && caption && (
-
- {caption}
-
+
+ {caption}
+
)}
diff --git a/app/views/ReportView/components/CopyNumber/index.scss b/app/views/ReportView/components/CopyNumber/index.scss
index 68b36001a..b54079612 100644
--- a/app/views/ReportView/components/CopyNumber/index.scss
+++ b/app/views/ReportView/components/CopyNumber/index.scss
@@ -1,3 +1,5 @@
+$montage-padding: 8px;
+
.copy-number {
padding: 16px;
@@ -14,6 +16,13 @@
}
&__title {
- padding: 16px;
+ padding: $montage-padding;
+ }
+
+ &__montage {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.25rem;
+ padding: $montage-padding;
}
}
diff --git a/app/views/ReportView/components/CopyNumber/index.tsx b/app/views/ReportView/components/CopyNumber/index.tsx
index 96e0baf84..29f244f12 100644
--- a/app/views/ReportView/components/CopyNumber/index.tsx
+++ b/app/views/ReportView/components/CopyNumber/index.tsx
@@ -45,6 +45,10 @@ const INFO_BUBBLES = {
lowExp: 'Copy number losses in known tumour supressor genes which are also lowly expressed.',
};
+const CHR_LEGEND = 'legend';
+const CHRS = Array.from({ length: 24 }, (_, i) => `chr${i + 1}`).join(',');
+const CHR_IMG_HEIGHT = 375 / 2;
+
type CopyNumberProps = WithLoadingInjectedProps;
const CopyNumber = ({
@@ -55,6 +59,7 @@ const CopyNumber = ({
const { canEdit } = useReport();
const theme = useTheme();
const [images, setImages] = useState
([]);
+ const [legend, setLegend] = useState([]);
const [circos, setCircos] = useState();
const [cnvs, setCnvs] = useState([]);
const [groupedCnvs, setGroupedCnvs] = useState({
@@ -82,7 +87,7 @@ const CopyNumber = ({
try {
const apiCalls = new ApiCallSet([
api.get(`/reports/${report.ident}/copy-variants`),
- api.get(`/reports/${report.ident}/image/retrieve/cnvLoh.circos,cnv.1,cnv.2,cnv.3,cnv.4,cnv.5,loh.1,loh.2,loh.3,loh.4,loh.5`),
+ api.get(`/reports/${report.ident}/image/retrieve/cnvLoh.circos,${CHR_LEGEND},${CHRS}`),
]);
const [cnvsResp, imagesResp] = await apiCalls.request() as [CopyNumberType[], ImageType[]];
@@ -109,11 +114,22 @@ const CopyNumber = ({
}
const circosIndex = imagesResp.findIndex((img) => img.key === 'cnvLoh.circos');
- const [circosResp] = imagesResp.splice(circosIndex, 1);
+ const splicedImages = imagesResp.splice(circosIndex, 1);
+
+ const legendIndex = imagesResp.findIndex((img) => img.key === 'legend');
+ const splicedLegend = imagesResp.splice(legendIndex, 1);
+
+ const [circosResp] = splicedImages;
+ const [legendResp] = splicedLegend;
setCnvs(cnvsResp);
setCircos(circosResp);
- setImages(imagesResp);
+ setImages(imagesResp.sort(({ key: a }, { key: b }) => {
+ const na = Number(a.replace(/\D/g, ''));
+ const nb = Number(b.replace(/\D/g, ''));
+ return na - nb;
+ }));
+ setLegend(legendResp);
} catch (err) {
snackbar.error(`Network error: ${err}`);
} finally {
@@ -204,6 +220,32 @@ const CopyNumber = ({
const handleVisibleColsChange = (change) => setVisibleCols(change);
+ const imagesSection = useMemo(() => {
+ if (images.length) {
+ return (
+
+
+ {
+ images.map((img) => (
+
+ ))
+ }
+
+ );
+ }
+ return No Copy Number & LOH Plots Available;
+ }, [images, legend]);
+
return (
Copy Number Analyses
@@ -248,23 +290,8 @@ const CopyNumber = ({
))}
>
)}
-
Copy Number & LOH
- {images.length ? (
-
- {[...Array(5).keys()].map((index) => (
-
- img.key === `cnv.${index + 1}`)}
- />
- img.key === `loh.${index + 1}`)}
- />
-
- ))}
-
- ) : (
-
No Copy Number & LOH Plots Available
- )}
+
Copy Number & LOH
+ {imagesSection}
>
)}