fix: max call stack exceeded for dicom tag browser (#4855)

This commit is contained in:
Pedro H. Köhler 2025-03-17 12:03:08 -03:00 committed by GitHub
parent 10976c2a48
commit 841320adfb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -18,7 +18,7 @@ export type Row = {
depth: number; depth: number;
parents?: string[]; parents?: string[];
children?: string[]; children?: string[];
areChildrenVisible?: true; areChildrenVisible?: boolean;
}; };
let rowCounter = 0; let rowCounter = 0;
@ -91,7 +91,7 @@ const DicomTagBrowser = ({
setShouldShowInstanceList(isImageStack && activeDisplaySet.images.length > 1); setShouldShowInstanceList(isImageStack && activeDisplaySet.images.length > 1);
const tags = getSortedTags(metadata); const tags = getSortedTags(metadata);
const rows = getFormattedRowsFromTags({ tags, metadata, depth: 0 }); const rows = getFormattedRowsFromTags({ tags, metadata });
return rows; return rows;
}, [getMetadata, activeDisplaySet]); }, [getMetadata, activeDisplaySet]);
@ -186,21 +186,27 @@ const DicomTagBrowser = ({
); );
}; };
function getFormattedRowsFromTags({ tags, metadata, depth, parents }) { function getFormattedRowsFromTags({ tags, metadata }) {
const rows: Row[] = []; const rows: Row[] = [];
const stack = [{ tags, depth: 0, parents: null, index: 0, children: [] }];
const parentChildMap = new Map();
tags.forEach(tagInfo => { while (stack.length > 0) {
const current = stack.pop();
const { tags, depth, parents, index, children } = current;
for (let i = index; i < tags.length; i++) {
const tagInfo = tags[i];
const uid = generateRowId(); const uid = generateRowId();
if (parents?.length > 0) {
parents.forEach(parent => {
parentChildMap.get(parent).push(uid);
});
}
if (tagInfo.vr === 'SQ') { if (tagInfo.vr === 'SQ') {
const children = tagInfo.values.flatMap(value => const row = {
getFormattedRowsFromTags({
tags: value,
metadata,
depth: depth + 1,
parents: parents ? [...parents, uid] : [uid],
})
);
const row: Row = {
uid, uid,
tag: tagInfo.tag, tag: tagInfo.tag,
valueRepresentation: tagInfo.vr, valueRepresentation: tagInfo.vr,
@ -209,10 +215,25 @@ function getFormattedRowsFromTags({ tags, metadata, depth, parents }) {
depth, depth,
isVisible: true, isVisible: true,
areChildrenVisible: true, areChildrenVisible: true,
children: children.map(child => child.uid), children: [],
parents, parents,
}; };
rows.push(row, ...children); rows.push(row);
parentChildMap.set(uid, row.children);
const newParents = parents ? [...parents, uid] : [uid];
if (tagInfo.values.length > 0) {
stack.push({ tags, depth, parents, index: i + 1, children });
stack.push({
tags: tagInfo.values.flat(),
depth: depth + 1,
parents: newParents,
index: 0,
children: [],
});
break;
}
} else { } else {
if (tagInfo.vr === 'xs') { if (tagInfo.vr === 'xs') {
try { try {
@ -223,7 +244,7 @@ function getFormattedRowsFromTags({ tags, metadata, depth, parents }) {
console.warn(`Failed to parse value representation for tag '${tagInfo.keyword}'`); console.warn(`Failed to parse value representation for tag '${tagInfo.keyword}'`);
} }
} }
const row: Row = { const row = {
uid, uid,
tag: tagInfo.tag, tag: tagInfo.tag,
valueRepresentation: tagInfo.vr, valueRepresentation: tagInfo.vr,
@ -235,8 +256,8 @@ function getFormattedRowsFromTags({ tags, metadata, depth, parents }) {
}; };
rows.push(row); rows.push(row);
} }
}); }
}
return rows; return rows;
} }