@gen-epix/ui 1.15.0 → 1.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/environment.d.ts +54 -0
- package/dist/index.d.ts +16078 -0
- package/dist/index.js.map +1 -0
- package/package.json +13 -16
- package/src/@types/environment.d.ts +0 -54
- package/src/api/api.ts +0 -43576
- package/src/api/base.ts +0 -111
- package/src/api/common.ts +0 -168
- package/src/api/configuration.ts +0 -118
- package/src/api/index.ts +0 -20
- package/src/assets/icons/CollectionIcon.svg +0 -1
- package/src/assets/icons/DnaIcon.svg +0 -1
- package/src/assets/icons/VirusIcon.svg +0 -1
- package/src/assets/logo/logo-rijksoverheid.svg +0 -42
- package/src/assets/logo/logo-rivm.svg +0 -6
- package/src/classes/Subject/Subject.ts +0 -26
- package/src/classes/Subject/index.ts +0 -1
- package/src/classes/TableEventBus/TableEventBus.ts +0 -14
- package/src/classes/TableEventBus/index.ts +0 -1
- package/src/classes/abstracts/EventBusAbstract/EventBusAbstract.ts +0 -37
- package/src/classes/abstracts/EventBusAbstract/index.ts +0 -1
- package/src/classes/abstracts/FilterAbstract/FilterAbstract.ts +0 -54
- package/src/classes/abstracts/FilterAbstract/index.ts +0 -1
- package/src/classes/abstracts/SubscribableAbstract/SubscribableAbstract.ts +0 -20
- package/src/classes/abstracts/SubscribableAbstract/index.ts +0 -1
- package/src/classes/errors/UploadError.ts +0 -11
- package/src/classes/errors/index.ts +0 -1
- package/src/classes/filters/BooleanFilter.ts +0 -31
- package/src/classes/filters/DateFilter.ts +0 -133
- package/src/classes/filters/GeoFilter.ts +0 -60
- package/src/classes/filters/MultiSelectFilter.ts +0 -70
- package/src/classes/filters/NumberRangeFilter.ts +0 -82
- package/src/classes/filters/SelectionFilter.ts +0 -25
- package/src/classes/filters/TextFilter.ts +0 -36
- package/src/classes/filters/TreeFilter.ts +0 -22
- package/src/classes/managers/AuthenticationManager/AuthenticationManager.ts +0 -94
- package/src/classes/managers/AuthenticationManager/index.ts +0 -1
- package/src/classes/managers/AuthorizationManager/AuthorizationManager.ts +0 -70
- package/src/classes/managers/AuthorizationManager/index.ts +0 -1
- package/src/classes/managers/BackendVersionManager/BackendVersionManager.ts +0 -23
- package/src/classes/managers/BackendVersionManager/index.ts +0 -1
- package/src/classes/managers/BreadcrumbManager/BreadcrumbManager.ts +0 -30
- package/src/classes/managers/BreadcrumbManager/index.ts +0 -1
- package/src/classes/managers/ConfigManager/ConfigManager.ts +0 -31
- package/src/classes/managers/ConfigManager/index.ts +0 -1
- package/src/classes/managers/DevicePixelRatioManager/DevicePixelRatioManager.ts +0 -27
- package/src/classes/managers/DevicePixelRatioManager/index.ts +0 -1
- package/src/classes/managers/EmotionCacheManager/EmotionCacheManager.ts +0 -27
- package/src/classes/managers/EmotionCacheManager/index.ts +0 -1
- package/src/classes/managers/EpiDataManager/EpiDataManager.ts +0 -196
- package/src/classes/managers/EpiDataManager/index.ts +0 -1
- package/src/classes/managers/EpiEventBusManager/EpiEventBusManager.ts +0 -61
- package/src/classes/managers/EpiEventBusManager/index.ts +0 -1
- package/src/classes/managers/EpiHighlightingManager/EpiHighlightingManager.ts +0 -32
- package/src/classes/managers/EpiHighlightingManager/index.ts +0 -1
- package/src/classes/managers/EpiLineListCaseSetMembersManager/EpiListsCaseSetMembersManager.ts +0 -118
- package/src/classes/managers/EpiLineListCaseSetMembersManager/index.ts +0 -1
- package/src/classes/managers/FeatureFlagsManager/FeatureFlagsManager.ts +0 -30
- package/src/classes/managers/FeatureFlagsManager/index.ts +0 -1
- package/src/classes/managers/I18nManager/I18nManager.ts +0 -105
- package/src/classes/managers/I18nManager/index.ts +0 -1
- package/src/classes/managers/InactivityManager/InactivityManager.ts +0 -119
- package/src/classes/managers/InactivityManager/index.ts +0 -1
- package/src/classes/managers/KeyboardShortcutManager/KeyboardShortcutManager.ts +0 -78
- package/src/classes/managers/KeyboardShortcutManager/index.ts +0 -1
- package/src/classes/managers/LogManager/LogManager.ts +0 -151
- package/src/classes/managers/LogManager/index.ts +0 -1
- package/src/classes/managers/NavigationHistoryManager/NavigationHistoryManager.ts +0 -16
- package/src/classes/managers/NavigationHistoryManager/index.ts +0 -1
- package/src/classes/managers/NotificationManager/NotificationManager.ts +0 -104
- package/src/classes/managers/NotificationManager/index.ts +0 -1
- package/src/classes/managers/PageEventBusManager/PageEventBusManager.ts +0 -116
- package/src/classes/managers/PageEventBusManager/index.ts +0 -1
- package/src/classes/managers/QueryClientManager/QueryClientManager.ts +0 -51
- package/src/classes/managers/QueryClientManager/index.ts +0 -1
- package/src/classes/managers/RouterManager/RouterManager.ts +0 -25
- package/src/classes/managers/RouterManager/index.ts +0 -1
- package/src/classes/managers/UserSettingsManager/UserSettingsManager.ts +0 -16
- package/src/classes/managers/UserSettingsManager/index.ts +0 -1
- package/src/classes/managers/WindowManager/WindowManager.test.ts +0 -23
- package/src/classes/managers/WindowManager/WindowManager.ts +0 -26
- package/src/classes/managers/WindowManager/index.ts +0 -1
- package/src/components/app/App/App.tsx +0 -58
- package/src/components/app/App/index.ts +0 -1
- package/src/components/app/ApplicationBootstrap/ApplicationBootstrap.tsx +0 -223
- package/src/components/app/ApplicationBootstrap/index.ts +0 -1
- package/src/components/app/RouterRoot/RouterRoot.tsx +0 -187
- package/src/components/app/RouterRoot/index.ts +0 -1
- package/src/components/epi/EpiAddCasesToEventDialog/EpiAddCasesToEventDialog.tsx +0 -347
- package/src/components/epi/EpiAddCasesToEventDialog/EpiAddCasesToEventDialogSuccessNotificationMessage.tsx +0 -38
- package/src/components/epi/EpiAddCasesToEventDialog/index.ts +0 -1
- package/src/components/epi/EpiBulkEditCaseDialog/EpiBulkEditCaseDialog.tsx +0 -61
- package/src/components/epi/EpiBulkEditCaseDialog/index.ts +0 -1
- package/src/components/epi/EpiCaseInfoDialog/EpiCaseCaseSetInfo.tsx +0 -137
- package/src/components/epi/EpiCaseInfoDialog/EpiCaseContent.tsx +0 -127
- package/src/components/epi/EpiCaseInfoDialog/EpiCaseForm.tsx +0 -111
- package/src/components/epi/EpiCaseInfoDialog/EpiCaseInfoDialog.tsx +0 -377
- package/src/components/epi/EpiCaseInfoDialog/EpiCaseSharingForm.tsx +0 -140
- package/src/components/epi/EpiCaseInfoDialog/EpiCaseSharingInfo.tsx +0 -23
- package/src/components/epi/EpiCaseInfoDialog/EpiReadOnlyCaseContent.tsx +0 -89
- package/src/components/epi/EpiCaseInfoDialog/index.ts +0 -1
- package/src/components/epi/EpiCaseSetInfoDialog/EpiCaseSetContent.tsx +0 -108
- package/src/components/epi/EpiCaseSetInfoDialog/EpiCaseSetDescription.tsx +0 -34
- package/src/components/epi/EpiCaseSetInfoDialog/EpiCaseSetForm.tsx +0 -151
- package/src/components/epi/EpiCaseSetInfoDialog/EpiCaseSetInfoDialog.tsx +0 -389
- package/src/components/epi/EpiCaseSetInfoDialog/EpiCaseSetSharingForm.tsx +0 -155
- package/src/components/epi/EpiCaseSetInfoDialog/EpiCaseSetSharingInfo.tsx +0 -23
- package/src/components/epi/EpiCaseSetInfoDialog/index.ts +0 -1
- package/src/components/epi/EpiCaseSummary/EpiCaseSummary.tsx +0 -141
- package/src/components/epi/EpiCaseSummary/index.ts +0 -1
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoAccessRights.tsx +0 -91
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoColAccessRights.tsx +0 -118
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoData.tsx +0 -38
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoDialog.tsx +0 -39
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoDialogContent.tsx +0 -169
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoDialogWithLoader.tsx +0 -42
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoRegions.tsx +0 -87
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoTrees.tsx +0 -73
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoValues.tsx +0 -61
- package/src/components/epi/EpiCaseTypeInfoDialog/EpiCaseTypeInfoVariableDetails.tsx +0 -151
- package/src/components/epi/EpiCaseTypeInfoDialog/index.ts +0 -10
- package/src/components/epi/EpiCasesAlreadyInCaseSetWarning/EpiCasesAlreadyInCaseSetWarning.tsx +0 -190
- package/src/components/epi/EpiCasesAlreadyInCaseSetWarning/EpiCasesAlreadyInCaseSetWarningCaseSetLink.tsx +0 -62
- package/src/components/epi/EpiCasesAlreadyInCaseSetWarning/index.ts +0 -1
- package/src/components/epi/EpiCompletCaseTypeLoader/EpiCompletCaseTypeLoader.tsx +0 -87
- package/src/components/epi/EpiCompletCaseTypeLoader/index.ts +0 -1
- package/src/components/epi/EpiContactDetailsDialog/EpiContactDetailsDialog.tsx +0 -151
- package/src/components/epi/EpiContactDetailsDialog/index.ts +0 -1
- package/src/components/epi/EpiContextMenu/EpiContextMenu.tsx +0 -155
- package/src/components/epi/EpiContextMenu/index.ts +0 -1
- package/src/components/epi/EpiCreateEventDialog/EpiCreateEventDialog.tsx +0 -386
- package/src/components/epi/EpiCreateEventDialog/EpiCreateEventDialogSuccessNotificationMessage.tsx +0 -30
- package/src/components/epi/EpiCreateEventDialog/index.ts +0 -1
- package/src/components/epi/EpiCurve/EpiCurve.tsx +0 -525
- package/src/components/epi/EpiCurve/index.ts +0 -1
- package/src/components/epi/EpiCustomTabPanel/EpiCustomTabPanel.tsx +0 -27
- package/src/components/epi/EpiCustomTabPanel/index.ts +0 -1
- package/src/components/epi/EpiDashboard/EpiDashboard.tsx +0 -390
- package/src/components/epi/EpiDashboard/EpiDashboardDownloadSidebarItem.tsx +0 -154
- package/src/components/epi/EpiDashboard/EpiDashboardGeneralSettingsForm.tsx +0 -89
- package/src/components/epi/EpiDashboard/EpiDashboardLayoutRenderer.tsx +0 -248
- package/src/components/epi/EpiDashboard/EpiDashboardLayoutSettingsForm.tsx +0 -160
- package/src/components/epi/EpiDashboard/EpiDashboardSettingsSidebarItem.tsx +0 -93
- package/src/components/epi/EpiDashboard/EpiDashboardTreeSettingsForm.tsx +0 -90
- package/src/components/epi/EpiDashboard/index.ts +0 -1
- package/src/components/epi/EpiDashboardStoreLoader/EpiDashboardStoreLoader.tsx +0 -34
- package/src/components/epi/EpiDashboardStoreLoader/EpiDashboardStoreLoaderContent.tsx +0 -73
- package/src/components/epi/EpiDashboardStoreLoader/index.ts +0 -2
- package/src/components/epi/EpiDashboardStoreLoader/withEpiDashboardStore.tsx +0 -19
- package/src/components/epi/EpiDataCollectionAccessInfo/EpiDataCollectionAccessInfo.tsx +0 -88
- package/src/components/epi/EpiDataCollectionAccessInfo/index.ts +0 -1
- package/src/components/epi/EpiFindSimilarCasesDialog/EpiFindSimilarCasesDialog.tsx +0 -302
- package/src/components/epi/EpiFindSimilarCasesDialog/index.ts +0 -1
- package/src/components/epi/EpiLegendaItem/EpiLegendaItem.tsx +0 -106
- package/src/components/epi/EpiLegendaItem/index.ts +0 -1
- package/src/components/epi/EpiLineList/EpiLineList.tsx +0 -492
- package/src/components/epi/EpiLineList/EpiLineListPrimaryMenu.tsx +0 -189
- package/src/components/epi/EpiLineList/EpiLineListSecondaryMenu.tsx +0 -56
- package/src/components/epi/EpiLineList/EpiLineListTitle.tsx +0 -28
- package/src/components/epi/EpiLineList/index.ts +0 -1
- package/src/components/epi/EpiLineList/useEpiLineListEmitDownloadOptions.tsx +0 -102
- package/src/components/epi/EpiMap/EpiMap.tsx +0 -547
- package/src/components/epi/EpiMap/index.ts +0 -1
- package/src/components/epi/EpiRemoveCasesFromEventDialog/EpiRemoveCasesFromEventDialog.tsx +0 -169
- package/src/components/epi/EpiRemoveCasesFromEventDialog/index.ts +0 -1
- package/src/components/epi/EpiRemoveFindSimilarCasesResultDialog/EpiRemoveFindSimilarCasesResultDialog.tsx +0 -216
- package/src/components/epi/EpiSequenceDownloadDialog/EpiSequenceDownloadDialog.tsx +0 -151
- package/src/components/epi/EpiSequenceDownloadDialog/index.ts +0 -1
- package/src/components/epi/EpiStratification/EpiStratification.tsx +0 -241
- package/src/components/epi/EpiStratification/index.ts +0 -1
- package/src/components/epi/EpiTree/EpiTree.tsx +0 -906
- package/src/components/epi/EpiTree/index.ts +0 -1
- package/src/components/epi/EpiTreeDescription/EpiTreeDescription.tsx +0 -71
- package/src/components/epi/EpiTreeDescription/index.ts +0 -1
- package/src/components/epi/EpiUpload/EpiUpload.tsx +0 -107
- package/src/components/epi/EpiUpload/EpiUploadCaseResultTable.tsx +0 -383
- package/src/components/epi/EpiUpload/EpiUploadCreateCases.tsx +0 -266
- package/src/components/epi/EpiUpload/EpiUploadMapColumns.tsx +0 -261
- package/src/components/epi/EpiUpload/EpiUploadMapSequences.tsx +0 -332
- package/src/components/epi/EpiUpload/EpiUploadNavigation.tsx +0 -52
- package/src/components/epi/EpiUpload/EpiUploadSelectFile.tsx +0 -285
- package/src/components/epi/EpiUpload/EpiUploadSelectSequenceFiles.tsx +0 -375
- package/src/components/epi/EpiUpload/EpiUploadValidate.tsx +0 -199
- package/src/components/epi/EpiUpload/EpiUploadValidateNavigation.tsx +0 -34
- package/src/components/epi/EpiUpload/index.ts +0 -1
- package/src/components/epi/EpiUserRightsDialog/EpiUserRightsDialog.tsx +0 -101
- package/src/components/epi/EpiUserRightsDialog/EpiUserRightsDialogCaseAccessPolicy.tsx +0 -160
- package/src/components/epi/EpiUserRightsDialog/index.ts +0 -1
- package/src/components/epi/EpiWarning/EpiWarning.tsx +0 -39
- package/src/components/epi/EpiWarning/index.ts +0 -1
- package/src/components/epi/EpiWidget/EpiWidget.tsx +0 -255
- package/src/components/epi/EpiWidget/index.ts +0 -1
- package/src/components/epi/EpiWidgetHeaderIconButton/EpiWidgetHeaderIconButton.tsx +0 -40
- package/src/components/epi/EpiWidgetHeaderIconButton/index.ts +0 -1
- package/src/components/epi/EpiWidgetMenu/EpiWidgetMenu.tsx +0 -56
- package/src/components/epi/EpiWidgetMenu/index.ts +0 -1
- package/src/components/epi/EpiWidgetUnavailable/EpiWidgetUnavailable.tsx +0 -51
- package/src/components/epi/EpiWidgetUnavailable/index.ts +0 -1
- package/src/components/filters/BooleanFilterField/BooleanFilterField.tsx +0 -26
- package/src/components/filters/BooleanFilterField/index.ts +0 -1
- package/src/components/filters/DateFilterField/DateFilterField.tsx +0 -23
- package/src/components/filters/DateFilterField/index.ts +0 -1
- package/src/components/filters/GeoFilterField/GeoFilterField.tsx +0 -32
- package/src/components/filters/GeoFilterField/index.ts +0 -1
- package/src/components/filters/MultiSelectFilterField/MultiSelectFilterField.tsx +0 -31
- package/src/components/filters/MultiSelectFilterField/index.ts +0 -1
- package/src/components/filters/NumberRangeFilterField/NumberRangeFilterField.tsx +0 -20
- package/src/components/filters/NumberRangeFilterField/index.ts +0 -1
- package/src/components/filters/TextFilterField/TextFilterField.tsx +0 -18
- package/src/components/filters/TextFilterField/index.ts +0 -1
- package/src/components/form/fields/Autocomplete/Autocomplete.tsx +0 -270
- package/src/components/form/fields/Autocomplete/index.ts +0 -1
- package/src/components/form/fields/CheckboxGroup/CheckboxGroup.tsx +0 -192
- package/src/components/form/fields/CheckboxGroup/index.ts +0 -1
- package/src/components/form/fields/DatePicker/DatePicker.tsx +0 -167
- package/src/components/form/fields/DatePicker/index.ts +0 -1
- package/src/components/form/fields/DateRangePicker/DateRangePicker.tsx +0 -359
- package/src/components/form/fields/DateRangePicker/index.ts +0 -1
- package/src/components/form/fields/NumberField/NumberField.tsx +0 -277
- package/src/components/form/fields/NumberField/index.ts +0 -1
- package/src/components/form/fields/NumberRangeInput/NumberRangeInput.tsx +0 -297
- package/src/components/form/fields/NumberRangeInput/index.ts +0 -1
- package/src/components/form/fields/RadioGroup/RadioGroup.tsx +0 -130
- package/src/components/form/fields/RadioGroup/index.ts +0 -1
- package/src/components/form/fields/RichTextEditor/RichTextEditor.tsx +0 -321
- package/src/components/form/fields/RichTextEditor/RichTextEditorContent.tsx +0 -34
- package/src/components/form/fields/RichTextEditor/index.ts +0 -2
- package/src/components/form/fields/RichTextEditor/useRichTextEditorExtensions.ts +0 -174
- package/src/components/form/fields/Select/Select.tsx +0 -219
- package/src/components/form/fields/Select/index.ts +0 -1
- package/src/components/form/fields/Switch/Switch.tsx +0 -116
- package/src/components/form/fields/Switch/index.ts +0 -1
- package/src/components/form/fields/TextField/TextField.tsx +0 -170
- package/src/components/form/fields/TextField/index.ts +0 -1
- package/src/components/form/fields/ToggleButtonGroup/ToggleButtonGroup.tsx +0 -118
- package/src/components/form/fields/ToggleButtonGroup/index.ts +0 -1
- package/src/components/form/fields/TransferList/TransferList.tsx +0 -360
- package/src/components/form/fields/TransferList/index.ts +0 -1
- package/src/components/form/fields/UploadButton/UploadButton.tsx +0 -157
- package/src/components/form/helpers/FormFieldHelperText/FormFieldHelperText.tsx +0 -68
- package/src/components/form/helpers/FormFieldHelperText/index.ts +0 -1
- package/src/components/form/helpers/FormFieldLoadingIndicator/FormFieldLoadingIndicator.tsx +0 -22
- package/src/components/form/helpers/FormFieldLoadingIndicator/index.ts +0 -1
- package/src/components/form/helpers/GenericForm/GenericForm.tsx +0 -187
- package/src/components/form/helpers/GenericForm/index.ts +0 -1
- package/src/components/ui/ApplicationBar/ApplicationBar.tsx +0 -74
- package/src/components/ui/ApplicationBar/ApplicationBarActions.tsx +0 -124
- package/src/components/ui/ApplicationBar/ApplicationBarActionsFeedbackItem.tsx +0 -102
- package/src/components/ui/ApplicationBar/ApplicationBarActionsInfotem.tsx +0 -60
- package/src/components/ui/ApplicationBar/ApplicationBarActionsNotificationsItem.tsx +0 -82
- package/src/components/ui/ApplicationBar/ApplicationBarActionsOrganizationSwitcherItem.tsx +0 -58
- package/src/components/ui/ApplicationBar/ApplicationBarActionsOutagesItem.tsx +0 -75
- package/src/components/ui/ApplicationBar/ApplicationBarActionsUserItem.tsx +0 -60
- package/src/components/ui/ApplicationBar/ApplicationBarNavigationMenu.tsx +0 -159
- package/src/components/ui/ApplicationBar/InfoMenu.tsx +0 -120
- package/src/components/ui/ApplicationBar/UserMenu.tsx +0 -208
- package/src/components/ui/ApplicationBar/UserOrganizationAdminMenuItem.tsx +0 -69
- package/src/components/ui/ApplicationBar/UserOwnOrganizationMenuItem.tsx +0 -54
- package/src/components/ui/ApplicationBar/index.ts +0 -1
- package/src/components/ui/ApplicationFooter/ApplicationFooter.tsx +0 -121
- package/src/components/ui/ApplicationFooter/ApplicationFooterLink.tsx +0 -48
- package/src/components/ui/ApplicationFooter/ApplicationFooterLinkSection.tsx +0 -56
- package/src/components/ui/ApplicationFooter/index.ts +0 -1
- package/src/components/ui/AuthenticationWrapper/AuthenticationWrapper.tsx +0 -208
- package/src/components/ui/AuthenticationWrapper/index.ts +0 -1
- package/src/components/ui/AuthorizationWrapper/AuthorizationWrapper.tsx +0 -75
- package/src/components/ui/AuthorizationWrapper/index.ts +0 -1
- package/src/components/ui/Breadcrumbs/Breadcrumbs.tsx +0 -92
- package/src/components/ui/Breadcrumbs/index.ts +0 -1
- package/src/components/ui/Confirmation/Confirmation.tsx +0 -10
- package/src/components/ui/Confirmation/ConfirmationRender.tsx +0 -81
- package/src/components/ui/Confirmation/index.ts +0 -2
- package/src/components/ui/ConsentDialog/ConsentDialog.tsx +0 -57
- package/src/components/ui/ConsentDialog/index.ts +0 -1
- package/src/components/ui/CopyToClipboardButton/CopyToClipboardButton.tsx +0 -94
- package/src/components/ui/CopyToClipboardButton/index.ts +0 -1
- package/src/components/ui/Dialog/Dialog.tsx +0 -196
- package/src/components/ui/Dialog/index.ts +0 -1
- package/src/components/ui/FileSelector/FileSelector.tsx +0 -358
- package/src/components/ui/FileSelector/index.ts +0 -1
- package/src/components/ui/GenericErrorMessage/GenericErrorMessage.tsx +0 -168
- package/src/components/ui/GenericErrorMessage/index.ts +0 -1
- package/src/components/ui/HomePageTrends/HomePageTrendCard.tsx +0 -132
- package/src/components/ui/HomePageTrends/HomePageTrends.tsx +0 -312
- package/src/components/ui/HomePageTrends/index.ts +0 -1
- package/src/components/ui/LicensesDialog/LicensesDialog.tsx +0 -231
- package/src/components/ui/LicensesDialog/index.ts +0 -1
- package/src/components/ui/LinearProgressWithLabel/LinearProgressWithLabel.tsx +0 -31
- package/src/components/ui/LinearProgressWithLabel/index.ts +0 -1
- package/src/components/ui/LoadingIndicator/LoadingIndicator.tsx +0 -11
- package/src/components/ui/LoadingIndicator/index.ts +0 -1
- package/src/components/ui/MyPermissionsDialog/MyPermissionsDialog.tsx +0 -95
- package/src/components/ui/MyPermissionsDialog/index.ts +0 -1
- package/src/components/ui/NavLink/NavLink.tsx +0 -47
- package/src/components/ui/NavLink/index.ts +0 -1
- package/src/components/ui/NestedMenu/IconMenuItem.tsx +0 -64
- package/src/components/ui/NestedMenu/NestedDropdown.tsx +0 -133
- package/src/components/ui/NestedMenu/NestedMenuItem.tsx +0 -250
- package/src/components/ui/NestedMenu/index.ts +0 -4
- package/src/components/ui/NestedMenu/nestedMenuItemsFromObject.tsx +0 -98
- package/src/components/ui/Notifications/NotificationItem.tsx +0 -70
- package/src/components/ui/Notifications/NotificationsDrawer.tsx +0 -161
- package/src/components/ui/Notifications/NotificationsStack.tsx +0 -45
- package/src/components/ui/Notifications/index.ts +0 -2
- package/src/components/ui/OrganizationSwitcherDialog/OrganizationSwitcherDialog.tsx +0 -204
- package/src/components/ui/OrganizationSwitcherDialog/index.ts +0 -1
- package/src/components/ui/OutageList/OutageItem.tsx +0 -48
- package/src/components/ui/OutageList/OutageList.tsx +0 -54
- package/src/components/ui/OutageList/OutageSection.tsx +0 -39
- package/src/components/ui/OutageList/index.ts +0 -1
- package/src/components/ui/OutagesDialog/OutagesDialog.tsx +0 -71
- package/src/components/ui/OutagesDialog/index.ts +0 -1
- package/src/components/ui/PageContainer/PageContainer.tsx +0 -207
- package/src/components/ui/PageContainer/index.ts +0 -1
- package/src/components/ui/PanelSeparator/PanelResizeHandle.tsx +0 -67
- package/src/components/ui/PanelSeparator/index.ts +0 -1
- package/src/components/ui/ResponseHandler/ResponseHandler.tsx +0 -79
- package/src/components/ui/ResponseHandler/index.ts +0 -1
- package/src/components/ui/Sidebar/SidebarItem.tsx +0 -138
- package/src/components/ui/Sidebar/SidebarMenu.tsx +0 -33
- package/src/components/ui/Sidebar/SidebarMenuItem.tsx +0 -61
- package/src/components/ui/Sidebar/index.ts +0 -3
- package/src/components/ui/SortableList/SortableList.tsx +0 -172
- package/src/components/ui/SortableList/SortableListItem.tsx +0 -73
- package/src/components/ui/SortableList/SortableListItemDragHandle.tsx +0 -53
- package/src/components/ui/SortableList/SortableOverlay.tsx +0 -35
- package/src/components/ui/SortableList/context/SortableListItemContext.tsx +0 -17
- package/src/components/ui/SortableList/context/SortableListItemContextProvider.tsx +0 -19
- package/src/components/ui/SortableList/context/useSortableListItemContext.tsx +0 -5
- package/src/components/ui/Spinner/Spinner.tsx +0 -84
- package/src/components/ui/Spinner/index.ts +0 -1
- package/src/components/ui/Stepper/Stepper.tsx +0 -194
- package/src/components/ui/Stepper/index.ts +0 -2
- package/src/components/ui/Stepper/stepperModel.ts +0 -4
- package/src/components/ui/Table/Table.tsx +0 -812
- package/src/components/ui/Table/TableActionsCell.tsx +0 -81
- package/src/components/ui/Table/TableCaption.tsx +0 -33
- package/src/components/ui/Table/TableCell.tsx +0 -162
- package/src/components/ui/Table/TableCellAsyncContent.tsx +0 -28
- package/src/components/ui/Table/TableCheckboxCell.tsx +0 -65
- package/src/components/ui/Table/TableCheckboxHeader.tsx +0 -72
- package/src/components/ui/Table/TableColumnsEditorDialog.tsx +0 -241
- package/src/components/ui/Table/TableFilter.tsx +0 -31
- package/src/components/ui/Table/TableFiltersSidebarItem.tsx +0 -398
- package/src/components/ui/Table/TableHeader.tsx +0 -40
- package/src/components/ui/Table/TableHeaderCell.tsx +0 -434
- package/src/components/ui/Table/TableHeaderFilter.tsx +0 -104
- package/src/components/ui/Table/TableMenu.tsx +0 -26
- package/src/components/ui/Table/TableReadableIndexCell.tsx +0 -65
- package/src/components/ui/Table/TableSidebarMenu.tsx +0 -59
- package/src/components/ui/Table/classNames.ts +0 -7
- package/src/components/ui/Table/index.ts +0 -12
- package/src/components/ui/UserFeedbackDialog/UserFeedbackDialog.tsx +0 -168
- package/src/components/ui/UserFeedbackDialog/index.ts +0 -1
- package/src/components/ui/UserInactivityConfirmation/UserInactivityConfirmation.tsx +0 -59
- package/src/components/ui/UserInactivityConfirmation/index.ts +0 -1
- package/src/components/ui/UsersEffectiveRightsDetailsDialog/UsersEffectiveRightsDetailsDialog.tsx +0 -584
- package/src/components/ui/UsersEffectiveRightsDetailsDialog/index.ts +0 -1
- package/src/context/caseAbac/CaseAbacContext.tsx +0 -24
- package/src/context/caseAbac/CaseAbacContextProvider.tsx +0 -69
- package/src/context/caseAbac/index.ts +0 -3
- package/src/context/caseAbac/useCaseAbacContext.tsx +0 -6
- package/src/context/caseTypeAbac/CaseTypeAbacContext.tsx +0 -16
- package/src/context/caseTypeAbac/CaseTypeAbacContextProvider.tsx +0 -40
- package/src/context/caseTypeAbac/index.ts +0 -3
- package/src/context/caseTypeAbac/useCaseTypeAbacContext.tsx +0 -6
- package/src/data/date.ts +0 -8
- package/src/data/queryDependencies.ts +0 -166
- package/src/dataHooks/useAssemblyProtocolsQuery/index.ts +0 -1
- package/src/dataHooks/useAssemblyProtocolsQuery/useAssemblyProtocolsQuery.ts +0 -39
- package/src/dataHooks/useCaseRightsQuery/index.ts +0 -1
- package/src/dataHooks/useCaseRightsQuery/useCaseRightsQuery.ts +0 -21
- package/src/dataHooks/useCaseSetCategoriesQuery/index.ts +0 -1
- package/src/dataHooks/useCaseSetCategoriesQuery/useCaseSetCategoriesQuery.ts +0 -39
- package/src/dataHooks/useCaseSetRightsQuery/index.ts +0 -1
- package/src/dataHooks/useCaseSetRightsQuery/useCaseSetRightsQuery.ts +0 -17
- package/src/dataHooks/useCaseSetStatsQuery/index.ts +0 -1
- package/src/dataHooks/useCaseSetStatsQuery/useCaseSetStatsQuery.ts +0 -31
- package/src/dataHooks/useCaseSetStatusesQuery/index.ts +0 -1
- package/src/dataHooks/useCaseSetStatusesQuery/useCaseSetStatusesQuery.ts +0 -39
- package/src/dataHooks/useCaseSetsQuery/index.ts +0 -1
- package/src/dataHooks/useCaseSetsQuery/useCaseSetsQuery.ts +0 -41
- package/src/dataHooks/useCaseTypeSetCategoriesQuery/index.ts +0 -1
- package/src/dataHooks/useCaseTypeSetCategoriesQuery/useCaseTypeSetCategoriesQuery.ts +0 -41
- package/src/dataHooks/useCaseTypeSetMembersQuery/index.ts +0 -1
- package/src/dataHooks/useCaseTypeSetMembersQuery/useCaseTypeSetMembersQuery.ts +0 -17
- package/src/dataHooks/useCaseTypeSetsQuery/index.ts +0 -1
- package/src/dataHooks/useCaseTypeSetsQuery/useCaseTypeSetsQuery.ts +0 -58
- package/src/dataHooks/useCaseTypeStatsQuery/index.ts +0 -1
- package/src/dataHooks/useCaseTypeStatsQuery/useCaseTypeStatsQuery.ts +0 -20
- package/src/dataHooks/useCaseTypesQuery/index.ts +0 -1
- package/src/dataHooks/useCaseTypesQuery/useCaseTypesQuery.ts +0 -43
- package/src/dataHooks/useColSetMembersQuery/index.ts +0 -1
- package/src/dataHooks/useColSetMembersQuery/useColSetMembersQuery.ts +0 -17
- package/src/dataHooks/useColSetsQuery/index.ts +0 -1
- package/src/dataHooks/useColSetsQuery/useColSetsQuery.ts +0 -39
- package/src/dataHooks/useColTypesQuery/index.ts +0 -1
- package/src/dataHooks/useColTypesQuery/useColTypesQuery.ts +0 -51
- package/src/dataHooks/useColsQuery/index.ts +0 -1
- package/src/dataHooks/useColsQuery/useColsQuery.ts +0 -60
- package/src/dataHooks/useConceptQuery/index.ts +0 -1
- package/src/dataHooks/useConceptQuery/useConceptQuery.ts +0 -52
- package/src/dataHooks/useConceptRelationTypeQuery/index.ts +0 -1
- package/src/dataHooks/useConceptRelationTypeQuery/useConceptRelationTypeQuery.ts +0 -21
- package/src/dataHooks/useConceptSetTypeQuery/index.ts +0 -1
- package/src/dataHooks/useConceptSetTypeQuery/useConceptSetTypeQuery.ts +0 -27
- package/src/dataHooks/useConceptSetsQuery/index.ts +0 -1
- package/src/dataHooks/useConceptSetsQuery/useConceptSetsQuery.ts +0 -38
- package/src/dataHooks/useDataCollectionSetMembersQuery/index.ts +0 -1
- package/src/dataHooks/useDataCollectionSetMembersQuery/useDataCollectionSetMembersQuery.ts +0 -17
- package/src/dataHooks/useDataCollectionsQuery/index.ts +0 -1
- package/src/dataHooks/useDataCollectionsQuery/useDataCollectionsQuery.ts +0 -45
- package/src/dataHooks/useDimTypesQuery/index.ts +0 -1
- package/src/dataHooks/useDimTypesQuery/useDimTypesQuery.ts +0 -26
- package/src/dataHooks/useDimsQuery/index.ts +0 -1
- package/src/dataHooks/useDimsQuery/useDimsQuery.ts +0 -55
- package/src/dataHooks/useDiseasesQuery/index.ts +0 -1
- package/src/dataHooks/useDiseasesQuery/useDiseasesQuery.ts +0 -39
- package/src/dataHooks/useEtiologicalAgentsQuery/index.ts +0 -1
- package/src/dataHooks/useEtiologicalAgentsQuery/useEtiologicalAgentsQuery.ts +0 -39
- package/src/dataHooks/useGeneticDistanceProtocolsQuery/index.ts +0 -1
- package/src/dataHooks/useGeneticDistanceProtocolsQuery/useGeneticDistanceProtocolsQuery.ts +0 -29
- package/src/dataHooks/useIdentifierIssuerOwnOrganizationQuery/index.ts +0 -1
- package/src/dataHooks/useIdentifierIssuerOwnOrganizationQuery/useIdentifierIssuerOwnOrganizationQuery.ts +0 -34
- package/src/dataHooks/useIdentifierIssuerQuery/index.ts +0 -1
- package/src/dataHooks/useIdentifierIssuerQuery/useIdentifierIssuerQuery.ts +0 -42
- package/src/dataHooks/useInviteUserConstraintsQuery/index.ts +0 -1
- package/src/dataHooks/useInviteUserConstraintsQuery/useInviteUserConstraintsQuery.ts +0 -32
- package/src/dataHooks/useOrganizationAccessCasePoliciesQuery/index.ts +0 -1
- package/src/dataHooks/useOrganizationAccessCasePoliciesQuery/useOrganizationAccessCasePoliciesQuery.ts +0 -20
- package/src/dataHooks/useOrganizationAdminPoliciesQuery/index.ts +0 -1
- package/src/dataHooks/useOrganizationAdminPoliciesQuery/useOrganizationAdminPoliciesQuery.ts +0 -60
- package/src/dataHooks/useOrganizationIdentifierIssuerLinksQuery/index.ts +0 -1
- package/src/dataHooks/useOrganizationIdentifierIssuerLinksQuery/useOrganizationIdentifierIssuerLinksQuery.ts +0 -18
- package/src/dataHooks/useOrganizationShareCasePoliciesQuery/index.ts +0 -1
- package/src/dataHooks/useOrganizationShareCasePoliciesQuery/useOrganizationShareCasePoliciesQuery.ts +0 -18
- package/src/dataHooks/useOrganizationsQuery/index.ts +0 -1
- package/src/dataHooks/useOrganizationsQuery/useOrganizationsQuery.ts +0 -40
- package/src/dataHooks/useRefColsQuery/index.ts +0 -1
- package/src/dataHooks/useRefColsQuery/useRefColsQuery.ts +0 -39
- package/src/dataHooks/useRefColsValidationRulesQuery/index.ts +0 -1
- package/src/dataHooks/useRefColsValidationRulesQuery/useRefColsValidationRulesQuery.ts +0 -17
- package/src/dataHooks/useRefDimsQuery/index.ts +0 -1
- package/src/dataHooks/useRefDimsQuery/useRefDimsQuery.ts +0 -39
- package/src/dataHooks/useRegionQuery/index.ts +0 -1
- package/src/dataHooks/useRegionQuery/useRegionQuery.ts +0 -52
- package/src/dataHooks/useRegionRelationTypeQuery/index.ts +0 -1
- package/src/dataHooks/useRegionRelationTypeQuery/useRegionRelationTypeQuery.ts +0 -24
- package/src/dataHooks/useRegionSetsQuery/index.ts +0 -1
- package/src/dataHooks/useRegionSetsQuery/useRegionSetsQuery.ts +0 -39
- package/src/dataHooks/useSequencingProtocolsQuery/index.ts +0 -1
- package/src/dataHooks/useSequencingProtocolsQuery/useSequencingProtocolsQuery.ts +0 -39
- package/src/dataHooks/useTreeAlgorithmCodesQuery/index.ts +0 -1
- package/src/dataHooks/useTreeAlgorithmCodesQuery/useTreeAlgorithmCodesQuery.ts +0 -42
- package/src/dataHooks/useUserAccessCasePoliciesQuery/index.ts +0 -1
- package/src/dataHooks/useUserAccessCasePoliciesQuery/useUserAccessCasePoliciesQuery.ts +0 -18
- package/src/dataHooks/useUserEffectiveRightsQuery/index.ts +0 -1
- package/src/dataHooks/useUserEffectiveRightsQuery/useUserEffectiveRightsQuery.ts +0 -125
- package/src/dataHooks/useUserShareCasePoliciesQuery/index.ts +0 -1
- package/src/dataHooks/useUserShareCasePoliciesQuery/useUserShareCasePoliciesQuery.ts +0 -18
- package/src/dataHooks/useUsersQuery/index.ts +0 -1
- package/src/dataHooks/useUsersQuery/useUsersQuery.ts +0 -43
- package/src/hoc/withDialog/index.ts +0 -1
- package/src/hoc/withDialog/withDialog.tsx +0 -132
- package/src/hoc/withPermissions/index.ts +0 -1
- package/src/hoc/withPermissions/withPermissions.tsx +0 -34
- package/src/hooks/useArray/index.ts +0 -1
- package/src/hooks/useArray/useArray.ts +0 -5
- package/src/hooks/useColumnsMenu/index.ts +0 -1
- package/src/hooks/useColumnsMenu/useColumnsMenu.tsx +0 -152
- package/src/hooks/useCreateMutation/index.ts +0 -1
- package/src/hooks/useCreateMutation/useCreateMutation.ts +0 -103
- package/src/hooks/useDeleteMutation/index.ts +0 -1
- package/src/hooks/useDeleteMutation/useDeleteMutation.ts +0 -92
- package/src/hooks/useDimensions/index.ts +0 -1
- package/src/hooks/useDimensions/useDimensions.ts +0 -82
- package/src/hooks/useEditMutation/index.ts +0 -1
- package/src/hooks/useEditMutation/useEditMutation.ts +0 -112
- package/src/hooks/useInitializeTableStore/index.ts +0 -1
- package/src/hooks/useInitializeTableStore/useInitializeTableStore.ts +0 -41
- package/src/hooks/useIsFormFieldRequiredFromSchema/index.ts +0 -1
- package/src/hooks/useIsFormFieldRequiredFromSchema/useIsFormFieldRequiredFromSchema.ts +0 -32
- package/src/hooks/useItemQuery/index.ts +0 -1
- package/src/hooks/useItemQuery/useItemQuery.ts +0 -82
- package/src/hooks/useOrganizationCasePolicyNameFactory/index.ts +0 -1
- package/src/hooks/useOrganizationCasePolicyNameFactory/useOrganizationCasePolicyNameFactory.ts +0 -31
- package/src/hooks/useQueryMemo/index.ts +0 -1
- package/src/hooks/useQueryMemo/useQueryMemo.ts +0 -24
- package/src/hooks/useScrollbarSize/index.ts +0 -1
- package/src/hooks/useScrollbarSize/useScrollbarSize.ts +0 -23
- package/src/hooks/useSubscribable/index.ts +0 -1
- package/src/hooks/useSubscribable/useSubscribable.ts +0 -30
- package/src/hooks/useUpdateBreadcrumb/index.ts +0 -1
- package/src/hooks/useUpdateBreadcrumb/useUpdateBreadcrumb.ts +0 -21
- package/src/hooks/useUpdateDocumentTitle/index.ts +0 -1
- package/src/hooks/useUpdateDocumentTitle/useUpdateDocumentTitle.ts +0 -10
- package/src/hooks/useUserCasePolicyNameFactory/index.ts +0 -1
- package/src/hooks/useUserCasePolicyNameFactory/useUserCasePolicyNameFactory.ts +0 -37
- package/src/index.ts +0 -301
- package/src/models/admin.ts +0 -7
- package/src/models/auth.ts +0 -14
- package/src/models/caseAccess.ts +0 -21
- package/src/models/config.ts +0 -153
- package/src/models/data.ts +0 -11
- package/src/models/dataHooks.ts +0 -18
- package/src/models/environment.ts +0 -10
- package/src/models/epi.ts +0 -188
- package/src/models/filter.ts +0 -39
- package/src/models/form.ts +0 -74
- package/src/models/generic.ts +0 -4
- package/src/models/nestedMenu.ts +0 -21
- package/src/models/notification.ts +0 -12
- package/src/models/outage.ts +0 -7
- package/src/models/query.ts +0 -75
- package/src/models/reactRouter.ts +0 -36
- package/src/models/table.ts +0 -191
- package/src/models/testId.ts +0 -1
- package/src/models/tree.ts +0 -32
- package/src/pages/AcceptInvitationPage/AcceptInvitationPage.tsx +0 -96
- package/src/pages/AcceptInvitationPage/index.ts +0 -1
- package/src/pages/AdminPage/AdminPage.tsx +0 -164
- package/src/pages/AdminPage/index.ts +0 -1
- package/src/pages/CaseSetStatusAdminPage/CaseSetStatusAdminPage.tsx +0 -98
- package/src/pages/CaseSetStatusAdminPage/index.ts +0 -1
- package/src/pages/CaseTypeSetCategoriesAdminPage/CaseTypeSetCategoriesAdminPage.tsx +0 -108
- package/src/pages/CaseTypeSetCategoriesAdminPage/index.ts +0 -1
- package/src/pages/CaseTypeSetsAdminPage/CaseTypeSetsAdminPage.tsx +0 -200
- package/src/pages/CaseTypeSetsAdminPage/index.ts +0 -1
- package/src/pages/CaseTypesAdminPage/CaseTypesAdminPage.tsx +0 -204
- package/src/pages/CaseTypesAdminPage/index.ts +0 -1
- package/src/pages/CasesDetailPage/CasesDetailPage.tsx +0 -57
- package/src/pages/CasesDetailPage/index.ts +0 -1
- package/src/pages/CasesPage/CasesPage.tsx +0 -338
- package/src/pages/CasesPage/index.ts +0 -1
- package/src/pages/ChooseIdentityProviderPage/ChooseIdentityProviderPage.tsx +0 -166
- package/src/pages/ChooseIdentityProviderPage/index.ts +0 -1
- package/src/pages/ColSetsAdminPage/ColSetsAdminPage.tsx +0 -175
- package/src/pages/ColSetsAdminPage/index.ts +0 -1
- package/src/pages/ColsAdminPage/ColsAdminPage.tsx +0 -400
- package/src/pages/ColsAdminPage/index.ts +0 -1
- package/src/pages/ConceptRelationsAdminPage/ConceptRelationsAdminPage.tsx +0 -134
- package/src/pages/ConceptRelationsAdminPage/index.ts +0 -1
- package/src/pages/ConceptSetsAdminPage/ConceptSetsAdminPage.tsx +0 -167
- package/src/pages/ConceptSetsAdminPage/index.ts +0 -1
- package/src/pages/ConceptsAdminPage/ConceptsAdminPage.tsx +0 -138
- package/src/pages/ConceptsAdminPage/index.ts +0 -1
- package/src/pages/CrudPage/CrudPage.tsx +0 -646
- package/src/pages/CrudPage/CrudPageDeleteDialog.tsx +0 -85
- package/src/pages/CrudPage/CrudPageEditDialog.tsx +0 -165
- package/src/pages/CrudPage/index.ts +0 -1
- package/src/pages/DataCollectionSetsAdminPage/DataCollectionSetsAdminPage.tsx +0 -156
- package/src/pages/DataCollectionSetsAdminPage/index.ts +0 -1
- package/src/pages/DataCollectionVisualizationPage/DataCollectionVisualizationPage.tsx +0 -238
- package/src/pages/DataCollectionVisualizationPage/index.ts +0 -1
- package/src/pages/DataCollectionsAdminPage/DataCollectionsAdminPage.tsx +0 -96
- package/src/pages/DataCollectionsAdminPage/index.ts +0 -1
- package/src/pages/DimsAdminPage/DimsAdminPage.tsx +0 -208
- package/src/pages/DimsAdminPage/index.ts +0 -1
- package/src/pages/DiseasesAdminPage/DiseasesAdminPage.tsx +0 -97
- package/src/pages/DiseasesAdminPage/index.ts +0 -1
- package/src/pages/ErrorPage/ErrorPage.tsx +0 -25
- package/src/pages/ErrorPage/index.ts +0 -1
- package/src/pages/EtiologicalAgentsAdminPage/EtiologicalAgentsAdminPage.tsx +0 -96
- package/src/pages/EtiologicalAgentsAdminPage/index.ts +0 -1
- package/src/pages/EtiologiesAdminPage/EtiologiesAdminPage.tsx +0 -110
- package/src/pages/EtiologiesAdminPage/index.ts +0 -1
- package/src/pages/EventsDetailPage/EventsDetailPage.tsx +0 -67
- package/src/pages/EventsDetailPage/index.ts +0 -1
- package/src/pages/EventsPage/EventsPage.tsx +0 -262
- package/src/pages/EventsPage/index.ts +0 -1
- package/src/pages/HomePage/HomePage.tsx +0 -47
- package/src/pages/HomePage/index.ts +0 -1
- package/src/pages/IdentifierIssuersAdminPage/IdentifierIssuersAdminPage.tsx +0 -106
- package/src/pages/IdentifierIssuersAdminPage/index.ts +0 -1
- package/src/pages/OrganizationAccessCasePoliciesAdminPage/OrganizationAccessCasePoliciesAdminPage.tsx +0 -217
- package/src/pages/OrganizationAccessCasePoliciesAdminPage/index.ts +0 -1
- package/src/pages/OrganizationAdminPoliciesAdminPage/OrganizationAdminPoliciesAdminPage.tsx +0 -119
- package/src/pages/OrganizationAdminPoliciesAdminPage/index.ts +0 -1
- package/src/pages/OrganizationContactsAdminPage/OrganizationContactsAdminPage.tsx +0 -127
- package/src/pages/OrganizationContactsAdminPage/index.ts +0 -1
- package/src/pages/OrganizationShareCasePoliciesAdminPage/OrganizationShareCasePoliciesAdminPage.tsx +0 -183
- package/src/pages/OrganizationShareCasePoliciesAdminPage/index.ts +0 -1
- package/src/pages/OrganizationSitesAdminPage/OrganizationSitesAdminPage.tsx +0 -132
- package/src/pages/OrganizationSitesAdminPage/index.ts +0 -1
- package/src/pages/OrganizationsAdminPage/OrganizationsAdminPage.tsx +0 -188
- package/src/pages/OrganizationsAdminPage/index.ts +0 -1
- package/src/pages/OutagesAdminPage/OutagesAdminPage.tsx +0 -158
- package/src/pages/OutagesAdminPage/index.ts +0 -1
- package/src/pages/PostLoginPage/PostLoginPage.tsx +0 -39
- package/src/pages/PostLoginPage/index.ts +0 -1
- package/src/pages/PostLogoutPage/PostLogoutPage.tsx +0 -44
- package/src/pages/PostLogoutPage/index.ts +0 -1
- package/src/pages/RefColsAdminPage/RefColsAdminPage.tsx +0 -286
- package/src/pages/RefColsAdminPage/index.ts +0 -1
- package/src/pages/RefDimsAdminPage/RefDimsAdminPage.tsx +0 -152
- package/src/pages/RefDimsAdminPage/index.ts +0 -1
- package/src/pages/RegionRelationsAdminPage/RegionRelationsAdminPage.tsx +0 -132
- package/src/pages/RegionRelationsAdminPage/index.ts +0 -1
- package/src/pages/RegionSetShapesAdminPage/RegionSetShapesAdminPage.tsx +0 -132
- package/src/pages/RegionSetShapesAdminPage/index.ts +0 -1
- package/src/pages/RegionSetsAdminPage/RegionSetsAdminPage.tsx +0 -147
- package/src/pages/RegionSetsAdminPage/index.ts +0 -1
- package/src/pages/RegionsAdminPage/RegionsAdminPage.tsx +0 -150
- package/src/pages/RegionsAdminPage/index.ts +0 -1
- package/src/pages/RouterErrorPage/RouterErrorPage.tsx +0 -23
- package/src/pages/RouterErrorPage/index.ts +0 -1
- package/src/pages/TrendsPage/TrendsPage.tsx +0 -17
- package/src/pages/TrendsPage/index.ts +0 -1
- package/src/pages/UploadPage/UploadPage.tsx +0 -40
- package/src/pages/UploadPage/index.ts +0 -1
- package/src/pages/UserAccessCasePoliciesAdminPage/UserAccessCasePoliciesAdminPage.tsx +0 -209
- package/src/pages/UserAccessCasePoliciesAdminPage/index.ts +0 -1
- package/src/pages/UserEffectiveRightsAdminPage/UserEffectiveRightsAdminPage.tsx +0 -331
- package/src/pages/UserEffectiveRightsAdminPage/index.ts +0 -1
- package/src/pages/UserEffectiveRightsTesterAdminPage/UserEffectiveRightsTesterAdminPage.tsx +0 -283
- package/src/pages/UserEffectiveRightsTesterAdminPage/index.ts +0 -1
- package/src/pages/UserInvitationsAdminPage/UserInvitationConsumeDialog.tsx +0 -143
- package/src/pages/UserInvitationsAdminPage/UserInvitationShareDialog.tsx +0 -100
- package/src/pages/UserInvitationsAdminPage/UserInvitationsAdminPage.tsx +0 -218
- package/src/pages/UserInvitationsAdminPage/index.ts +0 -1
- package/src/pages/UserShareCasePoliciesAdminPage/UserShareCasePoliciesAdminPage.tsx +0 -183
- package/src/pages/UserShareCasePoliciesAdminPage/index.ts +0 -1
- package/src/pages/UsersAdminPage/UsersAdminPage.tsx +0 -240
- package/src/pages/UsersAdminPage/index.ts +0 -1
- package/src/routes/adminRoutes.tsx +0 -801
- package/src/routes/index.ts +0 -2
- package/src/routes/routes.tsx +0 -235
- package/src/setup/index.ts +0 -1
- package/src/setup/setup.ts +0 -5
- package/src/setup/yup.ts +0 -203
- package/src/stores/epiDashboardStore/epiDashboardStore.ts +0 -750
- package/src/stores/epiDashboardStore/epiDashboardStoreContext.tsx +0 -6
- package/src/stores/epiDashboardStore/index.ts +0 -2
- package/src/stores/epiUploadStore/epiUploadStore.ts +0 -351
- package/src/stores/epiUploadStore/epiUploadStoreContext.tsx +0 -6
- package/src/stores/epiUploadStore/index.ts +0 -2
- package/src/stores/oidcStore/index.ts +0 -1
- package/src/stores/oidcStore/oidcStore.ts +0 -43
- package/src/stores/outagesStore/index.ts +0 -1
- package/src/stores/outagesStore/outagesStore.ts +0 -31
- package/src/stores/tableStore/TableStoreContext.tsx +0 -6
- package/src/stores/tableStore/TableStoreContextProvider.tsx +0 -20
- package/src/stores/tableStore/index.ts +0 -4
- package/src/stores/tableStore/tableStore.ts +0 -547
- package/src/stores/tableStore/useTableStoreContext.tsx +0 -7
- package/src/stores/userProfileStore/index.ts +0 -1
- package/src/stores/userProfileStore/userProfileStore.ts +0 -112
- package/src/test/integration/lib/render.tsx +0 -33
- package/src/test/integration/tests/integration-example/HelloWorld.test.tsx +0 -14
- package/src/test/integration/tests/integration-example/HelloWorld.tsx +0 -9
- package/src/test/setup-browser.ts +0 -3
- package/src/test/setup-jsdom.ts +0 -6
- package/src/test/setup.ts +0 -9
- package/src/utils/AbacUtil/AbacUtil.ts +0 -21
- package/src/utils/AbacUtil/index.ts +0 -1
- package/src/utils/AxiosUtil/AxiosUtil.test.ts +0 -66
- package/src/utils/AxiosUtil/AxiosUtil.ts +0 -47
- package/src/utils/AxiosUtil/index.ts +0 -1
- package/src/utils/CaseSelectionUtil/CaseSelectionUtil.ts +0 -32
- package/src/utils/CaseSelectionUtil/index.ts +0 -1
- package/src/utils/CaseSetUtil/CaseSetUtil.ts +0 -13
- package/src/utils/CaseSetUtil/index.ts +0 -1
- package/src/utils/CaseTypeUtil/CaseTypeUtil.ts +0 -178
- package/src/utils/CaseTypeUtil/index.ts +0 -1
- package/src/utils/CaseUtil/CaseUtil.ts +0 -401
- package/src/utils/CaseUtil/index.ts +0 -1
- package/src/utils/DashboardUtil/DashboardUtil.ts +0 -46
- package/src/utils/DashboardUtil/index.ts +0 -1
- package/src/utils/DataHookUtil/DataHookUtil.ts +0 -137
- package/src/utils/DataHookUtil/index.ts +0 -1
- package/src/utils/DataSetUtil/DataSetUtil.ts +0 -70
- package/src/utils/DataSetUtil/index.ts +0 -1
- package/src/utils/DataUtil/DataUtil.ts +0 -84
- package/src/utils/DataUtil/index.ts +0 -1
- package/src/utils/DownloadUtil/DownloadUtil.ts +0 -237
- package/src/utils/DownloadUtil/index.ts +0 -1
- package/src/utils/EffectiveRightsUtil/EffectiveRightsUtil.ts +0 -142
- package/src/utils/EffectiveRightsUtil/index.ts +0 -1
- package/src/utils/EpiCurveUtil/EpiCurveUtil.ts +0 -180
- package/src/utils/EpiCurveUtil/index.ts +0 -1
- package/src/utils/EpiFilterUtil/EpiFilterUtil.ts +0 -232
- package/src/utils/EpiFilterUtil/index.ts +0 -1
- package/src/utils/EpiLineListUtil/EpiLineListUtil.ts +0 -15
- package/src/utils/EpiLineListUtil/index.ts +0 -1
- package/src/utils/EpiMapUtil/EpiMapUtil.test.ts +0 -54
- package/src/utils/EpiMapUtil/EpiMapUtil.ts +0 -80
- package/src/utils/EpiMapUtil/index.ts +0 -1
- package/src/utils/EpiTreeUtil/EpiTreeUtil.test.ts +0 -2467
- package/src/utils/EpiTreeUtil/EpiTreeUtil.ts +0 -1055
- package/src/utils/EpiTreeUtil/index.ts +0 -1
- package/src/utils/EpiUploadUtil/EpiUploadUtil.ts +0 -857
- package/src/utils/EpiUploadUtil/index.ts +0 -1
- package/src/utils/FileUtil/FileUtil.ts +0 -22
- package/src/utils/FileUtil/index.ts +0 -1
- package/src/utils/FormUtil/FormUtil.test.ts +0 -36
- package/src/utils/FormUtil/FormUtil.ts +0 -63
- package/src/utils/FormUtil/index.ts +0 -1
- package/src/utils/MenuDataUtil/MenuDataUtil.ts +0 -54
- package/src/utils/MenuDataUtil/index.ts +0 -1
- package/src/utils/NewickUtil/NewickUtil.test.ts +0 -187
- package/src/utils/NewickUtil/NewickUtil.ts +0 -69
- package/src/utils/NewickUtil/index.ts +0 -1
- package/src/utils/NotificationUtil/NotificationUtil.ts +0 -28
- package/src/utils/NotificationUtil/index.ts +0 -1
- package/src/utils/NumberUtil/NumberUtil.test.ts +0 -113
- package/src/utils/NumberUtil/NumberUtil.ts +0 -67
- package/src/utils/NumberUtil/index.ts +0 -1
- package/src/utils/ObjectUtil/ObjectUtil.test.ts +0 -43
- package/src/utils/ObjectUtil/ObjectUtil.ts +0 -28
- package/src/utils/ObjectUtil/index.ts +0 -1
- package/src/utils/OutageUtil/OutageUtil.test.ts +0 -108
- package/src/utils/OutageUtil/OutageUtil.ts +0 -81
- package/src/utils/OutageUtil/index.ts +0 -1
- package/src/utils/QueryUtil/QueryUtil.test.ts +0 -42
- package/src/utils/QueryUtil/QueryUtil.ts +0 -105
- package/src/utils/QueryUtil/index.ts +0 -1
- package/src/utils/StringUtil/StringUtil.test.ts +0 -61
- package/src/utils/StringUtil/StringUtil.ts +0 -91
- package/src/utils/StringUtil/index.ts +0 -1
- package/src/utils/TableUtil/TableUtil.ts +0 -665
- package/src/utils/TableUtil/index.ts +0 -1
- package/src/utils/TestIdUtil/TestIdUtil.test.ts +0 -12
- package/src/utils/TestIdUtil/TestIdUtil.ts +0 -13
- package/src/utils/TestIdUtil/index.ts +0 -1
- package/src/utils/TimeUtil/TimeUtil.ts +0 -38
- package/src/utils/TimeUtil/index.ts +0 -1
- package/src/utils/UserManagerUtil/UserManagerUtil.test.ts +0 -41
- package/src/utils/UserManagerUtil/UserManagerUtil.ts +0 -39
- package/src/utils/UserManagerUtil/index.ts +0 -1
- package/src/utils/ValidationUtil/ValidationUtil.test.ts +0 -61
- package/src/utils/ValidationUtil/ValidationUtil.ts +0 -56
- package/src/utils/ValidationUtil/index.ts +0 -1
- /package/{src → dist}/locale/en.json +0 -0
- /package/{src → dist}/locale/nl.json +0 -0
- /package/{src/@types → dist}/mui.d.ts +0 -0
- /package/{src/@types → dist}/ui.d.ts +0 -0
- /package/{src/@types → dist}/vite-env.d.ts +0 -0
- /package/{src/@types → dist}/yup.d.ts +0 -0
|
@@ -1,1055 +0,0 @@
|
|
|
1
|
-
import Decimal from 'decimal.js';
|
|
2
|
-
import first from 'lodash/first';
|
|
3
|
-
import intersection from 'lodash/intersection';
|
|
4
|
-
import last from 'lodash/last';
|
|
5
|
-
import round from 'lodash/round';
|
|
6
|
-
import { type Theme } from '@mui/material';
|
|
7
|
-
|
|
8
|
-
import { NumberUtil } from '../NumberUtil';
|
|
9
|
-
import type { CompleteCaseType } from '../../api';
|
|
10
|
-
import { ColType } from '../../api';
|
|
11
|
-
import { ConfigManager } from '../../classes/managers/ConfigManager';
|
|
12
|
-
import type {
|
|
13
|
-
Stratification,
|
|
14
|
-
TreeConfiguration,
|
|
15
|
-
} from '../../models/epi';
|
|
16
|
-
import type {
|
|
17
|
-
TreeAssembly,
|
|
18
|
-
TreeNode,
|
|
19
|
-
TreePathProperties,
|
|
20
|
-
} from '../../models/tree';
|
|
21
|
-
import { EpiDataManager } from '../../classes/managers/EpiDataManager';
|
|
22
|
-
|
|
23
|
-
type SanitizeResult = { node: TreeNode; nodesToMove: TreeNode[] };
|
|
24
|
-
|
|
25
|
-
type TreeAssemblyContext = {
|
|
26
|
-
rootNode: TreeNode;
|
|
27
|
-
treeCanvasWidth: number;
|
|
28
|
-
treeAssembly: TreeAssembly;
|
|
29
|
-
pixelToGeneticDistanceRatio: number;
|
|
30
|
-
itemHeight: number;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
type NodeAssemblyResult = {
|
|
34
|
-
x: number;
|
|
35
|
-
y: number;
|
|
36
|
-
caseIds: string[];
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
// [number of lines to draw, genetic distance of single line, minGeneticScaleUnit]
|
|
40
|
-
type TickerMarkScale = [number, number, number];
|
|
41
|
-
|
|
42
|
-
export class EpiTreeUtil {
|
|
43
|
-
/**
|
|
44
|
-
* Calculates the vertical scroll position for a tree canvas based on the
|
|
45
|
-
* currently visible rows in a linked table/list view.
|
|
46
|
-
*
|
|
47
|
-
* The goal is to keep the visible portion of the tree centered on the same
|
|
48
|
-
* items that are currently visible in the linked view, accounting for zoom.
|
|
49
|
-
*
|
|
50
|
-
* @param kwArgs.treeCanvasHeight - Height of the visible tree canvas area in pixels.
|
|
51
|
-
* @param kwArgs.treeHeight - Total rendered height of the full tree in pixels.
|
|
52
|
-
* @param kwArgs.treeSize - Total number of leaf items (rows) in the tree.
|
|
53
|
-
* @param kwArgs.verticalScrollPosition - Current vertical scroll position of the linked view in pixels.
|
|
54
|
-
* @param kwArgs.zoomLevel - Current zoom level (>1 means zoomed out, items appear smaller).
|
|
55
|
-
* @returns The new vertical scroll position for the tree canvas, clamped to [0, treeHeight - treeCanvasHeight].
|
|
56
|
-
*/
|
|
57
|
-
public static getScrollPositionFromTreeVisibility(kwArgs: {
|
|
58
|
-
treeCanvasHeight: number;
|
|
59
|
-
treeHeight: number;
|
|
60
|
-
treeSize: number;
|
|
61
|
-
verticalScrollPosition: number;
|
|
62
|
-
zoomLevel: number;
|
|
63
|
-
itemHeight: number;
|
|
64
|
-
}): number {
|
|
65
|
-
const { treeCanvasHeight, treeHeight, verticalScrollPosition, zoomLevel, treeSize, itemHeight } = kwArgs;
|
|
66
|
-
|
|
67
|
-
const scaledItemHeight = itemHeight / zoomLevel;
|
|
68
|
-
const scrolledByItems = Math.round(verticalScrollPosition / scaledItemHeight);
|
|
69
|
-
const maxItemsInView = Math.round(treeCanvasHeight / scaledItemHeight);
|
|
70
|
-
|
|
71
|
-
const firstItemInView = Math.max(0, scrolledByItems);
|
|
72
|
-
const lastItemInView = Math.min(scrolledByItems + maxItemsInView, treeSize);
|
|
73
|
-
const averageItemInView = (firstItemInView + lastItemInView) / 2;
|
|
74
|
-
|
|
75
|
-
const newScrollPosition = Math.max(0, Math.min(treeHeight - treeCanvasHeight, averageItemInView * itemHeight - treeCanvasHeight / 2));
|
|
76
|
-
return newScrollPosition;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Sanitizes the tree by collapsing intermediate ancestor nodes that have a
|
|
82
|
-
* zero branch length, hoisting their children up to the parent level.
|
|
83
|
-
*
|
|
84
|
-
* This normalises Newick-parsed trees where polytomies or zero-distance
|
|
85
|
-
* internal nodes would otherwise produce visually redundant branching points.
|
|
86
|
-
*
|
|
87
|
-
* @param rootNode - The root of the tree to sanitize. Mutated in place.
|
|
88
|
-
* @returns The sanitized root node.
|
|
89
|
-
*/
|
|
90
|
-
public static sanitizeTree(rootNode: TreeNode): TreeNode {
|
|
91
|
-
const sanitize = (node: TreeNode): SanitizeResult => {
|
|
92
|
-
const results: SanitizeResult[] = [];
|
|
93
|
-
node.children?.forEach(child => {
|
|
94
|
-
results.push(sanitize(child));
|
|
95
|
-
});
|
|
96
|
-
results.filter(x => !!x).forEach((result) => {
|
|
97
|
-
node.children.splice(node.children.indexOf(result.node), result.node.children.length === result.nodesToMove.length ? 1 : 0, ...result.nodesToMove);
|
|
98
|
-
node.subTreeNames.splice(node.subTreeNames.indexOf(result.node.name), result.node.children.length === result.nodesToMove.length ? 1 : 0, ...result.nodesToMove.map(n => n.subTreeNames).flat());
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
if (node.children?.length) {
|
|
102
|
-
const nodesToMove: TreeNode[] = [];
|
|
103
|
-
node.children.forEach(child => {
|
|
104
|
-
if ((node.branchLength?.toNumber() ?? 0) === 0) {
|
|
105
|
-
nodesToMove.push(child);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
return {
|
|
109
|
-
node,
|
|
110
|
-
nodesToMove,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return null;
|
|
114
|
-
};
|
|
115
|
-
sanitize(rootNode);
|
|
116
|
-
return rootNode;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Assigns a dot-notation address to every node in the tree, representing its
|
|
121
|
-
* position in the hierarchy (e.g. `"1.2.1"`). Zero-branch-length children are
|
|
122
|
-
* always placed at index `1`; other children are indexed starting at `1` or
|
|
123
|
-
* `2` depending on whether a zero-branch sibling is present.
|
|
124
|
-
*
|
|
125
|
-
* @param rootNode - The root of the tree to address.
|
|
126
|
-
* @returns A map from node name to its dot-notation address string.
|
|
127
|
-
*/
|
|
128
|
-
public static createTreeAddresses(rootNode: TreeNode): { [key: string]: string } {
|
|
129
|
-
const treeAddresses: { [key: string]: string } = {};
|
|
130
|
-
const traverse = (node: TreeNode, address: number[] = []): TreeNode => {
|
|
131
|
-
treeAddresses[node.name] = address.join('.');
|
|
132
|
-
if (node.children?.length) {
|
|
133
|
-
const hasZeroBranchLength = node.children.some(child => (child.branchLength?.toNumber() ?? 0) === 0);
|
|
134
|
-
|
|
135
|
-
let index = hasZeroBranchLength ? 2 : 1;
|
|
136
|
-
node.children.forEach((child) => {
|
|
137
|
-
if ((child.branchLength?.toNumber() ?? 0) === 0) {
|
|
138
|
-
traverse(child, [...address, 1]);
|
|
139
|
-
} else {
|
|
140
|
-
traverse(child, [...address, index]);
|
|
141
|
-
index++;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
return node;
|
|
146
|
-
};
|
|
147
|
-
traverse(rootNode);
|
|
148
|
-
return treeAddresses;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Finds and returns a new root node for re-rooting the tree.
|
|
153
|
-
*
|
|
154
|
-
* When `selector` is `'node'`, the node with the given name becomes the new root.
|
|
155
|
-
* When `selector` is `'parent'`, the parent of the node with the given name is returned.
|
|
156
|
-
*
|
|
157
|
-
* The returned node has its `branchLength` reset to `0` and its `maxBranchLength`
|
|
158
|
-
* adjusted by subtracting the original branch length, so the scale remains consistent.
|
|
159
|
-
*
|
|
160
|
-
* @param rootNode - The current root of the tree.
|
|
161
|
-
* @param nodeName - Name of the node to search for.
|
|
162
|
-
* @param selector - Whether to return the matching node itself (`'node'`) or its parent (`'parent'`).
|
|
163
|
-
* @returns A shallow copy of the new root with adjusted branch length properties.
|
|
164
|
-
*/
|
|
165
|
-
public static findNewTreeRoot(rootNode: TreeNode, nodeName: string, selector: 'node' | 'parent'): TreeNode {
|
|
166
|
-
let newRoot: TreeNode;
|
|
167
|
-
const findNewRoot = (node: TreeNode) => {
|
|
168
|
-
if (newRoot) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (selector === 'node' && node.name === nodeName) {
|
|
173
|
-
newRoot = node;
|
|
174
|
-
}
|
|
175
|
-
if (node.children) {
|
|
176
|
-
const matchingChild = node.children.find(childNode => childNode.name === nodeName);
|
|
177
|
-
if (selector === 'parent' && matchingChild) {
|
|
178
|
-
newRoot = node;
|
|
179
|
-
} else {
|
|
180
|
-
node.children.forEach(childNode => findNewRoot(childNode));
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
findNewRoot(rootNode);
|
|
185
|
-
return {
|
|
186
|
-
...newRoot,
|
|
187
|
-
branchLength: new Decimal(0),
|
|
188
|
-
maxBranchLength: newRoot.maxBranchLength.sub(newRoot.branchLength),
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Finds the smallest non-zero branch length among all leaf nodes in the tree.
|
|
194
|
-
*
|
|
195
|
-
* This value is used as the minimum scale unit when computing tick mark
|
|
196
|
-
* intervals, ensuring the scale never subdivides below a single measurable step.
|
|
197
|
-
*
|
|
198
|
-
* @param tree - The root node of the tree to inspect.
|
|
199
|
-
* @returns The minimum positive branch length found on any leaf, or `Infinity`
|
|
200
|
-
* if the tree is empty or all leaves have zero/undefined branch lengths.
|
|
201
|
-
*/
|
|
202
|
-
public static getMinGeneticScaleUnit(tree: TreeNode): number {
|
|
203
|
-
if (!tree) {
|
|
204
|
-
return Infinity;
|
|
205
|
-
}
|
|
206
|
-
let min: number = Infinity;
|
|
207
|
-
const traverse = (node: TreeNode) => {
|
|
208
|
-
const branchLength = node.branchLength?.toNumber() ?? 0;
|
|
209
|
-
if (!node.children?.length && branchLength && branchLength < min) {
|
|
210
|
-
min = branchLength;
|
|
211
|
-
}
|
|
212
|
-
node?.children?.forEach(child => traverse(child));
|
|
213
|
-
};
|
|
214
|
-
traverse(tree);
|
|
215
|
-
return min;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Determines the optimal tick mark scale for the genetic distance axis.
|
|
220
|
-
*
|
|
221
|
-
* Selects the number of scale lines and the genetic distance represented by
|
|
222
|
-
* each interval by searching for the combination with the least leftover
|
|
223
|
-
* (i.e. the product of `numLines × increment` closest to `geneticTreeWidth`).
|
|
224
|
-
* Increments are drawn from `SCALE_INCREMENTS` scaled by an order-of-magnitude
|
|
225
|
-
* multiplier derived from `geneticTreeWidth`, and those smaller than
|
|
226
|
-
* `minGeneticScaleUnit` are skipped.
|
|
227
|
-
*
|
|
228
|
-
* @param params.treeWidthMinusPadding - Width of the drawable canvas area in pixels (excluding padding).
|
|
229
|
-
* @param params.geneticTreeWidth - Total genetic distance represented by the full tree width.
|
|
230
|
-
* @param params.minGeneticScaleUnit - The smallest meaningful genetic distance unit (see {@link getMinGeneticScaleUnit}).
|
|
231
|
-
* @param params.zoomLevel - Current zoom level; divides the effective pixel width.
|
|
232
|
-
* @returns A {@link TickerMarkScale} tuple: `[numberOfLines, geneticDistancePerLine, minGeneticScaleUnit]`.
|
|
233
|
-
* Returns `[0, 0, 0]` when any required input is falsy.
|
|
234
|
-
*/
|
|
235
|
-
public static getTickMarkScale(params: { treeWidthMinusPadding: number; geneticTreeWidth: Decimal; minGeneticScaleUnit: number; zoomLevel: number }): TickerMarkScale {
|
|
236
|
-
const { treeWidthMinusPadding, geneticTreeWidth, minGeneticScaleUnit, zoomLevel } = params;
|
|
237
|
-
if (!treeWidthMinusPadding || !geneticTreeWidth || !minGeneticScaleUnit) {
|
|
238
|
-
return [0, 0, 0];
|
|
239
|
-
}
|
|
240
|
-
const width = treeWidthMinusPadding / zoomLevel;
|
|
241
|
-
|
|
242
|
-
let minNumLines = Math.floor(width / ConfigManager.instance.config.epiTree.MAX_SCALE_WIDTH_PX) + 1;
|
|
243
|
-
let maxNumLines = Math.ceil(width / ConfigManager.instance.config.epiTree.MIN_SCALE_WIDTH_PX) + 1;
|
|
244
|
-
|
|
245
|
-
if (geneticTreeWidth.div(minGeneticScaleUnit).add(1).lessThan(maxNumLines)) {
|
|
246
|
-
maxNumLines = Math.max(geneticTreeWidth.div(minGeneticScaleUnit).ceil().toNumber(), 2);
|
|
247
|
-
}
|
|
248
|
-
if (minNumLines > maxNumLines) {
|
|
249
|
-
minNumLines = maxNumLines;
|
|
250
|
-
}
|
|
251
|
-
if (maxNumLines === 2) {
|
|
252
|
-
return [2, minGeneticScaleUnit, minGeneticScaleUnit];
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const geneticTreeWidthDecimal = new Decimal(geneticTreeWidth);
|
|
256
|
-
const multiplier = new Decimal(10).pow(geneticTreeWidthDecimal.log(10).floor().minus(1));
|
|
257
|
-
const multipliedIncrements = ConfigManager.instance.config.epiTree.SCALE_INCREMENTS.map(i => new Decimal(i).times(multiplier));
|
|
258
|
-
|
|
259
|
-
let bestCombination: [Decimal, Decimal, Decimal] = [new Decimal(0), new Decimal(0), new Decimal(Infinity)];
|
|
260
|
-
|
|
261
|
-
for (let numLines = minNumLines; numLines <= maxNumLines; numLines++) {
|
|
262
|
-
for (const increment of multipliedIncrements) {
|
|
263
|
-
if (increment.lt(minGeneticScaleUnit)) {
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
const product = increment.times(numLines);
|
|
267
|
-
const leftover = product.minus(geneticTreeWidthDecimal).abs();
|
|
268
|
-
if (leftover.lt(bestCombination[2])) {
|
|
269
|
-
bestCombination = [Decimal(numLines), increment, leftover];
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return [bestCombination[0].add(1).toNumber(), bestCombination[1].toNumber(), minGeneticScaleUnit];
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Traverses the tree and produces a {@link TreeAssembly} containing all
|
|
279
|
-
* pre-computed `Path2D` shapes and metadata needed to render the tree.
|
|
280
|
-
*
|
|
281
|
-
* Leaf nodes are assembled in DFS order (incrementing `leafIndex`), which
|
|
282
|
-
* determines their vertical position. Ancestor nodes are positioned vertically
|
|
283
|
-
* at the midpoint of their first and last child.
|
|
284
|
-
*
|
|
285
|
-
* @param params.rootNode - The root of the tree to assemble.
|
|
286
|
-
* @param params.treeCanvasWidth - Width of the tree canvas in pixels, used for support lines.
|
|
287
|
-
* @param params.pixelToGeneticDistanceRatio - Pixels per unit of genetic distance.
|
|
288
|
-
* @param params.itemHeight - Height of each row/item in pixels.
|
|
289
|
-
* @returns A fully populated {@link TreeAssembly} ready for rendering.
|
|
290
|
-
*/
|
|
291
|
-
public static assembleTree(params: { rootNode: TreeNode; treeCanvasWidth: number; pixelToGeneticDistanceRatio: number; itemHeight: number }): TreeAssembly {
|
|
292
|
-
const { rootNode, treeCanvasWidth, pixelToGeneticDistanceRatio, itemHeight } = params;
|
|
293
|
-
let leafIndex = 0;
|
|
294
|
-
const treeAssembly: TreeAssembly = {
|
|
295
|
-
verticalAncestorTreeLines: [],
|
|
296
|
-
horizontalAncestorTreeLines: [],
|
|
297
|
-
ancestorNodes: [],
|
|
298
|
-
leafNodes: [],
|
|
299
|
-
leafTreeLines: [],
|
|
300
|
-
supportLines: [],
|
|
301
|
-
distanceTexts: [],
|
|
302
|
-
nodePathPropertiesMap: new Map(),
|
|
303
|
-
horizontalLinePathPropertiesMap: new Map(),
|
|
304
|
-
verticalLinePathPropertiesMap: new Map(),
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
const treeAssemblyContext: TreeAssemblyContext = {
|
|
308
|
-
treeAssembly,
|
|
309
|
-
treeCanvasWidth,
|
|
310
|
-
pixelToGeneticDistanceRatio,
|
|
311
|
-
rootNode,
|
|
312
|
-
itemHeight,
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
const traverseTree = (node: TreeNode, distance = 0): NodeAssemblyResult => {
|
|
316
|
-
if (!node) {
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
const nodeRenderResults: NodeAssemblyResult[] = [];
|
|
320
|
-
node.children?.forEach(child => {
|
|
321
|
-
nodeRenderResults.push(traverseTree(child, distance + (node.branchLength?.toNumber() ?? 0)));
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
if (!node.children?.length) {
|
|
325
|
-
const result = EpiTreeUtil.assembleLeafNode(treeAssemblyContext, node, distance, leafIndex);
|
|
326
|
-
leafIndex++;
|
|
327
|
-
return result;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return EpiTreeUtil.assembleAncestorNode(treeAssemblyContext, node, nodeRenderResults);
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
traverseTree(rootNode);
|
|
334
|
-
|
|
335
|
-
return treeAssembly;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Assembles the visual elements for a single leaf node and appends them to
|
|
340
|
-
* the tree assembly.
|
|
341
|
-
*
|
|
342
|
-
* Produces: a horizontal branch line, an optional distance label, a dashed
|
|
343
|
-
* support line extending to the canvas edge, and a filled dot.
|
|
344
|
-
*
|
|
345
|
-
* @param treeAssemblyContext - Shared context holding the assembly target and canvas dimensions.
|
|
346
|
-
* @param node - The leaf tree node to assemble.
|
|
347
|
-
* @param distance - Accumulated genetic distance from the root to the start of this node's branch.
|
|
348
|
-
* @param leafIndex - Zero-based vertical index of this leaf, determining its Y position.
|
|
349
|
-
* @returns The pixel coordinates of the branch start and the node name, for use by the parent.
|
|
350
|
-
*/
|
|
351
|
-
private static assembleLeafNode(treeAssemblyContext: TreeAssemblyContext, node: TreeNode, distance = 0, leafIndex = 0): NodeAssemblyResult {
|
|
352
|
-
const leafX = distance + (node.branchLength?.toNumber() ?? 0);
|
|
353
|
-
const leafXPxEnd = leafX * treeAssemblyContext.pixelToGeneticDistanceRatio + ConfigManager.instance.config.epiTree.TREE_PADDING;
|
|
354
|
-
const leafYPx = ((leafIndex) * treeAssemblyContext.itemHeight) + (treeAssemblyContext.itemHeight / 2);
|
|
355
|
-
const leafXPxDistance = (node.branchLength?.toNumber() ?? 0) * treeAssemblyContext.pixelToGeneticDistanceRatio;
|
|
356
|
-
const leafXPxStart = leafXPxEnd - leafXPxDistance;
|
|
357
|
-
const label = EpiTreeUtil.getDistanceLabel(treeAssemblyContext, node.branchLength);
|
|
358
|
-
|
|
359
|
-
// add horizontal line according to distance
|
|
360
|
-
const horizontalLineAccordingToDistancePath = new Path2D();
|
|
361
|
-
horizontalLineAccordingToDistancePath.moveTo(leafXPxStart - 0.5, leafYPx);
|
|
362
|
-
horizontalLineAccordingToDistancePath.lineTo(leafXPxEnd, leafYPx);
|
|
363
|
-
horizontalLineAccordingToDistancePath.closePath();
|
|
364
|
-
treeAssemblyContext.treeAssembly.leafTreeLines.push({ nodeName: node.name, shape: horizontalLineAccordingToDistancePath });
|
|
365
|
-
treeAssemblyContext.treeAssembly.horizontalLinePathPropertiesMap.set(horizontalLineAccordingToDistancePath, {
|
|
366
|
-
subTreeLeaveNames: node.subTreeLeaveNames,
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
// add distance text
|
|
370
|
-
if (label) {
|
|
371
|
-
treeAssemblyContext.treeAssembly.distanceTexts.push({ nodeNames: [node.name], x: (leafXPxStart + leafXPxEnd) / 2, y: leafYPx + 12, text: label });
|
|
372
|
-
}
|
|
373
|
-
// add horizontal support line to max width
|
|
374
|
-
treeAssemblyContext.treeAssembly.supportLines.push({ nodeName: node.name, fromX: leafXPxEnd, toX: treeAssemblyContext.treeCanvasWidth, y: leafYPx });
|
|
375
|
-
|
|
376
|
-
// add a dot to represent the node
|
|
377
|
-
const circlePath = new Path2D();
|
|
378
|
-
circlePath.arc(leafXPxEnd, leafYPx, ConfigManager.instance.config.epiTree.LEAF_DOT_RADIUS, 0, 2 * Math.PI, false);
|
|
379
|
-
circlePath.closePath();
|
|
380
|
-
|
|
381
|
-
treeAssemblyContext.treeAssembly.nodePathPropertiesMap.set(circlePath, {
|
|
382
|
-
subTreeLeaveNames: node.subTreeLeaveNames,
|
|
383
|
-
treeNode: node,
|
|
384
|
-
});
|
|
385
|
-
treeAssemblyContext.treeAssembly.leafNodes.push({ nodeName: node.name, shape: circlePath });
|
|
386
|
-
|
|
387
|
-
return {
|
|
388
|
-
x: leafXPxStart,
|
|
389
|
-
y: leafYPx,
|
|
390
|
-
caseIds: [node.name],
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Assembles the visual elements for an ancestor (internal) node and appends
|
|
396
|
-
* them to the tree assembly.
|
|
397
|
-
*
|
|
398
|
-
* Produces: vertical connector lines from each child toward the ancestor's
|
|
399
|
-
* Y midpoint (split into two sorted groups above and below center to allow
|
|
400
|
-
* per-segment highlighting), a horizontal branch line, an optional distance
|
|
401
|
-
* label, and a filled dot when all children have positive branch lengths.
|
|
402
|
-
*
|
|
403
|
-
* @param treeAssemblyContext - Shared context holding the assembly target and canvas dimensions.
|
|
404
|
-
* @param node - The ancestor tree node to assemble.
|
|
405
|
-
* @param childRenderResults - Assembly results returned by all direct children.
|
|
406
|
-
* @returns The pixel coordinates of the branch start and aggregated case IDs, for use by the parent.
|
|
407
|
-
*/
|
|
408
|
-
private static assembleAncestorNode(treeAssemblyContext: TreeAssemblyContext, node: TreeNode, childRenderResults: NodeAssemblyResult[]): NodeAssemblyResult {
|
|
409
|
-
const firstChild = first(childRenderResults);
|
|
410
|
-
const lastChild = last(childRenderResults);
|
|
411
|
-
|
|
412
|
-
const ancestorXPxEnd = firstChild.x;
|
|
413
|
-
const ancestorXPxDistance = (node.branchLength?.toNumber() ?? 0) * treeAssemblyContext.pixelToGeneticDistanceRatio;
|
|
414
|
-
const ancestorXPxStart = ancestorXPxEnd - ancestorXPxDistance;
|
|
415
|
-
const ancestorYPx = (firstChild.y + lastChild.y) / 2;
|
|
416
|
-
const caseIds = childRenderResults.map(r => r.caseIds).flat();
|
|
417
|
-
const label = EpiTreeUtil.getDistanceLabel(treeAssemblyContext, node.branchLength);
|
|
418
|
-
|
|
419
|
-
const centerToTopChildRenderResults = childRenderResults.filter(c => c.y < ancestorYPx).sort((a, b) => a.y - b.y);
|
|
420
|
-
const centerToBottomChildRenderResults = childRenderResults.filter(c => c.y > ancestorYPx).sort((a, b) => b.y - a.y);
|
|
421
|
-
|
|
422
|
-
[centerToTopChildRenderResults, centerToBottomChildRenderResults].forEach(sortedChildRenderResults => {
|
|
423
|
-
const chunkCaseIds: string[] = [];
|
|
424
|
-
|
|
425
|
-
sortedChildRenderResults.forEach((childRenderResult, index) => {
|
|
426
|
-
const lineToYPx = index === sortedChildRenderResults.length - 1 ? ancestorYPx : sortedChildRenderResults[index + 1].y;
|
|
427
|
-
chunkCaseIds.push(...childRenderResult.caseIds);
|
|
428
|
-
|
|
429
|
-
const chunkPath = new Path2D();
|
|
430
|
-
chunkPath.moveTo(childRenderResult.x, childRenderResult.y);
|
|
431
|
-
chunkPath.lineTo(childRenderResult.x, lineToYPx);
|
|
432
|
-
chunkPath.closePath();
|
|
433
|
-
treeAssemblyContext.treeAssembly.verticalAncestorTreeLines.push({ nodeNames: [...chunkCaseIds], shape: chunkPath });
|
|
434
|
-
treeAssemblyContext.treeAssembly.verticalLinePathPropertiesMap.set(chunkPath, {
|
|
435
|
-
subTreeLeaveNames: chunkCaseIds,
|
|
436
|
-
});
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
// add horizontal line according to distance
|
|
441
|
-
const horizontalLineAccordingToDistancePath = new Path2D();
|
|
442
|
-
horizontalLineAccordingToDistancePath.moveTo(ancestorXPxStart - 0.5, ancestorYPx);
|
|
443
|
-
horizontalLineAccordingToDistancePath.lineTo(ancestorXPxEnd + 0.5, ancestorYPx);
|
|
444
|
-
horizontalLineAccordingToDistancePath.closePath();
|
|
445
|
-
treeAssemblyContext.treeAssembly.horizontalAncestorTreeLines.push({ nodeNames: [node.name, ...caseIds], shape: horizontalLineAccordingToDistancePath });
|
|
446
|
-
treeAssemblyContext.treeAssembly.horizontalLinePathPropertiesMap.set(horizontalLineAccordingToDistancePath, {
|
|
447
|
-
subTreeLeaveNames: caseIds,
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
// add distance text
|
|
451
|
-
if (label) {
|
|
452
|
-
treeAssemblyContext.treeAssembly.distanceTexts.push({ nodeNames: [node.name, ...caseIds], x: (ancestorXPxStart + ancestorXPxEnd) / 2, y: ancestorYPx + 12, text: label });
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
if (node.children.every(child => (child.branchLength?.toNumber() ?? 0) > 0)) {
|
|
456
|
-
// add circle at beginning of the line representing the node itself
|
|
457
|
-
const circlePath = new Path2D();
|
|
458
|
-
circlePath.arc(ancestorXPxEnd, ancestorYPx, ConfigManager.instance.config.epiTree.ANCESTOR_DOT_RADIUS, 0, 2 * Math.PI, false);
|
|
459
|
-
treeAssemblyContext.treeAssembly.ancestorNodes.push({ nodeNames: [node.name, ...caseIds], shape: circlePath });
|
|
460
|
-
treeAssemblyContext.treeAssembly.nodePathPropertiesMap.set(circlePath, {
|
|
461
|
-
subTreeLeaveNames: node.subTreeLeaveNames,
|
|
462
|
-
treeNode: node,
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
return {
|
|
467
|
-
x: ancestorXPxStart,
|
|
468
|
-
y: ancestorYPx,
|
|
469
|
-
caseIds,
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* Returns a formatted distance label string for a branch, or `null` if the
|
|
475
|
-
* label should be suppressed.
|
|
476
|
-
*
|
|
477
|
-
* A label is suppressed when:
|
|
478
|
-
* - The tree has no maximum branch length, or it is zero.
|
|
479
|
-
* - The branch length is zero or undefined.
|
|
480
|
-
* - The branch is shorter than `MINIMUM_DISTANCE_PERCENTAGE_TO_SHOW_LABEL`
|
|
481
|
-
* percent of the maximum branch length in the tree.
|
|
482
|
-
*
|
|
483
|
-
* Precision is derived from the magnitude of `maxBranchLength` to avoid
|
|
484
|
-
* excessive decimal places for large values.
|
|
485
|
-
*
|
|
486
|
-
* @param treeAssemblyContext - Context containing the root node (for `maxBranchLength`).
|
|
487
|
-
* @param branchLength - The genetic distance of the branch to label.
|
|
488
|
-
* @returns A rounded numeric string, or `null` if the label should be hidden.
|
|
489
|
-
*/
|
|
490
|
-
private static getDistanceLabel(treeAssemblyContext: TreeAssemblyContext, branchLength: Decimal): string {
|
|
491
|
-
const labelPrecision = treeAssemblyContext.rootNode.maxBranchLength ? Math.max(1, 4 - String(Math.round(treeAssemblyContext.rootNode.maxBranchLength.toNumber())).length) : null;
|
|
492
|
-
if (!treeAssemblyContext.rootNode.maxBranchLength || treeAssemblyContext.rootNode.maxBranchLength.toNumber() === 0 || !branchLength || branchLength.toNumber() === 0) {
|
|
493
|
-
return null;
|
|
494
|
-
}
|
|
495
|
-
if (branchLength.div(treeAssemblyContext.rootNode.maxBranchLength).mul(100).lessThan(ConfigManager.instance.config.epiTree.MINIMUM_DISTANCE_PERCENTAGE_TO_SHOW_LABEL)) {
|
|
496
|
-
return null;
|
|
497
|
-
}
|
|
498
|
-
return String(round(branchLength.toNumber(), labelPrecision));
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Renders the pre-assembled tree shapes onto a canvas using the 2D context.
|
|
503
|
-
*
|
|
504
|
-
* Applies a transform for zoom and scroll, then draws in order:
|
|
505
|
-
* vertical ancestor lines → horizontal ancestor lines → (linked) support lines
|
|
506
|
-
* → (highlighted) distance labels → ancestor dots → leaf branch lines → leaf dots.
|
|
507
|
-
*
|
|
508
|
-
* When nodes are highlighted, non-highlighted shapes are dimmed via the
|
|
509
|
-
* theme's `dimFn`. Leaf dot colours come from the stratification's `caseIdColors`
|
|
510
|
-
* when available.
|
|
511
|
-
*
|
|
512
|
-
* @param params.canvas - The canvas element to draw onto.
|
|
513
|
-
* @param params.theme - MUI theme providing colours and font settings.
|
|
514
|
-
* @param params.treeAssembly - Pre-computed tree shapes from {@link assembleTree}.
|
|
515
|
-
* @param params.stratification - Colour mapping per case ID for leaf dots.
|
|
516
|
-
* @param params.zoomLevel - Current zoom level applied as a canvas transform.
|
|
517
|
-
* @param params.highlightedNodeNames - Node names to highlight; all others are dimmed.
|
|
518
|
-
* @param params.verticalScrollPosition - Vertical scroll offset in pixels.
|
|
519
|
-
* @param params.horizontalScrollPosition - Horizontal scroll offset in pixels.
|
|
520
|
-
* @param params.shouldShowDistances - Whether to render branch distance labels.
|
|
521
|
-
* @param params.devicePixelRatio - Screen DPR for crisp rendering on HiDPI displays.
|
|
522
|
-
* @param params.isLinked - Whether to draw the dashed support lines linking leaf nodes to the table.
|
|
523
|
-
*/
|
|
524
|
-
public static drawTree(params: {
|
|
525
|
-
canvas: HTMLCanvasElement;
|
|
526
|
-
theme: Theme;
|
|
527
|
-
treeAssembly: TreeAssembly;
|
|
528
|
-
stratification: Stratification;
|
|
529
|
-
zoomLevel: number;
|
|
530
|
-
highlightedNodeNames: string[];
|
|
531
|
-
verticalScrollPosition: number;
|
|
532
|
-
horizontalScrollPosition: number;
|
|
533
|
-
shouldShowDistances: boolean;
|
|
534
|
-
devicePixelRatio: number;
|
|
535
|
-
isLinked: boolean;
|
|
536
|
-
}): void {
|
|
537
|
-
const { canvas, theme, treeAssembly, stratification, zoomLevel, isLinked, verticalScrollPosition, horizontalScrollPosition, shouldShowDistances, devicePixelRatio, highlightedNodeNames = [] } = params;
|
|
538
|
-
const ctx = canvas.getContext('2d');
|
|
539
|
-
ctx.setTransform(
|
|
540
|
-
(1 / zoomLevel) * devicePixelRatio, // The scale factor(X direction)
|
|
541
|
-
0, // The skew factor (X-axis)
|
|
542
|
-
0, // The skew factor (Y-axis)
|
|
543
|
-
(1 / zoomLevel) * devicePixelRatio, // The scale factor(Y direction)
|
|
544
|
-
-horizontalScrollPosition + 0.5, // The translation (X direction)
|
|
545
|
-
-verticalScrollPosition + 0.5, // The translation (Y direction)
|
|
546
|
-
);
|
|
547
|
-
|
|
548
|
-
ctx.fillStyle = 'black';
|
|
549
|
-
ctx.strokeStyle = 'black';
|
|
550
|
-
ctx.textAlign = 'center';
|
|
551
|
-
ctx.font = theme['gen-epix'].tree.font;
|
|
552
|
-
ctx.lineWidth = 1;
|
|
553
|
-
|
|
554
|
-
treeAssembly.verticalAncestorTreeLines.forEach(({ shape, nodeNames }) => {
|
|
555
|
-
ctx.strokeStyle = EpiTreeUtil.getFillStyle(theme['gen-epix'].tree.color, theme['gen-epix'].tree.dimFn, highlightedNodeNames, nodeNames);
|
|
556
|
-
ctx.stroke(shape);
|
|
557
|
-
});
|
|
558
|
-
treeAssembly.horizontalAncestorTreeLines.forEach(({ shape, nodeNames }) => {
|
|
559
|
-
ctx.strokeStyle = EpiTreeUtil.getFillStyle(theme['gen-epix'].tree.color, theme['gen-epix'].tree.dimFn, highlightedNodeNames, nodeNames);
|
|
560
|
-
ctx.stroke(shape);
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
if (isLinked) {
|
|
564
|
-
treeAssembly.supportLines.forEach(({ nodeName, fromX, toX, y }) => {
|
|
565
|
-
ctx.setLineDash([1, 4]);
|
|
566
|
-
ctx.beginPath();
|
|
567
|
-
ctx.strokeStyle = EpiTreeUtil.getFillStyle(theme['gen-epix'].tree.color, theme['gen-epix'].tree.dimFn, highlightedNodeNames, nodeName);
|
|
568
|
-
ctx.moveTo(fromX, y);
|
|
569
|
-
ctx.lineTo(toX + (horizontalScrollPosition / devicePixelRatio), y);
|
|
570
|
-
ctx.stroke();
|
|
571
|
-
ctx.setLineDash([]);
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
if (shouldShowDistances) {
|
|
576
|
-
treeAssembly.distanceTexts.forEach(({ x, y, text, nodeNames }) => {
|
|
577
|
-
const isHighlighted = highlightedNodeNames.length && intersection(nodeNames, highlightedNodeNames).length > 0;
|
|
578
|
-
if (isHighlighted) {
|
|
579
|
-
ctx.fillStyle = theme['gen-epix'].tree.color;
|
|
580
|
-
ctx.fillText(text, x, y);
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
treeAssembly.ancestorNodes.forEach(({ shape, nodeNames }) => {
|
|
586
|
-
ctx.fillStyle = EpiTreeUtil.getFillStyle(theme['gen-epix'].tree.color, theme['gen-epix'].tree.dimFn, highlightedNodeNames, nodeNames);
|
|
587
|
-
ctx.fill(shape);
|
|
588
|
-
});
|
|
589
|
-
|
|
590
|
-
treeAssembly.leafTreeLines.forEach(({ shape, nodeName }) => {
|
|
591
|
-
ctx.strokeStyle = EpiTreeUtil.getFillStyle(theme['gen-epix'].tree.color, theme['gen-epix'].tree.dimFn, highlightedNodeNames, nodeName);
|
|
592
|
-
ctx.stroke(shape);
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
treeAssembly.leafNodes.forEach(({ shape, nodeName }) => {
|
|
596
|
-
ctx.fillStyle = EpiTreeUtil.getFillStyle(stratification?.caseIdColors?.[nodeName] ?? theme['gen-epix'].tree.color, theme['gen-epix'].tree.dimFn, highlightedNodeNames, nodeName);
|
|
597
|
-
ctx.fill(shape);
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* Returns the fill/stroke colour for a shape, dimming it when highlighted
|
|
603
|
-
* nodes are active and the shape is not among them.
|
|
604
|
-
*
|
|
605
|
-
* @param color - The full-brightness colour to use when highlighted or no highlight is active.
|
|
606
|
-
* @param dimFn - A function that returns a dimmed version of the colour.
|
|
607
|
-
* @param highlightedNodeNames - The currently highlighted node names.
|
|
608
|
-
* @param nodeNames - The node name(s) associated with the shape being drawn.
|
|
609
|
-
* @returns The resolved colour string.
|
|
610
|
-
*/
|
|
611
|
-
private static getFillStyle(color: string, dimFn: (color: string) => string, highlightedNodeNames: string[], nodeNames: string | string[]): string {
|
|
612
|
-
if (highlightedNodeNames.length) {
|
|
613
|
-
let isHighlighted = false;
|
|
614
|
-
if (Array.isArray(nodeNames)) {
|
|
615
|
-
isHighlighted = intersection(nodeNames, highlightedNodeNames).length > 0;
|
|
616
|
-
} else {
|
|
617
|
-
isHighlighted = highlightedNodeNames.includes(nodeNames);
|
|
618
|
-
}
|
|
619
|
-
if (isHighlighted) {
|
|
620
|
-
return color;
|
|
621
|
-
}
|
|
622
|
-
return dimFn(color);
|
|
623
|
-
}
|
|
624
|
-
return color;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
/**
|
|
628
|
-
* Fully redraws the tree canvas from scratch.
|
|
629
|
-
*
|
|
630
|
-
* Resets the canvas, resizes it to match its CSS layout size at the current
|
|
631
|
-
* DPR, then sequentially calls {@link drawBackground}, {@link drawGuides},
|
|
632
|
-
* and {@link drawTree}.
|
|
633
|
-
*
|
|
634
|
-
* @param params.canvas - The canvas element to draw onto.
|
|
635
|
-
* @param params.theme - MUI theme used for colours and fonts.
|
|
636
|
-
* @param params.treeAssembly - Pre-computed tree shapes from {@link assembleTree}.
|
|
637
|
-
* @param params.stratification - Colour mapping per case ID.
|
|
638
|
-
* @param params.zoomLevel - Current zoom level.
|
|
639
|
-
* @param params.isLinked - Whether to draw dashed support lines.
|
|
640
|
-
* @param params.highlightedNodeNames - Node names to highlight.
|
|
641
|
-
* @param params.verticalScrollPosition - Vertical scroll offset in pixels.
|
|
642
|
-
* @param params.horizontalScrollPosition - Horizontal scroll offset in pixels.
|
|
643
|
-
* @param params.treeCanvasWidth - Logical canvas width in pixels.
|
|
644
|
-
* @param params.treeCanvasHeight - Logical canvas height in pixels.
|
|
645
|
-
* @param params.pixelToGeneticDistanceRatio - Pixels per unit of genetic distance.
|
|
646
|
-
* @param params.tickerMarkScale - Scale tuple from {@link getTickMarkScale}.
|
|
647
|
-
* @param params.shouldShowDistances - Whether to render branch labels.
|
|
648
|
-
* @param params.devicePixelRatio - Screen DPR for HiDPI rendering.
|
|
649
|
-
* @param params.geneticTreeWidth - Total genetic width of the tree, used for guide lines.
|
|
650
|
-
*/
|
|
651
|
-
public static drawTreeCanvas(params: {
|
|
652
|
-
canvas: HTMLCanvasElement;
|
|
653
|
-
theme: Theme;
|
|
654
|
-
treeAssembly: TreeAssembly;
|
|
655
|
-
stratification: Stratification;
|
|
656
|
-
zoomLevel: number;
|
|
657
|
-
isLinked: boolean;
|
|
658
|
-
highlightedNodeNames?: string[];
|
|
659
|
-
verticalScrollPosition: number;
|
|
660
|
-
horizontalScrollPosition: number;
|
|
661
|
-
treeCanvasWidth: number;
|
|
662
|
-
treeCanvasHeight: number;
|
|
663
|
-
pixelToGeneticDistanceRatio: number;
|
|
664
|
-
tickerMarkScale: TickerMarkScale;
|
|
665
|
-
shouldShowDistances: boolean;
|
|
666
|
-
devicePixelRatio: number;
|
|
667
|
-
geneticTreeWidth: Decimal;
|
|
668
|
-
}): void {
|
|
669
|
-
const { devicePixelRatio, geneticTreeWidth, canvas, theme, treeAssembly, stratification, zoomLevel, isLinked, highlightedNodeNames, horizontalScrollPosition, verticalScrollPosition, treeCanvasWidth, treeCanvasHeight, tickerMarkScale, pixelToGeneticDistanceRatio, shouldShowDistances } = params;
|
|
670
|
-
const ctx = canvas.getContext('2d');
|
|
671
|
-
ctx.reset();
|
|
672
|
-
canvas.width = canvas.clientWidth * devicePixelRatio;
|
|
673
|
-
canvas.height = canvas.clientHeight * devicePixelRatio;
|
|
674
|
-
ctx.imageSmoothingEnabled = zoomLevel > 1;
|
|
675
|
-
ctx.imageSmoothingQuality = 'high';
|
|
676
|
-
|
|
677
|
-
EpiTreeUtil.drawBackground({ canvas, theme, treeCanvasWidth, treeCanvasHeight, devicePixelRatio });
|
|
678
|
-
EpiTreeUtil.drawGuides({ canvas, geneticTreeWidth, tickerMarkScale, pixelToGeneticDistanceRatio, devicePixelRatio, horizontalScrollPosition, zoomLevel });
|
|
679
|
-
EpiTreeUtil.drawTree({ canvas, theme, treeAssembly, stratification, highlightedNodeNames, zoomLevel, isLinked, horizontalScrollPosition, verticalScrollPosition, shouldShowDistances, devicePixelRatio });
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
/**
|
|
683
|
-
* Fills the tree canvas background with the theme's paper colour.
|
|
684
|
-
*
|
|
685
|
-
* @param params.canvas - The canvas element to draw onto.
|
|
686
|
-
* @param params.theme - MUI theme providing the background colour.
|
|
687
|
-
* @param params.treeCanvasWidth - Width of the area to fill in pixels.
|
|
688
|
-
* @param params.treeCanvasHeight - Height of the area to fill in pixels.
|
|
689
|
-
* @param params.devicePixelRatio - Screen DPR for HiDPI rendering.
|
|
690
|
-
*/
|
|
691
|
-
private static drawBackground(params: { canvas: HTMLCanvasElement; theme: Theme; treeCanvasWidth: number; treeCanvasHeight: number; devicePixelRatio: number }): void {
|
|
692
|
-
const { canvas, theme, treeCanvasWidth, treeCanvasHeight, devicePixelRatio } = params;
|
|
693
|
-
EpiTreeUtil.draw(canvas, devicePixelRatio, (ctx) => {
|
|
694
|
-
ctx.fillStyle = theme.palette.background.paper;
|
|
695
|
-
ctx.fillRect(0, 0, treeCanvasWidth, treeCanvasHeight);
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
/**
|
|
700
|
-
* Iterates over each scale line position and invokes a callback with its
|
|
701
|
-
* canvas X coordinate.
|
|
702
|
-
*
|
|
703
|
-
* Computes the pixel offset for each tick so that the rightmost line aligns
|
|
704
|
-
* with the genetic tree width, accounting for the current scroll and zoom.
|
|
705
|
-
*
|
|
706
|
-
* @param params.tickerMarkScale - Scale tuple from {@link getTickMarkScale}.
|
|
707
|
-
* @param params.geneticTreeWidth - Total genetic width of the tree.
|
|
708
|
-
* @param params.pixelToGeneticDistanceRatio - Pixels per unit of genetic distance.
|
|
709
|
-
* @param params.zoomLevel - Current zoom level.
|
|
710
|
-
* @param params.devicePixelRatio - Screen DPR.
|
|
711
|
-
* @param params.horizontalScrollPosition - Current horizontal scroll offset in pixels (default 0).
|
|
712
|
-
* @param params.callback - Called for each line with `(x, index, numberOfLines)`.
|
|
713
|
-
*/
|
|
714
|
-
private static forEachScaleLine(params: { tickerMarkScale: TickerMarkScale; geneticTreeWidth: Decimal; pixelToGeneticDistanceRatio: number; zoomLevel: number; devicePixelRatio: number; horizontalScrollPosition?: number; callback: (x: number, i: number, numberOfLines: number) => void }): void {
|
|
715
|
-
const { tickerMarkScale, geneticTreeWidth, pixelToGeneticDistanceRatio, zoomLevel, devicePixelRatio, horizontalScrollPosition = 0, callback } = params;
|
|
716
|
-
|
|
717
|
-
const numberOfLines = tickerMarkScale[0];
|
|
718
|
-
const tickerGeneticWidth = tickerMarkScale[1];
|
|
719
|
-
const tickerWidth = new Decimal(tickerGeneticWidth).times(pixelToGeneticDistanceRatio).div(zoomLevel);
|
|
720
|
-
const totalTickerWidth = tickerWidth.times(numberOfLines - 1);
|
|
721
|
-
const geneticTreeWidthPx = geneticTreeWidth.times(pixelToGeneticDistanceRatio).div(zoomLevel);
|
|
722
|
-
const offset = totalTickerWidth.minus(geneticTreeWidthPx);
|
|
723
|
-
|
|
724
|
-
for (let i = 0; i < numberOfLines; i++) {
|
|
725
|
-
const x = new Decimal(i).times(tickerWidth).plus(new Decimal(ConfigManager.instance.config.epiTree.TREE_PADDING).div(zoomLevel)).minus(offset).minus(new Decimal(horizontalScrollPosition).div(devicePixelRatio)).toNumber();
|
|
726
|
-
callback(x, i, numberOfLines);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
/**
|
|
731
|
-
* Draws vertical dashed guide lines on the canvas at each tick mark position.
|
|
732
|
-
*
|
|
733
|
-
* @param params.canvas - The canvas element to draw onto.
|
|
734
|
-
* @param params.tickerMarkScale - Scale tuple from {@link getTickMarkScale}.
|
|
735
|
-
* @param params.geneticTreeWidth - Total genetic width of the tree.
|
|
736
|
-
* @param params.pixelToGeneticDistanceRatio - Pixels per unit of genetic distance.
|
|
737
|
-
* @param params.devicePixelRatio - Screen DPR.
|
|
738
|
-
* @param params.paddingTop - Top inset in pixels to leave blank (default 0).
|
|
739
|
-
* @param params.paddingBottom - Bottom inset in pixels to leave blank (default 0).
|
|
740
|
-
* @param params.zoomLevel - Current zoom level.
|
|
741
|
-
* @param params.horizontalScrollPosition - Current horizontal scroll offset in pixels.
|
|
742
|
-
*/
|
|
743
|
-
public static drawGuides(params: { canvas: HTMLCanvasElement; tickerMarkScale: TickerMarkScale; geneticTreeWidth: Decimal; pixelToGeneticDistanceRatio: number; devicePixelRatio: number; paddingTop?: number; paddingBottom?: number; zoomLevel: number; horizontalScrollPosition: number }): void {
|
|
744
|
-
const { canvas, geneticTreeWidth, tickerMarkScale, pixelToGeneticDistanceRatio, zoomLevel, devicePixelRatio, paddingTop = 0, paddingBottom = 0, horizontalScrollPosition = 0 } = params;
|
|
745
|
-
|
|
746
|
-
EpiTreeUtil.draw(canvas, devicePixelRatio, (ctx) => {
|
|
747
|
-
ctx.strokeStyle = ConfigManager.instance.config.epiTree.REGULAR_FILL_COLOR_SUPPORT_LINE;
|
|
748
|
-
ctx.setLineDash([3, 1]);
|
|
749
|
-
EpiTreeUtil.forEachScaleLine({
|
|
750
|
-
tickerMarkScale,
|
|
751
|
-
geneticTreeWidth,
|
|
752
|
-
pixelToGeneticDistanceRatio,
|
|
753
|
-
zoomLevel,
|
|
754
|
-
devicePixelRatio,
|
|
755
|
-
horizontalScrollPosition,
|
|
756
|
-
callback: (x) => {
|
|
757
|
-
// Draw the guide lines
|
|
758
|
-
ctx.beginPath();
|
|
759
|
-
ctx.moveTo(x, paddingTop);
|
|
760
|
-
ctx.lineTo(x, canvas.height - paddingBottom);
|
|
761
|
-
ctx.stroke();
|
|
762
|
-
ctx.closePath();
|
|
763
|
-
},
|
|
764
|
-
});
|
|
765
|
-
ctx.setLineDash([0, 0]);
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
/**
|
|
770
|
-
* Draws the genetic distance scale labels onto the canvas header area.
|
|
771
|
-
*
|
|
772
|
-
* Labels are drawn in reverse order (right-to-left distance decreasing) so
|
|
773
|
-
* the leftmost label shows the largest genetic distance.
|
|
774
|
-
*
|
|
775
|
-
* @param params.canvas - The canvas element to draw onto.
|
|
776
|
-
* @param params.theme - MUI theme providing the font family.
|
|
777
|
-
* @param params.tickerMarkScale - Scale tuple from {@link getTickMarkScale}.
|
|
778
|
-
* @param params.geneticTreeWidth - Total genetic width of the tree.
|
|
779
|
-
* @param params.pixelToGeneticDistanceRatio - Pixels per unit of genetic distance.
|
|
780
|
-
* @param params.zoomLevel - Current zoom level.
|
|
781
|
-
* @param params.devicePixelRatio - Screen DPR.
|
|
782
|
-
* @param params.horizontalScrollPosition - Current horizontal scroll offset in pixels.
|
|
783
|
-
*/
|
|
784
|
-
public static drawScale(params: { canvas: HTMLCanvasElement; theme: Theme; tickerMarkScale: TickerMarkScale; geneticTreeWidth: Decimal; pixelToGeneticDistanceRatio: number; zoomLevel: number; devicePixelRatio: number; horizontalScrollPosition: number }): void {
|
|
785
|
-
const { canvas, theme, tickerMarkScale, geneticTreeWidth, pixelToGeneticDistanceRatio, devicePixelRatio, zoomLevel, horizontalScrollPosition = 0 } = params;
|
|
786
|
-
EpiTreeUtil.draw(canvas, devicePixelRatio, (ctx) => {
|
|
787
|
-
EpiTreeUtil.forEachScaleLine({
|
|
788
|
-
tickerMarkScale,
|
|
789
|
-
geneticTreeWidth,
|
|
790
|
-
pixelToGeneticDistanceRatio,
|
|
791
|
-
zoomLevel,
|
|
792
|
-
devicePixelRatio,
|
|
793
|
-
horizontalScrollPosition,
|
|
794
|
-
callback: (x, i, numberOfLines) => {
|
|
795
|
-
ctx.beginPath();
|
|
796
|
-
ctx.textAlign = 'center';
|
|
797
|
-
ctx.font = `bold 11px ${theme.typography.fontFamily}`;
|
|
798
|
-
const label = new Decimal(tickerMarkScale[1]).times((numberOfLines - 1) - i).toNumber();
|
|
799
|
-
ctx.fillText(NumberUtil.toStringWithPrecision(label, tickerMarkScale[2]), x, ConfigManager.instance.config.epiTree.HEADER_HEIGHT * 0.61);
|
|
800
|
-
ctx.closePath();
|
|
801
|
-
},
|
|
802
|
-
});
|
|
803
|
-
});
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
/**
|
|
807
|
-
* Draws a thin horizontal divider line across the full canvas width.
|
|
808
|
-
*
|
|
809
|
-
* Used to visually separate the scale header from the tree body.
|
|
810
|
-
*
|
|
811
|
-
* @param params.canvas - The canvas element to draw onto.
|
|
812
|
-
* @param params.y - Vertical position of the divider in logical pixels.
|
|
813
|
-
* @param params.devicePixelRatio - Screen DPR for correct positioning.
|
|
814
|
-
*/
|
|
815
|
-
public static drawDivider(params: { canvas: HTMLCanvasElement; y: number; devicePixelRatio: number }): void {
|
|
816
|
-
const { canvas, y, devicePixelRatio } = params;
|
|
817
|
-
|
|
818
|
-
EpiTreeUtil.draw(canvas, devicePixelRatio, (ctx) => {
|
|
819
|
-
ctx.strokeStyle = '#EEEEEE';
|
|
820
|
-
ctx.lineWidth = 1;
|
|
821
|
-
ctx.beginPath();
|
|
822
|
-
ctx.moveTo(0, y);
|
|
823
|
-
ctx.lineTo(canvas.width, y);
|
|
824
|
-
ctx.stroke();
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
/**
|
|
829
|
-
* Helper that wraps a canvas drawing callback with a DPR-aware scale/translate
|
|
830
|
-
* transform, then restores the context to its pre-call state.
|
|
831
|
-
*
|
|
832
|
-
* @param canvas - The canvas element whose 2D context to use.
|
|
833
|
-
* @param devicePixelRatio - Screen DPR to scale up for HiDPI rendering.
|
|
834
|
-
* @param callback - Drawing operations to perform inside the transform.
|
|
835
|
-
*/
|
|
836
|
-
private static draw(canvas: HTMLCanvasElement, devicePixelRatio: number, callback: (ctx: CanvasRenderingContext2D) => void): void {
|
|
837
|
-
const ctx = canvas.getContext('2d');
|
|
838
|
-
ctx.scale(devicePixelRatio, devicePixelRatio);
|
|
839
|
-
ctx.translate(0.5, 0.5);
|
|
840
|
-
callback(ctx);
|
|
841
|
-
ctx.translate(-0.5, -0.5);
|
|
842
|
-
ctx.scale(1 / devicePixelRatio, 1 / devicePixelRatio);
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* Calculates the new scroll position after a zoom level change so that the
|
|
847
|
-
* point under the cursor stays in the same visual position.
|
|
848
|
-
*
|
|
849
|
-
* @param params.eventOffset - Pixel offset of the zoom event (e.g. mouse position) within the canvas.
|
|
850
|
-
* @param params.scrollPosition - Current scroll position before the zoom change.
|
|
851
|
-
* @param params.dimensionSize - Full logical size of the scrollable dimension in pixels.
|
|
852
|
-
* @param params.currentZoomLevel - The zoom level before the change.
|
|
853
|
-
* @param params.newZoomLevel - The zoom level after the change.
|
|
854
|
-
* @returns The adjusted scroll position that keeps the cursor-point visually stable.
|
|
855
|
-
*/
|
|
856
|
-
public static getNewScrollPositionForZoomLevel(params: { eventOffset: number; scrollPosition: number; dimensionSize: number; currentZoomLevel: number; newZoomLevel: number }): number {
|
|
857
|
-
const { eventOffset, scrollPosition, dimensionSize, currentZoomLevel, newZoomLevel } = params;
|
|
858
|
-
|
|
859
|
-
const fullSizeTreePosition = ((eventOffset * devicePixelRatio) + scrollPosition) * currentZoomLevel;
|
|
860
|
-
const currentSizeTreePosition = fullSizeTreePosition / (dimensionSize / (dimensionSize / currentZoomLevel));
|
|
861
|
-
const newSizeTreePosition = fullSizeTreePosition / (dimensionSize / (dimensionSize / newZoomLevel));
|
|
862
|
-
return scrollPosition - (currentSizeTreePosition - newSizeTreePosition);
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
/**
|
|
866
|
-
* Clamps X and Y scroll positions to their valid ranges for the current
|
|
867
|
-
* canvas dimensions, zoom level, and link state.
|
|
868
|
-
*
|
|
869
|
-
* When the tree is linked and at zoom level 1, y-scrolling is constrained
|
|
870
|
-
* tightly to the tree's pixel height. When unlinked or zoomed, the bounds
|
|
871
|
-
* include the full canvas extent to allow free panning.
|
|
872
|
-
*
|
|
873
|
-
* Also applies a device-pixel-ratio-dependent correction offset to prevent
|
|
874
|
-
* subtle over-scroll artefacts at non-integer DPR values (e.g. browser zoom).
|
|
875
|
-
*
|
|
876
|
-
* @param params.positionX - Requested horizontal scroll position.
|
|
877
|
-
* @param params.positionY - Requested vertical scroll position.
|
|
878
|
-
* @param params.treeCanvasWidth - Logical canvas width in pixels.
|
|
879
|
-
* @param params.treeCanvasHeight - Logical canvas height in pixels.
|
|
880
|
-
* @param params.treeHeight - Total rendered height of the full tree in pixels.
|
|
881
|
-
* @param params.devicePixelRatio - Current screen DPR.
|
|
882
|
-
* @param params.internalZoomLevel - Internal zoom level of the tree canvas.
|
|
883
|
-
* @param params.isLinked - Whether the tree is linked to the case list scroll position.
|
|
884
|
-
* @returns Clamped `{ newPositionX, newPositionY }` values.
|
|
885
|
-
*/
|
|
886
|
-
public static getSanitizedScrollPosition(params: { positionX: number; positionY: number; treeCanvasWidth: number; treeCanvasHeight: number; treeHeight: number; devicePixelRatio: number; internalZoomLevel: number; isLinked: boolean }): { newPositionX: number; newPositionY: number } {
|
|
887
|
-
const { positionX, positionY, treeCanvasWidth, treeCanvasHeight, treeHeight, devicePixelRatio, internalZoomLevel, isLinked } = params;
|
|
888
|
-
let positionYMax: number;
|
|
889
|
-
let positionYMin: number;
|
|
890
|
-
|
|
891
|
-
const relativeTreePadding = ((ConfigManager.instance.config.epiTree.TREE_PADDING) * devicePixelRatio);
|
|
892
|
-
|
|
893
|
-
if (isLinked && internalZoomLevel === 1) {
|
|
894
|
-
if (treeHeight < treeCanvasHeight) {
|
|
895
|
-
positionYMin = 0;
|
|
896
|
-
positionYMax = 0;
|
|
897
|
-
} else {
|
|
898
|
-
// some magic needs to be done here to prevent the tree from scrolling too far. I can't detect the exact reason, but it seems to be related to the devicePixelRatio
|
|
899
|
-
// this only happens when you use the zoom functionality of the browser
|
|
900
|
-
const roundedDevicePixelRatio = Math.round(devicePixelRatio * 100) / 100;
|
|
901
|
-
const thresholds = [
|
|
902
|
-
[1, 0],
|
|
903
|
-
[1.1, 1],
|
|
904
|
-
[1.25, 4],
|
|
905
|
-
[1.5, 7],
|
|
906
|
-
[1.75, 11],
|
|
907
|
-
[2, 0],
|
|
908
|
-
[2.2, 4],
|
|
909
|
-
[2.5, 7],
|
|
910
|
-
[3, 15],
|
|
911
|
-
];
|
|
912
|
-
const divePixelRatioOffset = thresholds.find(([threshold]) => roundedDevicePixelRatio <= threshold)?.[1] ?? 0;
|
|
913
|
-
|
|
914
|
-
positionYMin = 0;
|
|
915
|
-
positionYMax = (treeHeight * devicePixelRatio) - ((treeCanvasHeight) * devicePixelRatio) - divePixelRatioOffset;
|
|
916
|
-
}
|
|
917
|
-
} else {
|
|
918
|
-
positionYMin = (-treeCanvasHeight * devicePixelRatio) + relativeTreePadding + (ConfigManager.instance.config.epiTree.HEADER_HEIGHT * devicePixelRatio);
|
|
919
|
-
positionYMax = ((treeHeight / internalZoomLevel) * devicePixelRatio) - relativeTreePadding - (ConfigManager.instance.config.epiTree.HEADER_HEIGHT * devicePixelRatio);
|
|
920
|
-
}
|
|
921
|
-
const newPositionY = Math.max(Math.min(positionYMax, positionY), positionYMin);
|
|
922
|
-
|
|
923
|
-
const positionXMin = -treeCanvasWidth + (2 * relativeTreePadding);
|
|
924
|
-
const positionXMax = ((treeCanvasWidth / internalZoomLevel) * devicePixelRatio) - (2 * relativeTreePadding);
|
|
925
|
-
const newPositionX = Math.max(Math.min(positionXMax, positionX), positionXMin);
|
|
926
|
-
|
|
927
|
-
return {
|
|
928
|
-
newPositionX,
|
|
929
|
-
newPositionY,
|
|
930
|
-
};
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
/**
|
|
934
|
-
* Performs a hit-test against the tree assembly's path maps to find the
|
|
935
|
-
* tree node or line segment under the mouse cursor.
|
|
936
|
-
*
|
|
937
|
-
* Checks in priority order: node dots (via `isPointInPath`) → horizontal
|
|
938
|
-
* branch lines (with ±1 px vertical tolerance) → vertical connector lines
|
|
939
|
-
* (with ±1 px horizontal tolerance).
|
|
940
|
-
*
|
|
941
|
-
* @param params.canvas - The canvas element that received the mouse event.
|
|
942
|
-
* @param params.event - The mouse event providing cursor coordinates.
|
|
943
|
-
* @param params.treeAssembly - The assembly containing path maps to hit-test against.
|
|
944
|
-
* @param params.devicePixelRatio - Screen DPR for correct coordinate scaling.
|
|
945
|
-
* @returns The {@link TreePathProperties} of the hit shape, or `undefined` if nothing was hit.
|
|
946
|
-
*/
|
|
947
|
-
public static getPathPropertiesFromCanvas(params: { canvas: HTMLCanvasElement; event: MouseEvent; treeAssembly: TreeAssembly; devicePixelRatio: number }): TreePathProperties {
|
|
948
|
-
const { canvas, event, treeAssembly, devicePixelRatio } = params;
|
|
949
|
-
|
|
950
|
-
const ctx = canvas.getContext('2d');
|
|
951
|
-
const rect = (event.target as HTMLCanvasElement).getBoundingClientRect();
|
|
952
|
-
const canvasX = (event.clientX - rect.left) * devicePixelRatio;
|
|
953
|
-
const canvasY = (event.clientY - rect.top) * devicePixelRatio;
|
|
954
|
-
|
|
955
|
-
for (const path of treeAssembly.nodePathPropertiesMap.keys()) {
|
|
956
|
-
if (ctx.isPointInPath(path, canvasX, canvasY)) {
|
|
957
|
-
return treeAssembly.nodePathPropertiesMap.get(path);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
// Allow for a 1px vertical margin around the mouse position to allow for easier clicking
|
|
962
|
-
const canvasYs = [
|
|
963
|
-
((event.clientY - 1) - rect.top) * devicePixelRatio,
|
|
964
|
-
canvasY,
|
|
965
|
-
((event.clientY + 1) - rect.top) * devicePixelRatio,
|
|
966
|
-
];
|
|
967
|
-
|
|
968
|
-
for (const path of treeAssembly.horizontalLinePathPropertiesMap.keys()) {
|
|
969
|
-
for (const y of canvasYs) {
|
|
970
|
-
if (ctx.isPointInStroke(path, canvasX, y)) {
|
|
971
|
-
return treeAssembly.horizontalLinePathPropertiesMap.get(path);
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
// Allow for a 1px horizontal margin around the mouse position to allow for easier clicking
|
|
977
|
-
const canvasXs = [
|
|
978
|
-
((event.clientX - 1) - rect.left) * devicePixelRatio,
|
|
979
|
-
canvasX,
|
|
980
|
-
((event.clientX + 1) - rect.left) * devicePixelRatio,
|
|
981
|
-
];
|
|
982
|
-
for (const path of treeAssembly.verticalLinePathPropertiesMap.keys()) {
|
|
983
|
-
for (const x of canvasXs) {
|
|
984
|
-
if (ctx.isPointInStroke(path, x, canvasY)) {
|
|
985
|
-
return treeAssembly.verticalLinePathPropertiesMap.get(path);
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
/**
|
|
993
|
-
* Derives all possible tree configurations for the given case type.
|
|
994
|
-
*
|
|
995
|
-
* Iterates over all columns of type `GENETIC_DISTANCE`, then for each column
|
|
996
|
-
* produces one {@link TreeConfiguration} per available tree algorithm.
|
|
997
|
-
* Algorithms are sorted by their canonical order from `EpiDataManager`.
|
|
998
|
-
*
|
|
999
|
-
* @param completeCaseType - The fully-loaded case type containing columns,
|
|
1000
|
-
* reference columns, genetic distance protocols, and tree algorithms.
|
|
1001
|
-
* @returns An array of tree configurations, one per (column × algorithm) pair.
|
|
1002
|
-
*/
|
|
1003
|
-
public static getTreeConfigurations(completeCaseType: CompleteCaseType): TreeConfiguration[] {
|
|
1004
|
-
const treeConfigurations: TreeConfiguration[] = [];
|
|
1005
|
-
|
|
1006
|
-
const geneticDistanceCols = Object.values(completeCaseType.cols).filter(col => {
|
|
1007
|
-
const refCol = completeCaseType.ref_cols[col.ref_col_id];
|
|
1008
|
-
return refCol.col_type === ColType.GENETIC_DISTANCE;
|
|
1009
|
-
});
|
|
1010
|
-
|
|
1011
|
-
const sortedTreeAlgorithmCodes = EpiDataManager.instance.data.treeAlgorithms.map(x => x.code);
|
|
1012
|
-
|
|
1013
|
-
geneticDistanceCols.forEach(col => {
|
|
1014
|
-
const refCol = completeCaseType.ref_cols[col.ref_col_id];
|
|
1015
|
-
const geneticDistanceProtocol = completeCaseType.genetic_distance_protocols[refCol.genetic_distance_protocol_id];
|
|
1016
|
-
const treeAlgorithms = [...col.tree_algorithm_codes].sort((a, b) => {
|
|
1017
|
-
return sortedTreeAlgorithmCodes.indexOf(a) - sortedTreeAlgorithmCodes.indexOf(b);
|
|
1018
|
-
}).map(treeAlgorithmCode => completeCaseType.tree_algorithms[treeAlgorithmCode]);
|
|
1019
|
-
|
|
1020
|
-
treeAlgorithms.forEach(treeAlgorithm => {
|
|
1021
|
-
treeConfigurations.push({
|
|
1022
|
-
computedId: EpiTreeUtil.getTreeConfigurationId({ col, refCol, geneticDistanceProtocol, treeAlgorithm }),
|
|
1023
|
-
col,
|
|
1024
|
-
refCol,
|
|
1025
|
-
geneticDistanceProtocol,
|
|
1026
|
-
treeAlgorithm,
|
|
1027
|
-
});
|
|
1028
|
-
});
|
|
1029
|
-
});
|
|
1030
|
-
|
|
1031
|
-
return treeConfigurations;
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
/**
|
|
1035
|
-
* Produces a stable, unique string ID for a tree configuration by
|
|
1036
|
-
* concatenating the IDs of its column, reference column, genetic distance
|
|
1037
|
-
* protocol, and tree algorithm.
|
|
1038
|
-
*
|
|
1039
|
-
* @param treeConfiguration - The configuration to identify (without a pre-existing `computedId`).
|
|
1040
|
-
* @returns A string of the form `"colId_refColId_protocolId_algorithmId"`.
|
|
1041
|
-
*/
|
|
1042
|
-
public static getTreeConfigurationId(treeConfiguration: Omit<TreeConfiguration, 'computedId'>): string {
|
|
1043
|
-
return `${treeConfiguration.col.id}_${treeConfiguration.refCol.id}_${treeConfiguration.geneticDistanceProtocol.id}_${treeConfiguration.treeAlgorithm.id}`;
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
/**
|
|
1047
|
-
* Returns a human-readable display label for a tree configuration.
|
|
1048
|
-
*
|
|
1049
|
-
* @param config - The tree configuration to label.
|
|
1050
|
-
* @returns A string of the form `"<protocolName> - <algorithmName>"`.
|
|
1051
|
-
*/
|
|
1052
|
-
public static getTreeConfigurationLabel(config: TreeConfiguration): string {
|
|
1053
|
-
return `${config.geneticDistanceProtocol.name} - ${config.treeAlgorithm.name}`;
|
|
1054
|
-
}
|
|
1055
|
-
}
|