@tetrascience-npm/tetrascience-react-ui 0.5.0-beta.20.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 +4 -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":"PieChart.js","sources":["../../../../src/components/charts/PieChart/PieChart.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { COLORS } from \"@/utils/colors\";\n\ninterface PieDataSeries {\n labels: string[];\n values: number[];\n name: string;\n colors?: string[];\n}\n\ntype PieTextInfo =\n | \"none\"\n | \"label\"\n | \"percent\"\n | \"value\"\n | \"label+percent\"\n | \"label+value\"\n | \"value+percent\"\n | \"label+value+percent\";\n\ntype PieChartProps = {\n dataSeries: PieDataSeries;\n width?: number;\n height?: number;\n title?: string;\n textInfo?: PieTextInfo;\n hole?: number;\n rotation?: number;\n};\n\nconst DEFAULT_COLORS = [\n COLORS.BLUE,\n COLORS.GREEN,\n COLORS.ORANGE,\n COLORS.RED,\n COLORS.YELLOW,\n COLORS.PURPLE,\n];\n\nconst PieChart: React.FC<PieChartProps> = ({\n dataSeries,\n width = 400,\n height = 400,\n title = \"Pie Chart\",\n textInfo = \"percent\",\n hole = 0,\n rotation = 0,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n\n const colors = useMemo(() => {\n if (\n dataSeries.colors &&\n dataSeries.colors.length >= dataSeries.labels.length\n ) {\n return dataSeries.colors;\n }\n\n const result = [...(dataSeries.colors || [])];\n const missingColors = dataSeries.labels.length - result.length;\n\n if (missingColors <= 0) return result;\n\n for (let i = 0; i < missingColors; i++) {\n result.push(DEFAULT_COLORS[i % DEFAULT_COLORS.length]);\n }\n\n return result;\n }, [dataSeries.colors, dataSeries.labels.length]);\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const plotData = [\n {\n type: \"pie\" as const,\n labels: dataSeries.labels,\n values: dataSeries.values,\n name: dataSeries.name,\n marker: {\n colors: colors,\n },\n textinfo: textInfo,\n hoverinfo: \"label+text+value\" as const,\n insidetextfont: {\n size: 0,\n family: \"Inter, sans-serif\",\n color: \"transparent\",\n },\n hole: hole,\n rotation: rotation,\n },\n ];\n\n const layout = {\n width,\n height,\n font: {\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n showlegend: false,\n margin: { l: 40, r: 40, b: 40, t: 40 },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n };\n\n const config = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, plotData, layout, config);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [colors, dataSeries.labels, dataSeries.name, dataSeries.values, width, height, textInfo, hole, rotation, theme]);\n\n const PieChartLegend: React.FC<{ labels: string[]; colors: string[] }> = ({\n labels,\n colors,\n }) => {\n const items = labels.map((label, i) => (\n <React.Fragment key={label}>\n <div className=\"legend-item\">\n <span className=\"color-box\" style={{ background: colors[i] }} />\n {label}\n {i < labels.length - 1 && <span className=\"divider\" />}\n </div>\n </React.Fragment>\n ));\n\n const rowSize = 6;\n const rows = [];\n for (let i = 0; i < items.length; i += rowSize) {\n rows.push(\n <div className=\"legend-row\" key={i}>\n {items.slice(i, i + rowSize)}\n </div>\n );\n }\n return <div className=\"legend-container\">{rows}</div>;\n };\n\n return (\n <div className=\"card-container\" style={{ width: width }}>\n <div className=\"chart-container\">\n {title && (\n <div className=\"title-container\">\n <h2 className=\"title\">{title}</h2>\n </div>\n )}\n <div\n ref={plotRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n margin: \"0\",\n }}\n />\n <PieChartLegend labels={dataSeries.labels} colors={colors} />\n </div>\n </div>\n );\n};\n\nexport { PieChart };\nexport type { PieDataSeries, PieTextInfo, PieChartProps };\n"],"names":["DEFAULT_COLORS","COLORS","PieChart","dataSeries","width","height","title","textInfo","hole","rotation","plotRef","useRef","theme","usePlotlyTheme","colors","useMemo","result","missingColors","i","useEffect","plotData","layout","config","Plotly","plotElement","jsx","jsxs","labels","items","label","React","rowSize","rows"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),Re=require("plotly.js-dist"),m=require("react");;/* empty css */const r=require("./constants.cjs"),v=require("./types.cjs"),c=require("./utils.cjs"),tt=require("../../ui/button.cjs"),at=require("../../../hooks/use-plotly-theme.cjs"),lt=({data:S,layerConfigs:re,initialLayerId:we,onLayerChange:Pe,plateFormat:ne=v.PLATE_FORMAT_96,rows:be,columns:ze,visualizationMode:Ie="heatmap",categoryColors:ce,regions:x,title:C,xTitle:ie,yTitle:F,xLabels:De,yLabels:Fe,colorScale:je=r.DEFAULT_COLOR_SCALE,valueMin:ke,valueMax:Ge,emptyWellColor:T=r.COLORS.emptyWell,showColorBar:pe=!0,showLegend:$e=!0,legendConfig:_,width:N=800,height:j=500,precision:ue=0,markerShape:H="circle",onWellClick:de})=>{const me=m.useRef(null),h=at.usePlotlyTheme(),Y=m.useRef(de);Y.current=de;const[W,Ue]=m.useState(we);let i,p;if(ne===v.PLATE_FORMAT_CUSTOM)i=be??8,p=ze??12;else{const e=r.PLATE_CONFIGS[ne];i=e.rows,p=e.columns}const d=m.useMemo(()=>{if(Array.isArray(S)&&S.length>0&&"wellId"in S[0]){const e=S;if(c.hasMultiValueWells(e))return c.extractLayers(e,re)}return null},[S,re]),f=m.useMemo(()=>!d||d.length===0?null:W?d.find(e=>e.id===W)??d[0]:d[0],[d,W]),R=f?.visualizationMode??Ie,L=f?.colorScale??je,qe=f?.valueMin??ke,Ve=f?.valueMax??Ge,X=f?.valueUnit?` ${f.valueUnit}`:"",k=m.useMemo(()=>({...r.DEFAULT_CATEGORY_COLORS,...ce,...f?.categoryColors}),[ce,f?.categoryColors]),fe=f?.id,{grid:O,categoriesGrid:J,allValuesMap:K,tooltipDataMap:Q}=m.useMemo(()=>{let e,t=Array.from({length:i},()=>Array(p).fill(null)),l=new Map,o=new Map;if(Array.isArray(S)&&S.length>0){const a=c.wellDataToGrid(S,i,p,fe);e=a.grid,t=a.categories,l=a.allValues,o=a.tooltipData}else e=Array.from({length:i},()=>Array.from({length:p},()=>Math.random()*r.PLATEMAP_CONSTANTS.MAX_RANDOM_VALUE));return{grid:e,categoriesGrid:t,allValuesMap:l,tooltipDataMap:o}},[S,i,p,fe]),y=Fe??c.generateRowLabels(i),E=De??c.generateColumnLabels(p),ge=c.calculateValueRange(O),w=qe??ge.min,P=Ve??ge.max,G=O.some(e=>e.includes(null)),b=w-(P-w)*r.PLATEMAP_CONSTANTS.SENTINEL_RATIO-1,Ae=G?O.map(e=>e.map(t=>t===null?b:t)):O,Se=m.useMemo(()=>{if(!G)return L;let e;if(typeof L=="string"){const a=r.NAMED_COLORSCALES[L];if(a)e=a;else return L}else e=L;const t=P-b,l=(w-b)/t,o=[[0,T],[l*r.PLATEMAP_CONSTANTS.COLOR_SCALE_THRESHOLD,T]];for(const[a,u]of e){const g=l+a*(1-l);o.push([g,u])}return o},[L,G,w,P,b,T]),_e=G?b:w,Be=m.useMemo(()=>{const e=new Map;if(d)for(const t of d)e.set(t.id,t);return e},[d]),he=O.map((e,t)=>e.map((l,o)=>{const a=`${y[t]}${E[o]}`,u=String(a).toUpperCase();return c.buildWellHoverText({wellId:a,value:l,allValues:K.get(u),tooltipExtra:Q.get(u),activeLayerId:f?.id,layerConfigMap:Be,precision:ue,valueUnit:X})})),{categoricalGrid:ee,categoricalColorScale:te,uniqueTypes:ae,catMax:xe}=m.useMemo(()=>{if(R!=="categorical")return{categoricalGrid:null,categoricalColorScale:null,uniqueTypes:[],catMax:0};const e=new Set;let t=!1;for(const n of J)for(const A of n)A?e.add(A):t=!0;t&&e.add("empty");const l=[...e].sort(),o=new Map;l.forEach((n,A)=>o.set(n,A));const a=J.map(n=>n.map(A=>A===null?o.get("empty")??0:o.get(A)??o.get("empty")??0)),u=l.length,g=[];if(u===1){const n=k[l[0]]||T;g.push([0,n]),g.push([1,n])}else l.forEach((n,A)=>{const V=k[n]||T,B=A/(u-1),Z=.5/(u-1),oe=Math.max(0,B-Z),D=Math.min(1,B+Z-r.PLATEMAP_CONSTANTS.COLOR_SCALE_EPSILON);g.push([oe,V]),g.push([D,V])});return{categoricalGrid:a,categoricalColorScale:g,uniqueTypes:l,catMax:u-1}},[R,J,k,T]),Te=m.useMemo(()=>{if(!x||x.length===0)return[];const e=[];for(const t of x){const l=c.parseRegionWells(t.wells,y,E);if(!l)continue;const o=.49,a=l.minCol+1-o,u=l.maxCol+1+o,g=l.minRow-o,n=l.maxRow+o;e.push({type:"rect",xref:"x",yref:"y",x0:a,x1:u,y0:g,y1:n,line:{color:t.borderColor||r.COLORS.textDark,width:t.borderWidth??2},fillcolor:t.fillColor||"transparent",layer:"above"})}return e},[x,y,E]);m.useEffect(()=>{const e=me.current;if(!e)return;const t=R==="categorical",l=t&&ee?ee:Ae,o=t&&te?te:Se,a=t?0:_e,u=t?xe||1:P,g=t?!1:pe,{xData:n,yData:A,colorData:V,textData:B}=c.flattenGridData(l,y,he,i,p,a),Z=c.calculateMarkerSize(N,j,i,p,H,!!C,!!F),oe=[{x:n,y:A,mode:"markers",type:"scatter",marker:{symbol:H,size:Z,color:V,colorscale:o,cmin:a,cmax:u,showscale:g,colorbar:c.buildColorbarConfig(_?.position??"right",X,_?.title),line:{color:h.gridColor,width:1}},hoverinfo:"text",text:B}],D=_?.position??"right",Xe={autosize:!1,title:C?{text:C,font:{family:"Inter, sans-serif",size:20,color:h.textSecondary},x:c.calculateTitleX(D),xanchor:"center",y:.98,yanchor:"top"}:void 0,width:N,height:j,margin:c.buildPlotMargins(D,!!C,!!F),xaxis:{title:{text:ie||"",font:{size:16,color:h.textSecondary,family:"Inter, sans-serif"},standoff:15},side:"top",fixedrange:!0,dtick:1,range:[.5,p+.5],automargin:!1,tickmode:"array",tickvals:Array.from({length:p},(se,M)=>M+1),ticktext:E.map(String),tickangle:0,tickfont:{size:p>24?8:r.PLATEMAP_CONSTANTS.FONT_SIZE_LARGE},domain:c.calculateAxisDomain(D)},yaxis:{title:{text:F||"",font:{size:16,color:h.textSecondary,family:"Inter, sans-serif"},standoff:15},fixedrange:!0,dtick:1,range:[i+r.PLATEMAP_CONSTANTS.LABEL_CENTER_OFFSET,r.PLATEMAP_CONSTANTS.LABEL_CENTER_OFFSET],automargin:!1,tickmode:"array",tickvals:Array.from({length:i},(se,M)=>M),ticktext:y.map(String),tickfont:{size:i>16?8:r.PLATEMAP_CONSTANTS.FONT_SIZE_LARGE}},paper_bgcolor:h.paperBg,plot_bgcolor:h.plotBg,font:{family:"Inter, sans-serif",color:h.textSecondary},shapes:Te},Je={responsive:!0,displayModeBar:!1,displaylogo:!1};return Re.newPlot(e,oe,Xe,Je),e.on("plotly_click",se=>{if(!Y.current)return;const M=se.points[0];if(M){const Le=y,Oe=E,Ee=Le.indexOf(M.y),ve=Oe.indexOf(M.x);if(Ee>=0&&ve>=0){const Ce=`${Le[Ee]}${Oe[ve]}`,Ne=String(Ce).toUpperCase(),Ke=K.get(Ne),Qe=Q.get(Ne),et={wellId:Ce,values:Ke,tooltipData:Qe};Y.current?.(et)}}}),()=>{e&&Re.purge(e)}},[Ae,E,y,Se,pe,_e,P,X,C,ie,F,N,j,he,ue,Q,K,O,R,ee,te,ae.length,xe,Te,i,p,_,H,h]);const Ze=()=>!d||d.length<=1?null:s.jsx("div",{className:"platemap-layer-selector",children:d.map(e=>{const t=f?.id===e.id;return s.jsx(tt.Button,{variant:t?"default":"outline",size:"sm",onClick:()=>{Ue(e.id),Pe?.(e.id)},children:e.name},e.id)})}),z=_?.position??"right",le=_?.fontSize??12,He=_?.itemSpacing??4,$=_?.swatchSize??16,ye=_?.title,Me=120,I=z==="top"||z==="bottom",Ye=()=>{const e=R==="categorical"&&ae.length>0,t=x&&x.length>0;if(!$e||!e&&!t)return I?null:s.jsx("div",{className:"platemap-legend-placeholder",style:{width:Me}});const l=["platemap-legend"];I?l.push("platemap-legend--horizontal"):z==="left"?l.push("platemap-legend--left"):z==="right"&&l.push("platemap-legend--right");const o={gap:`${He}px`,width:I?void 0:Me};return s.jsxs("div",{className:l.join(" "),style:o,children:[ye&&s.jsx("div",{className:`platemap-legend__title${I?" platemap-legend__title--horizontal":""}`,style:{fontSize:`${le}px`},children:ye}),e&&ae.map(a=>s.jsxs("div",{className:"platemap-legend__item",children:[s.jsx("div",{className:"platemap-legend__swatch",style:{width:`${$}px`,height:`${$}px`,backgroundColor:k[a]||T}}),s.jsx("span",{className:"platemap-legend__label platemap-legend__label--capitalize",style:{fontSize:`${le}px`},children:a})]},a)),t&&x.map(a=>s.jsxs("div",{className:"platemap-legend__item",children:[s.jsx("div",{className:"platemap-legend__swatch platemap-legend__swatch--region",style:{width:`${$}px`,height:`${$}px`,backgroundColor:a.fillColor||"transparent",border:`${a.borderWidth||2}px solid ${a.borderColor||r.COLORS.regionBorder}`}}),s.jsx("span",{className:"platemap-legend__label",style:{fontSize:`${le}px`},children:a.name})]},a.id))]})},U=s.jsx("div",{ref:me,className:"platemap-plot",style:{width:N,height:j}}),q=Ye(),We=()=>{switch(z){case"left":return s.jsxs("div",{className:"platemap-plot-wrapper platemap-plot-wrapper--vertical",children:[q,U]});case"top":return s.jsxs("div",{className:"platemap-plot-wrapper platemap-plot-wrapper--horizontal",children:[q,U]});case"bottom":return s.jsxs("div",{className:"platemap-plot-wrapper platemap-plot-wrapper--horizontal",children:[U,q]});default:return s.jsxs("div",{className:"platemap-plot-wrapper platemap-plot-wrapper--vertical",children:[U,q]})}};return s.jsxs("div",{className:"platemap-container",style:{width:I?void 0:N},children:[Ze(),We()]})};exports.DEFAULT_CATEGORY_COLORS=r.DEFAULT_CATEGORY_COLORS;exports.PLATE_FORMAT_1536=v.PLATE_FORMAT_1536;exports.PLATE_FORMAT_384=v.PLATE_FORMAT_384;exports.PLATE_FORMAT_96=v.PLATE_FORMAT_96;exports.PLATE_FORMAT_CUSTOM=v.PLATE_FORMAT_CUSTOM;exports.PlateMap=lt;
|
|
2
|
+
//# sourceMappingURL=PlateMap.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlateMap.cjs","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":"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"}
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import { jsxs as y, jsx as g } from "react/jsx-runtime";
|
|
2
|
+
import Ne from "plotly.js-dist";
|
|
3
|
+
import { useRef as Oe, useState as at, useMemo as x, useEffect as ot } from "react";
|
|
4
|
+
/* empty css */
|
|
5
|
+
import { PLATE_CONFIGS as lt, DEFAULT_COLOR_SCALE as rt, DEFAULT_CATEGORY_COLORS as nt, PLATEMAP_CONSTANTS as S, COLORS as re, NAMED_COLORSCALES as st } from "./constants.js";
|
|
6
|
+
import { PLATE_FORMAT_96 as ct, PLATE_FORMAT_CUSTOM as it } from "./types.js";
|
|
7
|
+
import { PLATE_FORMAT_1536 as $t, PLATE_FORMAT_384 as Gt } from "./types.js";
|
|
8
|
+
import { hasMultiValueWells as pt, extractLayers as dt, wellDataToGrid as ut, generateRowLabels as mt, generateColumnLabels as ft, calculateValueRange as gt, buildWellHoverText as ht, parseRegionWells as yt, flattenGridData as xt, buildColorbarConfig as St, calculateMarkerSize as _t, calculateAxisDomain as vt, buildPlotMargins as Lt, calculateTitleX as At } from "./utils.js";
|
|
9
|
+
import { Button as wt } from "../../ui/button.js";
|
|
10
|
+
import { usePlotlyTheme as Mt } from "../../../hooks/use-plotly-theme.js";
|
|
11
|
+
const Dt = ({
|
|
12
|
+
data: m,
|
|
13
|
+
layerConfigs: ne,
|
|
14
|
+
initialLayerId: Re,
|
|
15
|
+
onLayerChange: ze,
|
|
16
|
+
plateFormat: se = ct,
|
|
17
|
+
rows: Ie,
|
|
18
|
+
columns: De,
|
|
19
|
+
visualizationMode: ke = "heatmap",
|
|
20
|
+
categoryColors: ce,
|
|
21
|
+
regions: _,
|
|
22
|
+
title: T,
|
|
23
|
+
xTitle: ie,
|
|
24
|
+
yTitle: k,
|
|
25
|
+
xLabels: Pe,
|
|
26
|
+
yLabels: $e,
|
|
27
|
+
colorScale: Ge = rt,
|
|
28
|
+
valueMin: Fe,
|
|
29
|
+
valueMax: Ue,
|
|
30
|
+
emptyWellColor: v = re.emptyWell,
|
|
31
|
+
showColorBar: pe = !0,
|
|
32
|
+
showLegend: Ve = !0,
|
|
33
|
+
legendConfig: f,
|
|
34
|
+
width: C = 800,
|
|
35
|
+
height: P = 500,
|
|
36
|
+
precision: de = 0,
|
|
37
|
+
markerShape: j = "circle",
|
|
38
|
+
onWellClick: ue
|
|
39
|
+
}) => {
|
|
40
|
+
const me = Oe(null), h = Mt(), q = Oe(ue);
|
|
41
|
+
q.current = ue;
|
|
42
|
+
const [W, Be] = at(Re);
|
|
43
|
+
let n, s;
|
|
44
|
+
if (se === it)
|
|
45
|
+
n = Ie ?? 8, s = De ?? 12;
|
|
46
|
+
else {
|
|
47
|
+
const e = lt[se];
|
|
48
|
+
n = e.rows, s = e.columns;
|
|
49
|
+
}
|
|
50
|
+
const i = x(() => {
|
|
51
|
+
if (Array.isArray(m) && m.length > 0 && "wellId" in m[0]) {
|
|
52
|
+
const e = m;
|
|
53
|
+
if (pt(e))
|
|
54
|
+
return dt(e, ne);
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}, [m, ne]), p = x(() => !i || i.length === 0 ? null : W ? i.find((e) => e.id === W) ?? i[0] : i[0], [i, W]), b = p?.visualizationMode ?? ke, w = p?.colorScale ?? Ge, Ze = p?.valueMin ?? Fe, He = p?.valueMax ?? Ue, X = p?.valueUnit ? ` ${p.valueUnit}` : "", $ = x(
|
|
58
|
+
() => ({ ...nt, ...ce, ...p?.categoryColors }),
|
|
59
|
+
[ce, p?.categoryColors]
|
|
60
|
+
), fe = p?.id, { grid: M, categoriesGrid: Y, allValuesMap: J, tooltipDataMap: K } = x(() => {
|
|
61
|
+
let e, t = Array.from(
|
|
62
|
+
{ length: n },
|
|
63
|
+
() => Array(s).fill(null)
|
|
64
|
+
), o = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map();
|
|
65
|
+
if (Array.isArray(m) && m.length > 0) {
|
|
66
|
+
const a = ut(m, n, s, fe);
|
|
67
|
+
e = a.grid, t = a.categories, o = a.allValues, l = a.tooltipData;
|
|
68
|
+
} else
|
|
69
|
+
e = Array.from(
|
|
70
|
+
{ length: n },
|
|
71
|
+
() => Array.from({ length: s }, () => Math.random() * S.MAX_RANDOM_VALUE)
|
|
72
|
+
);
|
|
73
|
+
return { grid: e, categoriesGrid: t, allValuesMap: o, tooltipDataMap: l };
|
|
74
|
+
}, [m, n, s, fe]), L = $e ?? mt(n), E = Pe ?? ft(s), ge = gt(M), N = Ze ?? ge.min, O = He ?? ge.max, G = M.some((e) => e.includes(null)), R = N - (O - N) * S.SENTINEL_RATIO - 1, he = G ? M.map((e) => e.map((t) => t === null ? R : t)) : M, ye = x(() => {
|
|
75
|
+
if (!G) return w;
|
|
76
|
+
let e;
|
|
77
|
+
if (typeof w == "string") {
|
|
78
|
+
const a = st[w];
|
|
79
|
+
if (a)
|
|
80
|
+
e = a;
|
|
81
|
+
else
|
|
82
|
+
return w;
|
|
83
|
+
} else
|
|
84
|
+
e = w;
|
|
85
|
+
const t = O - R, o = (N - R) / t, l = [
|
|
86
|
+
[0, v],
|
|
87
|
+
[o * S.COLOR_SCALE_THRESHOLD, v]
|
|
88
|
+
// Small band for empty wells
|
|
89
|
+
];
|
|
90
|
+
for (const [a, c] of e) {
|
|
91
|
+
const d = o + a * (1 - o);
|
|
92
|
+
l.push([d, c]);
|
|
93
|
+
}
|
|
94
|
+
return l;
|
|
95
|
+
}, [w, G, N, O, R, v]), xe = G ? R : N, je = x(() => {
|
|
96
|
+
const e = /* @__PURE__ */ new Map();
|
|
97
|
+
if (i)
|
|
98
|
+
for (const t of i)
|
|
99
|
+
e.set(t.id, t);
|
|
100
|
+
return e;
|
|
101
|
+
}, [i]), Se = M.map(
|
|
102
|
+
(e, t) => e.map((o, l) => {
|
|
103
|
+
const a = `${L[t]}${E[l]}`, c = String(a).toUpperCase();
|
|
104
|
+
return ht({
|
|
105
|
+
wellId: a,
|
|
106
|
+
value: o,
|
|
107
|
+
allValues: J.get(c),
|
|
108
|
+
tooltipExtra: K.get(c),
|
|
109
|
+
activeLayerId: p?.id,
|
|
110
|
+
layerConfigMap: je,
|
|
111
|
+
precision: de,
|
|
112
|
+
valueUnit: X
|
|
113
|
+
});
|
|
114
|
+
})
|
|
115
|
+
), { categoricalGrid: Q, categoricalColorScale: ee, uniqueTypes: te, catMax: _e } = x(() => {
|
|
116
|
+
if (b !== "categorical")
|
|
117
|
+
return { categoricalGrid: null, categoricalColorScale: null, uniqueTypes: [], catMax: 0 };
|
|
118
|
+
const e = /* @__PURE__ */ new Set();
|
|
119
|
+
let t = !1;
|
|
120
|
+
for (const r of Y)
|
|
121
|
+
for (const u of r)
|
|
122
|
+
u ? e.add(u) : t = !0;
|
|
123
|
+
t && e.add("empty");
|
|
124
|
+
const o = [...e].sort(), l = /* @__PURE__ */ new Map();
|
|
125
|
+
o.forEach((r, u) => l.set(r, u));
|
|
126
|
+
const a = Y.map(
|
|
127
|
+
(r) => r.map((u) => u === null ? l.get("empty") ?? 0 : l.get(u) ?? l.get("empty") ?? 0)
|
|
128
|
+
), c = o.length, d = [];
|
|
129
|
+
if (c === 1) {
|
|
130
|
+
const r = $[o[0]] || v;
|
|
131
|
+
d.push([0, r]), d.push([1, r]);
|
|
132
|
+
} else
|
|
133
|
+
o.forEach((r, u) => {
|
|
134
|
+
const B = $[r] || v, Z = u / (c - 1), H = 0.5 / (c - 1), oe = Math.max(0, Z - H), D = Math.min(1, Z + H - S.COLOR_SCALE_EPSILON);
|
|
135
|
+
d.push([oe, B]), d.push([D, B]);
|
|
136
|
+
});
|
|
137
|
+
return { categoricalGrid: a, categoricalColorScale: d, uniqueTypes: o, catMax: c - 1 };
|
|
138
|
+
}, [b, Y, $, v]), ve = x(() => {
|
|
139
|
+
if (!_ || _.length === 0)
|
|
140
|
+
return [];
|
|
141
|
+
const e = [];
|
|
142
|
+
for (const t of _) {
|
|
143
|
+
const o = yt(t.wells, L, E);
|
|
144
|
+
if (!o) continue;
|
|
145
|
+
const l = 0.49, a = o.minCol + 1 - l, c = o.maxCol + 1 + l, d = o.minRow - l, r = o.maxRow + l;
|
|
146
|
+
e.push({
|
|
147
|
+
type: "rect",
|
|
148
|
+
xref: "x",
|
|
149
|
+
yref: "y",
|
|
150
|
+
x0: a,
|
|
151
|
+
x1: c,
|
|
152
|
+
y0: d,
|
|
153
|
+
y1: r,
|
|
154
|
+
line: {
|
|
155
|
+
color: t.borderColor || re.textDark,
|
|
156
|
+
width: t.borderWidth ?? 2
|
|
157
|
+
},
|
|
158
|
+
fillcolor: t.fillColor || "transparent",
|
|
159
|
+
layer: "above"
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return e;
|
|
163
|
+
}, [_, L, E]);
|
|
164
|
+
ot(() => {
|
|
165
|
+
const e = me.current;
|
|
166
|
+
if (!e) return;
|
|
167
|
+
const t = b === "categorical", o = t && Q ? Q : he, l = t && ee ? ee : ye, a = t ? 0 : xe, c = t ? _e || 1 : O, d = t ? !1 : pe, { xData: r, yData: u, colorData: B, textData: Z } = xt(
|
|
168
|
+
o,
|
|
169
|
+
L,
|
|
170
|
+
Se,
|
|
171
|
+
n,
|
|
172
|
+
s,
|
|
173
|
+
a
|
|
174
|
+
), H = _t(
|
|
175
|
+
C,
|
|
176
|
+
P,
|
|
177
|
+
n,
|
|
178
|
+
s,
|
|
179
|
+
j,
|
|
180
|
+
!!T,
|
|
181
|
+
!!k
|
|
182
|
+
), oe = [
|
|
183
|
+
{
|
|
184
|
+
x: r,
|
|
185
|
+
y: u,
|
|
186
|
+
mode: "markers",
|
|
187
|
+
type: "scatter",
|
|
188
|
+
marker: {
|
|
189
|
+
symbol: j,
|
|
190
|
+
size: H,
|
|
191
|
+
color: B,
|
|
192
|
+
colorscale: l,
|
|
193
|
+
cmin: a,
|
|
194
|
+
cmax: c,
|
|
195
|
+
showscale: d,
|
|
196
|
+
colorbar: St(
|
|
197
|
+
f?.position ?? "right",
|
|
198
|
+
X,
|
|
199
|
+
f?.title
|
|
200
|
+
),
|
|
201
|
+
line: {
|
|
202
|
+
color: h.gridColor,
|
|
203
|
+
width: 1
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
hoverinfo: "text",
|
|
207
|
+
text: Z
|
|
208
|
+
}
|
|
209
|
+
], D = f?.position ?? "right", Je = {
|
|
210
|
+
autosize: !1,
|
|
211
|
+
// Prevent auto-sizing to maintain consistent layout
|
|
212
|
+
title: T ? {
|
|
213
|
+
text: T,
|
|
214
|
+
font: {
|
|
215
|
+
family: "Inter, sans-serif",
|
|
216
|
+
size: 20,
|
|
217
|
+
color: h.textSecondary
|
|
218
|
+
},
|
|
219
|
+
x: At(D),
|
|
220
|
+
xanchor: "center",
|
|
221
|
+
y: 0.98,
|
|
222
|
+
yanchor: "top"
|
|
223
|
+
} : void 0,
|
|
224
|
+
width: C,
|
|
225
|
+
height: P,
|
|
226
|
+
margin: Lt(D, !!T, !!k),
|
|
227
|
+
xaxis: {
|
|
228
|
+
title: {
|
|
229
|
+
text: ie || "",
|
|
230
|
+
font: {
|
|
231
|
+
size: 16,
|
|
232
|
+
color: h.textSecondary,
|
|
233
|
+
family: "Inter, sans-serif"
|
|
234
|
+
},
|
|
235
|
+
standoff: 15
|
|
236
|
+
},
|
|
237
|
+
side: "top",
|
|
238
|
+
fixedrange: !0,
|
|
239
|
+
dtick: 1,
|
|
240
|
+
range: [0.5, s + 0.5],
|
|
241
|
+
// Explicit range to prevent auto-padding
|
|
242
|
+
automargin: !1,
|
|
243
|
+
// Prevent auto margin adjustment
|
|
244
|
+
tickmode: "array",
|
|
245
|
+
tickvals: Array.from({ length: s }, (le, A) => A + 1),
|
|
246
|
+
ticktext: E.map(String),
|
|
247
|
+
tickangle: 0,
|
|
248
|
+
// Keep labels horizontal
|
|
249
|
+
tickfont: { size: s > 24 ? 8 : S.FONT_SIZE_LARGE },
|
|
250
|
+
// Smaller font for high-density plates
|
|
251
|
+
// Adjust domain based on legend position to prevent colorbar overlap
|
|
252
|
+
domain: vt(D)
|
|
253
|
+
},
|
|
254
|
+
yaxis: {
|
|
255
|
+
title: {
|
|
256
|
+
text: k || "",
|
|
257
|
+
font: {
|
|
258
|
+
size: 16,
|
|
259
|
+
color: h.textSecondary,
|
|
260
|
+
family: "Inter, sans-serif"
|
|
261
|
+
},
|
|
262
|
+
standoff: 15
|
|
263
|
+
},
|
|
264
|
+
fixedrange: !0,
|
|
265
|
+
dtick: 1,
|
|
266
|
+
range: [n + S.LABEL_CENTER_OFFSET, S.LABEL_CENTER_OFFSET],
|
|
267
|
+
// Reversed range: high to low puts row A at top
|
|
268
|
+
automargin: !1,
|
|
269
|
+
// Prevent auto margin adjustment
|
|
270
|
+
tickmode: "array",
|
|
271
|
+
tickvals: Array.from({ length: n }, (le, A) => A),
|
|
272
|
+
ticktext: L.map(String),
|
|
273
|
+
tickfont: { size: n > 16 ? 8 : S.FONT_SIZE_LARGE }
|
|
274
|
+
// Smaller font for high-density plates
|
|
275
|
+
},
|
|
276
|
+
paper_bgcolor: h.paperBg,
|
|
277
|
+
plot_bgcolor: h.plotBg,
|
|
278
|
+
font: {
|
|
279
|
+
family: "Inter, sans-serif",
|
|
280
|
+
color: h.textSecondary
|
|
281
|
+
},
|
|
282
|
+
shapes: ve
|
|
283
|
+
}, Ke = {
|
|
284
|
+
responsive: !0,
|
|
285
|
+
displayModeBar: !1,
|
|
286
|
+
displaylogo: !1
|
|
287
|
+
};
|
|
288
|
+
return Ne.newPlot(e, oe, Je, Ke), e.on("plotly_click", (le) => {
|
|
289
|
+
if (!q.current) return;
|
|
290
|
+
const A = le.points[0];
|
|
291
|
+
if (A) {
|
|
292
|
+
const we = L, Me = E, Ee = we.indexOf(A.y), Te = Me.indexOf(A.x);
|
|
293
|
+
if (Ee >= 0 && Te >= 0) {
|
|
294
|
+
const Ce = `${we[Ee]}${Me[Te]}`, be = String(Ce).toUpperCase(), Qe = J.get(be), et = K.get(be), tt = {
|
|
295
|
+
wellId: Ce,
|
|
296
|
+
values: Qe,
|
|
297
|
+
tooltipData: et
|
|
298
|
+
};
|
|
299
|
+
q.current?.(tt);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}), () => {
|
|
303
|
+
e && Ne.purge(e);
|
|
304
|
+
};
|
|
305
|
+
}, [
|
|
306
|
+
he,
|
|
307
|
+
E,
|
|
308
|
+
L,
|
|
309
|
+
ye,
|
|
310
|
+
pe,
|
|
311
|
+
xe,
|
|
312
|
+
O,
|
|
313
|
+
X,
|
|
314
|
+
T,
|
|
315
|
+
ie,
|
|
316
|
+
k,
|
|
317
|
+
C,
|
|
318
|
+
P,
|
|
319
|
+
Se,
|
|
320
|
+
de,
|
|
321
|
+
K,
|
|
322
|
+
J,
|
|
323
|
+
M,
|
|
324
|
+
b,
|
|
325
|
+
Q,
|
|
326
|
+
ee,
|
|
327
|
+
te.length,
|
|
328
|
+
_e,
|
|
329
|
+
ve,
|
|
330
|
+
n,
|
|
331
|
+
s,
|
|
332
|
+
f,
|
|
333
|
+
j,
|
|
334
|
+
h
|
|
335
|
+
]);
|
|
336
|
+
const qe = () => !i || i.length <= 1 ? null : /* @__PURE__ */ g("div", { className: "platemap-layer-selector", children: i.map((e) => {
|
|
337
|
+
const t = p?.id === e.id;
|
|
338
|
+
return /* @__PURE__ */ g(
|
|
339
|
+
wt,
|
|
340
|
+
{
|
|
341
|
+
variant: t ? "default" : "outline",
|
|
342
|
+
size: "sm",
|
|
343
|
+
onClick: () => {
|
|
344
|
+
Be(e.id), ze?.(e.id);
|
|
345
|
+
},
|
|
346
|
+
children: e.name
|
|
347
|
+
},
|
|
348
|
+
e.id
|
|
349
|
+
);
|
|
350
|
+
}) }), z = f?.position ?? "right", ae = f?.fontSize ?? 12, We = f?.itemSpacing ?? 4, F = f?.swatchSize ?? 16, Le = f?.title, Ae = 120, I = z === "top" || z === "bottom", Xe = () => {
|
|
351
|
+
const e = b === "categorical" && te.length > 0, t = _ && _.length > 0;
|
|
352
|
+
if (!Ve || !e && !t)
|
|
353
|
+
return I ? null : /* @__PURE__ */ g("div", { className: "platemap-legend-placeholder", style: { width: Ae } });
|
|
354
|
+
const o = ["platemap-legend"];
|
|
355
|
+
I ? o.push("platemap-legend--horizontal") : z === "left" ? o.push("platemap-legend--left") : z === "right" && o.push("platemap-legend--right");
|
|
356
|
+
const l = {
|
|
357
|
+
gap: `${We}px`,
|
|
358
|
+
width: I ? void 0 : Ae
|
|
359
|
+
};
|
|
360
|
+
return /* @__PURE__ */ y("div", { className: o.join(" "), style: l, children: [
|
|
361
|
+
Le && /* @__PURE__ */ g(
|
|
362
|
+
"div",
|
|
363
|
+
{
|
|
364
|
+
className: `platemap-legend__title${I ? " platemap-legend__title--horizontal" : ""}`,
|
|
365
|
+
style: { fontSize: `${ae}px` },
|
|
366
|
+
children: Le
|
|
367
|
+
}
|
|
368
|
+
),
|
|
369
|
+
e && te.map((a) => /* @__PURE__ */ y("div", { className: "platemap-legend__item", children: [
|
|
370
|
+
/* @__PURE__ */ g(
|
|
371
|
+
"div",
|
|
372
|
+
{
|
|
373
|
+
className: "platemap-legend__swatch",
|
|
374
|
+
style: {
|
|
375
|
+
width: `${F}px`,
|
|
376
|
+
height: `${F}px`,
|
|
377
|
+
backgroundColor: $[a] || v
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
),
|
|
381
|
+
/* @__PURE__ */ g(
|
|
382
|
+
"span",
|
|
383
|
+
{
|
|
384
|
+
className: "platemap-legend__label platemap-legend__label--capitalize",
|
|
385
|
+
style: { fontSize: `${ae}px` },
|
|
386
|
+
children: a
|
|
387
|
+
}
|
|
388
|
+
)
|
|
389
|
+
] }, a)),
|
|
390
|
+
t && _.map((a) => /* @__PURE__ */ y("div", { className: "platemap-legend__item", children: [
|
|
391
|
+
/* @__PURE__ */ g(
|
|
392
|
+
"div",
|
|
393
|
+
{
|
|
394
|
+
className: "platemap-legend__swatch platemap-legend__swatch--region",
|
|
395
|
+
style: {
|
|
396
|
+
width: `${F}px`,
|
|
397
|
+
height: `${F}px`,
|
|
398
|
+
backgroundColor: a.fillColor || "transparent",
|
|
399
|
+
border: `${a.borderWidth || 2}px solid ${a.borderColor || re.regionBorder}`
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
),
|
|
403
|
+
/* @__PURE__ */ g(
|
|
404
|
+
"span",
|
|
405
|
+
{
|
|
406
|
+
className: "platemap-legend__label",
|
|
407
|
+
style: { fontSize: `${ae}px` },
|
|
408
|
+
children: a.name
|
|
409
|
+
}
|
|
410
|
+
)
|
|
411
|
+
] }, a.id))
|
|
412
|
+
] });
|
|
413
|
+
}, U = /* @__PURE__ */ g("div", { ref: me, className: "platemap-plot", style: { width: C, height: P } }), V = Xe(), Ye = () => {
|
|
414
|
+
switch (z) {
|
|
415
|
+
case "left":
|
|
416
|
+
return /* @__PURE__ */ y("div", { className: "platemap-plot-wrapper platemap-plot-wrapper--vertical", children: [
|
|
417
|
+
V,
|
|
418
|
+
U
|
|
419
|
+
] });
|
|
420
|
+
case "top":
|
|
421
|
+
return /* @__PURE__ */ y("div", { className: "platemap-plot-wrapper platemap-plot-wrapper--horizontal", children: [
|
|
422
|
+
V,
|
|
423
|
+
U
|
|
424
|
+
] });
|
|
425
|
+
case "bottom":
|
|
426
|
+
return /* @__PURE__ */ y("div", { className: "platemap-plot-wrapper platemap-plot-wrapper--horizontal", children: [
|
|
427
|
+
U,
|
|
428
|
+
V
|
|
429
|
+
] });
|
|
430
|
+
default:
|
|
431
|
+
return /* @__PURE__ */ y("div", { className: "platemap-plot-wrapper platemap-plot-wrapper--vertical", children: [
|
|
432
|
+
U,
|
|
433
|
+
V
|
|
434
|
+
] });
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
return /* @__PURE__ */ y("div", { className: "platemap-container", style: { width: I ? void 0 : C }, children: [
|
|
438
|
+
qe(),
|
|
439
|
+
Ye()
|
|
440
|
+
] });
|
|
441
|
+
};
|
|
442
|
+
export {
|
|
443
|
+
nt as DEFAULT_CATEGORY_COLORS,
|
|
444
|
+
$t as PLATE_FORMAT_1536,
|
|
445
|
+
Gt as PLATE_FORMAT_384,
|
|
446
|
+
ct as PLATE_FORMAT_96,
|
|
447
|
+
it as PLATE_FORMAT_CUSTOM,
|
|
448
|
+
Dt as PlateMap
|
|
449
|
+
};
|
|
450
|
+
//# sourceMappingURL=PlateMap.js.map
|