@tetrascience-npm/tetrascience-react-ui 0.5.0-beta.19.1 → 0.5.0-beta.21.1
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/components/charts/AreaGraph/AreaGraph.cjs +2 -0
- package/dist/components/charts/AreaGraph/AreaGraph.cjs.map +1 -0
- package/dist/components/charts/AreaGraph/AreaGraph.js +209 -0
- package/dist/components/charts/AreaGraph/AreaGraph.js.map +1 -0
- package/dist/components/charts/BarGraph/BarGraph.cjs +2 -0
- package/dist/components/charts/BarGraph/BarGraph.cjs.map +1 -0
- package/dist/components/charts/BarGraph/BarGraph.js +175 -0
- package/dist/components/charts/BarGraph/BarGraph.js.map +1 -0
- package/dist/components/charts/Boxplot/Boxplot.cjs +2 -0
- package/dist/components/charts/Boxplot/Boxplot.cjs.map +1 -0
- package/dist/components/charts/Boxplot/Boxplot.js +171 -0
- package/dist/components/charts/Boxplot/Boxplot.js.map +1 -0
- package/dist/components/charts/Chromatogram/Chromatogram.cjs +2 -0
- package/dist/components/charts/Chromatogram/Chromatogram.cjs.map +1 -0
- package/dist/components/charts/Chromatogram/Chromatogram.js +164 -0
- package/dist/components/charts/Chromatogram/Chromatogram.js.map +1 -0
- package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs +2 -0
- package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs.map +1 -0
- package/dist/components/charts/ChromatogramChart/ChromatogramChart.js +219 -0
- package/dist/components/charts/ChromatogramChart/ChromatogramChart.js.map +1 -0
- package/dist/components/charts/ChromatogramChart/annotations.cjs +2 -0
- package/dist/components/charts/ChromatogramChart/annotations.cjs.map +1 -0
- package/dist/components/charts/ChromatogramChart/annotations.js +73 -0
- package/dist/components/charts/ChromatogramChart/annotations.js.map +1 -0
- package/dist/components/charts/ChromatogramChart/boundaryMarkers.cjs +2 -0
- package/dist/components/charts/ChromatogramChart/boundaryMarkers.cjs.map +1 -0
- package/dist/components/charts/ChromatogramChart/boundaryMarkers.js +34 -0
- package/dist/components/charts/ChromatogramChart/boundaryMarkers.js.map +1 -0
- package/dist/components/charts/ChromatogramChart/constants.cjs +2 -0
- package/dist/components/charts/ChromatogramChart/constants.cjs.map +1 -0
- package/dist/components/charts/ChromatogramChart/constants.js +24 -0
- package/dist/components/charts/ChromatogramChart/constants.js.map +1 -0
- package/dist/components/charts/ChromatogramChart/dataProcessing.cjs +2 -0
- package/dist/components/charts/ChromatogramChart/dataProcessing.cjs.map +1 -0
- package/dist/components/charts/ChromatogramChart/dataProcessing.js +90 -0
- package/dist/components/charts/ChromatogramChart/dataProcessing.js.map +1 -0
- package/dist/components/charts/ChromatogramChart/peakDetection.cjs +2 -0
- package/dist/components/charts/ChromatogramChart/peakDetection.cjs.map +1 -0
- package/dist/components/charts/ChromatogramChart/peakDetection.js +89 -0
- package/dist/components/charts/ChromatogramChart/peakDetection.js.map +1 -0
- package/dist/components/charts/DotPlot/DotPlot.cjs +2 -0
- package/dist/components/charts/DotPlot/DotPlot.cjs.map +1 -0
- package/dist/components/charts/DotPlot/DotPlot.js +184 -0
- package/dist/components/charts/DotPlot/DotPlot.js.map +1 -0
- package/dist/components/charts/Heatmap/Heatmap.cjs +2 -0
- package/dist/components/charts/Heatmap/Heatmap.cjs.map +1 -0
- package/dist/components/charts/Heatmap/Heatmap.js +67 -0
- package/dist/components/charts/Heatmap/Heatmap.js.map +1 -0
- package/dist/components/charts/Histogram/Histogram.cjs +2 -0
- package/dist/components/charts/Histogram/Histogram.cjs.map +1 -0
- package/dist/components/charts/Histogram/Histogram.js +209 -0
- package/dist/components/charts/Histogram/Histogram.js.map +1 -0
- package/dist/components/charts/LineGraph/LineGraph.cjs +2 -0
- package/dist/components/charts/LineGraph/LineGraph.cjs.map +1 -0
- package/dist/components/charts/LineGraph/LineGraph.js +185 -0
- package/dist/components/charts/LineGraph/LineGraph.js.map +1 -0
- package/dist/components/charts/PieChart/PieChart.cjs +2 -0
- package/dist/components/charts/PieChart/PieChart.cjs.map +1 -0
- package/dist/components/charts/PieChart/PieChart.js +106 -0
- package/dist/components/charts/PieChart/PieChart.js.map +1 -0
- package/dist/components/charts/PlateMap/PlateMap.cjs +2 -0
- package/dist/components/charts/PlateMap/PlateMap.cjs.map +1 -0
- package/dist/components/charts/PlateMap/PlateMap.js +450 -0
- package/dist/components/charts/PlateMap/PlateMap.js.map +1 -0
- package/dist/components/charts/PlateMap/constants.cjs +2 -0
- package/dist/components/charts/PlateMap/constants.cjs.map +1 -0
- package/dist/components/charts/PlateMap/constants.js +137 -0
- package/dist/components/charts/PlateMap/constants.js.map +1 -0
- package/dist/components/charts/PlateMap/types.cjs +2 -0
- package/dist/components/charts/PlateMap/types.cjs.map +1 -0
- package/dist/components/charts/PlateMap/types.js +8 -0
- package/dist/components/charts/PlateMap/types.js.map +1 -0
- package/dist/components/charts/PlateMap/utils.cjs +2 -0
- package/dist/components/charts/PlateMap/utils.cjs.map +1 -0
- package/dist/components/charts/PlateMap/utils.js +235 -0
- package/dist/components/charts/PlateMap/utils.js.map +1 -0
- package/dist/components/charts/ScatterGraph/ScatterGraph.cjs +2 -0
- package/dist/components/charts/ScatterGraph/ScatterGraph.cjs.map +1 -0
- package/dist/components/charts/ScatterGraph/ScatterGraph.js +186 -0
- package/dist/components/charts/ScatterGraph/ScatterGraph.js.map +1 -0
- package/dist/components/composed/AppHeader/AppHeader.cjs +2 -0
- package/dist/components/composed/AppHeader/AppHeader.cjs.map +1 -0
- package/dist/components/composed/AppHeader/AppHeader.js +35 -0
- package/dist/components/composed/AppHeader/AppHeader.js.map +1 -0
- package/dist/components/composed/AppLayout/AppLayout.cjs +2 -0
- package/dist/components/composed/AppLayout/AppLayout.cjs.map +1 -0
- package/dist/components/composed/AppLayout/AppLayout.js +65 -0
- package/dist/components/composed/AppLayout/AppLayout.js.map +1 -0
- package/dist/components/composed/AssistantModal/AssistantModal.cjs +2 -0
- package/dist/components/composed/AssistantModal/AssistantModal.cjs.map +1 -0
- package/dist/components/composed/AssistantModal/AssistantModal.js +75 -0
- package/dist/components/composed/AssistantModal/AssistantModal.js.map +1 -0
- package/dist/components/composed/CodeScriptEditorButton/CodeScriptEditorButton.cjs +3 -0
- package/dist/components/composed/CodeScriptEditorButton/CodeScriptEditorButton.cjs.map +1 -0
- package/dist/components/composed/CodeScriptEditorButton/CodeScriptEditorButton.js +74 -0
- package/dist/components/composed/CodeScriptEditorButton/CodeScriptEditorButton.js.map +1 -0
- package/dist/components/composed/LaunchContent/LaunchContent.cjs +6 -0
- package/dist/components/composed/LaunchContent/LaunchContent.cjs.map +1 -0
- package/dist/components/composed/LaunchContent/LaunchContent.js +66 -0
- package/dist/components/composed/LaunchContent/LaunchContent.js.map +1 -0
- package/dist/components/composed/Main/LaunchContentPanel.cjs +6 -0
- package/dist/components/composed/Main/LaunchContentPanel.cjs.map +1 -0
- package/dist/components/composed/Main/LaunchContentPanel.js +63 -0
- package/dist/components/composed/Main/LaunchContentPanel.js.map +1 -0
- package/dist/components/composed/Main/Main.cjs +2 -0
- package/dist/components/composed/Main/Main.cjs.map +1 -0
- package/dist/components/composed/Main/Main.js +276 -0
- package/dist/components/composed/Main/Main.js.map +1 -0
- package/dist/components/composed/Main/MainHeader.cjs +2 -0
- package/dist/components/composed/Main/MainHeader.cjs.map +1 -0
- package/dist/components/composed/Main/MainHeader.js +36 -0
- package/dist/components/composed/Main/MainHeader.js.map +1 -0
- package/dist/components/composed/Main/MainNavbar.cjs +2 -0
- package/dist/components/composed/Main/MainNavbar.cjs.map +1 -0
- package/dist/components/composed/Main/MainNavbar.js +25 -0
- package/dist/components/composed/Main/MainNavbar.js.map +1 -0
- package/dist/components/composed/Main/MainSidebar.cjs +2 -0
- package/dist/components/composed/Main/MainSidebar.cjs.map +1 -0
- package/dist/components/composed/Main/MainSidebar.js +12 -0
- package/dist/components/composed/Main/MainSidebar.js.map +1 -0
- package/dist/components/composed/Main/MainTabBar.cjs +2 -0
- package/dist/components/composed/Main/MainTabBar.cjs.map +1 -0
- package/dist/components/composed/Main/MainTabBar.js +7 -0
- package/dist/components/composed/Main/MainTabBar.js.map +1 -0
- package/dist/components/composed/Main/ProtocolConfigurationPanel.cjs +2 -0
- package/dist/components/composed/Main/ProtocolConfigurationPanel.cjs.map +1 -0
- package/dist/components/composed/Main/ProtocolConfigurationPanel.js +30 -0
- package/dist/components/composed/Main/ProtocolConfigurationPanel.js.map +1 -0
- package/dist/components/composed/Main/TemplateSidebarCard.cjs +2 -0
- package/dist/components/composed/Main/TemplateSidebarCard.cjs.map +1 -0
- package/dist/components/composed/Main/TemplateSidebarCard.js +71 -0
- package/dist/components/composed/Main/TemplateSidebarCard.js.map +1 -0
- package/dist/components/composed/Navbar/Navbar.cjs +2 -0
- package/dist/components/composed/Navbar/Navbar.cjs.map +1 -0
- package/dist/components/composed/Navbar/Navbar.js +25 -0
- package/dist/components/composed/Navbar/Navbar.js.map +1 -0
- package/dist/components/composed/ProtocolConfiguration/ProtocolConfiguration.cjs +2 -0
- package/dist/components/composed/ProtocolConfiguration/ProtocolConfiguration.cjs.map +1 -0
- package/dist/components/composed/ProtocolConfiguration/ProtocolConfiguration.js +44 -0
- package/dist/components/composed/ProtocolConfiguration/ProtocolConfiguration.js.map +1 -0
- package/dist/components/composed/ProtocolYamlCard/ProtocolYamlCard.cjs +2 -0
- package/dist/components/composed/ProtocolYamlCard/ProtocolYamlCard.cjs.map +1 -0
- package/dist/components/composed/ProtocolYamlCard/ProtocolYamlCard.js +53 -0
- package/dist/components/composed/ProtocolYamlCard/ProtocolYamlCard.js.map +1 -0
- package/dist/components/composed/PythonEditorModal/PythonEditorModal.cjs +2 -0
- package/dist/components/composed/PythonEditorModal/PythonEditorModal.cjs.map +1 -0
- package/dist/components/composed/PythonEditorModal/PythonEditorModal.js +51 -0
- package/dist/components/composed/PythonEditorModal/PythonEditorModal.js.map +1 -0
- package/dist/components/composed/Sidebar/Sidebar.cjs +2 -0
- package/dist/components/composed/Sidebar/Sidebar.cjs.map +1 -0
- package/dist/components/composed/Sidebar/Sidebar.js +46 -0
- package/dist/components/composed/Sidebar/Sidebar.js.map +1 -0
- package/dist/components/composed/TdpSearch/TdpSearch.cjs +2 -0
- package/dist/components/composed/TdpSearch/TdpSearch.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/TdpSearch.js +97 -0
- package/dist/components/composed/TdpSearch/TdpSearch.js.map +1 -0
- package/dist/components/composed/TdpSearch/components/DefaultFilters.cjs +2 -0
- package/dist/components/composed/TdpSearch/components/DefaultFilters.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/components/DefaultFilters.js +31 -0
- package/dist/components/composed/TdpSearch/components/DefaultFilters.js.map +1 -0
- package/dist/components/composed/TdpSearch/components/DefaultResults.cjs +2 -0
- package/dist/components/composed/TdpSearch/components/DefaultResults.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/components/DefaultResults.js +107 -0
- package/dist/components/composed/TdpSearch/components/DefaultResults.js.map +1 -0
- package/dist/components/composed/TdpSearch/components/DefaultSearchBar.cjs +2 -0
- package/dist/components/composed/TdpSearch/components/DefaultSearchBar.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/components/DefaultSearchBar.js +32 -0
- package/dist/components/composed/TdpSearch/components/DefaultSearchBar.js.map +1 -0
- package/dist/components/composed/TdpSearch/constants.cjs +2 -0
- package/dist/components/composed/TdpSearch/constants.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/constants.js +7 -0
- package/dist/components/composed/TdpSearch/constants.js.map +1 -0
- package/dist/components/composed/TdpSearch/hooks/useSearch.cjs +2 -0
- package/dist/components/composed/TdpSearch/hooks/useSearch.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/hooks/useSearch.js +52 -0
- package/dist/components/composed/TdpSearch/hooks/useSearch.js.map +1 -0
- package/dist/components/composed/TdpSearch/hooks/useTdpCredentials.cjs +2 -0
- package/dist/components/composed/TdpSearch/hooks/useTdpCredentials.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/hooks/useTdpCredentials.js +29 -0
- package/dist/components/composed/TdpSearch/hooks/useTdpCredentials.js.map +1 -0
- package/dist/components/composed/TdpSearch/utils.cjs +2 -0
- package/dist/components/composed/TdpSearch/utils.cjs.map +1 -0
- package/dist/components/composed/TdpSearch/utils.js +15 -0
- package/dist/components/composed/TdpSearch/utils.js.map +1 -0
- package/dist/components/composed/tdp-link.cjs +2 -0
- package/dist/components/composed/tdp-link.cjs.map +1 -0
- package/dist/components/composed/tdp-link.js +84 -0
- package/dist/components/composed/tdp-link.js.map +1 -0
- package/dist/components/composed/tdp-url.cjs +2 -0
- package/dist/components/composed/tdp-url.cjs.map +1 -0
- package/dist/components/composed/tdp-url.js +76 -0
- package/dist/components/composed/tdp-url.js.map +1 -0
- package/dist/components/ui/accordion.cjs +2 -0
- package/dist/components/ui/accordion.cjs.map +1 -0
- package/dist/components/ui/accordion.js +83 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/alert-dialog.cjs +2 -0
- package/dist/components/ui/alert-dialog.cjs.map +1 -0
- package/dist/components/ui/alert-dialog.js +181 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/alert.cjs +2 -0
- package/dist/components/ui/alert.cjs.map +1 -0
- package/dist/components/ui/alert.js +78 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/aspect-ratio.cjs +2 -0
- package/dist/components/ui/aspect-ratio.cjs.map +1 -0
- package/dist/components/ui/aspect-ratio.js +11 -0
- package/dist/components/ui/aspect-ratio.js.map +1 -0
- package/dist/components/ui/avatar.cjs +2 -0
- package/dist/components/ui/avatar.cjs.map +1 -0
- package/dist/components/ui/avatar.js +107 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.cjs +2 -0
- package/dist/components/ui/badge.cjs.map +1 -0
- package/dist/components/ui/badge.js +44 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/breadcrumb.cjs +2 -0
- package/dist/components/ui/breadcrumb.cjs.map +1 -0
- package/dist/components/ui/breadcrumb.js +118 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button-group.cjs +2 -0
- package/dist/components/ui/button-group.cjs.map +1 -0
- package/dist/components/ui/button-group.js +77 -0
- package/dist/components/ui/button-group.js.map +1 -0
- package/dist/components/ui/button.cjs +2 -0
- package/dist/components/ui/button.cjs.map +1 -0
- package/dist/components/ui/button.js +57 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.cjs +2 -0
- package/dist/components/ui/calendar.cjs.map +1 -0
- package/dist/components/ui/calendar.js +174 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.cjs +2 -0
- package/dist/components/ui/card.cjs.map +1 -0
- package/dist/components/ui/card.js +102 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/carousel.cjs +2 -0
- package/dist/components/ui/carousel.cjs.map +1 -0
- package/dist/components/ui/carousel.js +179 -0
- package/dist/components/ui/carousel.js.map +1 -0
- package/dist/components/ui/checkbox.cjs +2 -0
- package/dist/components/ui/checkbox.cjs.map +1 -0
- package/dist/components/ui/checkbox.js +35 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/code-editor.cjs +2 -0
- package/dist/components/ui/code-editor.cjs.map +1 -0
- package/dist/components/ui/code-editor.js +103 -0
- package/dist/components/ui/code-editor.js.map +1 -0
- package/dist/components/ui/collapsible.cjs +2 -0
- package/dist/components/ui/collapsible.cjs.map +1 -0
- package/dist/components/ui/collapsible.js +35 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/combobox.cjs +2 -0
- package/dist/components/ui/combobox.cjs.map +1 -0
- package/dist/components/ui/combobox.js +278 -0
- package/dist/components/ui/combobox.js.map +1 -0
- package/dist/components/ui/command.cjs +2 -0
- package/dist/components/ui/command.cjs.map +1 -0
- package/dist/components/ui/command.js +174 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.cjs +2 -0
- package/dist/components/ui/context-menu.cjs.map +1 -0
- package/dist/components/ui/context-menu.js +236 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/dialog.cjs +2 -0
- package/dist/components/ui/dialog.cjs.map +1 -0
- package/dist/components/ui/dialog.js +154 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/drawer.cjs +2 -0
- package/dist/components/ui/drawer.cjs.map +1 -0
- package/dist/components/ui/drawer.js +125 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.cjs +2 -0
- package/dist/components/ui/dropdown-menu.cjs.map +1 -0
- package/dist/components/ui/dropdown-menu.js +252 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/field.cjs +2 -0
- package/dist/components/ui/field.cjs.map +1 -0
- package/dist/components/ui/field.js +210 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/hover-card.cjs +2 -0
- package/dist/components/ui/hover-card.cjs.map +1 -0
- package/dist/components/ui/hover-card.js +39 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.cjs +2 -0
- package/dist/components/ui/input-group.cjs.map +1 -0
- package/dist/components/ui/input-group.js +145 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-otp.cjs +2 -0
- package/dist/components/ui/input-otp.cjs.map +1 -0
- package/dist/components/ui/input-otp.js +82 -0
- package/dist/components/ui/input-otp.js.map +1 -0
- package/dist/components/ui/input.cjs +2 -0
- package/dist/components/ui/input.cjs.map +1 -0
- package/dist/components/ui/input.js +20 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/item.cjs +2 -0
- package/dist/components/ui/item.cjs.map +1 -0
- package/dist/components/ui/item.js +191 -0
- package/dist/components/ui/item.js.map +1 -0
- package/dist/components/ui/kbd.cjs +2 -0
- package/dist/components/ui/kbd.cjs.map +1 -0
- package/dist/components/ui/kbd.js +30 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/label.cjs +2 -0
- package/dist/components/ui/label.cjs.map +1 -0
- package/dist/components/ui/label.js +23 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/menubar.cjs +2 -0
- package/dist/components/ui/menubar.cjs.map +1 -0
- package/dist/components/ui/menubar.js +256 -0
- package/dist/components/ui/menubar.js.map +1 -0
- package/dist/components/ui/navigation-menu.cjs +2 -0
- package/dist/components/ui/navigation-menu.cjs.map +1 -0
- package/dist/components/ui/navigation-menu.js +164 -0
- package/dist/components/ui/navigation-menu.js.map +1 -0
- package/dist/components/ui/radio-group.cjs +2 -0
- package/dist/components/ui/radio-group.cjs.map +1 -0
- package/dist/components/ui/radio-group.js +45 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.cjs +2 -0
- package/dist/components/ui/resizable.cjs.map +1 -0
- package/dist/components/ui/resizable.js +46 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.cjs +2 -0
- package/dist/components/ui/scroll-area.cjs.map +1 -0
- package/dist/components/ui/scroll-area.js +60 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.cjs +2 -0
- package/dist/components/ui/select.cjs.map +1 -0
- package/dist/components/ui/select.js +184 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.cjs +2 -0
- package/dist/components/ui/separator.cjs.map +1 -0
- package/dist/components/ui/separator.js +27 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.cjs +2 -0
- package/dist/components/ui/sheet.cjs.map +1 -0
- package/dist/components/ui/sheet.js +137 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.cjs +2 -0
- package/dist/components/ui/sidebar.cjs.map +1 -0
- package/dist/components/ui/sidebar.js +579 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.cjs +2 -0
- package/dist/components/ui/skeleton.cjs.map +1 -0
- package/dist/components/ui/skeleton.js +16 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.cjs +2 -0
- package/dist/components/ui/slider.cjs.map +1 -0
- package/dist/components/ui/slider.js +60 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.cjs +2 -0
- package/dist/components/ui/sonner.cjs.map +1 -0
- package/dist/components/ui/sonner.js +37 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/spinner.cjs +2 -0
- package/dist/components/ui/spinner.cjs.map +1 -0
- package/dist/components/ui/spinner.js +10 -0
- package/dist/components/ui/spinner.js.map +1 -0
- package/dist/components/ui/switch.cjs +2 -0
- package/dist/components/ui/switch.cjs.map +1 -0
- package/dist/components/ui/switch.js +32 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.cjs +2 -0
- package/dist/components/ui/table.cjs.map +1 -0
- package/dist/components/ui/table.js +115 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.cjs +2 -0
- package/dist/components/ui/tabs.cjs.map +1 -0
- package/dist/components/ui/tabs.js +91 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/tetrascience-icon.cjs +2 -0
- package/dist/components/ui/tetrascience-icon.cjs.map +1 -0
- package/dist/components/ui/tetrascience-icon.js +46 -0
- package/dist/components/ui/tetrascience-icon.js.map +1 -0
- package/dist/components/ui/textarea.cjs +2 -0
- package/dist/components/ui/textarea.cjs.map +1 -0
- package/dist/components/ui/textarea.js +19 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/toggle-group.cjs +2 -0
- package/dist/components/ui/toggle-group.cjs.map +1 -0
- package/dist/components/ui/toggle-group.js +77 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle.cjs +2 -0
- package/dist/components/ui/toggle.cjs.map +1 -0
- package/dist/components/ui/toggle.js +44 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.cjs +2 -0
- package/dist/components/ui/tooltip.cjs.map +1 -0
- package/dist/components/ui/tooltip.js +56 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/hooks/use-code-editor-theme.cjs +2 -0
- package/dist/hooks/use-code-editor-theme.cjs.map +1 -0
- package/dist/hooks/use-code-editor-theme.js +31 -0
- package/dist/hooks/use-code-editor-theme.js.map +1 -0
- package/dist/hooks/use-is-dark.cjs +2 -0
- package/dist/hooks/use-is-dark.cjs.map +1 -0
- package/dist/hooks/use-is-dark.js +18 -0
- package/dist/hooks/use-is-dark.js.map +1 -0
- package/dist/hooks/use-mobile.cjs +2 -0
- package/dist/hooks/use-mobile.cjs.map +1 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/hooks/use-plotly-theme.cjs +2 -0
- package/dist/hooks/use-plotly-theme.cjs.map +1 -0
- package/dist/hooks/use-plotly-theme.js +33 -0
- package/dist/hooks/use-plotly-theme.js.map +1 -0
- package/dist/index.cjs +1 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +389 -9435
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.cjs +2 -0
- package/dist/lib/utils.cjs.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/providers/athena.cjs +1 -1
- package/dist/providers/athena.cjs.map +1 -1
- package/dist/providers/athena.js +9 -157
- package/dist/providers/athena.js.map +1 -1
- package/dist/providers/databricks.cjs +1 -1
- package/dist/providers/databricks.cjs.map +1 -1
- package/dist/providers/databricks.js +9 -82
- package/dist/providers/databricks.js.map +1 -1
- package/dist/providers/snowflake.cjs +1 -1
- package/dist/providers/snowflake.cjs.map +1 -1
- package/dist/providers/snowflake.js +8 -118
- package/dist/providers/snowflake.js.map +1 -1
- package/dist/server/auth/JwtTokenManager.cjs +2 -0
- package/dist/server/auth/JwtTokenManager.cjs.map +1 -0
- package/dist/server/auth/JwtTokenManager.js +134 -0
- package/dist/server/auth/JwtTokenManager.js.map +1 -0
- package/dist/server/providers/AthenaProvider.cjs +2 -0
- package/dist/server/providers/AthenaProvider.cjs.map +1 -0
- package/dist/server/providers/AthenaProvider.js +154 -0
- package/dist/server/providers/AthenaProvider.js.map +1 -0
- package/dist/server/providers/DatabricksProvider.cjs +2 -0
- package/dist/server/providers/DatabricksProvider.cjs.map +1 -0
- package/dist/server/providers/DatabricksProvider.js +79 -0
- package/dist/server/providers/DatabricksProvider.js.map +1 -0
- package/dist/server/providers/SnowflakeProvider.cjs +2 -0
- package/dist/server/providers/SnowflakeProvider.cjs.map +1 -0
- package/dist/server/providers/SnowflakeProvider.js +116 -0
- package/dist/server/providers/SnowflakeProvider.js.map +1 -0
- package/dist/server/providers/buildProvider.cjs +2 -0
- package/dist/server/providers/buildProvider.cjs.map +1 -0
- package/dist/server/providers/buildProvider.js +22 -0
- package/dist/server/providers/buildProvider.js.map +1 -0
- package/dist/server/providers/exceptions.cjs +2 -0
- package/dist/server/providers/exceptions.cjs.map +1 -0
- package/dist/{exceptions-jCQ6h5C8.js → server/providers/exceptions.js} +11 -11
- package/dist/server/providers/exceptions.js.map +1 -0
- package/dist/server/providers/getProviderConfigurations.cjs +2 -0
- package/dist/server/providers/getProviderConfigurations.cjs.map +1 -0
- package/dist/server/providers/getProviderConfigurations.js +78 -0
- package/dist/server/providers/getProviderConfigurations.js.map +1 -0
- package/dist/server/providers/providerDiscovery.cjs +2 -0
- package/dist/server/providers/providerDiscovery.cjs.map +1 -0
- package/dist/server/providers/providerDiscovery.js +28 -0
- package/dist/server/providers/providerDiscovery.js.map +1 -0
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +27 -262
- package/dist/server.js.map +1 -1
- package/dist/utils/colors.cjs +2 -0
- package/dist/utils/colors.cjs.map +1 -0
- package/dist/utils/colors.js +98 -0
- package/dist/utils/colors.js.map +1 -0
- package/package.json +15 -1
- package/dist/exceptions-DN25pCDi.cjs +0 -2
- package/dist/exceptions-DN25pCDi.cjs.map +0 -1
- package/dist/exceptions-jCQ6h5C8.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlateMap.js","sources":["../../../../src/components/charts/PlateMap/PlateMap.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport \"./PlateMap.scss\";\nimport {\n PLATE_CONFIGS,\n DEFAULT_COLOR_SCALE,\n COLORS,\n DEFAULT_CATEGORY_COLORS,\n PLATEMAP_CONSTANTS,\n NAMED_COLORSCALES,\n} from \"./constants\";\nimport {\n PLATE_FORMAT_96,\n PLATE_FORMAT_CUSTOM,\n} from \"./types\";\nimport {\n generateRowLabels,\n generateColumnLabels,\n wellDataToGrid,\n calculateValueRange,\n hasMultiValueWells,\n extractLayers,\n parseRegionWells,\n buildWellHoverText,\n buildColorbarConfig,\n buildPlotMargins,\n calculateTitleX,\n calculateAxisDomain,\n flattenGridData,\n calculateMarkerSize,\n} from \"./utils\";\n\nimport type {\n PlateMapProps,\n LayerConfig,\n WellData,\n} from \"./types\";\n\n// Re-export types and constants for external consumers\nexport * from \"./types\";\nexport { DEFAULT_CATEGORY_COLORS } from \"./constants\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\n\n/**\n * PlateMap component for visualizing well plate data as a heatmap or categorical display.\n *\n * **Supported Plate Formats:**\n * - 96-well (8 rows × 12 columns, wells A1-H12)\n * - 384-well (16 rows × 24 columns, wells A1-P24)\n * - 1536-well (32 rows × 48 columns, wells A1-AF48)\n * - Custom dimensions with user-specified rows/columns\n *\n * **Visualization Modes:**\n * - `\"heatmap\"`: Continuous color gradient for quantitative values\n * - `\"categorical\"`: Discrete colors for well types (sample, control, empty)\n *\n * **Features:**\n * - Multiple data layers with independent visualization settings\n * - Control region highlighting with borders and fill colors\n * - Configurable color scales, tooltips, and click interactions\n * - Support for WellData arrays with multi-layer visualization\n *\n * **Data Format:**\n * - **WellData array**: `[{ wellId: \"A1\", values: { RFU: 100 }, tooltipData: {...} }, ...]`\n *\n */\nconst PlateMap: React.FC<PlateMapProps> = ({\n data,\n layerConfigs,\n initialLayerId,\n onLayerChange,\n plateFormat = PLATE_FORMAT_96,\n rows: customRows,\n columns: customColumns,\n visualizationMode: propVisualizationMode = \"heatmap\",\n categoryColors: customCategoryColors,\n regions,\n title,\n xTitle,\n yTitle,\n xLabels: customXLabels,\n yLabels: customYLabels,\n colorScale: propColorScale = DEFAULT_COLOR_SCALE,\n valueMin: propValueMin,\n valueMax: propValueMax,\n emptyWellColor = COLORS.emptyWell,\n showColorBar = true,\n showLegend = true,\n legendConfig,\n width = 800,\n height = 500,\n precision = 0,\n markerShape = \"circle\",\n onWellClick,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const onWellClickRef = useRef(onWellClick);\n onWellClickRef.current = onWellClick;\n\n // Internal state for layer toggling, initialized with initialLayerId\n const [activeLayerId, setActiveLayerId] = useState<string | undefined>(initialLayerId);\n\n // Determine plate dimensions\n let rows: number;\n let columns: number;\n\n if (plateFormat === PLATE_FORMAT_CUSTOM) {\n rows = customRows ?? 8;\n columns = customColumns ?? 12;\n } else {\n const config = PLATE_CONFIGS[plateFormat];\n rows = config.rows;\n columns = config.columns;\n }\n\n // Auto-generate layers from multi-value WellData\n const effectiveLayers = useMemo((): LayerConfig[] | null => {\n // Check if data contains multi-value wells\n if (Array.isArray(data) && data.length > 0 && \"wellId\" in (data[0] as WellData)) {\n const wellDataArray = data as WellData[];\n if (hasMultiValueWells(wellDataArray)) {\n return extractLayers(wellDataArray, layerConfigs);\n }\n }\n\n return null;\n }, [data, layerConfigs]);\n\n // Handle layer toggling - determine active layer\n const activeLayer = useMemo((): LayerConfig | null => {\n if (!effectiveLayers || effectiveLayers.length === 0) return null;\n if (activeLayerId) {\n return effectiveLayers.find((l) => l.id === activeLayerId) ?? effectiveLayers[0];\n }\n return effectiveLayers[0];\n }, [effectiveLayers, activeLayerId]);\n\n // Get effective props from active layer or default props\n // Data is always the same - we just change which layer is being visualized\n const visualizationMode = activeLayer?.visualizationMode ?? propVisualizationMode;\n const colorScale = activeLayer?.colorScale ?? propColorScale;\n const valueMin = activeLayer?.valueMin ?? propValueMin;\n const valueMax = activeLayer?.valueMax ?? propValueMax;\n // Derive valueUnit from layer config\n const valueUnit = activeLayer?.valueUnit ? ` ${activeLayer.valueUnit}` : \"\";\n\n // Merge custom category colors with defaults, including layer-specific colors\n const categoryColors = useMemo(\n () => ({ ...DEFAULT_CATEGORY_COLORS, ...customCategoryColors, ...activeLayer?.categoryColors }),\n [customCategoryColors, activeLayer?.categoryColors]\n );\n\n // Convert data to grid format - memoize to prevent re-render issues\n // Use activeLayer.id to extract the appropriate value from multi-value wells\n const activeLayerId_ = activeLayer?.id;\n const { grid, categoriesGrid, allValuesMap, tooltipDataMap } = useMemo(() => {\n let resultGrid: (number | null)[][];\n let resultCategories: (string | null)[][] = Array.from({ length: rows }, () =>\n Array(columns).fill(null)\n );\n let resultAllValues = new Map<string, Record<string, string | number | null>>();\n let resultTooltipData = new Map<string, Record<string, unknown>>();\n\n if (Array.isArray(data) && data.length > 0) {\n // WellData array format - pass activeLayerId to extract the right layer\n const result = wellDataToGrid(data, rows, columns, activeLayerId_);\n resultGrid = result.grid;\n resultCategories = result.categories;\n resultAllValues = result.allValues;\n resultTooltipData = result.tooltipData;\n } else {\n // Generate random data for demonstration when no data provided\n resultGrid = Array.from({ length: rows }, () =>\n Array.from({ length: columns }, () => Math.random() * PLATEMAP_CONSTANTS.MAX_RANDOM_VALUE)\n );\n }\n\n return { grid: resultGrid, categoriesGrid: resultCategories, allValuesMap: resultAllValues, tooltipDataMap: resultTooltipData };\n }, [data, rows, columns, activeLayerId_]);\n\n // Generate labels - use custom labels if provided, otherwise auto-generate\n const rowLabels = customYLabels ?? generateRowLabels(rows);\n const colLabels = customXLabels ?? generateColumnLabels(columns);\n\n // Calculate value range if not provided\n const range = calculateValueRange(grid);\n const zMin = valueMin ?? range.min;\n const zMax = valueMax ?? range.max;\n\n // Check if grid has any null values\n const hasNullValues = grid.some(row => row.includes(null));\n\n // Create sentinel value for empty wells (below the data range)\n // This allows us to show emptyWellColor for null cells\n const sentinelValue = zMin - (zMax - zMin) * PLATEMAP_CONSTANTS.SENTINEL_RATIO - 1;\n\n // Replace null values with sentinel for Plotly rendering\n const displayGrid = hasNullValues\n ? grid.map(row => row.map(val => val === null ? sentinelValue : val))\n : grid;\n\n // Extend colorscale to include emptyWellColor at the bottom for null values\n const effectiveColorScale = useMemo(() => {\n if (!hasNullValues) return colorScale;\n\n // Convert colorScale to array format if it's a named string scale\n let arrayColorScale: Array<[number, string]>;\n if (typeof colorScale === \"string\") {\n // Look up the named scale in our mapping\n const namedScale = NAMED_COLORSCALES[colorScale];\n if (namedScale) {\n arrayColorScale = namedScale;\n } else {\n // Unknown named scale - can't extend it, return as-is\n // This is a fallback for custom/unknown Plotly scale names\n return colorScale;\n }\n } else {\n arrayColorScale = colorScale;\n }\n\n // For array colorscales, prepend emptyWellColor at position 0\n // and shift all other positions proportionally\n const totalRange = zMax - sentinelValue;\n const dataStartRatio = (zMin - sentinelValue) / totalRange;\n\n // Create new colorscale with emptyWellColor at the bottom\n const extendedScale: Array<[number, string]> = [\n [0, emptyWellColor],\n [dataStartRatio * PLATEMAP_CONSTANTS.COLOR_SCALE_THRESHOLD, emptyWellColor], // Small band for empty wells\n ];\n\n // Remap original colorscale positions to the remaining range\n for (const [pos, color] of arrayColorScale) {\n const newPos = dataStartRatio + pos * (1 - dataStartRatio);\n extendedScale.push([newPos, color]);\n }\n\n return extendedScale;\n }, [colorScale, hasNullValues, zMin, zMax, sentinelValue, emptyWellColor]);\n\n // Effective zMin includes sentinel value if we have nulls\n const effectiveZMin = hasNullValues ? sentinelValue : zMin;\n\n // Create a lookup map for layer configs to get valueUnit for each layer\n const layerConfigMap = useMemo(() => {\n const map = new Map<string, LayerConfig>();\n if (effectiveLayers) {\n for (const layer of effectiveLayers) {\n map.set(layer.id, layer);\n }\n }\n return map;\n }, [effectiveLayers]);\n\n // Build custom hover text matrix - shows ALL values regardless of active layer\n const hoverText: string[][] = grid.map((row, rowIdx) =>\n row.map((val, colIdx) => {\n const wellId = `${rowLabels[rowIdx]}${colLabels[colIdx]}`;\n const wellIdUpper = String(wellId).toUpperCase();\n return buildWellHoverText({\n wellId,\n value: val,\n allValues: allValuesMap.get(wellIdUpper),\n tooltipExtra: tooltipDataMap.get(wellIdUpper),\n activeLayerId: activeLayer?.id,\n layerConfigMap,\n precision,\n valueUnit,\n });\n })\n );\n\n // Build categorical data for categorical mode\n const { categoricalGrid, categoricalColorScale, uniqueTypes, catMax } = useMemo(() => {\n if (visualizationMode !== \"categorical\") {\n return { categoricalGrid: null, categoricalColorScale: null, uniqueTypes: [], catMax: 0 };\n }\n\n // Collect unique categories from the categoriesGrid\n const typesSet = new Set<string>();\n let hasNullCategory = false;\n for (const row of categoriesGrid) {\n for (const category of row) {\n if (category) {\n typesSet.add(category);\n } else {\n hasNullCategory = true;\n }\n }\n }\n // Only include \"empty\" if there are actual null wells\n if (hasNullCategory) {\n typesSet.add(\"empty\");\n }\n const types = [...typesSet].sort();\n\n // Create numeric grid where each category maps to an index\n const typeToIndex = new Map<string, number>();\n types.forEach((type, idx) => typeToIndex.set(type, idx));\n\n const catGrid: number[][] = categoriesGrid.map((row) =>\n row.map((category) => {\n if (category === null) {\n return typeToIndex.get(\"empty\") ?? 0;\n }\n return typeToIndex.get(category) ?? typeToIndex.get(\"empty\") ?? 0;\n })\n );\n\n // Build discrete colorscale for categories\n // The grid contains integer indices 0, 1, 2, ... (numTypes - 1)\n // With cmin=0 and cmax=numTypes-1, Plotly maps:\n // index 0 -> normalized 0.0\n // index (numTypes-1) -> normalized 1.0\n // We need each index to map to a distinct color band\n const numTypes = types.length;\n const catColorScale: Array<[number, string]> = [];\n\n if (numTypes === 1) {\n // Single type: entire range is one color\n const color = categoryColors[types[0]] || emptyWellColor;\n catColorScale.push([0, color]);\n catColorScale.push([1, color]);\n } else {\n // Multiple types: create bands for each index\n // Index i maps to normalized value i / (numTypes - 1)\n types.forEach((type, idx) => {\n const color = categoryColors[type] || emptyWellColor;\n const normalizedPos = idx / (numTypes - 1);\n // Create a small band around each position\n const bandHalf = 0.5 / (numTypes - 1);\n const start = Math.max(0, normalizedPos - bandHalf);\n const end = Math.min(1, normalizedPos + bandHalf - PLATEMAP_CONSTANTS.COLOR_SCALE_EPSILON);\n catColorScale.push([start, color]);\n catColorScale.push([end, color]);\n });\n }\n\n // cmax should be numTypes - 1 to match the index range\n return { categoricalGrid: catGrid, categoricalColorScale: catColorScale, uniqueTypes: types, catMax: numTypes - 1 };\n }, [visualizationMode, categoriesGrid, categoryColors, emptyWellColor]);\n\n // Build Plotly shapes for highlighted regions\n const regionShapes = useMemo(() => {\n if (!regions || regions.length === 0) {\n return [];\n }\n\n const shapes: Array<Partial<Plotly.Shape>> = [];\n\n for (const region of regions) {\n const bounds = parseRegionWells(region.wells, rowLabels, colLabels);\n if (!bounds) continue;\n\n // Plotly heatmap uses the actual label values for positioning.\n // colLabels are 1-indexed (1, 2, 3, ...), so we need to convert from 0-indexed bounds.\n // Each cell is centered on its label, so we offset by inset to cover the cell.\n // For columns: bounds.minCol=0 means column label 1, so x0 = 1 - inset\n // For rows: bounds.minRow=0 means row index 0, which is correct for y-axis\n //\n // Use 0.49 inset to place boundary just inside cell edge,\n // avoiding line doubling when adjacent regions share a border\n const inset = 0.49;\n const x0 = (bounds.minCol + 1) - inset;\n const x1 = (bounds.maxCol + 1) + inset;\n const y0 = bounds.minRow - inset;\n const y1 = bounds.maxRow + inset;\n\n shapes.push({\n type: \"rect\",\n xref: \"x\",\n yref: \"y\",\n x0,\n x1,\n y0,\n y1,\n line: {\n color: region.borderColor || COLORS.textDark,\n width: region.borderWidth ?? 2,\n },\n fillcolor: region.fillColor || \"transparent\",\n layer: \"above\",\n });\n }\n\n return shapes;\n }, [regions, rowLabels, colLabels]);\n\n useEffect(() => {\n const currentRef = plotRef.current;\n if (!currentRef) return;\n\n // Determine which grid and colorscale to use based on mode\n const isCategorical = visualizationMode === \"categorical\";\n const plotZ = isCategorical && categoricalGrid ? categoricalGrid : displayGrid;\n const plotColorScale = isCategorical && categoricalColorScale ? categoricalColorScale : effectiveColorScale;\n const plotZMin = isCategorical ? 0 : effectiveZMin;\n const plotZMax = isCategorical ? (catMax || 1) : zMax;\n const plotShowScale = isCategorical ? false : showColorBar;\n\n // Flatten 2D grid data into arrays for scatter plot\n const { xData, yData, colorData, textData } = flattenGridData(\n plotZ,\n rowLabels,\n hoverText,\n rows,\n columns,\n plotZMin\n );\n\n // Calculate marker size based on plot dimensions\n const markerSize = calculateMarkerSize(\n width,\n height,\n rows,\n columns,\n markerShape,\n !!title,\n !!yTitle\n );\n\n // Create scatter plot with markers\n const plotData: Plotly.Data[] = [\n {\n x: xData,\n y: yData,\n mode: \"markers\" as const,\n type: \"scatter\" as const,\n marker: {\n symbol: markerShape,\n size: markerSize,\n color: colorData,\n colorscale: plotColorScale,\n cmin: plotZMin,\n cmax: plotZMax,\n showscale: plotShowScale,\n colorbar: buildColorbarConfig(\n legendConfig?.position ?? \"right\",\n valueUnit,\n legendConfig?.title\n ),\n line: {\n color: theme.gridColor,\n width: 1,\n },\n },\n hoverinfo: \"text\" as const,\n text: textData,\n },\n ];\n\n const legendPosition = legendConfig?.position ?? \"right\";\n\n const layout = {\n autosize: false, // Prevent auto-sizing to maintain consistent layout\n title: title\n ? {\n text: title,\n font: {\n family: \"Inter, sans-serif\",\n size: 20,\n color: theme.textSecondary,\n },\n x: calculateTitleX(legendPosition),\n xanchor: \"center\" as const,\n y: 0.98,\n yanchor: \"top\" as const,\n }\n : undefined,\n width,\n height,\n margin: buildPlotMargins(legendPosition, !!title, !!yTitle),\n xaxis: {\n title: {\n text: xTitle || \"\",\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n },\n standoff: 15,\n },\n side: \"top\" as const,\n fixedrange: true,\n dtick: 1,\n range: [0.5, columns + 0.5], // Explicit range to prevent auto-padding\n automargin: false, // Prevent auto margin adjustment\n tickmode: \"array\" as const,\n tickvals: Array.from({ length: columns }, (_, i) => i + 1),\n ticktext: colLabels.map(String),\n tickangle: 0, // Keep labels horizontal\n tickfont: { size: columns > 24 ? 8 : PLATEMAP_CONSTANTS.FONT_SIZE_LARGE }, // Smaller font for high-density plates\n // Adjust domain based on legend position to prevent colorbar overlap\n domain: calculateAxisDomain(legendPosition),\n },\n yaxis: {\n title: {\n text: yTitle || \"\",\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n },\n standoff: 15,\n },\n fixedrange: true,\n dtick: 1,\n range: [rows + PLATEMAP_CONSTANTS.LABEL_CENTER_OFFSET, PLATEMAP_CONSTANTS.LABEL_CENTER_OFFSET], // Reversed range: high to low puts row A at top\n automargin: false, // Prevent auto margin adjustment\n tickmode: \"array\" as const,\n tickvals: Array.from({ length: rows }, (_, i) => i),\n ticktext: rowLabels.map(String),\n tickfont: { size: rows > 16 ? 8 : PLATEMAP_CONSTANTS.FONT_SIZE_LARGE }, // Smaller font for high-density plates\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n color: theme.textSecondary,\n },\n shapes: regionShapes,\n };\n\n const config = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(currentRef, plotData, layout, config);\n\n // Always attach click handler - check onWellClickRef.current inside callback\n // This ensures handler is registered even if onWellClick is provided after initial render\n (currentRef as unknown as Plotly.PlotlyHTMLElement).on(\"plotly_click\", (eventData: Plotly.PlotMouseEvent) => {\n if (!onWellClickRef.current) return;\n const point = eventData.points[0];\n if (point) {\n // Cast labels to handle union type\n const rowLabelsArr = rowLabels as (string | number)[];\n const colLabelsArr = colLabels as (string | number)[];\n const rowIdx = rowLabelsArr.indexOf(point.y as string | number);\n const colIdx = colLabelsArr.indexOf(point.x as string | number);\n if (rowIdx >= 0 && colIdx >= 0) {\n const wellId = `${rowLabelsArr[rowIdx]}${colLabelsArr[colIdx]}`;\n const wellIdUpper = String(wellId).toUpperCase();\n // Get all values and tooltipData for this well\n const allValues = allValuesMap.get(wellIdUpper);\n const tooltipData = tooltipDataMap.get(wellIdUpper);\n const wellData: WellData = {\n wellId,\n values: allValues,\n tooltipData,\n };\n onWellClickRef.current?.(wellData);\n }\n }\n });\n\n return () => {\n if (currentRef) {\n Plotly.purge(currentRef);\n }\n };\n }, [\n displayGrid,\n colLabels,\n rowLabels,\n effectiveColorScale,\n showColorBar,\n effectiveZMin,\n zMax,\n valueUnit,\n title,\n xTitle,\n yTitle,\n width,\n height,\n hoverText,\n precision,\n tooltipDataMap,\n allValuesMap,\n grid,\n visualizationMode,\n categoricalGrid,\n categoricalColorScale,\n uniqueTypes.length,\n catMax,\n regionShapes,\n rows,\n columns,\n legendConfig,\n markerShape,\n theme,\n ]);\n\n // Render layer selector tabs\n const renderLayerSelector = () => {\n if (!effectiveLayers || effectiveLayers.length <= 1) {\n return null;\n }\n\n return (\n <div className=\"platemap-layer-selector\">\n {effectiveLayers.map((layer) => {\n const isActive = activeLayer?.id === layer.id;\n return (\n <Button\n key={layer.id}\n variant={isActive ? \"default\" : \"outline\"}\n size=\"sm\"\n onClick={() => {\n setActiveLayerId(layer.id);\n onLayerChange?.(layer.id);\n }}\n >\n {layer.name}\n </Button>\n );\n })}\n </div>\n );\n };\n\n // Legend configuration with defaults\n const legendPosition = legendConfig?.position ?? \"right\";\n const legendFontSize = legendConfig?.fontSize ?? 12;\n const legendItemSpacing = legendConfig?.itemSpacing ?? 4;\n const legendSwatchSize = legendConfig?.swatchSize ?? 16;\n const legendTitle = legendConfig?.title;\n\n // Fixed width for categorical legend to prevent layout shift\n const legendWidth = 120;\n\n // Determine if legend is horizontal (top/bottom) or vertical (left/right)\n const isHorizontalLegend = legendPosition === \"top\" || legendPosition === \"bottom\";\n\n // Render legend (categorical types and/or regions)\n const renderLegend = () => {\n const hasCategoricalItems = visualizationMode === \"categorical\" && uniqueTypes.length > 0;\n const hasRegions = regions && regions.length > 0;\n\n if (!showLegend || (!hasCategoricalItems && !hasRegions)) {\n // Return empty placeholder to maintain consistent width (only for vertical legends)\n if (!isHorizontalLegend) {\n return <div className=\"platemap-legend-placeholder\" style={{ width: legendWidth }} />;\n }\n return null;\n }\n\n // Build legend class names\n const legendClassNames = [\"platemap-legend\"];\n if (isHorizontalLegend) {\n legendClassNames.push(\"platemap-legend--horizontal\");\n } else if (legendPosition === \"left\") {\n legendClassNames.push(\"platemap-legend--left\");\n } else if (legendPosition === \"right\") {\n legendClassNames.push(\"platemap-legend--right\");\n }\n\n // Dynamic styles that depend on props\n const legendStyle: React.CSSProperties = {\n gap: `${legendItemSpacing}px`,\n width: isHorizontalLegend ? undefined : legendWidth,\n };\n\n return (\n <div className={legendClassNames.join(\" \")} style={legendStyle}>\n {legendTitle && (\n <div\n className={`platemap-legend__title${isHorizontalLegend ? \" platemap-legend__title--horizontal\" : \"\"}`}\n style={{ fontSize: `${legendFontSize}px` }}\n >\n {legendTitle}\n </div>\n )}\n {/* Categorical type items */}\n {hasCategoricalItems &&\n uniqueTypes.map((type) => (\n <div key={type} className=\"platemap-legend__item\">\n <div\n className=\"platemap-legend__swatch\"\n style={{\n width: `${legendSwatchSize}px`,\n height: `${legendSwatchSize}px`,\n backgroundColor: categoryColors[type] || emptyWellColor,\n }}\n />\n <span\n className=\"platemap-legend__label platemap-legend__label--capitalize\"\n style={{ fontSize: `${legendFontSize}px` }}\n >\n {type}\n </span>\n </div>\n ))}\n {/* Region items */}\n {hasRegions &&\n regions.map((region) => (\n <div key={region.id} className=\"platemap-legend__item\">\n <div\n className=\"platemap-legend__swatch platemap-legend__swatch--region\"\n style={{\n width: `${legendSwatchSize}px`,\n height: `${legendSwatchSize}px`,\n backgroundColor: region.fillColor || \"transparent\",\n border: `${region.borderWidth || 2}px solid ${region.borderColor || COLORS.regionBorder}`,\n }}\n />\n <span\n className=\"platemap-legend__label\"\n style={{ fontSize: `${legendFontSize}px` }}\n >\n {region.name}\n </span>\n </div>\n ))}\n </div>\n );\n };\n\n // Build the plot content based on legend position\n const plotContent = <div ref={plotRef} className=\"platemap-plot\" style={{ width, height }} />;\n const legendContent = renderLegend();\n\n const renderPlotWithLegend = () => {\n switch (legendPosition) {\n case \"left\":\n return (\n <div className=\"platemap-plot-wrapper platemap-plot-wrapper--vertical\">\n {legendContent}\n {plotContent}\n </div>\n );\n case \"top\":\n return (\n <div className=\"platemap-plot-wrapper platemap-plot-wrapper--horizontal\">\n {legendContent}\n {plotContent}\n </div>\n );\n case \"bottom\":\n return (\n <div className=\"platemap-plot-wrapper platemap-plot-wrapper--horizontal\">\n {plotContent}\n {legendContent}\n </div>\n );\n case \"right\":\n default:\n return (\n <div className=\"platemap-plot-wrapper platemap-plot-wrapper--vertical\">\n {plotContent}\n {legendContent}\n </div>\n );\n }\n };\n\n return (\n <div className=\"platemap-container\" style={{ width: isHorizontalLegend ? undefined : width }}>\n {renderLayerSelector()}\n {renderPlotWithLegend()}\n </div>\n );\n};\n\nexport { PlateMap };"],"names":["PlateMap","data","layerConfigs","initialLayerId","onLayerChange","plateFormat","PLATE_FORMAT_96","customRows","customColumns","propVisualizationMode","customCategoryColors","regions","title","xTitle","yTitle","customXLabels","customYLabels","propColorScale","DEFAULT_COLOR_SCALE","propValueMin","propValueMax","emptyWellColor","COLORS","showColorBar","showLegend","legendConfig","width","height","precision","markerShape","onWellClick","plotRef","useRef","theme","usePlotlyTheme","onWellClickRef","activeLayerId","setActiveLayerId","useState","rows","columns","PLATE_FORMAT_CUSTOM","config","PLATE_CONFIGS","effectiveLayers","useMemo","wellDataArray","hasMultiValueWells","extractLayers","activeLayer","l","visualizationMode","colorScale","valueMin","valueMax","valueUnit","categoryColors","DEFAULT_CATEGORY_COLORS","activeLayerId_","grid","categoriesGrid","allValuesMap","tooltipDataMap","resultGrid","resultCategories","resultAllValues","resultTooltipData","result","wellDataToGrid","PLATEMAP_CONSTANTS","rowLabels","generateRowLabels","colLabels","generateColumnLabels","range","calculateValueRange","zMin","zMax","hasNullValues","row","sentinelValue","displayGrid","val","effectiveColorScale","arrayColorScale","namedScale","NAMED_COLORSCALES","totalRange","dataStartRatio","extendedScale","pos","color","newPos","effectiveZMin","layerConfigMap","map","layer","hoverText","rowIdx","colIdx","wellId","wellIdUpper","buildWellHoverText","categoricalGrid","categoricalColorScale","uniqueTypes","catMax","typesSet","hasNullCategory","category","types","typeToIndex","type","idx","catGrid","numTypes","catColorScale","normalizedPos","bandHalf","start","end","regionShapes","shapes","region","bounds","parseRegionWells","inset","x0","x1","y0","y1","useEffect","currentRef","isCategorical","plotZ","plotColorScale","plotZMin","plotZMax","plotShowScale","xData","yData","colorData","textData","flattenGridData","markerSize","calculateMarkerSize","plotData","buildColorbarConfig","legendPosition","layout","calculateTitleX","buildPlotMargins","_","i","calculateAxisDomain","Plotly","eventData","point","rowLabelsArr","colLabelsArr","allValues","tooltipData","wellData","renderLayerSelector","isActive","jsx","Button","legendFontSize","legendItemSpacing","legendSwatchSize","legendTitle","legendWidth","isHorizontalLegend","renderLegend","hasCategoricalItems","hasRegions","legendClassNames","legendStyle","jsxs","plotContent","legendContent","renderPlotWithLegend"],"mappings":";;;;;;;;;;AAqEA,MAAMA,KAAoC,CAAC;AAAA,EACzC,MAAAC;AAAA,EACA,cAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,aAAAC,KAAcC;AAAA,EACd,MAAMC;AAAA,EACN,SAASC;AAAA,EACT,mBAAmBC,KAAwB;AAAA,EAC3C,gBAAgBC;AAAA,EAChB,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,SAASC;AAAA,EACT,SAASC;AAAA,EACT,YAAYC,KAAiBC;AAAA,EAC7B,UAAUC;AAAA,EACV,UAAUC;AAAA,EACV,gBAAAC,IAAiBC,GAAO;AAAA,EACxB,cAAAC,KAAe;AAAA,EACf,YAAAC,KAAa;AAAA,EACb,cAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC,IAAS;AAAA,EACT,WAAAC,KAAY;AAAA,EACZ,aAAAC,IAAc;AAAA,EACd,aAAAC;AACF,MAAM;AACJ,QAAMC,KAAUC,GAAuB,IAAI,GACrCC,IAAQC,GAAA,GACRC,IAAiBH,GAAOF,EAAW;AACzC,EAAAK,EAAe,UAAUL;AAGzB,QAAM,CAACM,GAAeC,EAAgB,IAAIC,GAA6BnC,EAAc;AAGrF,MAAIoC,GACAC;AAEJ,MAAInC,OAAgBoC;AAClB,IAAAF,IAAOhC,MAAc,GACrBiC,IAAUhC,MAAiB;AAAA,OACtB;AACL,UAAMkC,IAASC,GAActC,EAAW;AACxC,IAAAkC,IAAOG,EAAO,MACdF,IAAUE,EAAO;AAAA,EACnB;AAGA,QAAME,IAAkBC,EAAQ,MAA4B;AAE1D,QAAI,MAAM,QAAQ5C,CAAI,KAAKA,EAAK,SAAS,KAAK,YAAaA,EAAK,CAAC,GAAgB;AAC/E,YAAM6C,IAAgB7C;AACtB,UAAI8C,GAAmBD,CAAa;AAClC,eAAOE,GAAcF,GAAe5C,EAAY;AAAA,IAEpD;AAEA,WAAO;AAAA,EACT,GAAG,CAACD,GAAMC,EAAY,CAAC,GAGjB+C,IAAcJ,EAAQ,MACtB,CAACD,KAAmBA,EAAgB,WAAW,IAAU,OACzDR,IACKQ,EAAgB,KAAK,CAACM,MAAMA,EAAE,OAAOd,CAAa,KAAKQ,EAAgB,CAAC,IAE1EA,EAAgB,CAAC,GACvB,CAACA,GAAiBR,CAAa,CAAC,GAI7Be,IAAoBF,GAAa,qBAAqBxC,IACtD2C,IAAaH,GAAa,cAAchC,IACxCoC,KAAWJ,GAAa,YAAY9B,IACpCmC,KAAWL,GAAa,YAAY7B,IAEpCmC,IAAYN,GAAa,YAAY,IAAIA,EAAY,SAAS,KAAK,IAGnEO,IAAiBX;AAAA,IACrB,OAAO,EAAE,GAAGY,IAAyB,GAAG/C,IAAsB,GAAGuC,GAAa;IAC9E,CAACvC,IAAsBuC,GAAa,cAAc;AAAA,EAAA,GAK9CS,KAAiBT,GAAa,IAC9B,EAAE,MAAAU,GAAM,gBAAAC,GAAgB,cAAAC,GAAc,gBAAAC,EAAA,IAAmBjB,EAAQ,MAAM;AAC3E,QAAIkB,GACAC,IAAwC,MAAM;AAAA,MAAK,EAAE,QAAQzB,EAAA;AAAA,MAAQ,MACvE,MAAMC,CAAO,EAAE,KAAK,IAAI;AAAA,IAAA,GAEtByB,wBAAsB,IAAA,GACtBC,wBAAwB,IAAA;AAE5B,QAAI,MAAM,QAAQjE,CAAI,KAAKA,EAAK,SAAS,GAAG;AAE1C,YAAMkE,IAASC,GAAenE,GAAMsC,GAAMC,GAASkB,EAAc;AACjE,MAAAK,IAAaI,EAAO,MACpBH,IAAmBG,EAAO,YAC1BF,IAAkBE,EAAO,WACzBD,IAAoBC,EAAO;AAAA,IAC7B;AAEE,MAAAJ,IAAa,MAAM;AAAA,QAAK,EAAE,QAAQxB,EAAA;AAAA,QAAQ,MACxC,MAAM,KAAK,EAAE,QAAQC,KAAW,MAAM,KAAK,WAAW6B,EAAmB,gBAAgB;AAAA,MAAA;AAI7F,WAAO,EAAE,MAAMN,GAAY,gBAAgBC,GAAkB,cAAcC,GAAiB,gBAAgBC,EAAA;AAAA,EAC9G,GAAG,CAACjE,GAAMsC,GAAMC,GAASkB,EAAc,CAAC,GAGlCY,IAAYtD,MAAiBuD,GAAkBhC,CAAI,GACnDiC,IAAYzD,MAAiB0D,GAAqBjC,CAAO,GAGzDkC,KAAQC,GAAoBhB,CAAI,GAChCiB,IAAOvB,MAAYqB,GAAM,KACzBG,IAAOvB,MAAYoB,GAAM,KAGzBI,IAAgBnB,EAAK,KAAK,OAAOoB,EAAI,SAAS,IAAI,CAAC,GAInDC,IAAgBJ,KAAQC,IAAOD,KAAQP,EAAmB,iBAAiB,GAG3EY,KAAcH,IAChBnB,EAAK,IAAI,CAAAoB,MAAOA,EAAI,IAAI,CAAAG,MAAOA,MAAQ,OAAOF,IAAgBE,CAAG,CAAC,IAClEvB,GAGEwB,KAAsBtC,EAAQ,MAAM;AACxC,QAAI,CAACiC,EAAe,QAAO1B;AAG3B,QAAIgC;AACJ,QAAI,OAAOhC,KAAe,UAAU;AAElC,YAAMiC,IAAaC,GAAkBlC,CAAU;AAC/C,UAAIiC;AACF,QAAAD,IAAkBC;AAAA;AAIlB,eAAOjC;AAAA,IAEX;AACE,MAAAgC,IAAkBhC;AAKpB,UAAMmC,IAAaV,IAAOG,GACpBQ,KAAkBZ,IAAOI,KAAiBO,GAG1CE,IAAyC;AAAA,MAC7C,CAAC,GAAGpE,CAAc;AAAA,MAClB,CAACmE,IAAiBnB,EAAmB,uBAAuBhD,CAAc;AAAA;AAAA,IAAA;AAI5E,eAAW,CAACqE,GAAKC,CAAK,KAAKP,GAAiB;AAC1C,YAAMQ,IAASJ,IAAiBE,KAAO,IAAIF;AAC3C,MAAAC,EAAc,KAAK,CAACG,GAAQD,CAAK,CAAC;AAAA,IACpC;AAEA,WAAOF;AAAA,EACT,GAAG,CAACrC,GAAY0B,GAAeF,GAAMC,GAAMG,GAAe3D,CAAc,CAAC,GAGnEwE,KAAgBf,IAAgBE,IAAgBJ,GAGhDkB,KAAiBjD,EAAQ,MAAM;AACnC,UAAMkD,wBAAU,IAAA;AAChB,QAAInD;AACF,iBAAWoD,KAASpD;AAClB,QAAAmD,EAAI,IAAIC,EAAM,IAAIA,CAAK;AAG3B,WAAOD;AAAA,EACT,GAAG,CAACnD,CAAe,CAAC,GAGdqD,KAAwBtC,EAAK;AAAA,IAAI,CAACoB,GAAKmB,MAC3CnB,EAAI,IAAI,CAACG,GAAKiB,MAAW;AACvB,YAAMC,IAAS,GAAG9B,EAAU4B,CAAM,CAAC,GAAG1B,EAAU2B,CAAM,CAAC,IACjDE,IAAc,OAAOD,CAAM,EAAE,YAAA;AACnC,aAAOE,GAAmB;AAAA,QACxB,QAAAF;AAAA,QACA,OAAOlB;AAAA,QACP,WAAWrB,EAAa,IAAIwC,CAAW;AAAA,QACvC,cAAcvC,EAAe,IAAIuC,CAAW;AAAA,QAC5C,eAAepD,GAAa;AAAA,QAC5B,gBAAA6C;AAAA,QACA,WAAAlE;AAAA,QACA,WAAA2B;AAAA,MAAA,CACD;AAAA,IACH,CAAC;AAAA,EAAA,GAIG,EAAE,iBAAAgD,GAAiB,uBAAAC,IAAuB,aAAAC,IAAa,QAAAC,GAAA,IAAW7D,EAAQ,MAAM;AACpF,QAAIM,MAAsB;AACxB,aAAO,EAAE,iBAAiB,MAAM,uBAAuB,MAAM,aAAa,CAAA,GAAI,QAAQ,EAAA;AAIxF,UAAMwD,wBAAe,IAAA;AACrB,QAAIC,IAAkB;AACtB,eAAW7B,KAAOnB;AAChB,iBAAWiD,KAAY9B;AACrB,QAAI8B,IACFF,EAAS,IAAIE,CAAQ,IAErBD,IAAkB;AAKxB,IAAIA,KACFD,EAAS,IAAI,OAAO;AAEtB,UAAMG,IAAQ,CAAC,GAAGH,CAAQ,EAAE,KAAA,GAGtBI,wBAAkB,IAAA;AACxB,IAAAD,EAAM,QAAQ,CAACE,GAAMC,MAAQF,EAAY,IAAIC,GAAMC,CAAG,CAAC;AAEvD,UAAMC,IAAsBtD,EAAe;AAAA,MAAI,CAACmB,MAC9CA,EAAI,IAAI,CAAC8B,MACHA,MAAa,OACRE,EAAY,IAAI,OAAO,KAAK,IAE9BA,EAAY,IAAIF,CAAQ,KAAKE,EAAY,IAAI,OAAO,KAAK,CACjE;AAAA,IAAA,GASGI,IAAWL,EAAM,QACjBM,IAAyC,CAAA;AAE/C,QAAID,MAAa,GAAG;AAElB,YAAMxB,IAAQnC,EAAesD,EAAM,CAAC,CAAC,KAAKzF;AAC1C,MAAA+F,EAAc,KAAK,CAAC,GAAGzB,CAAK,CAAC,GAC7ByB,EAAc,KAAK,CAAC,GAAGzB,CAAK,CAAC;AAAA,IAC/B;AAGE,MAAAmB,EAAM,QAAQ,CAACE,GAAMC,MAAQ;AAC3B,cAAMtB,IAAQnC,EAAewD,CAAI,KAAK3F,GAChCgG,IAAgBJ,KAAOE,IAAW,IAElCG,IAAW,OAAOH,IAAW,IAC7BI,KAAQ,KAAK,IAAI,GAAGF,IAAgBC,CAAQ,GAC5CE,IAAM,KAAK,IAAI,GAAGH,IAAgBC,IAAWjD,EAAmB,mBAAmB;AACzF,QAAA+C,EAAc,KAAK,CAACG,IAAO5B,CAAK,CAAC,GACjCyB,EAAc,KAAK,CAACI,GAAK7B,CAAK,CAAC;AAAA,MACjC,CAAC;AAIH,WAAO,EAAE,iBAAiBuB,GAAS,uBAAuBE,GAAe,aAAaN,GAAO,QAAQK,IAAW,EAAA;AAAA,EAClH,GAAG,CAAChE,GAAmBS,GAAgBJ,GAAgBnC,CAAc,CAAC,GAGhEoG,KAAe5E,EAAQ,MAAM;AACjC,QAAI,CAAClC,KAAWA,EAAQ,WAAW;AACjC,aAAO,CAAA;AAGT,UAAM+G,IAAuC,CAAA;AAE7C,eAAWC,KAAUhH,GAAS;AAC5B,YAAMiH,IAASC,GAAiBF,EAAO,OAAOrD,GAAWE,CAAS;AAClE,UAAI,CAACoD,EAAQ;AAUb,YAAME,IAAQ,MACRC,IAAMH,EAAO,SAAS,IAAKE,GAC3BE,IAAMJ,EAAO,SAAS,IAAKE,GAC3BG,IAAKL,EAAO,SAASE,GACrBI,IAAKN,EAAO,SAASE;AAE3B,MAAAJ,EAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAAK;AAAA,QACA,IAAAC;AAAA,QACA,IAAAC;AAAA,QACA,IAAAC;AAAA,QACA,MAAM;AAAA,UACJ,OAAOP,EAAO,eAAerG,GAAO;AAAA,UACpC,OAAOqG,EAAO,eAAe;AAAA,QAAA;AAAA,QAE/B,WAAWA,EAAO,aAAa;AAAA,QAC/B,OAAO;AAAA,MAAA,CACR;AAAA,IACH;AAEA,WAAOD;AAAA,EACT,GAAG,CAAC/G,GAAS2D,GAAWE,CAAS,CAAC;AAElC,EAAA2D,GAAU,MAAM;AACd,UAAMC,IAAarG,GAAQ;AAC3B,QAAI,CAACqG,EAAY;AAGjB,UAAMC,IAAgBlF,MAAsB,eACtCmF,IAAQD,KAAiB9B,IAAkBA,IAAkBtB,IAC7DsD,IAAiBF,KAAiB7B,KAAwBA,KAAwBrB,IAClFqD,IAAWH,IAAgB,IAAIxC,IAC/B4C,IAAWJ,IAAiB3B,MAAU,IAAK7B,GAC3C6D,IAAgBL,IAAgB,KAAQ9G,IAGxC,EAAE,OAAAoH,GAAO,OAAAC,GAAO,WAAAC,GAAW,UAAAC,MAAaC;AAAA,MAC5CT;AAAA,MACAhE;AAAA,MACA2B;AAAA,MACA1D;AAAA,MACAC;AAAA,MACAgG;AAAA,IAAA,GAIIQ,IAAaC;AAAA,MACjBvH;AAAA,MACAC;AAAA,MACAY;AAAA,MACAC;AAAA,MACAX;AAAA,MACA,CAAC,CAACjB;AAAA,MACF,CAAC,CAACE;AAAA,IAAA,GAIEoI,KAA0B;AAAA,MAC9B;AAAA,QACE,GAAGP;AAAA,QACH,GAAGC;AAAA,QACH,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,QAAQ/G;AAAA,UACR,MAAMmH;AAAA,UACN,OAAOH;AAAA,UACP,YAAYN;AAAA,UACZ,MAAMC;AAAA,UACN,MAAMC;AAAA,UACN,WAAWC;AAAA,UACX,UAAUS;AAAA,YACR1H,GAAc,YAAY;AAAA,YAC1B8B;AAAA,YACA9B,GAAc;AAAA,UAAA;AAAA,UAEhB,MAAM;AAAA,YACJ,OAAOQ,EAAM;AAAA,YACb,OAAO;AAAA,UAAA;AAAA,QACT;AAAA,QAEF,WAAW;AAAA,QACX,MAAM6G;AAAA,MAAA;AAAA,IACR,GAGIM,IAAiB3H,GAAc,YAAY,SAE3C4H,KAAS;AAAA,MACb,UAAU;AAAA;AAAA,MACV,OAAOzI,IACH;AAAA,QACE,MAAMA;AAAA,QACN,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,OAAOqB,EAAM;AAAA,QAAA;AAAA,QAEf,GAAGqH,GAAgBF,CAAc;AAAA,QACjC,SAAS;AAAA,QACT,GAAG;AAAA,QACH,SAAS;AAAA,MAAA,IAEX;AAAA,MACJ,OAAA1H;AAAA,MACA,QAAAC;AAAA,MACA,QAAQ4H,GAAiBH,GAAgB,CAAC,CAACxI,GAAO,CAAC,CAACE,CAAM;AAAA,MAC1D,OAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAMD,MAAU;AAAA,UAChB,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAOoB,EAAM;AAAA,YACb,QAAQ;AAAA,UAAA;AAAA,UAEV,UAAU;AAAA,QAAA;AAAA,QAEZ,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,OAAO,CAAC,KAAKO,IAAU,GAAG;AAAA;AAAA,QAC1B,YAAY;AAAA;AAAA,QACZ,UAAU;AAAA,QACV,UAAU,MAAM,KAAK,EAAE,QAAQA,KAAW,CAACgH,IAAGC,MAAMA,IAAI,CAAC;AAAA,QACzD,UAAUjF,EAAU,IAAI,MAAM;AAAA,QAC9B,WAAW;AAAA;AAAA,QACX,UAAU,EAAE,MAAMhC,IAAU,KAAK,IAAI6B,EAAmB,gBAAA;AAAA;AAAA;AAAA,QAExD,QAAQqF,GAAoBN,CAAc;AAAA,MAAA;AAAA,MAE5C,OAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAMtI,KAAU;AAAA,UAChB,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAOmB,EAAM;AAAA,YACb,QAAQ;AAAA,UAAA;AAAA,UAEV,UAAU;AAAA,QAAA;AAAA,QAEZ,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,OAAO,CAACM,IAAO8B,EAAmB,qBAAqBA,EAAmB,mBAAmB;AAAA;AAAA,QAC7F,YAAY;AAAA;AAAA,QACZ,UAAU;AAAA,QACV,UAAU,MAAM,KAAK,EAAE,QAAQ9B,KAAQ,CAACiH,IAAGC,MAAMA,CAAC;AAAA,QAClD,UAAUnF,EAAU,IAAI,MAAM;AAAA,QAC9B,UAAU,EAAE,MAAM/B,IAAO,KAAK,IAAI8B,EAAmB,gBAAA;AAAA;AAAA,MAAgB;AAAA,MAEvE,eAAepC,EAAM;AAAA,MACrB,cAAcA,EAAM;AAAA,MACpB,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,OAAOA,EAAM;AAAA,MAAA;AAAA,MAEf,QAAQwF;AAAA,IAAA,GAGJ/E,KAAS;AAAA,MACb,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,IAAA;AAGf,WAAAiH,GAAO,QAAQvB,GAAYc,IAAUG,IAAQ3G,EAAM,GAIlD0F,EAAmD,GAAG,gBAAgB,CAACwB,OAAqC;AAC3G,UAAI,CAACzH,EAAe,QAAS;AAC7B,YAAM0H,IAAQD,GAAU,OAAO,CAAC;AAChC,UAAIC,GAAO;AAET,cAAMC,KAAexF,GACfyF,KAAevF,GACf0B,KAAS4D,GAAa,QAAQD,EAAM,CAAoB,GACxD1D,KAAS4D,GAAa,QAAQF,EAAM,CAAoB;AAC9D,YAAI3D,MAAU,KAAKC,MAAU,GAAG;AAC9B,gBAAMC,KAAS,GAAG0D,GAAa5D,EAAM,CAAC,GAAG6D,GAAa5D,EAAM,CAAC,IACvDE,KAAc,OAAOD,EAAM,EAAE,YAAA,GAE7B4D,KAAYnG,EAAa,IAAIwC,EAAW,GACxC4D,KAAcnG,EAAe,IAAIuC,EAAW,GAC5C6D,KAAqB;AAAA,YACzB,QAAA9D;AAAA,YACA,QAAQ4D;AAAA,YACR,aAAAC;AAAA,UAAA;AAEF,UAAA9H,EAAe,UAAU+H,EAAQ;AAAA,QACnC;AAAA,MACF;AAAA,IACF,CAAC,GAEM,MAAM;AACX,MAAI9B,KACFuB,GAAO,MAAMvB,CAAU;AAAA,IAE3B;AAAA,EACF,GAAG;AAAA,IACDnD;AAAA,IACAT;AAAA,IACAF;AAAA,IACAa;AAAA,IACA5D;AAAA,IACAsE;AAAA,IACAhB;AAAA,IACAtB;AAAA,IACA3C;AAAA,IACAC;AAAA,IACAC;AAAA,IACAY;AAAA,IACAC;AAAA,IACAsE;AAAA,IACArE;AAAA,IACAkC;AAAA,IACAD;AAAA,IACAF;AAAA,IACAR;AAAA,IACAoD;AAAA,IACAC;AAAA,IACAC,GAAY;AAAA,IACZC;AAAA,IACAe;AAAA,IACAlF;AAAA,IACAC;AAAA,IACAf;AAAA,IACAI;AAAA,IACAI;AAAA,EAAA,CACD;AAGD,QAAMkI,KAAsB,MACtB,CAACvH,KAAmBA,EAAgB,UAAU,IACzC,yBAIN,OAAA,EAAI,WAAU,2BACZ,UAAAA,EAAgB,IAAI,CAACoD,MAAU;AAC9B,UAAMoE,IAAWnH,GAAa,OAAO+C,EAAM;AAC3C,WACE,gBAAAqE;AAAA,MAACC;AAAA,MAAA;AAAA,QAEC,SAASF,IAAW,YAAY;AAAA,QAChC,MAAK;AAAA,QACL,SAAS,MAAM;AACb,UAAA/H,GAAiB2D,EAAM,EAAE,GACzB5F,KAAgB4F,EAAM,EAAE;AAAA,QAC1B;AAAA,QAEC,UAAAA,EAAM;AAAA,MAAA;AAAA,MARFA,EAAM;AAAA,IAAA;AAAA,EAWjB,CAAC,EAAA,CACH,GAKEoD,IAAiB3H,GAAc,YAAY,SAC3C8I,KAAiB9I,GAAc,YAAY,IAC3C+I,KAAoB/I,GAAc,eAAe,GACjDgJ,IAAmBhJ,GAAc,cAAc,IAC/CiJ,KAAcjJ,GAAc,OAG5BkJ,KAAc,KAGdC,IAAqBxB,MAAmB,SAASA,MAAmB,UAGpEyB,KAAe,MAAM;AACzB,UAAMC,IAAsB3H,MAAsB,iBAAiBsD,GAAY,SAAS,GAClFsE,IAAapK,KAAWA,EAAQ,SAAS;AAE/C,QAAI,CAACa,MAAe,CAACsJ,KAAuB,CAACC;AAE3C,aAAKH,IAGE,OAFE,gBAAAP,EAAC,SAAI,WAAU,+BAA8B,OAAO,EAAE,OAAOM,MAAe;AAMvF,UAAMK,IAAmB,CAAC,iBAAiB;AAC3C,IAAIJ,IACFI,EAAiB,KAAK,6BAA6B,IAC1C5B,MAAmB,SAC5B4B,EAAiB,KAAK,uBAAuB,IACpC5B,MAAmB,WAC5B4B,EAAiB,KAAK,wBAAwB;AAIhD,UAAMC,IAAmC;AAAA,MACvC,KAAK,GAAGT,EAAiB;AAAA,MACzB,OAAOI,IAAqB,SAAYD;AAAA,IAAA;AAG1C,WACE,gBAAAO,EAAC,SAAI,WAAWF,EAAiB,KAAK,GAAG,GAAG,OAAOC,GAChD,UAAA;AAAA,MAAAP,MACC,gBAAAL;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,yBAAyBO,IAAqB,wCAAwC,EAAE;AAAA,UACnG,OAAO,EAAE,UAAU,GAAGL,EAAc,KAAA;AAAA,UAEnC,UAAAG;AAAA,QAAA;AAAA,MAAA;AAAA,MAIJI,KACCrE,GAAY,IAAI,CAACO,MACf,gBAAAkE,EAAC,OAAA,EAAe,WAAU,yBACxB,UAAA;AAAA,QAAA,gBAAAb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO,GAAGI,CAAgB;AAAA,cAC1B,QAAQ,GAAGA,CAAgB;AAAA,cAC3B,iBAAiBjH,EAAewD,CAAI,KAAK3F;AAAA,YAAA;AAAA,UAC3C;AAAA,QAAA;AAAA,QAEF,gBAAAgJ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,UAAU,GAAGE,EAAc,KAAA;AAAA,YAEnC,UAAAvD;AAAA,UAAA;AAAA,QAAA;AAAA,MACH,EAAA,GAdQA,CAeV,CACD;AAAA,MAEF+D,KACCpK,EAAQ,IAAI,CAACgH,MACX,gBAAAuD,EAAC,OAAA,EAAoB,WAAU,yBAC7B,UAAA;AAAA,QAAA,gBAAAb;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO,GAAGI,CAAgB;AAAA,cAC1B,QAAQ,GAAGA,CAAgB;AAAA,cAC3B,iBAAiB9C,EAAO,aAAa;AAAA,cACrC,QAAQ,GAAGA,EAAO,eAAe,CAAC,YAAYA,EAAO,eAAerG,GAAO,YAAY;AAAA,YAAA;AAAA,UACzF;AAAA,QAAA;AAAA,QAEF,gBAAA+I;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO,EAAE,UAAU,GAAGE,EAAc,KAAA;AAAA,YAEnC,UAAA5C,EAAO;AAAA,UAAA;AAAA,QAAA;AAAA,MACV,EAAA,GAfQA,EAAO,EAgBjB,CACD;AAAA,IAAA,GACL;AAAA,EAEJ,GAGMwD,IAAc,gBAAAd,EAAC,OAAA,EAAI,KAAKtI,IAAS,WAAU,iBAAgB,OAAO,EAAE,OAAAL,GAAO,QAAAC,EAAA,EAAO,CAAG,GACrFyJ,IAAgBP,GAAA,GAEhBQ,KAAuB,MAAM;AACjC,YAAQjC,GAAA;AAAA,MACN,KAAK;AACH,eACE,gBAAA8B,EAAC,OAAA,EAAI,WAAU,yDACZ,UAAA;AAAA,UAAAE;AAAA,UACAD;AAAA,QAAA,GACH;AAAA,MAEJ,KAAK;AACH,eACE,gBAAAD,EAAC,OAAA,EAAI,WAAU,2DACZ,UAAA;AAAA,UAAAE;AAAA,UACAD;AAAA,QAAA,GACH;AAAA,MAEJ,KAAK;AACH,eACE,gBAAAD,EAAC,OAAA,EAAI,WAAU,2DACZ,UAAA;AAAA,UAAAC;AAAA,UACAC;AAAA,QAAA,GACH;AAAA,MAGJ;AACE,eACE,gBAAAF,EAAC,OAAA,EAAI,WAAU,yDACZ,UAAA;AAAA,UAAAC;AAAA,UACAC;AAAA,QAAA,GACH;AAAA,IAAA;AAAA,EAGR;AAEA,SACE,gBAAAF,EAAC,OAAA,EAAI,WAAU,sBAAqB,OAAO,EAAE,OAAON,IAAqB,SAAYlJ,EAAA,GAClF,UAAA;AAAA,IAAAyI,GAAA;AAAA,IACAkB,GAAA;AAAA,EAAqB,GACxB;AAEJ;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("./types.cjs"),O={sample:"#4575b4",control:"#d73027",empty:"#f0f0f0"},A={[f.PLATE_FORMAT_96]:{rows:8,columns:12},[f.PLATE_FORMAT_384]:{rows:16,columns:24},[f.PLATE_FORMAT_1536]:{rows:32,columns:48}},_=[[0,"#313695"],[.1,"#4575b4"],[.2,"#74add1"],[.3,"#abd9e9"],[.4,"#e0f3f8"],[.5,"#ffffbf"],[.6,"#fee090"],[.7,"#fdae61"],[.8,"#f46d43"],[.9,"#d73027"],[1,"#a50026"]],L={textDark:"#333",regionBorder:"#000",emptyWell:"#f0f0f0"},e={Viridis:[[0,"#440154"],[.25,"#414487"],[.5,"#2a788e"],[.75,"#22a884"],[1,"#7ad151"]],Blues:[[0,"#f7fbff"],[.25,"#c6dbef"],[.5,"#6baed6"],[.75,"#2171b5"],[1,"#08306b"]],RdBu:[[0,"#67001f"],[.25,"#d6604d"],[.5,"#f7f7f7"],[.75,"#4393c3"],[1,"#053061"]],Greens:[[0,"#f7fcf5"],[.25,"#c7e9c0"],[.5,"#74c476"],[.75,"#238b45"],[1,"#00441b"]],Reds:[[0,"#fff5f0"],[.25,"#fcbba1"],[.5,"#fb6a4a"],[.75,"#cb181d"],[1,"#67000d"]],Greys:[[0,"#ffffff"],[.25,"#d9d9d9"],[.5,"#969696"],[.75,"#525252"],[1,"#000000"]],Hot:[[0,"#000000"],[.33,"#e60000"],[.66,"#ffff00"],[1,"#ffffff"]],YlGnBu:[[0,"#ffffd9"],[.25,"#c7e9b4"],[.5,"#41b6c4"],[.75,"#225ea8"],[1,"#081d58"]],YlOrRd:[[0,"#ffffcc"],[.25,"#fed976"],[.5,"#fd8d3c"],[.75,"#e31a1c"],[1,"#800026"]],Plasma:[[0,"#0d0887"],[.25,"#7e03a8"],[.5,"#cc4778"],[.75,"#f89540"],[1,"#f0f921"]]},E={MAX_RANDOM_VALUE:5e4,SENTINEL_RATIO:.01,COLOR_SCALE_THRESHOLD:.99,COLOR_SCALE_EPSILON:.001,MULTI_VALUE_PRIMARY_RATIO:.575,MULTI_VALUE_SECONDARY_RATIO:.425,FONT_SIZE_LARGE:11,LABEL_CENTER_OFFSET:-.5,MARGIN_TOP:70,MARGIN_RIGHT:50,MARGIN_BOTTOM:40,MARGIN_LEFT:80,COLORBAR_LENGTH:130,DOMAIN_COLORBAR_OFFSET:.15,DOMAIN_COLORBAR_END:.85};exports.COLORS=L;exports.DEFAULT_CATEGORY_COLORS=O;exports.DEFAULT_COLOR_SCALE=_;exports.NAMED_COLORSCALES=e;exports.PLATEMAP_CONSTANTS=E;exports.PLATE_CONFIGS=A;
|
|
2
|
+
//# sourceMappingURL=constants.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.cjs","sources":["../../../../src/components/charts/PlateMap/constants.ts"],"sourcesContent":["import {\n PLATE_FORMAT_96,\n PLATE_FORMAT_384,\n PLATE_FORMAT_1536,\n} from \"./types\";\n\n/**\n * Default category colors for well types in categorical visualization mode.\n * Override these by passing custom colors via the `categoryColors` prop.\n */\nexport const DEFAULT_CATEGORY_COLORS: Record<string, string> = {\n sample: \"#4575b4\", // Blue\n control: \"#d73027\", // Red\n empty: \"#f0f0f0\", // Light gray\n};\n\n/**\n * Plate dimension configurations\n */\nexport const PLATE_CONFIGS: Record<\n typeof PLATE_FORMAT_96 | typeof PLATE_FORMAT_384 | typeof PLATE_FORMAT_1536,\n { rows: number; columns: number }\n> = {\n [PLATE_FORMAT_96]: { rows: 8, columns: 12 },\n [PLATE_FORMAT_384]: { rows: 16, columns: 24 },\n [PLATE_FORMAT_1536]: { rows: 32, columns: 48 },\n};\n\n/**\n * Default color scale (blue to red gradient suitable for plate data)\n */\nexport const DEFAULT_COLOR_SCALE: Array<[number, string]> = [\n [0, \"#313695\"],\n [0.1, \"#4575b4\"],\n [0.2, \"#74add1\"],\n [0.3, \"#abd9e9\"],\n [0.4, \"#e0f3f8\"],\n [0.5, \"#ffffbf\"],\n [0.6, \"#fee090\"],\n [0.7, \"#fdae61\"],\n [0.8, \"#f46d43\"],\n [0.9, \"#d73027\"],\n [1, \"#a50026\"],\n];\n\n/**\n * UI color constants for PlateMap component styling\n */\nexport const COLORS = {\n /** Primary blue color for active states */\n primary: \"#4575b4\",\n /** White background */\n white: \"#fff\",\n /** Light gray for borders */\n borderLight: \"#ccc\",\n /** Dark gray for text */\n textDark: \"#333\",\n /** Default region border color */\n regionBorder: \"#000\",\n /** Default empty well color (light gray) */\n emptyWell: \"#f0f0f0\",\n} as const;\n\n/**\n * Named Plotly colorscales converted to array format.\n * Used to extend colorscales with emptyWellColor when there are null values.\n * Reference: https://plotly.com/javascript/colorscales/\n */\nexport const NAMED_COLORSCALES: Record<string, Array<[number, string]>> = {\n Viridis: [\n [0, \"#440154\"],\n [0.25, \"#414487\"],\n [0.5, \"#2a788e\"],\n [0.75, \"#22a884\"],\n [1, \"#7ad151\"],\n ],\n Blues: [\n [0, \"#f7fbff\"],\n [0.25, \"#c6dbef\"],\n [0.5, \"#6baed6\"],\n [0.75, \"#2171b5\"],\n [1, \"#08306b\"],\n ],\n RdBu: [\n [0, \"#67001f\"],\n [0.25, \"#d6604d\"],\n [0.5, \"#f7f7f7\"],\n [0.75, \"#4393c3\"],\n [1, \"#053061\"],\n ],\n Greens: [\n [0, \"#f7fcf5\"],\n [0.25, \"#c7e9c0\"],\n [0.5, \"#74c476\"],\n [0.75, \"#238b45\"],\n [1, \"#00441b\"],\n ],\n Reds: [\n [0, \"#fff5f0\"],\n [0.25, \"#fcbba1\"],\n [0.5, \"#fb6a4a\"],\n [0.75, \"#cb181d\"],\n [1, \"#67000d\"],\n ],\n Greys: [\n [0, \"#ffffff\"],\n [0.25, \"#d9d9d9\"],\n [0.5, \"#969696\"],\n [0.75, \"#525252\"],\n [1, \"#000000\"],\n ],\n Hot: [\n [0, \"#000000\"],\n [0.33, \"#e60000\"],\n [0.66, \"#ffff00\"],\n [1, \"#ffffff\"],\n ],\n YlGnBu: [\n [0, \"#ffffd9\"],\n [0.25, \"#c7e9b4\"],\n [0.5, \"#41b6c4\"],\n [0.75, \"#225ea8\"],\n [1, \"#081d58\"],\n ],\n YlOrRd: [\n [0, \"#ffffcc\"],\n [0.25, \"#fed976\"],\n [0.5, \"#fd8d3c\"],\n [0.75, \"#e31a1c\"],\n [1, \"#800026\"],\n ],\n Plasma: [\n [0, \"#0d0887\"],\n [0.25, \"#7e03a8\"],\n [0.5, \"#cc4778\"],\n [0.75, \"#f89540\"],\n [1, \"#f0f921\"],\n ],\n};\n\n/**\n * Numeric constants for PlateMap calculations and layout\n */\nexport const PLATEMAP_CONSTANTS = {\n /** Maximum random data value for demonstration */\n MAX_RANDOM_VALUE: 50000,\n /** Sentinel value ratio for empty wells below data range */\n SENTINEL_RATIO: 0.01,\n /** Color scale data start ratio for extended scales */\n COLOR_SCALE_THRESHOLD: 0.99,\n /** Small epsilon for color scale band calculations */\n COLOR_SCALE_EPSILON: 0.001,\n /** Proportions for multi-value well display */\n MULTI_VALUE_PRIMARY_RATIO: 0.575,\n MULTI_VALUE_SECONDARY_RATIO: 0.425,\n /** Font sizes */\n FONT_SIZE_LARGE: 11,\n /** Offset for centering labels */\n LABEL_CENTER_OFFSET: -0.5,\n /** Opacity values */\n HOVER_OPACITY_FAINT: 0.15,\n HOVER_OPACITY_VISIBLE: 0.85,\n /** Layout margins */\n MARGIN_TOP: 70,\n MARGIN_RIGHT: 50,\n MARGIN_BOTTOM: 40,\n MARGIN_LEFT: 80,\n /** Colorbar dimensions */\n COLORBAR_LENGTH: 130,\n COLORBAR_X_OFFSET: 70,\n /** Domain position constants for legend placement */\n DOMAIN_COLORBAR_OFFSET: 0.15,\n DOMAIN_COLORBAR_END: 0.85,\n} as const;\n"],"names":["DEFAULT_CATEGORY_COLORS","PLATE_CONFIGS","PLATE_FORMAT_96","PLATE_FORMAT_384","PLATE_FORMAT_1536","DEFAULT_COLOR_SCALE","COLORS","NAMED_COLORSCALES","PLATEMAP_CONSTANTS"],"mappings":"+GAUaA,EAAkD,CAC7D,OAAQ,UACR,QAAS,UACT,MAAO,SACT,EAKaC,EAGT,CACF,CAACC,EAAAA,eAAe,EAAG,CAAE,KAAM,EAAG,QAAS,EAAA,EACvC,CAACC,EAAAA,gBAAgB,EAAG,CAAE,KAAM,GAAI,QAAS,EAAA,EACzC,CAACC,EAAAA,iBAAiB,EAAG,CAAE,KAAM,GAAI,QAAS,EAAA,CAC5C,EAKaC,EAA+C,CAC1D,CAAC,EAAG,SAAS,EACb,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,GAAK,SAAS,EACf,CAAC,EAAG,SAAS,CACf,EAKaC,EAAS,CAQpB,SAAU,OAEV,aAAc,OAEd,UAAW,SACb,EAOaC,EAA6D,CACxE,QAAS,CACP,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,MAAO,CACL,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,KAAM,CACJ,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,OAAQ,CACN,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,KAAM,CACJ,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,MAAO,CACL,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,IAAK,CACH,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,OAAQ,CACN,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,OAAQ,CACN,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,EAEf,OAAQ,CACN,CAAC,EAAG,SAAS,EACb,CAAC,IAAM,SAAS,EAChB,CAAC,GAAK,SAAS,EACf,CAAC,IAAM,SAAS,EAChB,CAAC,EAAG,SAAS,CAAA,CAEjB,EAKaC,EAAqB,CAEhC,iBAAkB,IAElB,eAAgB,IAEhB,sBAAuB,IAEvB,oBAAqB,KAErB,0BAA2B,KAC3B,4BAA6B,KAE7B,gBAAiB,GAEjB,oBAAqB,IAKrB,WAAY,GACZ,aAAc,GACd,cAAe,GACf,YAAa,GAEb,gBAAiB,IAGjB,uBAAwB,IACxB,oBAAqB,GACvB"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { PLATE_FORMAT_1536 as f, PLATE_FORMAT_384 as O, PLATE_FORMAT_96 as A } from "./types.js";
|
|
2
|
+
const R = {
|
|
3
|
+
sample: "#4575b4",
|
|
4
|
+
// Blue
|
|
5
|
+
control: "#d73027",
|
|
6
|
+
// Red
|
|
7
|
+
empty: "#f0f0f0"
|
|
8
|
+
// Light gray
|
|
9
|
+
}, L = {
|
|
10
|
+
[A]: { rows: 8, columns: 12 },
|
|
11
|
+
[O]: { rows: 16, columns: 24 },
|
|
12
|
+
[f]: { rows: 32, columns: 48 }
|
|
13
|
+
}, E = [
|
|
14
|
+
[0, "#313695"],
|
|
15
|
+
[0.1, "#4575b4"],
|
|
16
|
+
[0.2, "#74add1"],
|
|
17
|
+
[0.3, "#abd9e9"],
|
|
18
|
+
[0.4, "#e0f3f8"],
|
|
19
|
+
[0.5, "#ffffbf"],
|
|
20
|
+
[0.6, "#fee090"],
|
|
21
|
+
[0.7, "#fdae61"],
|
|
22
|
+
[0.8, "#f46d43"],
|
|
23
|
+
[0.9, "#d73027"],
|
|
24
|
+
[1, "#a50026"]
|
|
25
|
+
], e = {
|
|
26
|
+
/** Dark gray for text */
|
|
27
|
+
textDark: "#333",
|
|
28
|
+
/** Default region border color */
|
|
29
|
+
regionBorder: "#000",
|
|
30
|
+
/** Default empty well color (light gray) */
|
|
31
|
+
emptyWell: "#f0f0f0"
|
|
32
|
+
}, T = {
|
|
33
|
+
Viridis: [
|
|
34
|
+
[0, "#440154"],
|
|
35
|
+
[0.25, "#414487"],
|
|
36
|
+
[0.5, "#2a788e"],
|
|
37
|
+
[0.75, "#22a884"],
|
|
38
|
+
[1, "#7ad151"]
|
|
39
|
+
],
|
|
40
|
+
Blues: [
|
|
41
|
+
[0, "#f7fbff"],
|
|
42
|
+
[0.25, "#c6dbef"],
|
|
43
|
+
[0.5, "#6baed6"],
|
|
44
|
+
[0.75, "#2171b5"],
|
|
45
|
+
[1, "#08306b"]
|
|
46
|
+
],
|
|
47
|
+
RdBu: [
|
|
48
|
+
[0, "#67001f"],
|
|
49
|
+
[0.25, "#d6604d"],
|
|
50
|
+
[0.5, "#f7f7f7"],
|
|
51
|
+
[0.75, "#4393c3"],
|
|
52
|
+
[1, "#053061"]
|
|
53
|
+
],
|
|
54
|
+
Greens: [
|
|
55
|
+
[0, "#f7fcf5"],
|
|
56
|
+
[0.25, "#c7e9c0"],
|
|
57
|
+
[0.5, "#74c476"],
|
|
58
|
+
[0.75, "#238b45"],
|
|
59
|
+
[1, "#00441b"]
|
|
60
|
+
],
|
|
61
|
+
Reds: [
|
|
62
|
+
[0, "#fff5f0"],
|
|
63
|
+
[0.25, "#fcbba1"],
|
|
64
|
+
[0.5, "#fb6a4a"],
|
|
65
|
+
[0.75, "#cb181d"],
|
|
66
|
+
[1, "#67000d"]
|
|
67
|
+
],
|
|
68
|
+
Greys: [
|
|
69
|
+
[0, "#ffffff"],
|
|
70
|
+
[0.25, "#d9d9d9"],
|
|
71
|
+
[0.5, "#969696"],
|
|
72
|
+
[0.75, "#525252"],
|
|
73
|
+
[1, "#000000"]
|
|
74
|
+
],
|
|
75
|
+
Hot: [
|
|
76
|
+
[0, "#000000"],
|
|
77
|
+
[0.33, "#e60000"],
|
|
78
|
+
[0.66, "#ffff00"],
|
|
79
|
+
[1, "#ffffff"]
|
|
80
|
+
],
|
|
81
|
+
YlGnBu: [
|
|
82
|
+
[0, "#ffffd9"],
|
|
83
|
+
[0.25, "#c7e9b4"],
|
|
84
|
+
[0.5, "#41b6c4"],
|
|
85
|
+
[0.75, "#225ea8"],
|
|
86
|
+
[1, "#081d58"]
|
|
87
|
+
],
|
|
88
|
+
YlOrRd: [
|
|
89
|
+
[0, "#ffffcc"],
|
|
90
|
+
[0.25, "#fed976"],
|
|
91
|
+
[0.5, "#fd8d3c"],
|
|
92
|
+
[0.75, "#e31a1c"],
|
|
93
|
+
[1, "#800026"]
|
|
94
|
+
],
|
|
95
|
+
Plasma: [
|
|
96
|
+
[0, "#0d0887"],
|
|
97
|
+
[0.25, "#7e03a8"],
|
|
98
|
+
[0.5, "#cc4778"],
|
|
99
|
+
[0.75, "#f89540"],
|
|
100
|
+
[1, "#f0f921"]
|
|
101
|
+
]
|
|
102
|
+
}, d = {
|
|
103
|
+
/** Maximum random data value for demonstration */
|
|
104
|
+
MAX_RANDOM_VALUE: 5e4,
|
|
105
|
+
/** Sentinel value ratio for empty wells below data range */
|
|
106
|
+
SENTINEL_RATIO: 0.01,
|
|
107
|
+
/** Color scale data start ratio for extended scales */
|
|
108
|
+
COLOR_SCALE_THRESHOLD: 0.99,
|
|
109
|
+
/** Small epsilon for color scale band calculations */
|
|
110
|
+
COLOR_SCALE_EPSILON: 1e-3,
|
|
111
|
+
/** Proportions for multi-value well display */
|
|
112
|
+
MULTI_VALUE_PRIMARY_RATIO: 0.575,
|
|
113
|
+
MULTI_VALUE_SECONDARY_RATIO: 0.425,
|
|
114
|
+
/** Font sizes */
|
|
115
|
+
FONT_SIZE_LARGE: 11,
|
|
116
|
+
/** Offset for centering labels */
|
|
117
|
+
LABEL_CENTER_OFFSET: -0.5,
|
|
118
|
+
/** Layout margins */
|
|
119
|
+
MARGIN_TOP: 70,
|
|
120
|
+
MARGIN_RIGHT: 50,
|
|
121
|
+
MARGIN_BOTTOM: 40,
|
|
122
|
+
MARGIN_LEFT: 80,
|
|
123
|
+
/** Colorbar dimensions */
|
|
124
|
+
COLORBAR_LENGTH: 130,
|
|
125
|
+
/** Domain position constants for legend placement */
|
|
126
|
+
DOMAIN_COLORBAR_OFFSET: 0.15,
|
|
127
|
+
DOMAIN_COLORBAR_END: 0.85
|
|
128
|
+
};
|
|
129
|
+
export {
|
|
130
|
+
e as COLORS,
|
|
131
|
+
R as DEFAULT_CATEGORY_COLORS,
|
|
132
|
+
E as DEFAULT_COLOR_SCALE,
|
|
133
|
+
T as NAMED_COLORSCALES,
|
|
134
|
+
d as PLATEMAP_CONSTANTS,
|
|
135
|
+
L as PLATE_CONFIGS
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../../src/components/charts/PlateMap/constants.ts"],"sourcesContent":["import {\n PLATE_FORMAT_96,\n PLATE_FORMAT_384,\n PLATE_FORMAT_1536,\n} from \"./types\";\n\n/**\n * Default category colors for well types in categorical visualization mode.\n * Override these by passing custom colors via the `categoryColors` prop.\n */\nexport const DEFAULT_CATEGORY_COLORS: Record<string, string> = {\n sample: \"#4575b4\", // Blue\n control: \"#d73027\", // Red\n empty: \"#f0f0f0\", // Light gray\n};\n\n/**\n * Plate dimension configurations\n */\nexport const PLATE_CONFIGS: Record<\n typeof PLATE_FORMAT_96 | typeof PLATE_FORMAT_384 | typeof PLATE_FORMAT_1536,\n { rows: number; columns: number }\n> = {\n [PLATE_FORMAT_96]: { rows: 8, columns: 12 },\n [PLATE_FORMAT_384]: { rows: 16, columns: 24 },\n [PLATE_FORMAT_1536]: { rows: 32, columns: 48 },\n};\n\n/**\n * Default color scale (blue to red gradient suitable for plate data)\n */\nexport const DEFAULT_COLOR_SCALE: Array<[number, string]> = [\n [0, \"#313695\"],\n [0.1, \"#4575b4\"],\n [0.2, \"#74add1\"],\n [0.3, \"#abd9e9\"],\n [0.4, \"#e0f3f8\"],\n [0.5, \"#ffffbf\"],\n [0.6, \"#fee090\"],\n [0.7, \"#fdae61\"],\n [0.8, \"#f46d43\"],\n [0.9, \"#d73027\"],\n [1, \"#a50026\"],\n];\n\n/**\n * UI color constants for PlateMap component styling\n */\nexport const COLORS = {\n /** Primary blue color for active states */\n primary: \"#4575b4\",\n /** White background */\n white: \"#fff\",\n /** Light gray for borders */\n borderLight: \"#ccc\",\n /** Dark gray for text */\n textDark: \"#333\",\n /** Default region border color */\n regionBorder: \"#000\",\n /** Default empty well color (light gray) */\n emptyWell: \"#f0f0f0\",\n} as const;\n\n/**\n * Named Plotly colorscales converted to array format.\n * Used to extend colorscales with emptyWellColor when there are null values.\n * Reference: https://plotly.com/javascript/colorscales/\n */\nexport const NAMED_COLORSCALES: Record<string, Array<[number, string]>> = {\n Viridis: [\n [0, \"#440154\"],\n [0.25, \"#414487\"],\n [0.5, \"#2a788e\"],\n [0.75, \"#22a884\"],\n [1, \"#7ad151\"],\n ],\n Blues: [\n [0, \"#f7fbff\"],\n [0.25, \"#c6dbef\"],\n [0.5, \"#6baed6\"],\n [0.75, \"#2171b5\"],\n [1, \"#08306b\"],\n ],\n RdBu: [\n [0, \"#67001f\"],\n [0.25, \"#d6604d\"],\n [0.5, \"#f7f7f7\"],\n [0.75, \"#4393c3\"],\n [1, \"#053061\"],\n ],\n Greens: [\n [0, \"#f7fcf5\"],\n [0.25, \"#c7e9c0\"],\n [0.5, \"#74c476\"],\n [0.75, \"#238b45\"],\n [1, \"#00441b\"],\n ],\n Reds: [\n [0, \"#fff5f0\"],\n [0.25, \"#fcbba1\"],\n [0.5, \"#fb6a4a\"],\n [0.75, \"#cb181d\"],\n [1, \"#67000d\"],\n ],\n Greys: [\n [0, \"#ffffff\"],\n [0.25, \"#d9d9d9\"],\n [0.5, \"#969696\"],\n [0.75, \"#525252\"],\n [1, \"#000000\"],\n ],\n Hot: [\n [0, \"#000000\"],\n [0.33, \"#e60000\"],\n [0.66, \"#ffff00\"],\n [1, \"#ffffff\"],\n ],\n YlGnBu: [\n [0, \"#ffffd9\"],\n [0.25, \"#c7e9b4\"],\n [0.5, \"#41b6c4\"],\n [0.75, \"#225ea8\"],\n [1, \"#081d58\"],\n ],\n YlOrRd: [\n [0, \"#ffffcc\"],\n [0.25, \"#fed976\"],\n [0.5, \"#fd8d3c\"],\n [0.75, \"#e31a1c\"],\n [1, \"#800026\"],\n ],\n Plasma: [\n [0, \"#0d0887\"],\n [0.25, \"#7e03a8\"],\n [0.5, \"#cc4778\"],\n [0.75, \"#f89540\"],\n [1, \"#f0f921\"],\n ],\n};\n\n/**\n * Numeric constants for PlateMap calculations and layout\n */\nexport const PLATEMAP_CONSTANTS = {\n /** Maximum random data value for demonstration */\n MAX_RANDOM_VALUE: 50000,\n /** Sentinel value ratio for empty wells below data range */\n SENTINEL_RATIO: 0.01,\n /** Color scale data start ratio for extended scales */\n COLOR_SCALE_THRESHOLD: 0.99,\n /** Small epsilon for color scale band calculations */\n COLOR_SCALE_EPSILON: 0.001,\n /** Proportions for multi-value well display */\n MULTI_VALUE_PRIMARY_RATIO: 0.575,\n MULTI_VALUE_SECONDARY_RATIO: 0.425,\n /** Font sizes */\n FONT_SIZE_LARGE: 11,\n /** Offset for centering labels */\n LABEL_CENTER_OFFSET: -0.5,\n /** Opacity values */\n HOVER_OPACITY_FAINT: 0.15,\n HOVER_OPACITY_VISIBLE: 0.85,\n /** Layout margins */\n MARGIN_TOP: 70,\n MARGIN_RIGHT: 50,\n MARGIN_BOTTOM: 40,\n MARGIN_LEFT: 80,\n /** Colorbar dimensions */\n COLORBAR_LENGTH: 130,\n COLORBAR_X_OFFSET: 70,\n /** Domain position constants for legend placement */\n DOMAIN_COLORBAR_OFFSET: 0.15,\n DOMAIN_COLORBAR_END: 0.85,\n} as const;\n"],"names":["DEFAULT_CATEGORY_COLORS","PLATE_CONFIGS","PLATE_FORMAT_96","PLATE_FORMAT_384","PLATE_FORMAT_1536","DEFAULT_COLOR_SCALE","COLORS","NAMED_COLORSCALES","PLATEMAP_CONSTANTS"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.cjs","sources":["../../../../src/components/charts/PlateMap/types.ts"],"sourcesContent":["/**\n * Plate format string constants for standard microplate configurations.\n */\nexport const PLATE_FORMAT_96 = \"96\" as const;\nexport const PLATE_FORMAT_384 = \"384\" as const;\nexport const PLATE_FORMAT_1536 = \"1536\" as const;\nexport const PLATE_FORMAT_CUSTOM = \"custom\" as const;\n\n/**\n * Plate format presets for standard microplate configurations.\n * - `\"96\"`: 8 rows × 12 columns (wells A1-H12)\n * - `\"384\"`: 16 rows × 24 columns (wells A1-P24)\n * - `\"1536\"`: 32 rows × 48 columns (wells A1-AF48)\n * - `\"custom\"`: User-defined dimensions via `rows` and `columns` props\n */\nexport type PlateFormat =\n | typeof PLATE_FORMAT_96\n | typeof PLATE_FORMAT_384\n | typeof PLATE_FORMAT_1536\n | typeof PLATE_FORMAT_CUSTOM;\n\n/**\n * Visualization mode for the plate map.\n * - `\"heatmap\"`: Displays quantitative values as a continuous color gradient.\n * Use for OD readings, fluorescence intensity, or other numeric measurements.\n * - `\"categorical\"`: Displays well types with discrete colors.\n * Use for showing sample types, control positions, or experimental conditions.\n */\nexport type VisualizationMode = \"heatmap\" | \"categorical\";\n\n/**\n * Well type for categorical visualization.\n * Common types include:\n * - `\"sample\"`: Test samples (blue by default)\n * - `\"control\"`: Positive/negative controls (red by default)\n * - `\"empty\"`: Unused wells (light gray by default)\n *\n * Custom types can be added and colored via the `categoryColors` prop.\n */\nexport type WellType = \"sample\" | \"control\" | \"empty\" | string;\n\n/**\n * Color scale definition for the heatmap visualization mode.\n *\n * Can be:\n * - A named Plotly colorscale (e.g., \"Viridis\", \"Blues\", \"Hot\")\n * - An array of [position, color] tuples where position is 0-1\n *\n * @example\n * // Named colorscale\n * colorScale=\"Viridis\"\n *\n * @example\n * // Custom gradient\n * colorScale={[\n * [0, \"#313695\"], // Dark blue at min\n * [0.5, \"#ffffbf\"], // Yellow at midpoint\n * [1, \"#a50026\"], // Dark red at max\n * ]}\n */\nexport type ColorScale = string | Array<[number, string]>;\n\n/**\n * Position for the legend display.\n * - `\"right\"`: Legend appears to the right of the plate (default)\n * - `\"bottom\"`: Legend appears below the plate\n * - `\"left\"`: Legend appears to the left of the plate\n * - `\"top\"`: Legend appears above the plate\n */\nexport type LegendPosition = \"right\" | \"bottom\" | \"left\" | \"top\";\n\n/**\n * Well data for individual wells.\n *\n * @example\n * // Well with a single numeric value\n * { wellId: \"A1\", values: { \"Fluorescence\": 1500 } }\n *\n * @example\n * // Well with multiple values (creates multiple layers)\n * { wellId: \"A1\", values: { \"Raw\": 1500, \"Normalized\": 0.85, \"Status\": \"positive\" } }\n *\n * @example\n * // Well with tooltip-only data\n * { wellId: \"A1\", values: { \"Value\": 500 }, tooltipData: { compound: \"Drug A\", concentration: \"10µM\" } }\n */\nexport interface WellData {\n /**\n * Well identifier in standard microplate notation.\n * - Single letter + number for 96/384-well: \"A1\", \"H12\", \"P24\"\n * - Double letter + number for 1536-well: \"A1\", \"AA1\", \"AF48\"\n * Case-insensitive (\"a1\" and \"A1\" are equivalent).\n */\n wellId: string;\n /**\n * Named values for the well. Each key can become a visualization layer.\n *\n * - Numeric values: Displayed using heatmap visualization\n * - String values: Displayed using categorical visualization\n * - null: Empty/no data for that property\n *\n * All values are shown in the tooltip regardless of which layer is active.\n *\n * @example\n * // Well with multiple measurement values (numeric)\n * { wellId: \"A1\", values: { \"Raw\": 1500, \"Normalized\": 0.85, \"Z-Score\": 1.2 } }\n *\n * @example\n * // Well with categorical values (string)\n * { wellId: \"A1\", values: { \"Status\": \"positive\", \"QC\": \"pass\" } }\n *\n * @example\n * // Mixed numeric and categorical\n * { wellId: \"A1\", values: { \"Fluorescence\": 1500, \"Status\": \"positive\" } }\n */\n values?: Record<string, string | number | null>;\n /**\n * Optional data for tooltip display only (not visualized as layers).\n * Keys become labels, values are displayed.\n *\n * @example\n * { tooltipData: { sampleId: \"S001\", compound: \"Drug A\", concentration: \"10µM\" } }\n */\n tooltipData?: Record<string, unknown>;\n}\n\n/**\n * Configuration for auto-generated layers when using WellData with `values`.\n *\n * When wells have multiple values (via the `values` property), layers are\n * auto-generated from the unique keys. Use LayerConfig to customize the\n * display name, visualization mode, and color scale for each layer.\n *\n * @example\n * // Configure layers for wells with { values: { \"Raw\": 100, \"Normalized\": 0.5 } }\n * const layerConfigs: LayerConfig[] = [\n * { id: \"Raw\", name: \"Raw Data\", colorScale: \"Blues\" },\n * { id: \"Normalized\", name: \"Normalized Values\", valueMin: 0, valueMax: 1 },\n * ];\n */\nexport interface LayerConfig {\n /** Layer ID (must match a key in WellData.values) */\n id: string;\n /** Display name for the layer (defaults to id if not provided) */\n name?: string;\n /** Visualization mode for this layer */\n visualizationMode?: VisualizationMode;\n /** Color scale for this layer (for heatmap mode) */\n colorScale?: ColorScale;\n /** Minimum value for color scaling */\n valueMin?: number;\n /** Maximum value for color scaling */\n valueMax?: number;\n /** Value unit suffix for tooltips and colorbar (e.g., \"RFU\", \"%\"). A space is automatically added before the unit. */\n valueUnit?: string;\n /**\n * Custom colors for categorical visualization mode.\n * Keys are category values (strings from `values`), values are hex colors.\n * Merged with DEFAULT_CATEGORY_COLORS.\n */\n categoryColors?: Record<string, string>;\n}\n\n/**\n * Configuration for legend styling and positioning.\n *\n * @example\n * // Legend on the bottom with custom styling\n * legendConfig={{\n * position: \"bottom\",\n * fontSize: 14,\n * itemSpacing: 12,\n * swatchSize: 20,\n * }}\n */\nexport interface LegendConfig {\n /**\n * Position of the legend relative to the plate.\n * @default \"right\"\n */\n position?: LegendPosition;\n /**\n * Font size for legend labels in pixels.\n * @default 12\n */\n fontSize?: number;\n /**\n * Spacing between legend items in pixels.\n * @default 4\n */\n itemSpacing?: number;\n /**\n * Size of the color swatch in pixels.\n * @default 16\n */\n swatchSize?: number;\n /**\n * Title to display above the legend.\n */\n title?: string;\n}\n\n/**\n * A region to highlight on the plate (e.g., controls, sample areas, empty wells)\n */\nexport interface PlateRegion {\n /** Unique identifier for the region */\n id: string;\n /** Display name for the region (shown in legend) */\n name: string;\n /**\n * Wells included in this region using range notation.\n * Format: \"StartWell:EndWell\" (e.g., \"A1:B6\" for a rectangular block from A1 to B6)\n */\n wells: string;\n /** Border color for the region highlight */\n borderColor?: string;\n /** Border width in pixels (default: 2) */\n borderWidth?: number;\n /** Optional fill color with transparency (e.g., \"rgba(255, 0, 0, 0.1)\") */\n fillColor?: string;\n}\n\n/**\n * Props for PlateMap component\n */\nexport interface PlateMapProps {\n /**\n * Well data array as WellData objects with wellId and values.\n *\n * If wells have multiple values (via `values` property), layers are\n * auto-generated for each unique key, enabling layer toggling.\n */\n data?: WellData[];\n\n /**\n * Configuration for auto-generated layers when using WellData with `values`.\n * Use this to customize display names, colors, and ranges for each layer.\n * Only used when `data` contains wells with `values` property.\n */\n layerConfigs?: LayerConfig[];\n\n /**\n * Initial layer ID to display when the component mounts.\n * If not provided, defaults to the first layer.\n */\n initialLayerId?: string;\n\n /**\n * Optional callback notified when the active layer changes.\n * This is purely informational - the component manages layer state internally.\n * Use this for logging, analytics, or syncing with external state.\n */\n onLayerChange?: (layerId: string) => void;\n\n /** Plate format preset (default: \"96\") */\n plateFormat?: PlateFormat;\n\n /** Number of rows for custom format (default: 8 for 96-well, 16 for 384-well) */\n rows?: number;\n\n /** Number of columns for custom format (default: 12 for 96-well, 24 for 384-well) */\n columns?: number;\n\n /**\n * Visualization mode (default: \"heatmap\")\n * - \"heatmap\": Display quantitative values with color gradient\n * - \"categorical\": Display well types with discrete colors\n */\n visualizationMode?: VisualizationMode;\n\n /**\n * Custom colors for categorical visualization mode.\n * Keys are well types, values are hex colors.\n * Merged with DEFAULT_CATEGORY_COLORS.\n */\n categoryColors?: Record<string, string>;\n\n /**\n * Regions to highlight on the plate (e.g., controls, sample areas, empty wells).\n * Each region can specify wells and styling for visual distinction.\n */\n regions?: PlateRegion[];\n\n /** Chart title */\n title?: string;\n\n /** X-axis title (e.g., \"Columns\") */\n xTitle?: string;\n\n /** Y-axis title (e.g., \"Rows\") */\n yTitle?: string;\n\n /** Custom x-axis labels (overrides auto-generated column numbers) */\n xLabels?: string[] | number[];\n\n /** Custom y-axis labels (overrides auto-generated row letters) */\n yLabels?: string[] | number[];\n\n /** Color scale for the heatmap (only used in heatmap mode) */\n colorScale?: ColorScale;\n\n /** Minimum value for color scale (auto-calculated if not provided) */\n valueMin?: number;\n\n /** Maximum value for color scale (auto-calculated if not provided) */\n valueMax?: number;\n\n /** Color for empty/null wells (default: \"#f0f0f0\") */\n emptyWellColor?: string;\n\n /** Show color bar legend for heatmap mode (default: true) */\n showColorBar?: boolean;\n\n /** Show categorical legend for categorical mode (default: true) */\n showLegend?: boolean;\n\n /**\n * Configuration for legend positioning and styling.\n * Applies to both heatmap colorbar and categorical legend.\n *\n * @example\n * // Position legend at bottom with larger text\n * legendConfig={{ position: \"bottom\", fontSize: 14 }}\n */\n legendConfig?: LegendConfig;\n\n /** Chart width in pixels (default: 800) */\n width?: number;\n\n /** Chart height in pixels (default: 500) */\n height?: number;\n\n /** Number of decimal places for values (default: 0) */\n precision?: number;\n\n /**\n * Marker shape for wells (default: \"circle\")\n * - \"circle\": Round markers, ideal for plate-based data\n * - \"square\": Square markers, ideal for generic heatmaps\n */\n markerShape?: \"circle\" | \"square\";\n\n /**\n * Callback when a well/cell is clicked.\n * @param wellData - The full well data object including wellId, values, and tooltipData\n */\n onWellClick?: (wellData: WellData) => void;\n}\n\n/**\n * Result of converting WellData array to grids\n */\nexport interface WellDataGridResult {\n /** 2D grid of numeric values for the active layer */\n grid: (number | null)[][];\n /** 2D grid of string values for categorical visualization */\n categories: (string | null)[][];\n /** Map of wellId -> all values (for tooltip display) */\n allValues: Map<string, Record<string, string | number | null>>;\n /** Map of wellId -> tooltipData */\n tooltipData: Map<string, Record<string, unknown>>;\n}\n\n"],"names":["PLATE_FORMAT_96","PLATE_FORMAT_384","PLATE_FORMAT_1536","PLATE_FORMAT_CUSTOM"],"mappings":"gFAGO,MAAMA,EAAkB,KAClBC,EAAmB,MACnBC,EAAoB,OACpBC,EAAsB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../../src/components/charts/PlateMap/types.ts"],"sourcesContent":["/**\n * Plate format string constants for standard microplate configurations.\n */\nexport const PLATE_FORMAT_96 = \"96\" as const;\nexport const PLATE_FORMAT_384 = \"384\" as const;\nexport const PLATE_FORMAT_1536 = \"1536\" as const;\nexport const PLATE_FORMAT_CUSTOM = \"custom\" as const;\n\n/**\n * Plate format presets for standard microplate configurations.\n * - `\"96\"`: 8 rows × 12 columns (wells A1-H12)\n * - `\"384\"`: 16 rows × 24 columns (wells A1-P24)\n * - `\"1536\"`: 32 rows × 48 columns (wells A1-AF48)\n * - `\"custom\"`: User-defined dimensions via `rows` and `columns` props\n */\nexport type PlateFormat =\n | typeof PLATE_FORMAT_96\n | typeof PLATE_FORMAT_384\n | typeof PLATE_FORMAT_1536\n | typeof PLATE_FORMAT_CUSTOM;\n\n/**\n * Visualization mode for the plate map.\n * - `\"heatmap\"`: Displays quantitative values as a continuous color gradient.\n * Use for OD readings, fluorescence intensity, or other numeric measurements.\n * - `\"categorical\"`: Displays well types with discrete colors.\n * Use for showing sample types, control positions, or experimental conditions.\n */\nexport type VisualizationMode = \"heatmap\" | \"categorical\";\n\n/**\n * Well type for categorical visualization.\n * Common types include:\n * - `\"sample\"`: Test samples (blue by default)\n * - `\"control\"`: Positive/negative controls (red by default)\n * - `\"empty\"`: Unused wells (light gray by default)\n *\n * Custom types can be added and colored via the `categoryColors` prop.\n */\nexport type WellType = \"sample\" | \"control\" | \"empty\" | string;\n\n/**\n * Color scale definition for the heatmap visualization mode.\n *\n * Can be:\n * - A named Plotly colorscale (e.g., \"Viridis\", \"Blues\", \"Hot\")\n * - An array of [position, color] tuples where position is 0-1\n *\n * @example\n * // Named colorscale\n * colorScale=\"Viridis\"\n *\n * @example\n * // Custom gradient\n * colorScale={[\n * [0, \"#313695\"], // Dark blue at min\n * [0.5, \"#ffffbf\"], // Yellow at midpoint\n * [1, \"#a50026\"], // Dark red at max\n * ]}\n */\nexport type ColorScale = string | Array<[number, string]>;\n\n/**\n * Position for the legend display.\n * - `\"right\"`: Legend appears to the right of the plate (default)\n * - `\"bottom\"`: Legend appears below the plate\n * - `\"left\"`: Legend appears to the left of the plate\n * - `\"top\"`: Legend appears above the plate\n */\nexport type LegendPosition = \"right\" | \"bottom\" | \"left\" | \"top\";\n\n/**\n * Well data for individual wells.\n *\n * @example\n * // Well with a single numeric value\n * { wellId: \"A1\", values: { \"Fluorescence\": 1500 } }\n *\n * @example\n * // Well with multiple values (creates multiple layers)\n * { wellId: \"A1\", values: { \"Raw\": 1500, \"Normalized\": 0.85, \"Status\": \"positive\" } }\n *\n * @example\n * // Well with tooltip-only data\n * { wellId: \"A1\", values: { \"Value\": 500 }, tooltipData: { compound: \"Drug A\", concentration: \"10µM\" } }\n */\nexport interface WellData {\n /**\n * Well identifier in standard microplate notation.\n * - Single letter + number for 96/384-well: \"A1\", \"H12\", \"P24\"\n * - Double letter + number for 1536-well: \"A1\", \"AA1\", \"AF48\"\n * Case-insensitive (\"a1\" and \"A1\" are equivalent).\n */\n wellId: string;\n /**\n * Named values for the well. Each key can become a visualization layer.\n *\n * - Numeric values: Displayed using heatmap visualization\n * - String values: Displayed using categorical visualization\n * - null: Empty/no data for that property\n *\n * All values are shown in the tooltip regardless of which layer is active.\n *\n * @example\n * // Well with multiple measurement values (numeric)\n * { wellId: \"A1\", values: { \"Raw\": 1500, \"Normalized\": 0.85, \"Z-Score\": 1.2 } }\n *\n * @example\n * // Well with categorical values (string)\n * { wellId: \"A1\", values: { \"Status\": \"positive\", \"QC\": \"pass\" } }\n *\n * @example\n * // Mixed numeric and categorical\n * { wellId: \"A1\", values: { \"Fluorescence\": 1500, \"Status\": \"positive\" } }\n */\n values?: Record<string, string | number | null>;\n /**\n * Optional data for tooltip display only (not visualized as layers).\n * Keys become labels, values are displayed.\n *\n * @example\n * { tooltipData: { sampleId: \"S001\", compound: \"Drug A\", concentration: \"10µM\" } }\n */\n tooltipData?: Record<string, unknown>;\n}\n\n/**\n * Configuration for auto-generated layers when using WellData with `values`.\n *\n * When wells have multiple values (via the `values` property), layers are\n * auto-generated from the unique keys. Use LayerConfig to customize the\n * display name, visualization mode, and color scale for each layer.\n *\n * @example\n * // Configure layers for wells with { values: { \"Raw\": 100, \"Normalized\": 0.5 } }\n * const layerConfigs: LayerConfig[] = [\n * { id: \"Raw\", name: \"Raw Data\", colorScale: \"Blues\" },\n * { id: \"Normalized\", name: \"Normalized Values\", valueMin: 0, valueMax: 1 },\n * ];\n */\nexport interface LayerConfig {\n /** Layer ID (must match a key in WellData.values) */\n id: string;\n /** Display name for the layer (defaults to id if not provided) */\n name?: string;\n /** Visualization mode for this layer */\n visualizationMode?: VisualizationMode;\n /** Color scale for this layer (for heatmap mode) */\n colorScale?: ColorScale;\n /** Minimum value for color scaling */\n valueMin?: number;\n /** Maximum value for color scaling */\n valueMax?: number;\n /** Value unit suffix for tooltips and colorbar (e.g., \"RFU\", \"%\"). A space is automatically added before the unit. */\n valueUnit?: string;\n /**\n * Custom colors for categorical visualization mode.\n * Keys are category values (strings from `values`), values are hex colors.\n * Merged with DEFAULT_CATEGORY_COLORS.\n */\n categoryColors?: Record<string, string>;\n}\n\n/**\n * Configuration for legend styling and positioning.\n *\n * @example\n * // Legend on the bottom with custom styling\n * legendConfig={{\n * position: \"bottom\",\n * fontSize: 14,\n * itemSpacing: 12,\n * swatchSize: 20,\n * }}\n */\nexport interface LegendConfig {\n /**\n * Position of the legend relative to the plate.\n * @default \"right\"\n */\n position?: LegendPosition;\n /**\n * Font size for legend labels in pixels.\n * @default 12\n */\n fontSize?: number;\n /**\n * Spacing between legend items in pixels.\n * @default 4\n */\n itemSpacing?: number;\n /**\n * Size of the color swatch in pixels.\n * @default 16\n */\n swatchSize?: number;\n /**\n * Title to display above the legend.\n */\n title?: string;\n}\n\n/**\n * A region to highlight on the plate (e.g., controls, sample areas, empty wells)\n */\nexport interface PlateRegion {\n /** Unique identifier for the region */\n id: string;\n /** Display name for the region (shown in legend) */\n name: string;\n /**\n * Wells included in this region using range notation.\n * Format: \"StartWell:EndWell\" (e.g., \"A1:B6\" for a rectangular block from A1 to B6)\n */\n wells: string;\n /** Border color for the region highlight */\n borderColor?: string;\n /** Border width in pixels (default: 2) */\n borderWidth?: number;\n /** Optional fill color with transparency (e.g., \"rgba(255, 0, 0, 0.1)\") */\n fillColor?: string;\n}\n\n/**\n * Props for PlateMap component\n */\nexport interface PlateMapProps {\n /**\n * Well data array as WellData objects with wellId and values.\n *\n * If wells have multiple values (via `values` property), layers are\n * auto-generated for each unique key, enabling layer toggling.\n */\n data?: WellData[];\n\n /**\n * Configuration for auto-generated layers when using WellData with `values`.\n * Use this to customize display names, colors, and ranges for each layer.\n * Only used when `data` contains wells with `values` property.\n */\n layerConfigs?: LayerConfig[];\n\n /**\n * Initial layer ID to display when the component mounts.\n * If not provided, defaults to the first layer.\n */\n initialLayerId?: string;\n\n /**\n * Optional callback notified when the active layer changes.\n * This is purely informational - the component manages layer state internally.\n * Use this for logging, analytics, or syncing with external state.\n */\n onLayerChange?: (layerId: string) => void;\n\n /** Plate format preset (default: \"96\") */\n plateFormat?: PlateFormat;\n\n /** Number of rows for custom format (default: 8 for 96-well, 16 for 384-well) */\n rows?: number;\n\n /** Number of columns for custom format (default: 12 for 96-well, 24 for 384-well) */\n columns?: number;\n\n /**\n * Visualization mode (default: \"heatmap\")\n * - \"heatmap\": Display quantitative values with color gradient\n * - \"categorical\": Display well types with discrete colors\n */\n visualizationMode?: VisualizationMode;\n\n /**\n * Custom colors for categorical visualization mode.\n * Keys are well types, values are hex colors.\n * Merged with DEFAULT_CATEGORY_COLORS.\n */\n categoryColors?: Record<string, string>;\n\n /**\n * Regions to highlight on the plate (e.g., controls, sample areas, empty wells).\n * Each region can specify wells and styling for visual distinction.\n */\n regions?: PlateRegion[];\n\n /** Chart title */\n title?: string;\n\n /** X-axis title (e.g., \"Columns\") */\n xTitle?: string;\n\n /** Y-axis title (e.g., \"Rows\") */\n yTitle?: string;\n\n /** Custom x-axis labels (overrides auto-generated column numbers) */\n xLabels?: string[] | number[];\n\n /** Custom y-axis labels (overrides auto-generated row letters) */\n yLabels?: string[] | number[];\n\n /** Color scale for the heatmap (only used in heatmap mode) */\n colorScale?: ColorScale;\n\n /** Minimum value for color scale (auto-calculated if not provided) */\n valueMin?: number;\n\n /** Maximum value for color scale (auto-calculated if not provided) */\n valueMax?: number;\n\n /** Color for empty/null wells (default: \"#f0f0f0\") */\n emptyWellColor?: string;\n\n /** Show color bar legend for heatmap mode (default: true) */\n showColorBar?: boolean;\n\n /** Show categorical legend for categorical mode (default: true) */\n showLegend?: boolean;\n\n /**\n * Configuration for legend positioning and styling.\n * Applies to both heatmap colorbar and categorical legend.\n *\n * @example\n * // Position legend at bottom with larger text\n * legendConfig={{ position: \"bottom\", fontSize: 14 }}\n */\n legendConfig?: LegendConfig;\n\n /** Chart width in pixels (default: 800) */\n width?: number;\n\n /** Chart height in pixels (default: 500) */\n height?: number;\n\n /** Number of decimal places for values (default: 0) */\n precision?: number;\n\n /**\n * Marker shape for wells (default: \"circle\")\n * - \"circle\": Round markers, ideal for plate-based data\n * - \"square\": Square markers, ideal for generic heatmaps\n */\n markerShape?: \"circle\" | \"square\";\n\n /**\n * Callback when a well/cell is clicked.\n * @param wellData - The full well data object including wellId, values, and tooltipData\n */\n onWellClick?: (wellData: WellData) => void;\n}\n\n/**\n * Result of converting WellData array to grids\n */\nexport interface WellDataGridResult {\n /** 2D grid of numeric values for the active layer */\n grid: (number | null)[][];\n /** 2D grid of string values for categorical visualization */\n categories: (string | null)[][];\n /** Map of wellId -> all values (for tooltip display) */\n allValues: Map<string, Record<string, string | number | null>>;\n /** Map of wellId -> tooltipData */\n tooltipData: Map<string, Record<string, unknown>>;\n}\n\n"],"names":["PLATE_FORMAT_96","PLATE_FORMAT_384","PLATE_FORMAT_1536","PLATE_FORMAT_CUSTOM"],"mappings":"AAGO,MAAMA,IAAkB,MAClBC,IAAmB,OACnBC,IAAoB,QACpBC,IAAsB;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./constants.cjs"),T=65,d=26;function P(e){return Array.from({length:e},(t,n)=>n<d?String.fromCharCode(T+n):"A"+String.fromCharCode(T+(n-d)))}function R(e){return Array.from({length:e},(t,n)=>n+1)}function M(e){const t=e.match(/^([A-Z]{1,2})(\d{1,2})$/i);if(!t)return null;const n=t[1].toUpperCase(),r=n.length===1?n.charCodeAt(0)-T:d+(n.charCodeAt(1)-T),o=parseInt(t[2],10)-1;return{row:r,col:o}}function C(e,t,n){if(!e)return!1;const{row:r,col:o}=e;return r>=0&&o>=0&&r<t&&o<n}function m(e,t){if(!e)return null;const n=t??Object.keys(e)[0];return n?e[n]:null}function O(e,t,n,r,o){typeof e=="number"?r[t][n]=e:typeof e=="string"&&(o[t][n]=e)}function y(e,t,n,r){const o=Array.from({length:t},()=>Array(n).fill(null)),a=Array.from({length:t},()=>Array(n).fill(null)),i=new Map,s=new Map;for(const l of e){const f=M(l.wellId);if(!C(f,t,n))continue;const u=l.wellId.toUpperCase();l.values&&i.set(u,l.values),l.tooltipData&&s.set(u,l.tooltipData);const A=m(l.values,r);O(A,f.row,f.col,o,a)}return{grid:o,categories:a,allValues:i,tooltipData:s}}function b(e){let t=1/0,n=-1/0;for(const r of e)for(const o of r)o!==null&&Number.isFinite(o)&&(t=Math.min(t,o),n=Math.max(n,o));return Number.isFinite(t)||(t=0),Number.isFinite(n)||(n=1),t===n&&(n=t+1),{min:t,max:n}}function x(e){return e.some(t=>t.values&&Object.keys(t.values).length>0)}function _(e){const t=new Set;for(const n of e)n.values&&Object.keys(n.values).forEach(r=>t.add(r));return[...t]}function I(e,t){for(const n of e)if(typeof n.values?.[t]=="string")return!0;return!1}function E(e,t){return _(e).map(r=>{const o=t?.find(i=>i.id===r),a=I(e,r);return{id:r,name:o?.name??r,visualizationMode:o?.visualizationMode??(a?"categorical":void 0),colorScale:o?.colorScale,valueMin:o?.valueMin,valueMax:o?.valueMax,valueUnit:o?.valueUnit,categoryColors:o?.categoryColors}})}function p(e,t,n){const r=e.match(/^([A-Z]{1,2})(\d{1,2}):([A-Z]{1,2})(\d{1,2})$/i);if(!r)return null;const o=M(`${r[1]}${r[2]}`),a=M(`${r[3]}${r[4]}`),i=Math.min(o.row,a.row),s=Math.max(o.row,a.row),l=Math.min(o.col,a.col),f=Math.max(o.col,a.col),u=t.length,A=n.length;return i>=u||s>=u||l>=A||f>=A?null:{minRow:i,maxRow:s,minCol:l,maxCol:f}}function w({wellId:e,value:t,allValues:n,tooltipExtra:r,activeLayerId:o,layerConfigMap:a,precision:i,valueUnit:s}){let l=`Well ${e}`;return n?l+=v(n,o,a,i):t!==null?l+=`<br>Value: ${t.toFixed(i)}${s}`:o?l+=`<br>▶ ${o}: -`:l+="<br>No data",r&&(l+=G(r)),l}function v(e,t,n,r){let o="";for(const[a,i]of Object.entries(e)){const l=a===t?"▶ ":"",f=n.get(a)?.valueUnit,u=f?` ${f}`:"";i===null?o+=`<br>${l}${a}: -`:typeof i=="number"?o+=`<br>${l}${a}: ${i.toFixed(r)}${u}`:o+=`<br>${l}${a}: ${i.charAt(0).toUpperCase()+i.slice(1)}`}return o}function G(e){let t="";for(const[n,r]of Object.entries(e))t+=`<br>${n}: ${String(r)}`;return t}function $(e,t,n){const r=n?{text:n}:void 0;switch(e){case"bottom":return{orientation:"h",thickness:20,len:.75,outlinewidth:0,ticksuffix:t,y:-.15,yanchor:"top",x:.5,xanchor:"center",title:r?{...r,side:"top"}:void 0};case"top":return{orientation:"h",thickness:20,len:.75,outlinewidth:0,ticksuffix:t,y:1.15,yanchor:"bottom",x:.5,xanchor:"center",title:r?{...r,side:"bottom"}:void 0};case"left":return{thickness:28,len:1,outlinewidth:0,ticksuffix:t,y:.5,yanchor:"middle",x:-.15,xanchor:"right",title:r?{...r,side:"right"}:void 0};default:return{thickness:20,len:.9,outlinewidth:0,ticksuffix:t,x:.88,xanchor:"left",y:.5,yanchor:"middle",title:r?{...r,side:"right"}:void 0}}}function D(e,t,n){const r=n?c.PLATEMAP_CONSTANTS.MARGIN_TOP:c.PLATEMAP_CONSTANTS.MARGIN_RIGHT,o=c.PLATEMAP_CONSTANTS.MARGIN_RIGHT,a=e==="left"?r+c.PLATEMAP_CONSTANTS.MARGIN_RIGHT:r,i=e==="right"?o+c.PLATEMAP_CONSTANTS.MARGIN_RIGHT:o,s=e==="bottom"?c.PLATEMAP_CONSTANTS.MARGIN_LEFT:c.PLATEMAP_CONSTANTS.MARGIN_RIGHT;let l;return t?l=e==="top"?c.PLATEMAP_CONSTANTS.COLORBAR_LENGTH:100:l=e==="top"?c.PLATEMAP_CONSTANTS.MARGIN_TOP:c.PLATEMAP_CONSTANTS.MARGIN_BOTTOM,{l:a,r:i,b:s,t:l,pad:5}}function k(e){switch(e){case"left":return c.PLATEMAP_CONSTANTS.MULTI_VALUE_PRIMARY_RATIO;case"right":return c.PLATEMAP_CONSTANTS.MULTI_VALUE_SECONDARY_RATIO;default:return .5}}function H(e){switch(e){case"left":return[c.PLATEMAP_CONSTANTS.DOMAIN_COLORBAR_OFFSET,1];case"right":return[0,c.PLATEMAP_CONSTANTS.DOMAIN_COLORBAR_END];default:return[0,1]}}function U(e,t,n,r,o,a){const i=[],s=[],l=[],f=[];for(let u=0;u<r;u++)for(let A=0;A<o;A++){i.push(A+1),s.push(t[u]);const h=e[u][A];l.push(h??a),f.push(n[u][A])}return{xData:i,yData:s,colorData:l,textData:f}}const W=4,V=1,z=.8,g=100;function F(e,t,n,r,o,a,i){const s=i?c.PLATEMAP_CONSTANTS.MARGIN_TOP:c.PLATEMAP_CONSTANTS.MARGIN_RIGHT,l=g,f=a?g:c.PLATEMAP_CONSTANTS.MARGIN_BOTTOM,u=c.PLATEMAP_CONSTANTS.MARGIN_RIGHT,A=e-s-l,h=t-f-u,N=A/r,S=h/n,L=o==="square"?Math.max(N,S):Math.min(N,S);return Math.max(W,L*(o==="square"?V:z))}exports.buildColorbarConfig=$;exports.buildPlotMargins=D;exports.buildWellHoverText=w;exports.calculateAxisDomain=H;exports.calculateMarkerSize=F;exports.calculateTitleX=k;exports.calculateValueRange=b;exports.extractLayerIds=_;exports.extractLayers=E;exports.flattenGridData=U;exports.generateColumnLabels=R;exports.generateRowLabels=P;exports.hasMultiValueWells=x;exports.isStringValueLayer=I;exports.parseRegionWells=p;exports.parseWellId=M;exports.wellDataToGrid=y;
|
|
2
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","sources":["../../../../src/components/charts/PlateMap/utils.ts"],"sourcesContent":["import { PLATEMAP_CONSTANTS } from \"./constants\";\n\nimport type { WellData, WellDataGridResult, LayerConfig, LegendPosition } from \"./types\";\n\n/** ASCII code for uppercase 'A' */\nconst ASCII_UPPERCASE_A = 65;\n/** Number of letters in the alphabet */\nconst ALPHABET_LENGTH = 26;\n\n/**\n * Generate row labels (A, B, C, ... for 96-well; A-P for 384-well; A-AF for 1536-well)\n * For rows beyond Z (26), uses AA, AB, AC, etc.\n */\nexport function generateRowLabels(count: number): string[] {\n return Array.from({ length: count }, (_, i) =>\n i < ALPHABET_LENGTH\n ? String.fromCharCode(ASCII_UPPERCASE_A + i)\n : \"A\" + String.fromCharCode(ASCII_UPPERCASE_A + (i - ALPHABET_LENGTH))\n );\n}\n\n/**\n * Generate column labels (1, 2, 3, ...)\n */\nexport function generateColumnLabels(count: number): number[] {\n return Array.from({ length: count }, (_, i) => i + 1);\n}\n\n/**\n * Parse well ID to row and column indices\n * @param wellId - Well identifier (e.g., \"A1\", \"H12\", \"P24\", \"AA1\", \"AF48\")\n * @returns { row, col } zero-indexed\n */\nexport function parseWellId(wellId: string): { row: number; col: number } | null {\n // Match single letter (A-Z) or double letter (AA-AF) followed by 1-2 digits\n const match = wellId.match(/^([A-Z]{1,2})(\\d{1,2})$/i);\n if (!match) return null;\n\n const rowStr = match[1].toUpperCase();\n const row =\n rowStr.length === 1\n ? rowStr.charCodeAt(0) - ASCII_UPPERCASE_A\n : ALPHABET_LENGTH + (rowStr.charCodeAt(1) - ASCII_UPPERCASE_A);\n\n const col = parseInt(match[2], 10) - 1;\n\n return { row, col };\n}\n\n/** Parsed well position */\ninterface ParsedWellPosition {\n row: number;\n col: number;\n}\n\n/**\n * Checks if a parsed well position is within grid bounds.\n */\nfunction isValidWellPosition(\n parsed: ParsedWellPosition | null,\n rows: number,\n columns: number\n): parsed is ParsedWellPosition {\n if (!parsed) return false;\n const { row, col } = parsed;\n // Check bounds including >= 0 to prevent negative indices (e.g., \"A0\" -> col=-1)\n return row >= 0 && col >= 0 && row < rows && col < columns;\n}\n\n/**\n * Extracts the layer value from well values for the specified layer.\n */\nfunction extractLayerValue(\n values: Record<string, string | number | null> | undefined,\n layerId?: string\n): string | number | null {\n if (!values) return null;\n const effectiveLayerId = layerId ?? Object.keys(values)[0];\n return effectiveLayerId ? values[effectiveLayerId] : null;\n}\n\n/**\n * Stores the layer value in the appropriate grid based on its type.\n */\nfunction storeLayerValue(\n layerValue: string | number | null,\n row: number,\n col: number,\n grid: (number | null)[][],\n categories: (string | null)[][]\n): void {\n if (typeof layerValue === \"number\") {\n grid[row][col] = layerValue;\n } else if (typeof layerValue === \"string\") {\n categories[row][col] = layerValue;\n }\n}\n\n/**\n * Convert WellData array to 2D grids for a specific layer\n */\nexport function wellDataToGrid(\n wells: WellData[],\n rows: number,\n columns: number,\n layerId?: string\n): WellDataGridResult {\n // Initialize grids with nulls\n const grid: (number | null)[][] = Array.from({ length: rows }, () =>\n Array(columns).fill(null)\n );\n const categories: (string | null)[][] = Array.from({ length: rows }, () =>\n Array(columns).fill(null)\n );\n const allValues = new Map<string, Record<string, string | number | null>>();\n const tooltipData = new Map<string, Record<string, unknown>>();\n\n for (const well of wells) {\n const parsed = parseWellId(well.wellId);\n if (!isValidWellPosition(parsed, rows, columns)) continue;\n\n const wellIdUpper = well.wellId.toUpperCase();\n\n // Store all values for tooltip\n if (well.values) {\n allValues.set(wellIdUpper, well.values);\n }\n\n // Store tooltipData\n if (well.tooltipData) {\n tooltipData.set(wellIdUpper, well.tooltipData);\n }\n\n // Extract and store the layer value\n const layerValue = extractLayerValue(well.values, layerId);\n storeLayerValue(layerValue, parsed.row, parsed.col, grid, categories);\n }\n\n return { grid, categories, allValues, tooltipData };\n}\n\n/**\n * Calculate min/max values from grid, ignoring nulls\n */\nexport function calculateValueRange(grid: (number | null)[][]): { min: number; max: number } {\n let min = Infinity;\n let max = -Infinity;\n\n for (const row of grid) {\n for (const val of row) {\n if (val !== null && Number.isFinite(val)) {\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n }\n }\n\n // Handle case where all values are null\n if (!Number.isFinite(min)) min = 0;\n if (!Number.isFinite(max)) max = 1;\n\n // Ensure min < max\n if (min === max) {\n max = min + 1;\n }\n\n return { min, max };\n}\n\n/**\n * Check if WellData array contains multi-value wells (has `values` property)\n */\nexport function hasMultiValueWells(data: WellData[]): boolean {\n return data.some((well) => well.values && Object.keys(well.values).length > 0);\n}\n\n/**\n * Extract unique layer IDs from WellData array with `values`\n */\nexport function extractLayerIds(data: WellData[]): string[] {\n const layerIds = new Set<string>();\n for (const well of data) {\n if (well.values) {\n Object.keys(well.values).forEach((k) => layerIds.add(k));\n }\n }\n return [...layerIds];\n}\n\n/**\n * Check if a layer contains string values (categorical) or numeric values (heatmap)\n */\nexport function isStringValueLayer(data: WellData[], layerId: string): boolean {\n for (const well of data) {\n const val = well.values?.[layerId];\n if (typeof val === \"string\") {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Extract layer configs from multi-value WellData array.\n * Creates a layer entry for each unique key found in the `values` objects.\n * Merges with user-provided layerConfigs to apply custom settings.\n */\nexport function extractLayers(\n data: WellData[],\n layerConfigs?: LayerConfig[]\n): LayerConfig[] {\n const layerIds = extractLayerIds(data);\n\n return layerIds.map((id) => {\n const config = layerConfigs?.find((c) => c.id === id);\n const isStringLayer = isStringValueLayer(data, id);\n\n return {\n id,\n name: config?.name ?? id,\n // Auto-set categorical mode for string layers if not explicitly configured\n visualizationMode: config?.visualizationMode ?? (isStringLayer ? \"categorical\" : undefined),\n colorScale: config?.colorScale,\n valueMin: config?.valueMin,\n valueMax: config?.valueMax,\n valueUnit: config?.valueUnit,\n categoryColors: config?.categoryColors,\n };\n });\n}\n\n/**\n * Parse region wells from range notation like \"A1:B6\"\n * Returns the bounding box coordinates for overlay rendering\n */\nexport function parseRegionWells(\n wells: string,\n rowLabels: readonly (string | number)[],\n colLabels: readonly (string | number)[]\n): { minRow: number; maxRow: number; minCol: number; maxCol: number } | null {\n // Parse range notation like \"A1:B6\"\n const rangeMatch = wells.match(/^([A-Z]{1,2})(\\d{1,2}):([A-Z]{1,2})(\\d{1,2})$/i);\n if (!rangeMatch) {\n return null;\n }\n\n // The regex above guarantees valid well ID format, so parseWellId will always succeed\n const startWell = parseWellId(`${rangeMatch[1]}${rangeMatch[2]}`)!;\n const endWell = parseWellId(`${rangeMatch[3]}${rangeMatch[4]}`)!;\n\n const minRow = Math.min(startWell.row, endWell.row);\n const maxRow = Math.max(startWell.row, endWell.row);\n const minCol = Math.min(startWell.col, endWell.col);\n const maxCol = Math.max(startWell.col, endWell.col);\n\n // Validate bounds against actual labels\n const numRows = rowLabels.length;\n const numCols = colLabels.length;\n if (minRow >= numRows || maxRow >= numRows || minCol >= numCols || maxCol >= numCols) {\n return null;\n }\n\n return { minRow, maxRow, minCol, maxCol };\n}\n\n/** Options for building hover text for a well */\nexport interface BuildHoverTextOptions {\n wellId: string;\n value: number | null;\n allValues: Record<string, number | string | null> | undefined;\n tooltipExtra: Record<string, unknown> | undefined;\n activeLayerId: string | undefined;\n layerConfigMap: Map<string, LayerConfig>;\n precision: number;\n valueUnit: string;\n}\n\n/**\n * Builds the hover text HTML for a single well.\n * Shows all layer values with the active layer marked.\n */\nexport function buildWellHoverText({\n wellId,\n value,\n allValues,\n tooltipExtra,\n activeLayerId,\n layerConfigMap,\n precision,\n valueUnit,\n}: BuildHoverTextOptions): string {\n let text = `Well ${wellId}`;\n\n if (allValues) {\n text += formatAllLayerValues(allValues, activeLayerId, layerConfigMap, precision);\n } else if (value !== null) {\n text += `<br>Value: ${value.toFixed(precision)}${valueUnit}`;\n } else if (activeLayerId) {\n text += `<br>▶ ${activeLayerId}: -`;\n } else {\n text += `<br>No data`;\n }\n\n if (tooltipExtra) {\n text += formatTooltipExtra(tooltipExtra);\n }\n\n return text;\n}\n\n/** Formats all layer values for hover text display */\nfunction formatAllLayerValues(\n allValues: Record<string, number | string | null>,\n activeLayerId: string | undefined,\n layerConfigMap: Map<string, LayerConfig>,\n precision: number\n): string {\n let result = \"\";\n for (const [key, value] of Object.entries(allValues)) {\n const isActiveLayer = key === activeLayerId;\n const prefix = isActiveLayer ? \"▶ \" : \"\";\n const rawLayerUnit = layerConfigMap.get(key)?.valueUnit;\n const layerUnit = rawLayerUnit ? ` ${rawLayerUnit}` : \"\";\n\n if (value === null) {\n result += `<br>${prefix}${key}: -`;\n } else if (typeof value === \"number\") {\n result += `<br>${prefix}${key}: ${value.toFixed(precision)}${layerUnit}`;\n } else {\n result += `<br>${prefix}${key}: ${value.charAt(0).toUpperCase() + value.slice(1)}`;\n }\n }\n return result;\n}\n\n/** Formats tooltip extra data for display */\nfunction formatTooltipExtra(tooltipExtra: Record<string, unknown>): string {\n let result = \"\";\n for (const [key, value] of Object.entries(tooltipExtra)) {\n result += `<br>${key}: ${String(value)}`;\n }\n return result;\n}\n\n/** Colorbar configuration for a specific position */\nexport interface ColorbarConfig {\n orientation?: \"h\" | \"v\";\n thickness: number;\n len: number;\n outlinewidth: number;\n ticksuffix: string;\n x: number;\n xanchor: \"left\" | \"center\" | \"right\";\n y: number;\n yanchor: \"top\" | \"middle\" | \"bottom\";\n title?: { text: string; side: \"top\" | \"bottom\" | \"right\" };\n}\n\n/**\n * Builds the colorbar configuration based on legend position.\n */\nexport function buildColorbarConfig(\n position: LegendPosition,\n valueUnit: string,\n legendTitle?: string\n): ColorbarConfig {\n const title = legendTitle ? { text: legendTitle } : undefined;\n\n switch (position) {\n case \"bottom\":\n return {\n orientation: \"h\",\n thickness: 20,\n len: 0.75,\n outlinewidth: 0,\n ticksuffix: valueUnit,\n y: -0.15,\n yanchor: \"top\",\n x: 0.5,\n xanchor: \"center\",\n title: title ? { ...title, side: \"top\" } : undefined,\n };\n case \"top\":\n return {\n orientation: \"h\",\n thickness: 20,\n len: 0.75,\n outlinewidth: 0,\n ticksuffix: valueUnit,\n y: 1.15,\n yanchor: \"bottom\",\n x: 0.5,\n xanchor: \"center\",\n title: title ? { ...title, side: \"bottom\" } : undefined,\n };\n case \"left\":\n return {\n thickness: 28,\n len: 1,\n outlinewidth: 0,\n ticksuffix: valueUnit,\n y: 0.5,\n yanchor: \"middle\",\n x: -0.15,\n xanchor: \"right\",\n title: title ? { ...title, side: \"right\" } : undefined,\n };\n default:\n // \"right\" (default)\n return {\n thickness: 20,\n len: 0.9,\n outlinewidth: 0,\n ticksuffix: valueUnit,\n x: 0.88,\n xanchor: \"left\",\n y: 0.5,\n yanchor: \"middle\",\n title: title ? { ...title, side: \"right\" } : undefined,\n };\n }\n}\n\n/** Margin configuration for the plot */\nexport interface PlotMargins {\n l: number;\n r: number;\n b: number;\n t: number;\n pad: number;\n}\n\n/**\n * Builds the margin configuration based on legend position and title presence.\n */\nexport function buildPlotMargins(\n position: LegendPosition,\n hasTitle: boolean,\n hasYTitle: boolean\n): PlotMargins {\n const baseLeft = hasYTitle ? PLATEMAP_CONSTANTS.MARGIN_TOP : PLATEMAP_CONSTANTS.MARGIN_RIGHT;\n const baseRight = PLATEMAP_CONSTANTS.MARGIN_RIGHT;\n\n const leftMargin = position === \"left\" ? baseLeft + PLATEMAP_CONSTANTS.MARGIN_RIGHT : baseLeft;\n const rightMargin = position === \"right\" ? baseRight + PLATEMAP_CONSTANTS.MARGIN_RIGHT : baseRight;\n const bottomMargin = position === \"bottom\" ? PLATEMAP_CONSTANTS.MARGIN_LEFT : PLATEMAP_CONSTANTS.MARGIN_RIGHT;\n\n let topMargin: number;\n if (hasTitle) {\n topMargin = position === \"top\" ? PLATEMAP_CONSTANTS.COLORBAR_LENGTH : 100;\n } else {\n topMargin = position === \"top\" ? PLATEMAP_CONSTANTS.MARGIN_TOP : PLATEMAP_CONSTANTS.MARGIN_BOTTOM;\n }\n\n return { l: leftMargin, r: rightMargin, b: bottomMargin, t: topMargin, pad: 5 };\n}\n\n/**\n * Calculates the title X position based on legend position.\n */\nexport function calculateTitleX(position: LegendPosition): number {\n switch (position) {\n case \"left\":\n return PLATEMAP_CONSTANTS.MULTI_VALUE_PRIMARY_RATIO;\n case \"right\":\n return PLATEMAP_CONSTANTS.MULTI_VALUE_SECONDARY_RATIO;\n default:\n return 0.5;\n }\n}\n\n/**\n * Calculates the X-axis domain based on legend position.\n */\nexport function calculateAxisDomain(position: LegendPosition): [number, number] {\n switch (position) {\n case \"left\":\n return [PLATEMAP_CONSTANTS.DOMAIN_COLORBAR_OFFSET, 1];\n case \"right\":\n return [0, PLATEMAP_CONSTANTS.DOMAIN_COLORBAR_END];\n default:\n return [0, 1];\n }\n}\n\n/** Data arrays for scatter plot */\nexport interface ScatterPlotData {\n xData: number[];\n yData: string[];\n colorData: number[];\n textData: string[];\n}\n\n/**\n * Flattens 2D grid data into arrays for scatter plot rendering.\n */\nexport function flattenGridData(\n plotZ: (number | null)[][],\n rowLabels: (string | number)[],\n hoverText: string[][],\n rows: number,\n columns: number,\n plotZMin: number\n): ScatterPlotData {\n const xData: number[] = [];\n const yData: string[] = [];\n const colorData: number[] = [];\n const textData: string[] = [];\n\n for (let rowIdx = 0; rowIdx < rows; rowIdx++) {\n for (let colIdx = 0; colIdx < columns; colIdx++) {\n xData.push(colIdx + 1); // 1-indexed columns\n yData.push(rowLabels[rowIdx] as string);\n const zValue = plotZ[rowIdx][colIdx];\n colorData.push(zValue ?? plotZMin); // Use min value for null wells\n textData.push(hoverText[rowIdx][colIdx]);\n }\n }\n\n return { xData, yData, colorData, textData };\n}\n\n/** Marker size calculation result */\nexport interface MarkerSizeResult {\n markerSize: number;\n}\n\n/** Minimum marker size in pixels */\nconst MIN_MARKER_SIZE = 4;\n/** Size multiplier for square markers (fill entire cell) */\nconst SQUARE_SIZE_MULTIPLIER = 1.0;\n/** Size multiplier for circle markers (leave gaps) */\nconst CIRCLE_SIZE_MULTIPLIER = 0.8;\n/** Default colorbar space reservation */\nconst COLORBAR_SPACE = 100;\n\n/**\n * Calculates the marker size based on plot dimensions and marker shape.\n */\nexport function calculateMarkerSize(\n width: number,\n height: number,\n rows: number,\n columns: number,\n markerShape: \"circle\" | \"square\",\n hasTitle: boolean,\n hasYTitle: boolean\n): number {\n const leftMargin = hasYTitle ? PLATEMAP_CONSTANTS.MARGIN_TOP : PLATEMAP_CONSTANTS.MARGIN_RIGHT;\n const rightMargin = COLORBAR_SPACE; // Always reserve space for colorbar\n const topMargin = hasTitle ? COLORBAR_SPACE : PLATEMAP_CONSTANTS.MARGIN_BOTTOM;\n const bottomMargin = PLATEMAP_CONSTANTS.MARGIN_RIGHT;\n const plotWidth = width - leftMargin - rightMargin;\n const plotHeight = height - topMargin - bottomMargin;\n\n const cellWidth = plotWidth / columns;\n const cellHeight = plotHeight / rows;\n\n // Circles: use smaller dimension; Squares: use larger dimension\n const cellSize = markerShape === \"square\"\n ? Math.max(cellWidth, cellHeight)\n : Math.min(cellWidth, cellHeight);\n\n const sizeMultiplier = markerShape === \"square\" ? SQUARE_SIZE_MULTIPLIER : CIRCLE_SIZE_MULTIPLIER;\n return Math.max(MIN_MARKER_SIZE, cellSize * sizeMultiplier);\n}\n"],"names":["ASCII_UPPERCASE_A","ALPHABET_LENGTH","generateRowLabels","count","_","i","generateColumnLabels","parseWellId","wellId","match","rowStr","row","col","isValidWellPosition","parsed","rows","columns","extractLayerValue","values","layerId","effectiveLayerId","storeLayerValue","layerValue","grid","categories","wellDataToGrid","wells","allValues","tooltipData","well","wellIdUpper","calculateValueRange","min","max","val","hasMultiValueWells","data","extractLayerIds","layerIds","k","isStringValueLayer","extractLayers","layerConfigs","id","config","c","isStringLayer","parseRegionWells","rowLabels","colLabels","rangeMatch","startWell","endWell","minRow","maxRow","minCol","maxCol","numRows","numCols","buildWellHoverText","value","tooltipExtra","activeLayerId","layerConfigMap","precision","valueUnit","text","formatAllLayerValues","formatTooltipExtra","result","key","prefix","rawLayerUnit","layerUnit","buildColorbarConfig","position","legendTitle","title","buildPlotMargins","hasTitle","hasYTitle","baseLeft","PLATEMAP_CONSTANTS","baseRight","leftMargin","rightMargin","bottomMargin","topMargin","calculateTitleX","calculateAxisDomain","flattenGridData","plotZ","hoverText","plotZMin","xData","yData","colorData","textData","rowIdx","colIdx","zValue","MIN_MARKER_SIZE","SQUARE_SIZE_MULTIPLIER","CIRCLE_SIZE_MULTIPLIER","COLORBAR_SPACE","calculateMarkerSize","width","height","markerShape","plotWidth","plotHeight","cellWidth","cellHeight","cellSize"],"mappings":"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"}
|