ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

OHIF Study Browser 深度定制指南:StudyMode、缩略图细节与排序函数的全套配置方案

OHIF Study Browser 深度定制指南:StudyMode、缩略图细节与排序函数的全套配置方案 OHIF Study Browser 深度定制指南StudyMode、缩略图细节与排序函数的全套配置方案【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/Viewers导读Study Browser研究浏览器是 OHIF 查看器中用于浏览与管理影像研究Study的核心面板组件用户在加载检查后通过它查看系列Series缩略图、切换列表/缩略图视图、对系列进行排序并通过右键菜单执行打开 DICOM 标签浏览器、删除系列等操作。本文以官方文档 StudyBrowser.md 为骨架结合sampleCustomizations.tsx中的studyBrowserCustomizations完整清单与 ui-next 源码实现系统讲解 Study Browser 的 10 个可定制项研究模式、视图预设、排序函数、缩略图右键菜单、缩略图详情行、命名取值源、命名测试、研究级右键菜单、双击回调与实例排序标准。读者学完后可独立完成从仅看当前研究到自定义缩略图详情行并配 JSONC 数据文件的完整定制。一、Study Browser 是什么官方文档对 Study Browser 的定义非常简洁The Study Browser is a component that allows users to browse and manage studies.——它是一个让用户浏览并管理研究的组件。从源码看该组件位于 platform/ui-next/src/components/StudyBrowser/StudyBrowser.tsx其职责包括以 Tab标签页形式组织研究列表tabs与activeTabName每个 Tab 下渲染多个StudyItem提供视图切换列表list/ 缩略图thumbnails由viewPresets中selected: true的项决定当前视图StudyBrowser.tsx顶部的设置栏渲染StudyBrowserViewOptionsTab 切换与StudyBrowserSort排序下拉与升降序切换每个系列项支持单击展开、双击缩略图、缩略图右键菜单ThumbnailMenuItems与研究级右键菜单StudyMenuItems缩略图下方有详情行detail line用于显示系列号、实例数等信息。在 OHIF 中Study Browser 通常作为模式Mode工作区的左侧/右侧面板出现是工作流导航的关键入口。由于它承载了大量交互OHIF 通过customizationService暴露了 10 个studyBrowser.*定制点全部定义在 platform/docs/docs/platform/services/customization-service/sampleCustomizations.tsx 的studyBrowserCustomizations数组中。二、定制机制基础customizationService 与 immutability-helper 命令所有 Study Browser 定制都通过window.config中的customizationService数组下发核心语法基于 immutability-helper 的命令式更新。官方文档 customizationService.md 定义了六种命令写配置前必须先掌握命令作用典型场景$set整体替换某个值替换整个数组/对象$push向数组末尾追加元素追加一个排序函数或详情行项$unshift向数组头部插入元素让自定义项排在最前$splice在指定下标插入/替换/删除精确调整数组顺序$merge合并对象的部分字段往命名源注册表里追加一个 key$apply用函数动态计算新值基于现有数组做复杂变换$filter递归查找匹配项并施加$merge/$set修改某个已有子项配置统一放在 HTML 中的window.config里结构为window.config { // 其余 window config customizationService: [ { studyBrowser.xxx: { $set: /* 或 $push / $merge / $splice / $apply / $filter */, }, }, ], };$push会保留默认项并追加$set会整体替换——在需要保留默认行为时优先用$push/$merge在需要完全自定义时用$set。三、研究模式studyBrowser.studyMode定制点studyBrowser.studyMode默认值all该定制控制 Study Browser 显示哪些研究是显示全部研究含既往研究 prior studies还是只显示当前研究。取值含义all默认显示全部研究包括既往研究primary仅显示当前主研究recent显示最近的研究配置示例sampleCustomizations.tsxwindow.config { // rest of window config customizationService: [ { studyBrowser.studyMode: { $set: primary, // or recent }, }, ], };实际使用中primary模式常用于需要屏蔽既往研究、聚焦当前检查的工作流例如放疗或随访场景避免医生被多个历史研究干扰。四、视图预设studyBrowser.viewPresets定制点studyBrowser.viewPresets默认值[ { id: list, iconName: ListView, selected: false }, { id: thumbnails, iconName: ThumbnailView, selected: true }, ]该定制定义 Study Browser 可用的视图模式列表视图 / 缩略图视图。selected: true的项为默认视图。从 StudyBrowser.tsx 的源码可以看到视图选择的真实逻辑const viewPreset viewPresets ? viewPresets.filter(preset preset.selected)[0]?.id : thumbnails;即selected: true的预设的id会被当作当前视图传入每个StudyItem若viewPresets为空则回退到thumbnails。若想让列表视图成为默认视图配置如下sampleCustomizations.tsxwindow.config { // rest of window config customizationService: [ { studyBrowser.viewPresets: { $set: [ { id: list, iconName: ListView, selected: true, // Makes the list view the default selected option }, { id: thumbnails, iconName: ThumbnailView, selected: false, }, ], }, }, ], };五、排序函数studyBrowser.sortFunctions定制点studyBrowser.sortFunctions默认值两个排序项——按SeriesNumber系列号与按SeriesDate系列日期新日期在前[ { label: Series Number, sortFunction: (a, b) a?.SeriesNumber - b?.SeriesNumber, }, { label: Series Date, sortFunction: (a, b) { const dateA new Date(formatDate(a?.SeriesDate)); const dateB new Date(formatDate(b?.SeriesDate)); return dateB.getTime() - dateA.getTime(); }, }, ]工作方式Study Browser 顶部的StudyBrowserSort组件platform/ui-next/src/components/StudyBrowserSort/StudyBrowserSort.tsx通过customizationService.getCustomization(studyBrowser.sortFunctions)读取该数组将其渲染为一个下拉菜单显示label并提供升降序切换按钮。切换后调用displaySetService.sortDisplaySets(selectedSort.sortFunction, sortDirection)对显示集排序并订阅DISPLAY_SETS_CHANGED与DISPLAY_SET_SERIES_METADATA_INVALIDATED事件在数据变化时重排。追加自定义排序函数示例为 sampleCustomizations.tsx 中示意性写法实际请替换为真实比较逻辑window.config { // rest of window config customizationService: [ { studyBrowser.sortFunctions: { $push: [ { label: Series Stuff, sortFunction: (a, b) Stuff, // 替换为 (a, b) a?.x - b?.x 之类 }, ], }, }, ], };每个排序项对象至少包含label下拉菜单显示名与sortFunction接收两个显示集并返回数值。排序函数中可使用formatDate等 formatter 对 DICOM 日期字符串做格式化后再比较与默认的 Series Date 实现一致。六、缩略图右键菜单studyBrowser.thumbnailMenuItems定制点studyBrowser.thumbnailMenuItems默认值仅一个Tag Browser打开 DICOM 标签浏览器[ { id: tagBrowser, label: Tag Browser, iconName: DicomTagBrowser, commands: openDICOMTagViewer, }, ]每个菜单项包含id唯一标识label菜单显示文本iconName图标名对应 ui-next Icons 集合中的图标commands点击后执行的命令可以是命令名字符串、命令对象或函数。示例用$set整体替换为标签浏览器 删除 收藏三个菜单项sampleCustomizations.tsxwindow.config { // rest of window config customizationService: [ { studyBrowser.thumbnailMenuItems: { $set: [ { id: tagBrowser, label: Tag Browser, iconName: DicomTagBrowser, commands: openDICOMTagViewer, }, { id: deleteThumbnail, label: Delete, iconName: Delete, commands: deleteThumbnail, }, { id: markAsFavorite, label: Mark as Favorite, commands: markAsFavorite, }, ], }, }, ], };菜单项作为ThumbnailMenuItems属性传入 StudyBrowser.tsx最终被StudyItem→Thumbnail渲染为右键弹出菜单。七、缩略图详情行studyBrowser.thumbnailDetails定制点studyBrowser.thumbnailDetails默认值[ { id: SeriesNumber, label: S:, source: seriesNumber }, { id: InstanceCount, source: numInstances, iconName: ({ displaySet }) displaySet?.countIcon || InfoSeries, }, ]详情行是缩略图上位于模态modality与系列描述下方的那一行文字默认显示系列号与实例数。其声明方式与 viewport overlay 项一致每个项可包含id唯一标识label值的前缀文本如S:title鼠标悬停提示tooltipiconName值前的图标可以是字符串或函数condition是否显示该行的条件可以是函数或命名测试value的来源三选一contentF一个函数返回要显示的值source引用studyBrowser.thumbnailDetailSources中的命名取值源attribute直接取实例instance上的 DICOM 属性名。无值的项会被自动省略若所有项都被省略或整条定制解析为空数组缩略图会回退到默认详情行而不是显示空行——这一行为在 Thumbnail.tsx 中有明确注释??而非||保证了未解析与解析为空两种状态的区分。测试 Thumbnail.test.ts 也验证了自定义详情行渲染S:5、3、19-Aug-2026 14:30以及空 details 渲染空行两种情形。用$push追加两个详情项示例来自 sampleCustomizations.tsxwindow.config { // rest of window config customizationService: [ { studyBrowser.thumbnailDetails: { $push: [ { id: InstanceDateTime, // Named source and test, so this can also be written in a // ?customization JSONC file, which is data and never executed. source: instanceDateTime, condition: isDerivedDisplaySet, title: Created, }, { // Or supply the functions directly. id: BodyPart, label: Part:, attribute: BodyPartExamined, condition: ({ displaySet }) displaySet.Modality CT, }, ], }, }, ], };注意第二个项condition是函数仅 CT 显示第一个项source/condition都是名字——这种全数据化写法可以直接放进 JSONC 配置文件而不会被执行。7.1 命名取值源studyBrowser.thumbnailDetailSources定制点studyBrowser.thumbnailDetailSources默认值sampleCustomizations.tsx{ seriesNumber: ({ displaySet }) displaySet?.SeriesNumber, numInstances: ({ displaySet }) (displaySet?.numImageFrames ?? displaySet?.instances?.length) || 1, seriesDate: ({ displaySet, formatters }) formatters.formatDate(displaySet?.SeriesDate), instanceDateTime: (the creation date/time, see getLatestInstanceDateTime), }每个命名源接收{ displaySet, instance, formatters }并返回详情行的值。追加新源时必须使用$merge——因为$set会整体替换注册表导致默认项引用的seriesNumber、numInstances等源全部消失window.config { // rest of window config customizationService: [ { studyBrowser.thumbnailDetailSources: { $merge: { seriesDescription: ({ displaySet }) displaySet.SeriesDescription, }, }, }, ], };7.2 命名测试studyBrowser.thumbnailDetailTests定制点studyBrowser.thumbnailDetailTests默认值{ isDerivedDisplaySet: ({ displaySet }) !!displaySet?.isDerivedDisplaySet, }命名测试让详情项的condition也能以字符串形式写在 JSONC 数据文件中与命名源一样接收{ displaySet, instance, formatters }并返回布尔值window.config { // rest of window config customizationService: [ { studyBrowser.thumbnailDetailTests: { $merge: { isMultiframe: ({ displaySet }) displaySet.isMultiFrame, }, }, }, ], };7.3 实战用 JSONC 文件为派生系列加创建时间仓库中提供了一个可直接通过 URL 加载的完整范例 platform/app/public/customizations/studyBrowser/derivedDateTime.jsonc。它解决了一个真实痛点SR、SEG、RTSTRUCT、PMAP 等派生系列在列表中按实例创建时间倒序排列但默认详情行只显示系列号和实例数同一天保存的多份报告看不出区别。通过?customizationstudyBrowser/derivedDateTime加载后每个派生系列缩略图会增加一行Created创建时间{ global: { studyBrowser.thumbnailDetails: { $push: [ { id: InstanceDateTime, source: instanceDateTime, condition: isDerivedDisplaySet, title: Created } ] } } }关键点source与condition都是名字而非函数整个文件是纯数据、永不执行可安全用于运行时加载的定制配置$push保留默认的系列号与实例数两项。加载方式为在应用 URL 后追加?customizationstudyBrowser/derivedDateTime。八、研究级右键菜单studyBrowser.studyMenuItems定制点studyBrowser.studyMenuItems默认值[]空与缩略图菜单不同这是研究Study级别的右键菜单作用于整个研究条目。默认为空可用$set定义window.config { // rest of window config customizationService: [ { studyBrowser.studyMenuItems: { $set: [ { id: downloadStudy, label: Download Study, iconName: Download, commands: () { console.debug(downloadStudy); }, }, ], }, }, ], };菜单项结构与缩略图菜单一致id/label/iconName/commandscommands也可替换为实际命令名或commandsManager.run可接受的命令描述对象。九、双击回调studyBrowser.thumbnailDoubleClickCallback定制点studyBrowser.thumbnailDoubleClickCallback默认值内置的将显示集放入视口回调完整实现见 sampleCustomizations.tsx。其核心逻辑为callback: ({ activeViewportId, servicesManager, isHangingProtocolLayout }) async displaySetInstanceUID { const { hangingProtocolService, viewportGridService, uiNotificationService } servicesManager.services; let updatedViewports []; const viewportId activeViewportId; try { updatedViewports hangingProtocolService.getViewportsRequireUpdate( viewportId, displaySetInstanceUID, isHangingProtocolLayout ); } catch (error) { console.warn(error); uiNotificationService.show({ title: Thumbnail Double Click, message: The selected display sets could not be added to the viewport., type: error, duration: 3000, }); } commandsManager.run({ commandName: setDisplaySetsForViewports, commandOptions: { viewportsToUpdate: updatedViewports }, }); },流程为先通过hangingProtocolService.getViewportsRequireUpdate计算需要更新的视口集合失败时用uiNotificationService弹出错误通知最后运行setDisplaySetsForViewports命令把显示集放入对应视口。自定义示例在回调中先做黑名单模态过滤再走默认流程sampleCustomizations.tsxwindow.config { // rest of window config customizationService: [ { studyBrowser.thumbnailDoubleClickCallback: { callback: ({ activeViewportId, commandsManager, servicesManager, isHangingProtocolLayout }) async displaySetInstanceUID { const { hangingProtocolService, viewportGridService, uiNotificationService } servicesManager.services; let updatedViewports []; const viewportId activeViewportId; // Changing original function here: if (isBlacklistedModality(displaySetInstanceUID)) { return; } try { updatedViewports hangingProtocolService.getViewportsRequireUpdate( viewportId, displaySetInstanceUID, isHangingProtocolLayout ); } catch (error) { console.warn(error); uiNotificationService.show({ title: Thumbnail Double Click, message: The selected display sets could not be added to the viewport., type: error, duration: 3000, }); } commandsManager.run({ commandName: setDisplaySetsForViewports, commandOptions: { viewportsToUpdate: updatedViewports }, }); }, }, }, ], };注意自定义回调的入参中显式解构了commandsManager可用于在回调内直接运行命令。十、实例排序标准instanceSortingCriteria定制点instanceSortingCriteria默认值{ sortFunctions: {}, defaultSortFunctionName: , }该定制定义图像实例instance层面的排序标准与studyBrowser.sortFunctions显示集层面不同它作用于单个实例的播放/浏览顺序window.config { // rest of window config customizationService: [ { instanceSortingCriteria: { $set: { sortFunctions: { sort: (a, b) {}, }, defaultSortFunctionName: sort, }, }, }, ], };结构为sortFunctions是一个命名函数映射defaultSortFunctionName指定默认使用的那个排序函数名。十一、十个定制点速查表定制点 ID默认值作用推荐操作studyBrowser.studyModeall显示全部/仅当前/最近研究$setstudyBrowser.viewPresetslist thumbnails默认 thumbnails定义视图预设与默认视图$setstudyBrowser.sortFunctions按系列号、按系列日期显示集排序选项$push追加studyBrowser.thumbnailMenuItemsTag Browser缩略图右键菜单$set替换studyBrowser.thumbnailDetails系列号 S: 实例数缩略图详情行$push追加studyBrowser.thumbnailDetailSourcesseriesNumber / numInstances / seriesDate / instanceDateTime详情行命名取值源$merge追加studyBrowser.thumbnailDetailTestsisDerivedDisplaySet详情行命名条件测试$merge追加studyBrowser.studyMenuItems[]研究级右键菜单$setstudyBrowser.thumbnailDoubleClickCallback默认放图回调双击缩略图行为$set整体替换instanceSortingCriteria空实例层排序标准$set十二、实践要点与常见陷阱$push与$set的选择对sortFunctions、thumbnailDetails这类默认项要保留的数组用$push或$unshift追加对viewPresets、thumbnailMenuItems、studyMenuItems这类整体重定义的数组用$set。thumbnailDetailSources/thumbnailDetailTests千万别用$set它们是对象注册表$set会清掉默认项引用的所有源/测试导致默认详情行解析失败。函数与数据分离只要详情项只用命名source和命名condition整条定制就能写成 derivedDateTime.jsonc 这种纯数据 JSONC 文件通过?customization在运行时加载且不会被执行一旦混入contentF/condition函数就必须回到window.config的 JS 环境。未注册的源/测试会静默跳过详情项引用了一个未注册的命名源或测试时该项会被略过并产生警告若最终一个项都不剩缩略图会保留默认详情行而非显示空行。默认值语义所有默认值均可在 sampleCustomizations.tsx 的studyBrowserCustomizations中直接查看它是权威参考StudyBrowser.tsx、StudyBrowserSort.tsx、Thumbnail.tsx则分别印证了视图预设解析、排序函数调用链与详情行渲染逻辑。十三、参考资料官方定制文档StudyBrowser.md、customizationService.md全部定制项定义与配置示例sampleCustomizations.tsx组件实现StudyBrowser.tsx、StudyBrowserSort.tsx、Thumbnail.tsx、Thumbnail.test.ts运行时 JSONC 定制范例derivedDateTime.jsonc历史版本3.11对照version-3.11 StudyBrowser.md【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/Viewers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表