@sqlrooms/mosaic 0.29.0-rc.8 → 0.29.0-rc.9
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/README.md +84 -74
- package/dist/ai/agentIntent.d.ts +5 -0
- package/dist/ai/agentIntent.d.ts.map +1 -0
- package/dist/ai/agentIntent.js +8 -0
- package/dist/ai/agentIntent.js.map +1 -0
- package/dist/ai/block-document/constants.d.ts +9 -0
- package/dist/ai/block-document/constants.d.ts.map +1 -0
- package/dist/ai/block-document/constants.js +9 -0
- package/dist/ai/block-document/constants.js.map +1 -0
- package/dist/ai/block-document/createAddMosaicDashboardBlockTool.d.ts +48 -0
- package/dist/ai/block-document/createAddMosaicDashboardBlockTool.d.ts.map +1 -0
- package/dist/ai/block-document/createAddMosaicDashboardBlockTool.js +59 -0
- package/dist/ai/block-document/createAddMosaicDashboardBlockTool.js.map +1 -0
- package/dist/ai/block-document/createBlockDocumentChartTools.d.ts +19 -0
- package/dist/ai/block-document/createBlockDocumentChartTools.d.ts.map +1 -0
- package/dist/ai/block-document/createBlockDocumentChartTools.js +37 -0
- package/dist/ai/block-document/createBlockDocumentChartTools.js.map +1 -0
- package/dist/ai/block-document/createBlockDocumentDataTableExplorerTool.d.ts +32 -0
- package/dist/ai/block-document/createBlockDocumentDataTableExplorerTool.d.ts.map +1 -0
- package/dist/ai/block-document/createBlockDocumentDataTableExplorerTool.js +37 -0
- package/dist/ai/block-document/createBlockDocumentDataTableExplorerTool.js.map +1 -0
- package/dist/ai/constants.d.ts +3 -0
- package/dist/ai/constants.d.ts.map +1 -0
- package/dist/ai/constants.js +3 -0
- package/dist/ai/constants.js.map +1 -0
- package/dist/ai/createDataTableExplorerTool.d.ts +69 -0
- package/dist/ai/createDataTableExplorerTool.d.ts.map +1 -0
- package/dist/ai/createDataTableExplorerTool.js +68 -0
- package/dist/ai/createDataTableExplorerTool.js.map +1 -0
- package/dist/ai/dashboard/constants.d.ts +6 -0
- package/dist/ai/dashboard/constants.d.ts.map +1 -0
- package/dist/ai/dashboard/constants.js +6 -0
- package/dist/ai/dashboard/constants.js.map +1 -0
- package/dist/ai/dashboard/createDashboardAgentTool.d.ts +17 -0
- package/dist/ai/dashboard/createDashboardAgentTool.d.ts.map +1 -0
- package/dist/ai/dashboard/createDashboardAgentTool.js +205 -0
- package/dist/ai/dashboard/createDashboardAgentTool.js.map +1 -0
- package/dist/ai/dashboard/createDashboardAiAdapter.d.ts +14 -0
- package/dist/ai/dashboard/createDashboardAiAdapter.d.ts.map +1 -0
- package/dist/ai/dashboard/createDashboardAiAdapter.js +75 -0
- package/dist/ai/dashboard/createDashboardAiAdapter.js.map +1 -0
- package/dist/ai/dashboard/createDashboardAiTools.d.ts +26 -0
- package/dist/ai/dashboard/createDashboardAiTools.d.ts.map +1 -0
- package/dist/ai/dashboard/createDashboardAiTools.js +40 -0
- package/dist/ai/dashboard/createDashboardAiTools.js.map +1 -0
- package/dist/ai/dashboard/createDashboardChartTools.d.ts +27 -0
- package/dist/ai/dashboard/createDashboardChartTools.d.ts.map +1 -0
- package/dist/ai/dashboard/createDashboardChartTools.js +55 -0
- package/dist/ai/dashboard/createDashboardChartTools.js.map +1 -0
- package/dist/ai/dashboard/createDashboardDataTableExplorerTool.d.ts +23 -0
- package/dist/ai/dashboard/createDashboardDataTableExplorerTool.d.ts.map +1 -0
- package/dist/ai/dashboard/createDashboardDataTableExplorerTool.js +29 -0
- package/dist/ai/dashboard/createDashboardDataTableExplorerTool.js.map +1 -0
- package/dist/ai/dashboard/createListDashboardPanelsTool.d.ts +28 -0
- package/dist/ai/dashboard/createListDashboardPanelsTool.d.ts.map +1 -0
- package/dist/ai/dashboard/createListDashboardPanelsTool.js +54 -0
- package/dist/ai/dashboard/createListDashboardPanelsTool.js.map +1 -0
- package/dist/ai/dashboard/dashboard-types.d.ts +59 -0
- package/dist/ai/dashboard/dashboard-types.d.ts.map +1 -0
- package/dist/ai/dashboard/dashboard-types.js +2 -0
- package/dist/ai/dashboard/dashboard-types.js.map +1 -0
- package/dist/ai/database-types.d.ts +12 -0
- package/dist/ai/database-types.d.ts.map +1 -0
- package/dist/ai/database-types.js +2 -0
- package/dist/ai/database-types.js.map +1 -0
- package/dist/ai/errors.d.ts +8 -0
- package/dist/ai/errors.d.ts.map +1 -0
- package/dist/ai/errors.js +11 -0
- package/dist/ai/errors.js.map +1 -0
- package/dist/ai/tool-helpers.d.ts +28 -29
- package/dist/ai/tool-helpers.d.ts.map +1 -1
- package/dist/ai/tool-helpers.js +38 -76
- package/dist/ai/tool-helpers.js.map +1 -1
- package/dist/ai/tool-schemas.d.ts +9 -4
- package/dist/ai/tool-schemas.d.ts.map +1 -1
- package/dist/ai/tool-schemas.js +12 -12
- package/dist/ai/tool-schemas.js.map +1 -1
- package/dist/ai/tool-types.d.ts +19 -1
- package/dist/ai/tool-types.d.ts.map +1 -1
- package/dist/ai/tool-types.js.map +1 -1
- package/dist/ai/types.d.ts +64 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +2 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/ai.d.ts +16 -2
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +14 -5
- package/dist/ai.js.map +1 -1
- package/dist/charts/MosaicChart.js +1 -1
- package/dist/charts/MosaicChart.js.map +1 -1
- package/dist/charts/MosaicChartView.d.ts.map +1 -1
- package/dist/charts/MosaicChartView.js +1 -2
- package/dist/charts/MosaicChartView.js.map +1 -1
- package/dist/charts/chart-settings/MosaicChartSpecViewerPanel.d.ts.map +1 -1
- package/dist/charts/chart-settings/MosaicChartSpecViewerPanel.js +2 -1
- package/dist/charts/chart-settings/MosaicChartSpecViewerPanel.js.map +1 -1
- package/dist/charts/chart-settings/MosaicChartTypeSelector.d.ts.map +1 -1
- package/dist/charts/chart-settings/MosaicChartTypeSelector.js +4 -11
- package/dist/charts/chart-settings/MosaicChartTypeSelector.js.map +1 -1
- package/dist/charts/chart-types/base-types.d.ts +27 -23
- package/dist/charts/chart-types/base-types.d.ts.map +1 -1
- package/dist/charts/chart-types/base-types.js +3 -1
- package/dist/charts/chart-types/base-types.js.map +1 -1
- package/dist/charts/chart-types/box-plot/definition.d.ts.map +1 -1
- package/dist/charts/chart-types/box-plot/definition.js +1 -0
- package/dist/charts/chart-types/box-plot/definition.js.map +1 -1
- package/dist/charts/chart-types/box-plot/renderer/BoxPlotClient.d.ts +37 -3
- package/dist/charts/chart-types/box-plot/renderer/BoxPlotClient.d.ts.map +1 -1
- package/dist/charts/chart-types/box-plot/renderer/BoxPlotClient.js +26 -6
- package/dist/charts/chart-types/box-plot/renderer/BoxPlotClient.js.map +1 -1
- package/dist/charts/chart-types/box-plot/renderer/BoxPlotPanelRenderer.js +2 -2
- package/dist/charts/chart-types/box-plot/renderer/BoxPlotPanelRenderer.js.map +1 -1
- package/dist/charts/chart-types/box-plot/renderer/useBoxPlotClient.d.ts +12 -1
- package/dist/charts/chart-types/box-plot/renderer/useBoxPlotClient.d.ts.map +1 -1
- package/dist/charts/chart-types/box-plot/renderer/useBoxPlotClient.js +13 -3
- package/dist/charts/chart-types/box-plot/renderer/useBoxPlotClient.js.map +1 -1
- package/dist/charts/chart-types/box-plot/tool.d.ts +20 -24
- package/dist/charts/chart-types/box-plot/tool.d.ts.map +1 -1
- package/dist/charts/chart-types/box-plot/tool.js +25 -33
- package/dist/charts/chart-types/box-plot/tool.js.map +1 -1
- package/dist/charts/chart-types/box-plot/validation.d.ts +9 -0
- package/dist/charts/chart-types/box-plot/validation.d.ts.map +1 -0
- package/dist/charts/chart-types/box-plot/validation.js +32 -0
- package/dist/charts/chart-types/box-plot/validation.js.map +1 -0
- package/dist/charts/chart-types/column-types.d.ts +8 -0
- package/dist/charts/chart-types/column-types.d.ts.map +1 -0
- package/dist/charts/chart-types/column-types.js +2 -0
- package/dist/charts/chart-types/column-types.js.map +1 -0
- package/dist/charts/chart-types/count-plot/definition.d.ts.map +1 -1
- package/dist/charts/chart-types/count-plot/definition.js +1 -0
- package/dist/charts/chart-types/count-plot/definition.js.map +1 -1
- package/dist/charts/chart-types/count-plot/spec.d.ts.map +1 -1
- package/dist/charts/chart-types/count-plot/spec.js +1 -19
- package/dist/charts/chart-types/count-plot/spec.js.map +1 -1
- package/dist/charts/chart-types/count-plot/tool.d.ts +19 -24
- package/dist/charts/chart-types/count-plot/tool.d.ts.map +1 -1
- package/dist/charts/chart-types/count-plot/tool.js +25 -32
- package/dist/charts/chart-types/count-plot/tool.js.map +1 -1
- package/dist/charts/chart-types/count-plot/validation.d.ts +8 -0
- package/dist/charts/chart-types/count-plot/validation.d.ts.map +1 -0
- package/dist/charts/chart-types/count-plot/validation.js +20 -0
- package/dist/charts/chart-types/count-plot/validation.js.map +1 -0
- package/dist/charts/chart-types/createChartInstructions.d.ts +3 -0
- package/dist/charts/chart-types/createChartInstructions.d.ts.map +1 -0
- package/dist/charts/chart-types/createChartInstructions.js +12 -0
- package/dist/charts/chart-types/createChartInstructions.js.map +1 -0
- package/dist/charts/chart-types/createChartTools.d.ts +15 -9
- package/dist/charts/chart-types/createChartTools.d.ts.map +1 -1
- package/dist/charts/chart-types/createChartTools.js +16 -10
- package/dist/charts/chart-types/createChartTools.js.map +1 -1
- package/dist/charts/chart-types/custom-spec/definition.d.ts.map +1 -1
- package/dist/charts/chart-types/custom-spec/definition.js +1 -0
- package/dist/charts/chart-types/custom-spec/definition.js.map +1 -1
- package/dist/charts/chart-types/errors.d.ts +10 -0
- package/dist/charts/chart-types/errors.d.ts.map +1 -1
- package/dist/charts/chart-types/errors.js +18 -0
- package/dist/charts/chart-types/errors.js.map +1 -1
- package/dist/charts/chart-types/heatmap/definition.d.ts.map +1 -1
- package/dist/charts/chart-types/heatmap/definition.js +1 -0
- package/dist/charts/chart-types/heatmap/definition.js.map +1 -1
- package/dist/charts/chart-types/heatmap/spec.d.ts.map +1 -1
- package/dist/charts/chart-types/heatmap/spec.js +1 -33
- package/dist/charts/chart-types/heatmap/spec.js.map +1 -1
- package/dist/charts/chart-types/heatmap/tool.d.ts +20 -24
- package/dist/charts/chart-types/heatmap/tool.d.ts.map +1 -1
- package/dist/charts/chart-types/heatmap/tool.js +26 -36
- package/dist/charts/chart-types/heatmap/tool.js.map +1 -1
- package/dist/charts/chart-types/heatmap/validation.d.ts +9 -0
- package/dist/charts/chart-types/heatmap/validation.d.ts.map +1 -0
- package/dist/charts/chart-types/heatmap/validation.js +34 -0
- package/dist/charts/chart-types/heatmap/validation.js.map +1 -0
- package/dist/charts/chart-types/histogram/definition.d.ts.map +1 -1
- package/dist/charts/chart-types/histogram/definition.js +1 -0
- package/dist/charts/chart-types/histogram/definition.js.map +1 -1
- package/dist/charts/chart-types/histogram/spec.d.ts.map +1 -1
- package/dist/charts/chart-types/histogram/spec.js +1 -21
- package/dist/charts/chart-types/histogram/spec.js.map +1 -1
- package/dist/charts/chart-types/histogram/tool.d.ts +37 -24
- package/dist/charts/chart-types/histogram/tool.d.ts.map +1 -1
- package/dist/charts/chart-types/histogram/tool.js +38 -32
- package/dist/charts/chart-types/histogram/tool.js.map +1 -1
- package/dist/charts/chart-types/histogram/validation.d.ts +9 -0
- package/dist/charts/chart-types/histogram/validation.d.ts.map +1 -0
- package/dist/charts/chart-types/histogram/validation.js +22 -0
- package/dist/charts/chart-types/histogram/validation.js.map +1 -0
- package/dist/charts/chart-types/index.d.ts +1 -7
- package/dist/charts/chart-types/index.d.ts.map +1 -1
- package/dist/charts/chart-types/index.js +2 -8
- package/dist/charts/chart-types/index.js.map +1 -1
- package/dist/charts/chart-types/line-chart/definition.d.ts.map +1 -1
- package/dist/charts/chart-types/line-chart/definition.js +1 -0
- package/dist/charts/chart-types/line-chart/definition.js.map +1 -1
- package/dist/charts/chart-types/line-chart/spec.d.ts.map +1 -1
- package/dist/charts/chart-types/line-chart/spec.js +5 -46
- package/dist/charts/chart-types/line-chart/spec.js.map +1 -1
- package/dist/charts/chart-types/line-chart/tool.d.ts +26 -24
- package/dist/charts/chart-types/line-chart/tool.d.ts.map +1 -1
- package/dist/charts/chart-types/line-chart/tool.js +26 -38
- package/dist/charts/chart-types/line-chart/tool.js.map +1 -1
- package/dist/charts/chart-types/line-chart/validation.d.ts +16 -0
- package/dist/charts/chart-types/line-chart/validation.d.ts.map +1 -0
- package/dist/charts/chart-types/line-chart/validation.js +43 -0
- package/dist/charts/chart-types/line-chart/validation.js.map +1 -0
- package/dist/charts/chart-types/resolveChartTypes.d.ts +3 -0
- package/dist/charts/chart-types/resolveChartTypes.d.ts.map +1 -0
- package/dist/charts/chart-types/resolveChartTypes.js +8 -0
- package/dist/charts/chart-types/resolveChartTypes.js.map +1 -0
- package/dist/charts/chart-types/scatter-plot/definition.d.ts.map +1 -1
- package/dist/charts/chart-types/scatter-plot/definition.js +1 -0
- package/dist/charts/chart-types/scatter-plot/definition.js.map +1 -1
- package/dist/charts/chart-types/scatter-plot/spec.d.ts.map +1 -1
- package/dist/charts/chart-types/scatter-plot/spec.js +1 -45
- package/dist/charts/chart-types/scatter-plot/spec.js.map +1 -1
- package/dist/charts/chart-types/scatter-plot/tool.d.ts +21 -24
- package/dist/charts/chart-types/scatter-plot/tool.d.ts.map +1 -1
- package/dist/charts/chart-types/scatter-plot/tool.js +28 -41
- package/dist/charts/chart-types/scatter-plot/tool.js.map +1 -1
- package/dist/charts/chart-types/scatter-plot/validation.d.ts +13 -0
- package/dist/charts/chart-types/scatter-plot/validation.d.ts.map +1 -0
- package/dist/charts/chart-types/scatter-plot/validation.js +52 -0
- package/dist/charts/chart-types/scatter-plot/validation.js.map +1 -0
- package/dist/charts/chart-types/tool-types.d.ts +43 -0
- package/dist/charts/chart-types/tool-types.d.ts.map +1 -0
- package/dist/charts/chart-types/tool-types.js +2 -0
- package/dist/charts/chart-types/tool-types.js.map +1 -0
- package/dist/charts/chart-types/utils.d.ts +3 -0
- package/dist/charts/chart-types/utils.d.ts.map +1 -0
- package/dist/charts/chart-types/utils.js +4 -0
- package/dist/charts/chart-types/utils.js.map +1 -0
- package/dist/charts/dashboard/MosaicDashboardChartRenderer.d.ts.map +1 -1
- package/dist/charts/dashboard/MosaicDashboardChartRenderer.js +5 -3
- package/dist/charts/dashboard/MosaicDashboardChartRenderer.js.map +1 -1
- package/dist/charts/useChartDataPolicy.js +2 -2
- package/dist/charts/useChartDataPolicy.js.map +1 -1
- package/dist/components/AggregationSelector.d.ts.map +1 -1
- package/dist/components/AggregationSelector.js +1 -1
- package/dist/components/AggregationSelector.js.map +1 -1
- package/dist/components/ColorSelector.d.ts.map +1 -1
- package/dist/components/ColorSelector.js +1 -2
- package/dist/components/ColorSelector.js.map +1 -1
- package/dist/components/FieldSelectorInput.d.ts.map +1 -1
- package/dist/components/FieldSelectorInput.js +3 -3
- package/dist/components/FieldSelectorInput.js.map +1 -1
- package/dist/components/TemporalGranularitySelector.d.ts.map +1 -1
- package/dist/components/TemporalGranularitySelector.js +1 -1
- package/dist/components/TemporalGranularitySelector.js.map +1 -1
- package/dist/dashboard/MosaicDashboardCommands.d.ts +19 -0
- package/dist/dashboard/MosaicDashboardCommands.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardCommands.js +226 -0
- package/dist/dashboard/MosaicDashboardCommands.js.map +1 -0
- package/dist/dashboard/dashboard-types.d.ts.map +1 -1
- package/dist/dashboard/dashboard-types.js.map +1 -1
- package/dist/dashboard/panel/MosaicDashboardPanel.d.ts.map +1 -1
- package/dist/dashboard/panel/MosaicDashboardPanel.js +1 -1
- package/dist/dashboard/panel/MosaicDashboardPanel.js.map +1 -1
- package/dist/dashboard/panel/MosaicDashboardPanelLayout.d.ts.map +1 -1
- package/dist/dashboard/panel/MosaicDashboardPanelLayout.js +3 -3
- package/dist/dashboard/panel/MosaicDashboardPanelLayout.js.map +1 -1
- package/dist/dashboard/panel/MosaicDashboardPanels.d.ts.map +1 -1
- package/dist/dashboard/panel/MosaicDashboardPanels.js +4 -2
- package/dist/dashboard/panel/MosaicDashboardPanels.js.map +1 -1
- package/dist/dashboard/toolbar/MosaicDashboardDataTableSelector.d.ts.map +1 -1
- package/dist/dashboard/toolbar/MosaicDashboardDataTableSelector.js +4 -4
- package/dist/dashboard/toolbar/MosaicDashboardDataTableSelector.js.map +1 -1
- package/dist/dashboard/toolbar/MosaicDashboardToolbar.d.ts.map +1 -1
- package/dist/dashboard/toolbar/MosaicDashboardToolbar.js +5 -3
- package/dist/dashboard/toolbar/MosaicDashboardToolbar.js.map +1 -1
- package/dist/dashboard/useSelectedOrFirstTable.d.ts +1 -1
- package/dist/dashboard/useSelectedOrFirstTable.d.ts.map +1 -1
- package/dist/dashboard/useSelectedOrFirstTable.js +10 -8
- package/dist/dashboard/useSelectedOrFirstTable.js.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerCategoryClient.d.ts +3 -2
- package/dist/data-table-explorer/DataTableExplorerCategoryClient.d.ts.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerCategoryClient.js +3 -3
- package/dist/data-table-explorer/DataTableExplorerCategoryClient.js.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerCountClient.d.ts +3 -1
- package/dist/data-table-explorer/DataTableExplorerCountClient.d.ts.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerCountClient.js +3 -3
- package/dist/data-table-explorer/DataTableExplorerCountClient.js.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerHistogramClient.d.ts +3 -2
- package/dist/data-table-explorer/DataTableExplorerHistogramClient.d.ts.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerHistogramClient.js +4 -4
- package/dist/data-table-explorer/DataTableExplorerHistogramClient.js.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerPageClient.d.ts +3 -1
- package/dist/data-table-explorer/DataTableExplorerPageClient.d.ts.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerPageClient.js +3 -1
- package/dist/data-table-explorer/DataTableExplorerPageClient.js.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerUnsupportedSummaryClient.d.ts +3 -2
- package/dist/data-table-explorer/DataTableExplorerUnsupportedSummaryClient.d.ts.map +1 -1
- package/dist/data-table-explorer/DataTableExplorerUnsupportedSummaryClient.js +3 -3
- package/dist/data-table-explorer/DataTableExplorerUnsupportedSummaryClient.js.map +1 -1
- package/dist/data-table-explorer/dashboard/MosaicDashboardDataTableExplorerPanelRenderer.d.ts.map +1 -1
- package/dist/data-table-explorer/dashboard/MosaicDashboardDataTableExplorerPanelRenderer.js +7 -4
- package/dist/data-table-explorer/dashboard/MosaicDashboardDataTableExplorerPanelRenderer.js.map +1 -1
- package/dist/data-table-explorer/dataTableExplorerController.d.ts +58 -2
- package/dist/data-table-explorer/dataTableExplorerController.d.ts.map +1 -1
- package/dist/data-table-explorer/dataTableExplorerController.js +68 -8
- package/dist/data-table-explorer/dataTableExplorerController.js.map +1 -1
- package/dist/data-table-explorer/hooks/useDataTableExplorerLifecycles.d.ts +23 -1
- package/dist/data-table-explorer/hooks/useDataTableExplorerLifecycles.d.ts.map +1 -1
- package/dist/data-table-explorer/hooks/useDataTableExplorerLifecycles.js +46 -13
- package/dist/data-table-explorer/hooks/useDataTableExplorerLifecycles.js.map +1 -1
- package/dist/data-table-explorer/hooks/useDataTableExplorerQueryState.d.ts +17 -3
- package/dist/data-table-explorer/hooks/useDataTableExplorerQueryState.d.ts.map +1 -1
- package/dist/data-table-explorer/hooks/useDataTableExplorerQueryState.js +9 -6
- package/dist/data-table-explorer/hooks/useDataTableExplorerQueryState.js.map +1 -1
- package/dist/data-table-explorer/types.d.ts +10 -0
- package/dist/data-table-explorer/types.d.ts.map +1 -1
- package/dist/data-table-explorer/types.js.map +1 -1
- package/dist/data-table-explorer/useDataTableExplorer.d.ts.map +1 -1
- package/dist/data-table-explorer/useDataTableExplorer.js +10 -6
- package/dist/data-table-explorer/useDataTableExplorer.js.map +1 -1
- package/dist/data-table-explorer/utils.d.ts +64 -6
- package/dist/data-table-explorer/utils.d.ts.map +1 -1
- package/dist/data-table-explorer/utils.js +58 -0
- package/dist/data-table-explorer/utils.js.map +1 -1
- package/dist/data-table-explorer/worksheet/DataTableBlockRenderer.d.ts.map +1 -1
- package/dist/data-table-explorer/worksheet/DataTableBlockRenderer.js +2 -2
- package/dist/data-table-explorer/worksheet/DataTableBlockRenderer.js.map +1 -1
- package/dist/index.d.ts +49 -29
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -25
- package/dist/index.js.map +1 -1
- package/dist/mosaicTableReference.d.ts +59 -0
- package/dist/mosaicTableReference.d.ts.map +1 -0
- package/dist/mosaicTableReference.js +68 -0
- package/dist/mosaicTableReference.js.map +1 -0
- package/dist/useVgPlotChartRender.d.ts.map +1 -1
- package/dist/useVgPlotChartRender.js +26 -1
- package/dist/useVgPlotChartRender.js.map +1 -1
- package/dist/utils/table-lookup.d.ts +7 -0
- package/dist/utils/table-lookup.d.ts.map +1 -0
- package/dist/utils/table-lookup.js +10 -0
- package/dist/utils/table-lookup.js.map +1 -0
- package/package.json +14 -14
- package/dist/ai/ai.d.ts +0 -108
- package/dist/ai/ai.d.ts.map +0 -1
- package/dist/ai/ai.js +0 -461
- package/dist/ai/ai.js.map +0 -1
- package/dist/ai/data-table-explorer-tool.d.ts +0 -40
- package/dist/ai/data-table-explorer-tool.d.ts.map +0 -1
- package/dist/ai/data-table-explorer-tool.js +0 -75
- package/dist/ai/data-table-explorer-tool.js.map +0 -1
- package/dist/ai/list-panels-tool.d.ts +0 -35
- package/dist/ai/list-panels-tool.d.ts.map +0 -1
- package/dist/ai/list-panels-tool.js +0 -66
- package/dist/ai/list-panels-tool.js.map +0 -1
- package/dist/ai/remove-panel-tool.d.ts +0 -31
- package/dist/ai/remove-panel-tool.d.ts.map +0 -1
- package/dist/ai/remove-panel-tool.js +0 -55
- package/dist/ai/remove-panel-tool.js.map +0 -1
- package/dist/ai/tool-validation.d.ts +0 -3
- package/dist/ai/tool-validation.d.ts.map +0 -1
- package/dist/ai/tool-validation.js +0 -11
- package/dist/ai/tool-validation.js.map +0 -1
- package/dist/components/Combobox.d.ts +0 -45
- package/dist/components/Combobox.d.ts.map +0 -1
- package/dist/components/Combobox.js +0 -58
- package/dist/components/Combobox.js.map +0 -1
- package/dist/components/useCombobox.d.ts +0 -23
- package/dist/components/useCombobox.d.ts.map +0 -1
- package/dist/components/useCombobox.js +0 -26
- package/dist/components/useCombobox.js.map +0 -1
|
@@ -13,15 +13,11 @@ import type { Selection } from '@uwdata/mosaic-core';
|
|
|
13
13
|
import type { DataTableExplorerPanelConfig } from '../../dashboard/core-types';
|
|
14
14
|
import type { MosaicDashboardEntry } from '../../dashboard/dashboard-types';
|
|
15
15
|
import type { ChartDataPolicy, ChartDataPolicyContext, ChartRuntimeIssue, ChartRuntimeIssueContext, ChartRuntimeIssueReporter } from '../../chart-runtime';
|
|
16
|
+
import { ChartToolParams } from './tool-types';
|
|
16
17
|
import { DataTable, type QualifiedTableName } from '@sqlrooms/duckdb';
|
|
18
|
+
import type { ChartBuilderColumn } from './column-types';
|
|
17
19
|
export type { ChartType };
|
|
18
|
-
|
|
19
|
-
* Column info passed to chart builder UI
|
|
20
|
-
*/
|
|
21
|
-
export interface ChartBuilderColumn {
|
|
22
|
-
name: string;
|
|
23
|
-
type: string;
|
|
24
|
-
}
|
|
20
|
+
export type { ChartBuilderColumn };
|
|
25
21
|
/**
|
|
26
22
|
* Describes a field selector in a chart builder UI
|
|
27
23
|
*/
|
|
@@ -41,7 +37,7 @@ export interface ChartBuilderField {
|
|
|
41
37
|
}
|
|
42
38
|
/**
|
|
43
39
|
* Result of table resolution.
|
|
44
|
-
* tableName is the
|
|
40
|
+
* tableName is the canonical quoted string boundary form
|
|
45
41
|
* (QualifiedTableName.toString()); qualifiedName is the canonical structured
|
|
46
42
|
* identity when available.
|
|
47
43
|
*/
|
|
@@ -63,24 +59,16 @@ export interface PanelPatch {
|
|
|
63
59
|
* Dependencies injected into dashboard tool creation functions.
|
|
64
60
|
* Provides the resources and operations needed to create dashboard panels.
|
|
65
61
|
*/
|
|
62
|
+
/**
|
|
63
|
+
* Dependencies for dashboard-specific tools that manage panels.
|
|
64
|
+
*/
|
|
66
65
|
export interface DashboardToolDeps {
|
|
67
|
-
/**
|
|
68
|
-
* Resolves the dashboard artifact ID.
|
|
69
|
-
* Use this when you only need the artifact and not table information.
|
|
70
|
-
*/
|
|
71
|
-
resolveArtifact: (artifactId?: string, createIfMissing?: boolean, context?: ChartToolExecutionContext) => string;
|
|
72
|
-
/**
|
|
73
|
-
* Resolves user/display table input to canonical table identity and columns.
|
|
74
|
-
* Bare names are accepted only when unambiguous.
|
|
75
|
-
*/
|
|
76
|
-
resolveTable: (artifactId: string, tableName?: string | QualifiedTableName) => ResolvedTable;
|
|
77
66
|
addPanel: (dashboardId: string, panel: any) => string;
|
|
78
67
|
updatePanel: (dashboardId: string, panelId: string, patch: Partial<PanelPatch>) => void;
|
|
79
68
|
getDashboard: (dashboardId: string) => MosaicDashboardEntry | undefined;
|
|
80
69
|
getPanelIssue?: (dashboardId: string, panelId: string) => ChartRuntimeIssue | undefined;
|
|
81
70
|
removePanel: (dashboardId: string, panelId: string) => void;
|
|
82
71
|
setCurrentArtifact: (artifactId: string) => void;
|
|
83
|
-
maxDataPoints: number;
|
|
84
72
|
}
|
|
85
73
|
export type ChartToolExecutionContext = object & {
|
|
86
74
|
sessionId?: string;
|
|
@@ -107,14 +95,26 @@ export type ChartRetainer = {
|
|
|
107
95
|
};
|
|
108
96
|
export type BrushSelectionParams = Map<string, Selection>;
|
|
109
97
|
/**
|
|
110
|
-
* Props passed to chart
|
|
98
|
+
* Props passed to component-based chart renderers.
|
|
99
|
+
*
|
|
100
|
+
* Renderers receive the resolved chart configuration, Mosaic coordinator, and
|
|
101
|
+
* optional runtime services needed to participate in dashboard filtering and
|
|
102
|
+
* error reporting. The `table` property is the canonical structured SQLRooms
|
|
103
|
+
* table identity; renderers must convert it through the appropriate SQL dialect
|
|
104
|
+
* helper instead of reconstructing table references from display names.
|
|
111
105
|
*/
|
|
112
106
|
export interface ChartRendererProps<TConfig extends ChartConfig = ChartConfig> {
|
|
113
|
-
|
|
107
|
+
/** Canonical qualified table identity for the chart's data source. */
|
|
108
|
+
table: QualifiedTableName;
|
|
109
|
+
/** Validated chart configuration for this renderer. */
|
|
114
110
|
config: TConfig;
|
|
111
|
+
/** Mosaic coordinator used to connect query clients and selections. */
|
|
115
112
|
coordinator: Coordinator;
|
|
113
|
+
/** Optional row-limit policy applied to renderer-managed queries. */
|
|
116
114
|
dataPolicy?: ChartDataPolicy | null;
|
|
115
|
+
/** Context attached to runtime issues reported by the renderer. */
|
|
117
116
|
runtimeIssueContext?: ChartRuntimeIssueContext;
|
|
117
|
+
/** Reporter used to surface renderer query or policy failures. */
|
|
118
118
|
runtimeIssueReporter?: ChartRuntimeIssueReporter;
|
|
119
119
|
/**
|
|
120
120
|
* Pre-defined params/selections to inject when rendering vgplot specs.
|
|
@@ -134,6 +134,8 @@ type BaseChartTypeDefinition<TConfig extends ChartConfig = ChartConfig> = {
|
|
|
134
134
|
label?: string;
|
|
135
135
|
/** Short description of what this builder creates */
|
|
136
136
|
description: string;
|
|
137
|
+
/** Concise description for AI agents explaining when and how to use this chart type */
|
|
138
|
+
aiDescription: string;
|
|
137
139
|
/** Zod schema for runtime validation of settings */
|
|
138
140
|
schema: z.ZodType<TConfig['settings']>;
|
|
139
141
|
/** Generate a chart title from selected field values */
|
|
@@ -146,8 +148,8 @@ type BaseChartTypeDefinition<TConfig extends ChartConfig = ChartConfig> = {
|
|
|
146
148
|
icon: ComponentType<{
|
|
147
149
|
className?: string;
|
|
148
150
|
}>;
|
|
149
|
-
/** Optional function to create
|
|
150
|
-
createTool?: (deps:
|
|
151
|
+
/** Optional function to create a chart configuration AI tool */
|
|
152
|
+
createTool?: (deps: ChartToolParams) => Tool;
|
|
151
153
|
/** Optional runtime data policy for renderer-specific query validation. */
|
|
152
154
|
getDataPolicy?: (context: ChartDataPolicyContext<TConfig>) => ChartDataPolicy | null | undefined;
|
|
153
155
|
};
|
|
@@ -156,7 +158,9 @@ export type CreateSpecOptions<TSettings = ChartSettings> = {
|
|
|
156
158
|
settings: TSettings;
|
|
157
159
|
selectionName?: string;
|
|
158
160
|
};
|
|
161
|
+
export type ValidateSpecOptions<TSettings = ChartSettings> = Pick<CreateSpecOptions<TSettings>, 'dataTable' | 'settings'>;
|
|
159
162
|
export declare function getChartTableReference(dataTable: DataTable): string;
|
|
163
|
+
export declare const getChartTableReferenceString: typeof getChartTableReference;
|
|
160
164
|
export type SpecChartTypeDefinition<TConfig extends ChartConfig = ChartConfig> = BaseChartTypeDefinition<TConfig> & {
|
|
161
165
|
createSpec: (options: CreateSpecOptions<TConfig['settings']>) => Spec;
|
|
162
166
|
canViewSpec?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-types.d.ts","sourceRoot":"","sources":["../../../src/charts/chart-types/base-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,IAAI,CAAC;AAC7B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,KAAK,CAAC,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAC,4BAA4B,EAAC,MAAM,4BAA4B,CAAC;AAC7E,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EACV,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,SAAS,EAAE,KAAK,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AAEpE,
|
|
1
|
+
{"version":3,"file":"base-types.d.ts","sourceRoot":"","sources":["../../../src/charts/chart-types/base-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
* Base types for chart configurations.
|
|
3
3
|
* Separated to avoid circular dependencies.
|
|
4
4
|
*/
|
|
5
|
+
import { getMosaicVgPlotTableReference } from '../../mosaicTableReference';
|
|
5
6
|
export function getChartTableReference(dataTable) {
|
|
6
|
-
return dataTable.table
|
|
7
|
+
return getMosaicVgPlotTableReference(dataTable.table);
|
|
7
8
|
}
|
|
9
|
+
export const getChartTableReferenceString = getChartTableReference;
|
|
8
10
|
export function isSpecChartType(chartType) {
|
|
9
11
|
return 'createSpec' in chartType;
|
|
10
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-types.js","sourceRoot":"","sources":["../../../src/charts/chart-types/base-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"base-types.js","sourceRoot":"","sources":["../../../src/charts/chart-types/base-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqBH,OAAO,EAAC,6BAA6B,EAAC,MAAM,4BAA4B,CAAC;AA8KzE,MAAM,UAAU,sBAAsB,CAAC,SAAoB;IACzD,OAAO,6BAA6B,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,MAAM,4BAA4B,GAAG,sBAAsB,CAAC;AAsBnE,MAAM,UAAU,eAAe,CAC7B,SAAuC;IAEvC,OAAO,YAAY,IAAI,SAAS,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,SAAuC;IAEvC,OAAO,UAAU,IAAI,SAAS,CAAC;AACjC,CAAC","sourcesContent":["/**\n * Base types for chart configurations.\n * Separated to avoid circular dependencies.\n */\n\nimport type {Spec} from '@uwdata/mosaic-spec';\nimport {type Tool} from 'ai';\nimport type {Coordinator} from '@uwdata/mosaic-core';\nimport type {ComponentType} from 'react';\nimport type * as z from 'zod';\nimport {ChartConfig, ChartSettings, ChartType} from './chart-config';\nimport {RetainedVgPlotChart} from '../../VgPlotChart';\nimport type {Selection} from '@uwdata/mosaic-core';\nimport type {DataTableExplorerPanelConfig} from '../../dashboard/core-types';\nimport type {MosaicDashboardEntry} from '../../dashboard/dashboard-types';\nimport type {\n ChartDataPolicy,\n ChartDataPolicyContext,\n ChartRuntimeIssue,\n ChartRuntimeIssueContext,\n ChartRuntimeIssueReporter,\n} from '../../chart-runtime';\nimport {ChartToolParams} from './tool-types';\nimport {DataTable, type QualifiedTableName} from '@sqlrooms/duckdb';\nimport {getMosaicVgPlotTableReference} from '../../mosaicTableReference';\nimport type {ChartBuilderColumn} from './column-types';\n\nexport type {ChartType};\nexport type {ChartBuilderColumn};\n\n/**\n * Describes a field selector in a chart builder UI\n */\nexport interface ChartBuilderField {\n /** Unique key for this field */\n key: string;\n /** Display label */\n label: string;\n /** Whether the field is required */\n required?: boolean;\n /** Filter columns by DuckDB type (e.g. 'INTEGER', 'VARCHAR', 'DOUBLE') */\n types?: string[];\n /** Optional helper text for AI or custom UIs */\n description?: string;\n /** Whether this field accepts multiple values (array) */\n multiple?: boolean;\n}\n\n/**\n * Result of table resolution.\n * tableName is the canonical quoted string boundary form\n * (QualifiedTableName.toString()); qualifiedName is the canonical structured\n * identity when available.\n */\nexport interface ResolvedTable {\n tableName: string;\n qualifiedName: QualifiedTableName;\n columns: ChartBuilderColumn[];\n}\n\n/**\n * Partial update to apply to a dashboard panel.\n * Config can be any of the panel config types (chart, dataTableExplorer).\n */\nexport interface PanelPatch {\n title?: string;\n source?: ChartBuilderPanelSource;\n config?: ChartConfig | DataTableExplorerPanelConfig;\n}\n\n/**\n * Dependencies injected into dashboard tool creation functions.\n * Provides the resources and operations needed to create dashboard panels.\n */\n/**\n * Dependencies for dashboard-specific tools that manage panels.\n */\nexport interface DashboardToolDeps {\n addPanel: (dashboardId: string, panel: any) => string;\n updatePanel: (\n dashboardId: string,\n panelId: string,\n patch: Partial<PanelPatch>,\n ) => void;\n getDashboard: (dashboardId: string) => MosaicDashboardEntry | undefined;\n getPanelIssue?: (\n dashboardId: string,\n panelId: string,\n ) => ChartRuntimeIssue | undefined;\n removePanel: (dashboardId: string, panelId: string) => void;\n setCurrentArtifact: (artifactId: string) => void;\n}\n\nexport type ChartToolExecutionContext = object & {\n sessionId?: string;\n aiRunContext?: unknown;\n};\n\nexport type ChartBuilderPanelSource = {\n tableName?: string;\n sqlQuery?: string;\n};\n\nexport type ChartBuilderVgPlotOutput = {\n kind: 'vgplot';\n spec: Spec;\n};\n\nexport type ChartBuilderDashboardPanelOutput = {\n kind: 'dashboard-panel';\n type: string;\n source?: ChartBuilderPanelSource;\n config?: Record<string, unknown>;\n};\n\nexport type ChartBuilderOutput =\n | ChartBuilderVgPlotOutput\n | ChartBuilderDashboardPanelOutput;\n\nexport type ChartRetainer = {\n chart: RetainedVgPlotChart | undefined;\n setChart: (chart: RetainedVgPlotChart) => void;\n};\n\nexport type BrushSelectionParams = Map<string, Selection>;\n\n/**\n * Props passed to component-based chart renderers.\n *\n * Renderers receive the resolved chart configuration, Mosaic coordinator, and\n * optional runtime services needed to participate in dashboard filtering and\n * error reporting. The `table` property is the canonical structured SQLRooms\n * table identity; renderers must convert it through the appropriate SQL dialect\n * helper instead of reconstructing table references from display names.\n */\nexport interface ChartRendererProps<TConfig extends ChartConfig = ChartConfig> {\n /** Canonical qualified table identity for the chart's data source. */\n table: QualifiedTableName;\n /** Validated chart configuration for this renderer. */\n config: TConfig;\n /** Mosaic coordinator used to connect query clients and selections. */\n coordinator: Coordinator;\n /** Optional row-limit policy applied to renderer-managed queries. */\n dataPolicy?: ChartDataPolicy | null;\n /** Context attached to runtime issues reported by the renderer. */\n runtimeIssueContext?: ChartRuntimeIssueContext;\n /** Reporter used to surface renderer query or policy failures. */\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n /**\n * Pre-defined params/selections to inject when rendering vgplot specs.\n * Keys are param names (without $), values are Param or Selection instances.\n */\n params?: BrushSelectionParams;\n /**\n * Optional retention adapter for preserving the underlying vgplot\n * instance across temporary unmount/remount cycles.\n */\n retention?: ChartRetainer;\n}\n\ntype BaseChartTypeDefinition<TConfig extends ChartConfig = ChartConfig> = {\n /** Unique identifier */\n id: ChartType;\n /** Short human-friendly name used in chart-type grids and prompts */\n label?: string;\n /** Short description of what this builder creates */\n description: string;\n /** Concise description for AI agents explaining when and how to use this chart type */\n aiDescription: string;\n /** Zod schema for runtime validation of settings */\n schema: z.ZodType<TConfig['settings']>;\n /** Generate a chart title from selected field values */\n buildTitle?: (fieldValues: Record<string, unknown>) => string;\n /** Optional availability override for a given table schema */\n isAvailable?: (columns: ChartBuilderColumn[]) => boolean;\n /** Explicit settings component for this chart type */\n settingsComponent: ComponentType;\n /** Optional icon component for chart-type grids */\n icon: ComponentType<{className?: string}>;\n /** Optional function to create a chart configuration AI tool */\n createTool?: (deps: ChartToolParams) => Tool;\n /** Optional runtime data policy for renderer-specific query validation. */\n getDataPolicy?: (\n context: ChartDataPolicyContext<TConfig>,\n ) => ChartDataPolicy | null | undefined;\n};\n\nexport type CreateSpecOptions<TSettings = ChartSettings> = {\n dataTable: DataTable;\n settings: TSettings;\n selectionName?: string;\n};\n\nexport type ValidateSpecOptions<TSettings = ChartSettings> = Pick<\n CreateSpecOptions<TSettings>,\n 'dataTable' | 'settings'\n>;\n\nexport function getChartTableReference(dataTable: DataTable): string {\n return getMosaicVgPlotTableReference(dataTable.table);\n}\n\nexport const getChartTableReferenceString = getChartTableReference;\n\nexport type SpecChartTypeDefinition<TConfig extends ChartConfig = ChartConfig> =\n BaseChartTypeDefinition<TConfig> & {\n createSpec: (options: CreateSpecOptions<TConfig['settings']>) => Spec;\n canViewSpec?: boolean;\n };\n\nexport type ComponentChartTypeDefinition<\n TConfig extends ChartConfig = ChartConfig,\n> = BaseChartTypeDefinition<TConfig> & {\n renderer: ComponentType<ChartRendererProps<TConfig>>;\n};\n\n/**\n * Shared chart-type definition used by both the chart-builder UI and\n * assistant-driven chart creation.\n */\nexport type ChartTypeDefinition<TConfig extends ChartConfig = ChartConfig> =\n | SpecChartTypeDefinition<TConfig>\n | ComponentChartTypeDefinition<TConfig>;\n\nexport function isSpecChartType<TConfig extends ChartConfig>(\n chartType: ChartTypeDefinition<TConfig>,\n): chartType is SpecChartTypeDefinition<TConfig> {\n return 'createSpec' in chartType;\n}\n\nexport function isComponentChartType<TConfig extends ChartConfig>(\n chartType: ChartTypeDefinition<TConfig>,\n): chartType is ComponentChartTypeDefinition<TConfig> {\n return 'renderer' in chartType;\n}\n\n/**\n * Backward-compatible alias for earlier chart-builder helper APIs.\n * @deprecated Use {@link ChartTypeDefinition} instead.\n */\nexport type ChartSpec = ChartTypeDefinition;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../../../src/charts/chart-types/box-plot/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,4BAA4B,EAAC,MAAM,eAAe,CAAC;AAChE,OAAO,EAAC,kBAAkB,EAAuB,MAAM,UAAU,CAAC;AAUlE,eAAO,MAAM,gBAAgB,EAAE,4BAA4B,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../../../src/charts/chart-types/box-plot/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,4BAA4B,EAAC,MAAM,eAAe,CAAC;AAChE,OAAO,EAAC,kBAAkB,EAAuB,MAAM,UAAU,CAAC;AAUlE,eAAO,MAAM,gBAAgB,EAAE,4BAA4B,CAAC,kBAAkB,CAiB3E,CAAC"}
|
|
@@ -10,6 +10,7 @@ export const boxPlotChartType = {
|
|
|
10
10
|
id: 'box-plot',
|
|
11
11
|
label: 'Box Plot',
|
|
12
12
|
description: DESCRIPTION,
|
|
13
|
+
aiDescription: `${DESCRIPTION} - compare distributions across categories`,
|
|
13
14
|
icon: AlignHorizontalDistributeCenter,
|
|
14
15
|
schema: BoxPlotChartSettings,
|
|
15
16
|
settingsComponent: BoxPlotSettingsComponent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../../src/charts/chart-types/box-plot/definition.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,oBAAoB,EAAC,MAAM,UAAU,CAAC;AAClE,OAAO,EAAC,oBAAoB,EAAC,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAC,wBAAwB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAC,mBAAmB,EAAC,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAC,+BAA+B,EAAC,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAC,6BAA6B,EAAC,MAAM,wBAAwB,CAAC;AAErE,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC,MAAM,CAAC,MAAM,gBAAgB,GAC3B;IACE,EAAE,EAAE,UAAU;IACd,KAAK,EAAE,UAAU;IACjB,WAAW,EAAE,WAAW;IACxB,IAAI,EAAE,+BAA+B;IACrC,MAAM,EAAE,oBAAoB;IAC5B,iBAAiB,EAAE,wBAAwB;IAC3C,UAAU,EAAE,oBAAoB,CAAC,WAAW,CAAC;IAC7C,QAAQ,EAAE,oBAAoB;IAC9B,UAAU,EAAE,mBAAmB;IAC/B,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;QACpB,OAAO,EAAE,6BAA6B;QACtC,MAAM,EACJ,+GAA+G;KAClH,CAAC;CACH,CAAC","sourcesContent":["import type {ComponentChartTypeDefinition} from '../base-types';\nimport {BoxPlotChartConfig, BoxPlotChartSettings} from './schema';\nimport {titleFromDescription} from '../../../chart-builders/chartTypeUtils';\nimport {BoxPlotPanelRenderer} from './renderer/BoxPlotPanelRenderer';\nimport {BoxPlotSettingsComponent} from './BoxPlotSettings';\nimport {createBoxPlotAiTool} from './tool';\nimport {AlignHorizontalDistributeCenter} from 'lucide-react';\nimport {DEFAULT_CHART_MAX_DATA_POINTS} from '../../../chart-runtime';\n\nconst DESCRIPTION = 'Create a box plot';\n\nexport const boxPlotChartType: ComponentChartTypeDefinition<BoxPlotChartConfig> =\n {\n id: 'box-plot',\n label: 'Box Plot',\n description: DESCRIPTION,\n icon: AlignHorizontalDistributeCenter,\n schema: BoxPlotChartSettings,\n settingsComponent: BoxPlotSettingsComponent,\n buildTitle: titleFromDescription(DESCRIPTION),\n renderer: BoxPlotPanelRenderer,\n createTool: createBoxPlotAiTool,\n getDataPolicy: () => ({\n maxRows: DEFAULT_CHART_MAX_DATA_POINTS,\n reason:\n 'Box plots render summaries plus outlier points. Too many outliers can make the chart too expensive to render.',\n }),\n };\n"]}
|
|
1
|
+
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../../../src/charts/chart-types/box-plot/definition.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,oBAAoB,EAAC,MAAM,UAAU,CAAC;AAClE,OAAO,EAAC,oBAAoB,EAAC,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAC,wBAAwB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAC,mBAAmB,EAAC,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAC,+BAA+B,EAAC,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAC,6BAA6B,EAAC,MAAM,wBAAwB,CAAC;AAErE,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC,MAAM,CAAC,MAAM,gBAAgB,GAC3B;IACE,EAAE,EAAE,UAAU;IACd,KAAK,EAAE,UAAU;IACjB,WAAW,EAAE,WAAW;IACxB,aAAa,EAAE,GAAG,WAAW,4CAA4C;IACzE,IAAI,EAAE,+BAA+B;IACrC,MAAM,EAAE,oBAAoB;IAC5B,iBAAiB,EAAE,wBAAwB;IAC3C,UAAU,EAAE,oBAAoB,CAAC,WAAW,CAAC;IAC7C,QAAQ,EAAE,oBAAoB;IAC9B,UAAU,EAAE,mBAAmB;IAC/B,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;QACpB,OAAO,EAAE,6BAA6B;QACtC,MAAM,EACJ,+GAA+G;KAClH,CAAC;CACH,CAAC","sourcesContent":["import type {ComponentChartTypeDefinition} from '../base-types';\nimport {BoxPlotChartConfig, BoxPlotChartSettings} from './schema';\nimport {titleFromDescription} from '../../../chart-builders/chartTypeUtils';\nimport {BoxPlotPanelRenderer} from './renderer/BoxPlotPanelRenderer';\nimport {BoxPlotSettingsComponent} from './BoxPlotSettings';\nimport {createBoxPlotAiTool} from './tool';\nimport {AlignHorizontalDistributeCenter} from 'lucide-react';\nimport {DEFAULT_CHART_MAX_DATA_POINTS} from '../../../chart-runtime';\n\nconst DESCRIPTION = 'Create a box plot';\n\nexport const boxPlotChartType: ComponentChartTypeDefinition<BoxPlotChartConfig> =\n {\n id: 'box-plot',\n label: 'Box Plot',\n description: DESCRIPTION,\n aiDescription: `${DESCRIPTION} - compare distributions across categories`,\n icon: AlignHorizontalDistributeCenter,\n schema: BoxPlotChartSettings,\n settingsComponent: BoxPlotSettingsComponent,\n buildTitle: titleFromDescription(DESCRIPTION),\n renderer: BoxPlotPanelRenderer,\n createTool: createBoxPlotAiTool,\n getDataPolicy: () => ({\n maxRows: DEFAULT_CHART_MAX_DATA_POINTS,\n reason:\n 'Box plots render summaries plus outlier points. Too many outliers can make the chart too expensive to render.',\n }),\n };\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MosaicClient, type Selection } from '@uwdata/mosaic-core';
|
|
2
|
+
import { type QualifiedTableName } from '@sqlrooms/duckdb';
|
|
2
3
|
import type { FilterExpr } from '@uwdata/mosaic-sql';
|
|
3
4
|
import { type ChartDataPolicy, type ChartRuntimeIssueContext, type ChartRuntimeIssueReporter } from '../../../../chart-runtime';
|
|
4
5
|
export type BoxPlotSummaryRow = {
|
|
@@ -23,26 +24,59 @@ export type BoxPlotState = {
|
|
|
23
24
|
summaries: BoxPlotSummaryRow[];
|
|
24
25
|
yBrush?: [number, number];
|
|
25
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Options used to construct a {@link BoxPlotClient}.
|
|
29
|
+
*
|
|
30
|
+
* @property dataPolicy - Optional row-limit policy to validate query results.
|
|
31
|
+
* @property onStateChange - Callback invoked whenever query or brush state changes.
|
|
32
|
+
* @property runtimeIssueContext - Optional context attached to reported runtime issues.
|
|
33
|
+
* @property runtimeIssueReporter - Optional reporter used for query and policy failures.
|
|
34
|
+
* @property selection - Mosaic selection used for external filters and y-axis brushing.
|
|
35
|
+
* @property table - Canonical SQLRooms table identity. The client converts it
|
|
36
|
+
* with `getMosaicRawSqlTableReference`, so callers should pass the structured
|
|
37
|
+
* `QualifiedTableName` instead of a pre-rendered SQL string.
|
|
38
|
+
* @property x - Category column name.
|
|
39
|
+
* @property y - Numeric value column name.
|
|
40
|
+
*/
|
|
26
41
|
export type BoxPlotClientOptions = {
|
|
27
42
|
dataPolicy?: ChartDataPolicy | null;
|
|
28
43
|
onStateChange: (state: BoxPlotState) => void;
|
|
29
44
|
runtimeIssueContext?: ChartRuntimeIssueContext;
|
|
30
45
|
runtimeIssueReporter?: ChartRuntimeIssueReporter;
|
|
31
46
|
selection: Selection;
|
|
32
|
-
|
|
47
|
+
table: QualifiedTableName;
|
|
33
48
|
x: string;
|
|
34
49
|
y: string;
|
|
35
50
|
};
|
|
36
51
|
type BuildBoxPlotQueryArgs = {
|
|
37
52
|
filter?: FilterExpr | null;
|
|
38
|
-
|
|
53
|
+
table: QualifiedTableName;
|
|
39
54
|
x: string;
|
|
40
55
|
y: string;
|
|
41
56
|
};
|
|
57
|
+
/**
|
|
58
|
+
* Builds the SQL used by {@link BoxPlotClient} to compute box plot summaries.
|
|
59
|
+
*
|
|
60
|
+
* @param args - Query inputs including the source table, selected columns, and
|
|
61
|
+
* optional Mosaic filter expression.
|
|
62
|
+
* @returns SQL that returns summary rows and outlier rows for the box plot.
|
|
63
|
+
*
|
|
64
|
+
* The structured `QualifiedTableName` is converted with
|
|
65
|
+
* `getMosaicRawSqlTableReference`, which intentionally produces the
|
|
66
|
+
* catalog-free SQL fragment expected by Mosaic's active connector.
|
|
67
|
+
*/
|
|
42
68
|
export declare function buildBoxPlotQuery(args: BuildBoxPlotQueryArgs): string;
|
|
69
|
+
/**
|
|
70
|
+
* Mosaic query client that powers the custom box plot renderer.
|
|
71
|
+
*
|
|
72
|
+
* The client owns SQL generation, query-result normalization, runtime issue
|
|
73
|
+
* reporting, and y-axis brush selection updates. It accepts a structured
|
|
74
|
+
* `QualifiedTableName` so table identity remains canonical until the query is
|
|
75
|
+
* rendered for Mosaic SQL.
|
|
76
|
+
*/
|
|
43
77
|
export declare class BoxPlotClient extends MosaicClient {
|
|
44
78
|
private readonly onStateChange;
|
|
45
|
-
private readonly
|
|
79
|
+
private readonly table;
|
|
46
80
|
private readonly x;
|
|
47
81
|
private readonly y;
|
|
48
82
|
private readonly selection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BoxPlotClient.d.ts","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/BoxPlotClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,KAAK,SAAS,EACf,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"BoxPlotClient.d.ts","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/BoxPlotClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MosaicClient, clauseInterval, } from '@uwdata/mosaic-core';
|
|
2
|
-
import { escapeId
|
|
2
|
+
import { escapeId } from '@sqlrooms/duckdb';
|
|
3
3
|
import { assertChartDataPolicy, createChartRuntimeIssueFromError, } from '../../../../chart-runtime';
|
|
4
|
+
import { getMosaicRawSqlTableReference } from '../../../../mosaicTableReference';
|
|
4
5
|
function normalizeFilter(filter) {
|
|
5
6
|
if (!filter) {
|
|
6
7
|
return [];
|
|
@@ -57,8 +58,19 @@ function numericValue(value) {
|
|
|
57
58
|
const numeric = Number(value);
|
|
58
59
|
return Number.isFinite(numeric) ? numeric : undefined;
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Builds the SQL used by {@link BoxPlotClient} to compute box plot summaries.
|
|
63
|
+
*
|
|
64
|
+
* @param args - Query inputs including the source table, selected columns, and
|
|
65
|
+
* optional Mosaic filter expression.
|
|
66
|
+
* @returns SQL that returns summary rows and outlier rows for the box plot.
|
|
67
|
+
*
|
|
68
|
+
* The structured `QualifiedTableName` is converted with
|
|
69
|
+
* `getMosaicRawSqlTableReference`, which intentionally produces the
|
|
70
|
+
* catalog-free SQL fragment expected by Mosaic's active connector.
|
|
71
|
+
*/
|
|
60
72
|
export function buildBoxPlotQuery(args) {
|
|
61
|
-
const
|
|
73
|
+
const tableReference = getMosaicRawSqlTableReference(args.table);
|
|
62
74
|
const x = escapeId(args.x);
|
|
63
75
|
const y = escapeId(args.y);
|
|
64
76
|
const filters = normalizeFilter(args.filter).join(' AND ');
|
|
@@ -68,7 +80,7 @@ WITH base AS (
|
|
|
68
80
|
SELECT
|
|
69
81
|
${x} AS "category",
|
|
70
82
|
TRY_CAST(${y} AS DOUBLE) AS "value"
|
|
71
|
-
FROM ${
|
|
83
|
+
FROM ${tableReference}
|
|
72
84
|
WHERE ${where}
|
|
73
85
|
),
|
|
74
86
|
stats AS (
|
|
@@ -138,9 +150,17 @@ SELECT * FROM outliers
|
|
|
138
150
|
ORDER BY "category", "rowKind", "value"
|
|
139
151
|
`.trim();
|
|
140
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Mosaic query client that powers the custom box plot renderer.
|
|
155
|
+
*
|
|
156
|
+
* The client owns SQL generation, query-result normalization, runtime issue
|
|
157
|
+
* reporting, and y-axis brush selection updates. It accepts a structured
|
|
158
|
+
* `QualifiedTableName` so table identity remains canonical until the query is
|
|
159
|
+
* rendered for Mosaic SQL.
|
|
160
|
+
*/
|
|
141
161
|
export class BoxPlotClient extends MosaicClient {
|
|
142
162
|
onStateChange;
|
|
143
|
-
|
|
163
|
+
table;
|
|
144
164
|
x;
|
|
145
165
|
y;
|
|
146
166
|
selection;
|
|
@@ -159,7 +179,7 @@ export class BoxPlotClient extends MosaicClient {
|
|
|
159
179
|
this.onStateChange = options.onStateChange;
|
|
160
180
|
this.runtimeIssueContext = options.runtimeIssueContext;
|
|
161
181
|
this.runtimeIssueReporter = options.runtimeIssueReporter;
|
|
162
|
-
this.
|
|
182
|
+
this.table = options.table;
|
|
163
183
|
this.x = options.x;
|
|
164
184
|
this.y = options.y;
|
|
165
185
|
this.selection = options.selection;
|
|
@@ -184,7 +204,7 @@ export class BoxPlotClient extends MosaicClient {
|
|
|
184
204
|
query(filter) {
|
|
185
205
|
return buildBoxPlotQuery({
|
|
186
206
|
filter,
|
|
187
|
-
|
|
207
|
+
table: this.table,
|
|
188
208
|
x: this.x,
|
|
189
209
|
y: this.y,
|
|
190
210
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BoxPlotClient.js","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/BoxPlotClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n MosaicClient,\n clauseInterval,\n type Selection,\n} from '@uwdata/mosaic-core';\nimport {escapeId, quoteTableReference} from '@sqlrooms/duckdb';\nimport type {ExprNode, FilterExpr} from '@uwdata/mosaic-sql';\nimport {\n assertChartDataPolicy,\n createChartRuntimeIssueFromError,\n type ChartDataPolicy,\n type ChartRuntimeIssueContext,\n type ChartRuntimeIssueReporter,\n} from '../../../../chart-runtime';\n\nexport type BoxPlotSummaryRow = {\n category: unknown;\n count: number;\n lowerFence: number;\n median: number;\n q1: number;\n q3: number;\n upperFence: number;\n whiskerHigh: number;\n whiskerLow: number;\n};\n\nexport type BoxPlotOutlierRow = {\n category: unknown;\n value: number;\n};\n\nexport type BoxPlotState = {\n error?: Error;\n isLoading: boolean;\n outliers: BoxPlotOutlierRow[];\n summaries: BoxPlotSummaryRow[];\n yBrush?: [number, number];\n};\n\nexport type BoxPlotClientOptions = {\n dataPolicy?: ChartDataPolicy | null;\n onStateChange: (state: BoxPlotState) => void;\n runtimeIssueContext?: ChartRuntimeIssueContext;\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n selection: Selection;\n tableName: string;\n x: string;\n y: string;\n};\n\ntype BoxPlotQueryRow = Partial<BoxPlotSummaryRow & BoxPlotOutlierRow> & {\n rowKind?: 'summary' | 'outlier';\n};\n\nfunction normalizeFilter(filter?: FilterExpr | null): string[] {\n if (!filter) {\n return [];\n }\n const filters = Array.isArray(filter) ? filter.flat(Infinity) : [filter];\n return filters\n .map((expr) => {\n if (typeof expr === 'boolean') {\n return expr ? null : 'FALSE';\n }\n return `(${(expr as string | ExprNode).toString()})`;\n })\n .filter((expr): expr is string => Boolean(expr));\n}\n\n/**\n * Type guard to check if data has a toArray method.\n */\nfunction hasToArrayMethod(data: unknown): data is {toArray: () => unknown} {\n return (\n data !== null &&\n data !== undefined &&\n typeof data === 'object' &&\n 'toArray' in data &&\n typeof (data as Record<string, unknown>).toArray === 'function'\n );\n}\n\n/**\n * Safely extract rows from query result data.\n * Handles both direct arrays and objects with toArray() method.\n * Returns empty array if data is invalid or doesn't have expected structure.\n */\nfunction rowsFromQueryResult<T>(data: unknown): T[] {\n // Handle direct arrays\n if (Array.isArray(data)) {\n return data as T[];\n }\n\n // Handle objects with toArray() method (Arrow Tables, Mosaic results, etc.)\n if (!hasToArrayMethod(data)) {\n return [];\n }\n\n try {\n const result = data.toArray();\n\n // Validate that toArray() returned an array\n if (!Array.isArray(result)) {\n console.warn(\n 'BoxPlotClient: toArray() did not return an array',\n typeof result,\n );\n return [];\n }\n\n return result as T[];\n } catch (error) {\n console.error('BoxPlotClient: Error calling toArray():', error);\n return [];\n }\n}\n\nfunction numericValue(value: unknown): number | undefined {\n const numeric = Number(value);\n return Number.isFinite(numeric) ? numeric : undefined;\n}\n\ntype BuildBoxPlotQueryArgs = {\n filter?: FilterExpr | null;\n tableName: string;\n x: string;\n y: string;\n};\n\nexport function buildBoxPlotQuery(args: BuildBoxPlotQueryArgs): string {\n const table = quoteTableReference(args.tableName);\n const x = escapeId(args.x);\n const y = escapeId(args.y);\n const filters = normalizeFilter(args.filter).join(' AND ');\n const where = [`${y} IS NOT NULL`, filters].filter(Boolean).join(' AND ');\n\n return `\nWITH base AS (\n SELECT\n ${x} AS \"category\",\n TRY_CAST(${y} AS DOUBLE) AS \"value\"\n FROM ${table}\n WHERE ${where}\n),\nstats AS (\n SELECT\n \"category\",\n COUNT(*)::DOUBLE AS \"count\",\n quantile_cont(\"value\", 0.25) AS \"q1\",\n quantile_cont(\"value\", 0.5) AS \"median\",\n quantile_cont(\"value\", 0.75) AS \"q3\"\n FROM base\n WHERE \"value\" IS NOT NULL\n GROUP BY \"category\"\n),\nfences AS (\n SELECT\n *,\n \"q1\" - 1.5 * (\"q3\" - \"q1\") AS \"lowerFence\",\n \"q3\" + 1.5 * (\"q3\" - \"q1\") AS \"upperFence\"\n FROM stats\n),\nwhiskers AS (\n SELECT\n b.\"category\",\n MIN(b.\"value\") AS \"whiskerLow\",\n MAX(b.\"value\") AS \"whiskerHigh\"\n FROM base b\n JOIN fences f ON b.\"category\" IS NOT DISTINCT FROM f.\"category\"\n WHERE b.\"value\" BETWEEN f.\"lowerFence\" AND f.\"upperFence\"\n GROUP BY b.\"category\"\n),\nsummary AS (\n SELECT\n 'summary' AS \"rowKind\",\n f.\"category\",\n f.\"count\",\n f.\"q1\",\n f.\"median\",\n f.\"q3\",\n f.\"lowerFence\",\n f.\"upperFence\",\n w.\"whiskerLow\",\n w.\"whiskerHigh\",\n NULL::DOUBLE AS \"value\"\n FROM fences f\n JOIN whiskers w ON w.\"category\" IS NOT DISTINCT FROM f.\"category\"\n),\noutliers AS (\n SELECT\n 'outlier' AS \"rowKind\",\n b.\"category\",\n NULL::DOUBLE AS \"count\",\n NULL::DOUBLE AS \"q1\",\n NULL::DOUBLE AS \"median\",\n NULL::DOUBLE AS \"q3\",\n NULL::DOUBLE AS \"lowerFence\",\n NULL::DOUBLE AS \"upperFence\",\n NULL::DOUBLE AS \"whiskerLow\",\n NULL::DOUBLE AS \"whiskerHigh\",\n b.\"value\"\n FROM base b\n JOIN fences f ON b.\"category\" IS NOT DISTINCT FROM f.\"category\"\n WHERE b.\"value\" < f.\"lowerFence\" OR b.\"value\" > f.\"upperFence\"\n)\nSELECT * FROM summary\nUNION ALL\nSELECT * FROM outliers\nORDER BY \"category\", \"rowKind\", \"value\"\n`.trim();\n}\n\nexport class BoxPlotClient extends MosaicClient {\n private readonly onStateChange: (state: BoxPlotState) => void;\n private readonly tableName: string;\n private readonly x: string;\n private readonly y: string;\n private readonly selection: Selection;\n private readonly dataPolicy?: ChartDataPolicy | null;\n private readonly runtimeIssueContext?: ChartRuntimeIssueContext;\n private readonly runtimeIssueReporter?: ChartRuntimeIssueReporter;\n private state: BoxPlotState = {\n isLoading: true,\n outliers: [],\n summaries: [],\n };\n private destroyed = false;\n\n constructor(options: BoxPlotClientOptions) {\n super(options.selection);\n this.dataPolicy = options.dataPolicy;\n this.onStateChange = options.onStateChange;\n this.runtimeIssueContext = options.runtimeIssueContext;\n this.runtimeIssueReporter = options.runtimeIssueReporter;\n this.tableName = options.tableName;\n this.x = options.x;\n this.y = options.y;\n this.selection = options.selection;\n }\n\n override get filterStable(): boolean {\n return false;\n }\n\n fields(): string[] {\n return [this.x, this.y];\n }\n\n private emitState(next: Partial<BoxPlotState>) {\n if (this.destroyed) {\n return;\n }\n this.state = {...this.state, ...next};\n this.onStateChange(this.state);\n }\n\n override queryPending(): this {\n this.emitState({error: undefined, isLoading: true});\n return this;\n }\n\n override query(filter?: FilterExpr | null): string {\n return buildBoxPlotQuery({\n filter,\n tableName: this.tableName,\n x: this.x,\n y: this.y,\n });\n }\n\n override queryResult(data: unknown): this {\n try {\n assertChartDataPolicy(this.dataPolicy, data);\n this.runtimeIssueReporter?.clearIssue();\n } catch (error) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n if (this.runtimeIssueContext) {\n this.runtimeIssueReporter?.reportIssue(\n createChartRuntimeIssueFromError(\n normalizedError,\n this.runtimeIssueContext,\n this.dataPolicy,\n ),\n );\n }\n this.emitState({error: normalizedError, isLoading: false});\n return this;\n }\n\n const rows = rowsFromQueryResult<BoxPlotQueryRow>(data);\n const summaries: BoxPlotSummaryRow[] = [];\n const outliers: BoxPlotOutlierRow[] = [];\n\n for (const row of rows) {\n if (row.rowKind === 'summary') {\n const count = numericValue(row.count);\n const q1 = numericValue(row.q1);\n const median = numericValue(row.median);\n const q3 = numericValue(row.q3);\n const lowerFence = numericValue(row.lowerFence);\n const upperFence = numericValue(row.upperFence);\n const whiskerLow = numericValue(row.whiskerLow);\n const whiskerHigh = numericValue(row.whiskerHigh);\n if (\n count === undefined ||\n q1 === undefined ||\n median === undefined ||\n q3 === undefined ||\n lowerFence === undefined ||\n upperFence === undefined ||\n whiskerLow === undefined ||\n whiskerHigh === undefined\n ) {\n continue;\n }\n summaries.push({\n category: row.category,\n count,\n lowerFence,\n median,\n q1,\n q3,\n upperFence,\n whiskerHigh,\n whiskerLow,\n });\n } else if (row.rowKind === 'outlier') {\n const value = numericValue(row.value);\n if (value !== undefined) {\n outliers.push({\n category: row.category,\n value,\n });\n }\n }\n }\n\n this.emitState({\n error: undefined,\n isLoading: false,\n outliers,\n summaries,\n });\n return this;\n }\n\n override queryError(error: Error): this {\n if (this.runtimeIssueContext) {\n this.runtimeIssueReporter?.reportIssue(\n createChartRuntimeIssueFromError(\n error,\n this.runtimeIssueContext,\n this.dataPolicy,\n ),\n );\n }\n this.emitState({error, isLoading: false});\n return this;\n }\n\n updateYBrush(extent?: [number, number]) {\n const normalized = extent\n ? ([Math.min(...extent), Math.max(...extent)] as [number, number])\n : undefined;\n this.emitState({yBrush: normalized});\n const clause = clauseInterval(this.y, normalized ?? null, {source: this});\n this.selection.update(clause);\n }\n\n reset() {\n this.updateYBrush();\n }\n\n override destroy() {\n this.destroyed = true;\n super.destroy();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BoxPlotClient.js","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/BoxPlotClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n MosaicClient,\n clauseInterval,\n type Selection,\n} from '@uwdata/mosaic-core';\nimport {escapeId, type QualifiedTableName} from '@sqlrooms/duckdb';\nimport type {ExprNode, FilterExpr} from '@uwdata/mosaic-sql';\nimport {\n assertChartDataPolicy,\n createChartRuntimeIssueFromError,\n type ChartDataPolicy,\n type ChartRuntimeIssueContext,\n type ChartRuntimeIssueReporter,\n} from '../../../../chart-runtime';\nimport {getMosaicRawSqlTableReference} from '../../../../mosaicTableReference';\n\nexport type BoxPlotSummaryRow = {\n category: unknown;\n count: number;\n lowerFence: number;\n median: number;\n q1: number;\n q3: number;\n upperFence: number;\n whiskerHigh: number;\n whiskerLow: number;\n};\n\nexport type BoxPlotOutlierRow = {\n category: unknown;\n value: number;\n};\n\nexport type BoxPlotState = {\n error?: Error;\n isLoading: boolean;\n outliers: BoxPlotOutlierRow[];\n summaries: BoxPlotSummaryRow[];\n yBrush?: [number, number];\n};\n\n/**\n * Options used to construct a {@link BoxPlotClient}.\n *\n * @property dataPolicy - Optional row-limit policy to validate query results.\n * @property onStateChange - Callback invoked whenever query or brush state changes.\n * @property runtimeIssueContext - Optional context attached to reported runtime issues.\n * @property runtimeIssueReporter - Optional reporter used for query and policy failures.\n * @property selection - Mosaic selection used for external filters and y-axis brushing.\n * @property table - Canonical SQLRooms table identity. The client converts it\n * with `getMosaicRawSqlTableReference`, so callers should pass the structured\n * `QualifiedTableName` instead of a pre-rendered SQL string.\n * @property x - Category column name.\n * @property y - Numeric value column name.\n */\nexport type BoxPlotClientOptions = {\n dataPolicy?: ChartDataPolicy | null;\n onStateChange: (state: BoxPlotState) => void;\n runtimeIssueContext?: ChartRuntimeIssueContext;\n runtimeIssueReporter?: ChartRuntimeIssueReporter;\n selection: Selection;\n table: QualifiedTableName;\n x: string;\n y: string;\n};\n\ntype BoxPlotQueryRow = Partial<BoxPlotSummaryRow & BoxPlotOutlierRow> & {\n rowKind?: 'summary' | 'outlier';\n};\n\nfunction normalizeFilter(filter?: FilterExpr | null): string[] {\n if (!filter) {\n return [];\n }\n const filters = Array.isArray(filter) ? filter.flat(Infinity) : [filter];\n return filters\n .map((expr) => {\n if (typeof expr === 'boolean') {\n return expr ? null : 'FALSE';\n }\n return `(${(expr as string | ExprNode).toString()})`;\n })\n .filter((expr): expr is string => Boolean(expr));\n}\n\n/**\n * Type guard to check if data has a toArray method.\n */\nfunction hasToArrayMethod(data: unknown): data is {toArray: () => unknown} {\n return (\n data !== null &&\n data !== undefined &&\n typeof data === 'object' &&\n 'toArray' in data &&\n typeof (data as Record<string, unknown>).toArray === 'function'\n );\n}\n\n/**\n * Safely extract rows from query result data.\n * Handles both direct arrays and objects with toArray() method.\n * Returns empty array if data is invalid or doesn't have expected structure.\n */\nfunction rowsFromQueryResult<T>(data: unknown): T[] {\n // Handle direct arrays\n if (Array.isArray(data)) {\n return data as T[];\n }\n\n // Handle objects with toArray() method (Arrow Tables, Mosaic results, etc.)\n if (!hasToArrayMethod(data)) {\n return [];\n }\n\n try {\n const result = data.toArray();\n\n // Validate that toArray() returned an array\n if (!Array.isArray(result)) {\n console.warn(\n 'BoxPlotClient: toArray() did not return an array',\n typeof result,\n );\n return [];\n }\n\n return result as T[];\n } catch (error) {\n console.error('BoxPlotClient: Error calling toArray():', error);\n return [];\n }\n}\n\nfunction numericValue(value: unknown): number | undefined {\n const numeric = Number(value);\n return Number.isFinite(numeric) ? numeric : undefined;\n}\n\ntype BuildBoxPlotQueryArgs = {\n filter?: FilterExpr | null;\n table: QualifiedTableName;\n x: string;\n y: string;\n};\n\n/**\n * Builds the SQL used by {@link BoxPlotClient} to compute box plot summaries.\n *\n * @param args - Query inputs including the source table, selected columns, and\n * optional Mosaic filter expression.\n * @returns SQL that returns summary rows and outlier rows for the box plot.\n *\n * The structured `QualifiedTableName` is converted with\n * `getMosaicRawSqlTableReference`, which intentionally produces the\n * catalog-free SQL fragment expected by Mosaic's active connector.\n */\nexport function buildBoxPlotQuery(args: BuildBoxPlotQueryArgs): string {\n const tableReference = getMosaicRawSqlTableReference(args.table);\n const x = escapeId(args.x);\n const y = escapeId(args.y);\n const filters = normalizeFilter(args.filter).join(' AND ');\n const where = [`${y} IS NOT NULL`, filters].filter(Boolean).join(' AND ');\n\n return `\nWITH base AS (\n SELECT\n ${x} AS \"category\",\n TRY_CAST(${y} AS DOUBLE) AS \"value\"\n FROM ${tableReference}\n WHERE ${where}\n),\nstats AS (\n SELECT\n \"category\",\n COUNT(*)::DOUBLE AS \"count\",\n quantile_cont(\"value\", 0.25) AS \"q1\",\n quantile_cont(\"value\", 0.5) AS \"median\",\n quantile_cont(\"value\", 0.75) AS \"q3\"\n FROM base\n WHERE \"value\" IS NOT NULL\n GROUP BY \"category\"\n),\nfences AS (\n SELECT\n *,\n \"q1\" - 1.5 * (\"q3\" - \"q1\") AS \"lowerFence\",\n \"q3\" + 1.5 * (\"q3\" - \"q1\") AS \"upperFence\"\n FROM stats\n),\nwhiskers AS (\n SELECT\n b.\"category\",\n MIN(b.\"value\") AS \"whiskerLow\",\n MAX(b.\"value\") AS \"whiskerHigh\"\n FROM base b\n JOIN fences f ON b.\"category\" IS NOT DISTINCT FROM f.\"category\"\n WHERE b.\"value\" BETWEEN f.\"lowerFence\" AND f.\"upperFence\"\n GROUP BY b.\"category\"\n),\nsummary AS (\n SELECT\n 'summary' AS \"rowKind\",\n f.\"category\",\n f.\"count\",\n f.\"q1\",\n f.\"median\",\n f.\"q3\",\n f.\"lowerFence\",\n f.\"upperFence\",\n w.\"whiskerLow\",\n w.\"whiskerHigh\",\n NULL::DOUBLE AS \"value\"\n FROM fences f\n JOIN whiskers w ON w.\"category\" IS NOT DISTINCT FROM f.\"category\"\n),\noutliers AS (\n SELECT\n 'outlier' AS \"rowKind\",\n b.\"category\",\n NULL::DOUBLE AS \"count\",\n NULL::DOUBLE AS \"q1\",\n NULL::DOUBLE AS \"median\",\n NULL::DOUBLE AS \"q3\",\n NULL::DOUBLE AS \"lowerFence\",\n NULL::DOUBLE AS \"upperFence\",\n NULL::DOUBLE AS \"whiskerLow\",\n NULL::DOUBLE AS \"whiskerHigh\",\n b.\"value\"\n FROM base b\n JOIN fences f ON b.\"category\" IS NOT DISTINCT FROM f.\"category\"\n WHERE b.\"value\" < f.\"lowerFence\" OR b.\"value\" > f.\"upperFence\"\n)\nSELECT * FROM summary\nUNION ALL\nSELECT * FROM outliers\nORDER BY \"category\", \"rowKind\", \"value\"\n`.trim();\n}\n\n/**\n * Mosaic query client that powers the custom box plot renderer.\n *\n * The client owns SQL generation, query-result normalization, runtime issue\n * reporting, and y-axis brush selection updates. It accepts a structured\n * `QualifiedTableName` so table identity remains canonical until the query is\n * rendered for Mosaic SQL.\n */\nexport class BoxPlotClient extends MosaicClient {\n private readonly onStateChange: (state: BoxPlotState) => void;\n private readonly table: QualifiedTableName;\n private readonly x: string;\n private readonly y: string;\n private readonly selection: Selection;\n private readonly dataPolicy?: ChartDataPolicy | null;\n private readonly runtimeIssueContext?: ChartRuntimeIssueContext;\n private readonly runtimeIssueReporter?: ChartRuntimeIssueReporter;\n private state: BoxPlotState = {\n isLoading: true,\n outliers: [],\n summaries: [],\n };\n private destroyed = false;\n\n constructor(options: BoxPlotClientOptions) {\n super(options.selection);\n this.dataPolicy = options.dataPolicy;\n this.onStateChange = options.onStateChange;\n this.runtimeIssueContext = options.runtimeIssueContext;\n this.runtimeIssueReporter = options.runtimeIssueReporter;\n this.table = options.table;\n this.x = options.x;\n this.y = options.y;\n this.selection = options.selection;\n }\n\n override get filterStable(): boolean {\n return false;\n }\n\n fields(): string[] {\n return [this.x, this.y];\n }\n\n private emitState(next: Partial<BoxPlotState>) {\n if (this.destroyed) {\n return;\n }\n this.state = {...this.state, ...next};\n this.onStateChange(this.state);\n }\n\n override queryPending(): this {\n this.emitState({error: undefined, isLoading: true});\n return this;\n }\n\n override query(filter?: FilterExpr | null): string {\n return buildBoxPlotQuery({\n filter,\n table: this.table,\n x: this.x,\n y: this.y,\n });\n }\n\n override queryResult(data: unknown): this {\n try {\n assertChartDataPolicy(this.dataPolicy, data);\n this.runtimeIssueReporter?.clearIssue();\n } catch (error) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n if (this.runtimeIssueContext) {\n this.runtimeIssueReporter?.reportIssue(\n createChartRuntimeIssueFromError(\n normalizedError,\n this.runtimeIssueContext,\n this.dataPolicy,\n ),\n );\n }\n this.emitState({error: normalizedError, isLoading: false});\n return this;\n }\n\n const rows = rowsFromQueryResult<BoxPlotQueryRow>(data);\n const summaries: BoxPlotSummaryRow[] = [];\n const outliers: BoxPlotOutlierRow[] = [];\n\n for (const row of rows) {\n if (row.rowKind === 'summary') {\n const count = numericValue(row.count);\n const q1 = numericValue(row.q1);\n const median = numericValue(row.median);\n const q3 = numericValue(row.q3);\n const lowerFence = numericValue(row.lowerFence);\n const upperFence = numericValue(row.upperFence);\n const whiskerLow = numericValue(row.whiskerLow);\n const whiskerHigh = numericValue(row.whiskerHigh);\n if (\n count === undefined ||\n q1 === undefined ||\n median === undefined ||\n q3 === undefined ||\n lowerFence === undefined ||\n upperFence === undefined ||\n whiskerLow === undefined ||\n whiskerHigh === undefined\n ) {\n continue;\n }\n summaries.push({\n category: row.category,\n count,\n lowerFence,\n median,\n q1,\n q3,\n upperFence,\n whiskerHigh,\n whiskerLow,\n });\n } else if (row.rowKind === 'outlier') {\n const value = numericValue(row.value);\n if (value !== undefined) {\n outliers.push({\n category: row.category,\n value,\n });\n }\n }\n }\n\n this.emitState({\n error: undefined,\n isLoading: false,\n outliers,\n summaries,\n });\n return this;\n }\n\n override queryError(error: Error): this {\n if (this.runtimeIssueContext) {\n this.runtimeIssueReporter?.reportIssue(\n createChartRuntimeIssueFromError(\n error,\n this.runtimeIssueContext,\n this.dataPolicy,\n ),\n );\n }\n this.emitState({error, isLoading: false});\n return this;\n }\n\n updateYBrush(extent?: [number, number]) {\n const normalized = extent\n ? ([Math.min(...extent), Math.max(...extent)] as [number, number])\n : undefined;\n this.emitState({yBrush: normalized});\n const clause = clauseInterval(this.y, normalized ?? null, {source: this});\n this.selection.update(clause);\n }\n\n reset() {\n this.updateYBrush();\n }\n\n override destroy() {\n this.destroyed = true;\n super.destroy();\n }\n}\n"]}
|
|
@@ -11,7 +11,7 @@ import { BoxPlotErrorBoundary } from './BoxPlotErrorBoundary';
|
|
|
11
11
|
* Custom renderer for box-plot chart type.
|
|
12
12
|
* Uses BoxPlotClient for SQL-based quartile calculations and custom Observable Plot rendering.
|
|
13
13
|
*/
|
|
14
|
-
export const BoxPlotPanelRenderer = ({
|
|
14
|
+
export const BoxPlotPanelRenderer = ({ table, config, coordinator, params, dataPolicy, runtimeIssueContext, runtimeIssueReporter, }) => {
|
|
15
15
|
const configX = config.settings.x;
|
|
16
16
|
const configY = config.settings.y;
|
|
17
17
|
const boxPlotConfig = useMemo(() => typeof configX === 'string' && typeof configY === 'string'
|
|
@@ -27,7 +27,7 @@ export const BoxPlotPanelRenderer = ({ tableName, config, coordinator, params, d
|
|
|
27
27
|
params,
|
|
28
28
|
runtimeIssueContext,
|
|
29
29
|
runtimeIssueReporter,
|
|
30
|
-
|
|
30
|
+
table,
|
|
31
31
|
});
|
|
32
32
|
const summaries = useMemo(() => state.summaries.map((row) => ({
|
|
33
33
|
...row,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BoxPlotPanelRenderer.js","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/BoxPlotPanelRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {FC, PointerEvent as ReactPointerEvent} from 'react';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {SpinnerPane} from '@sqlrooms/ui';\nimport {type PlotSize, ResponsivePlot} from '../../../../ResponsivePlot';\nimport type {ChartRendererProps} from '../../base-types';\nimport {\n DRAG_CLICK_THRESHOLD,\n MARGINS,\n type PlotOutlierDatum,\n type PlotSummaryDatum,\n} from './constants';\nimport {createBoxPlotElement} from './plot';\nimport type {BoxPlotChartConfig} from '../schema';\nimport {useBoxPlotClient} from './useBoxPlotClient';\nimport {formatCategory, getYDomain, yPixelToValue} from './utils';\nimport {BoxPlotErrorBoundary} from './BoxPlotErrorBoundary';\n\n/**\n * Custom renderer for box-plot chart type.\n * Uses BoxPlotClient for SQL-based quartile calculations and custom Observable Plot rendering.\n */\nexport const BoxPlotPanelRenderer: FC<\n ChartRendererProps<BoxPlotChartConfig>\n> = ({\n tableName,\n config,\n coordinator,\n params,\n dataPolicy,\n runtimeIssueContext,\n runtimeIssueReporter,\n}) => {\n const configX = config.settings.x;\n const configY = config.settings.y;\n const boxPlotConfig = useMemo(\n () =>\n typeof configX === 'string' && typeof configY === 'string'\n ? {x: configX, y: configY}\n : null,\n [configX, configY],\n );\n\n const [size, setSize] = useState<PlotSize | null>(null);\n const [drag, setDrag] = useState<{startY: number; currentY: number} | null>(\n null,\n );\n const plotRef = useRef<HTMLDivElement>(null);\n\n const {clientRef, state} = useBoxPlotClient({\n config: boxPlotConfig,\n coordinator,\n dataPolicy,\n params,\n runtimeIssueContext,\n runtimeIssueReporter,\n tableName,\n });\n\n const summaries = useMemo<PlotSummaryDatum[]>(\n () =>\n state.summaries.map((row) => ({\n ...row,\n categoryLabel: formatCategory(row.category),\n })),\n [state.summaries],\n );\n const outliers = useMemo<PlotOutlierDatum[]>(\n () =>\n state.outliers.map((row) => ({\n ...row,\n categoryLabel: formatCategory(row.category),\n })),\n [state.outliers],\n );\n const yDomain = useMemo(\n () => getYDomain(state.summaries, state.outliers),\n [state.outliers, state.summaries],\n );\n\n useEffect(() => {\n const container = plotRef.current;\n if (!container || !size || !boxPlotConfig) {\n return;\n }\n if (!summaries.length) {\n container.replaceChildren();\n return;\n }\n\n const plot = createBoxPlotElement({\n config: boxPlotConfig,\n domain: yDomain,\n outliers,\n size,\n summaries,\n });\n container.replaceChildren(plot);\n }, [boxPlotConfig, outliers, size, summaries, yDomain]);\n\n const getLocalY = useCallback((event: ReactPointerEvent<HTMLDivElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n return event.clientY - rect.top;\n }, []);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!size || !summaries.length) return;\n event.currentTarget.setPointerCapture(event.pointerId);\n const y = getLocalY(event);\n setDrag({currentY: y, startY: y});\n },\n [getLocalY, size, summaries.length],\n );\n\n const handlePointerMove = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!drag) return;\n setDrag({...drag, currentY: getLocalY(event)});\n },\n [drag, getLocalY],\n );\n\n const finishDrag = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!drag || !size) return;\n event.currentTarget.releasePointerCapture(event.pointerId);\n const currentY = getLocalY(event);\n const pixelDistance = Math.abs(currentY - drag.startY);\n setDrag(null);\n if (pixelDistance < DRAG_CLICK_THRESHOLD) {\n clientRef.current?.updateYBrush();\n return;\n }\n clientRef.current?.updateYBrush([\n yPixelToValue(drag.startY, size, yDomain),\n yPixelToValue(currentY, size, yDomain),\n ]);\n },\n [clientRef, drag, getLocalY, size, yDomain],\n );\n\n const brushStyle = useMemo(() => {\n const extent = drag\n ? [drag.startY, drag.currentY]\n : state.yBrush && size\n ? state.yBrush.map((value) => {\n const plotHeight = Math.max(\n 1,\n size.height - MARGINS.top - MARGINS.bottom,\n );\n const span = yDomain[1] - yDomain[0] || 1;\n const pixelPos =\n MARGINS.top + ((yDomain[1] - value) / span) * plotHeight;\n return Math.max(\n MARGINS.top,\n Math.min(MARGINS.top + plotHeight, pixelPos),\n );\n })\n : null;\n if (!extent) return undefined;\n const top = Math.max(MARGINS.top, Math.min(...extent));\n const bottom = Math.min(\n size?.height ? size.height - MARGINS.bottom : Number.POSITIVE_INFINITY,\n Math.max(...extent),\n );\n return {\n height: `${Math.max(0, bottom - top)}px`,\n left: `${MARGINS.left}px`,\n right: `${MARGINS.right}px`,\n top: `${top}px`,\n };\n }, [drag, size, state.yBrush, yDomain]);\n\n if (!config.settings.x || !config.settings.y) {\n return (\n <div className=\"flex h-full flex-col items-center justify-center\">\n <div className=\"text-center font-medium\">\n Configure chart to display visualization\n </div>\n <div className=\"text-center text-xs\">\n X and Y fields are required for box plot\n </div>\n </div>\n );\n }\n\n return (\n <BoxPlotErrorBoundary>\n <div className=\"h-full min-h-0 overflow-auto p-2\">\n <div className=\"bg-background text-foreground relative flex h-full min-h-[220px] w-full items-center justify-center rounded-md p-2\">\n {state.error ? (\n <div className=\"text-destructive flex h-full items-center justify-center p-4 text-sm\">\n {state.error.message}\n </div>\n ) : state.isLoading && !state.summaries.length ? (\n <SpinnerPane className=\"h-full w-full\" />\n ) : !state.summaries.length ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center text-sm\">\n No numeric values for this box plot\n </div>\n ) : (\n <ResponsivePlot\n onResize={setSize}\n className=\"relative h-full min-h-[220px] w-full\"\n >\n <div ref={plotRef} className=\"absolute inset-0\" />\n {brushStyle ? (\n <div\n className=\"bg-primary/15 border-primary/60 pointer-events-none absolute border\"\n style={brushStyle}\n />\n ) : null}\n <div\n className=\"absolute inset-0 cursor-crosshair touch-none\"\n onPointerCancel={finishDrag}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={finishDrag}\n />\n </ResponsivePlot>\n )}\n </div>\n </div>\n </BoxPlotErrorBoundary>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"BoxPlotPanelRenderer.js","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/BoxPlotPanelRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {FC, PointerEvent as ReactPointerEvent} from 'react';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {SpinnerPane} from '@sqlrooms/ui';\nimport {type PlotSize, ResponsivePlot} from '../../../../ResponsivePlot';\nimport type {ChartRendererProps} from '../../base-types';\nimport {\n DRAG_CLICK_THRESHOLD,\n MARGINS,\n type PlotOutlierDatum,\n type PlotSummaryDatum,\n} from './constants';\nimport {createBoxPlotElement} from './plot';\nimport type {BoxPlotChartConfig} from '../schema';\nimport {useBoxPlotClient} from './useBoxPlotClient';\nimport {formatCategory, getYDomain, yPixelToValue} from './utils';\nimport {BoxPlotErrorBoundary} from './BoxPlotErrorBoundary';\n\n/**\n * Custom renderer for box-plot chart type.\n * Uses BoxPlotClient for SQL-based quartile calculations and custom Observable Plot rendering.\n */\nexport const BoxPlotPanelRenderer: FC<\n ChartRendererProps<BoxPlotChartConfig>\n> = ({\n table,\n config,\n coordinator,\n params,\n dataPolicy,\n runtimeIssueContext,\n runtimeIssueReporter,\n}) => {\n const configX = config.settings.x;\n const configY = config.settings.y;\n const boxPlotConfig = useMemo(\n () =>\n typeof configX === 'string' && typeof configY === 'string'\n ? {x: configX, y: configY}\n : null,\n [configX, configY],\n );\n\n const [size, setSize] = useState<PlotSize | null>(null);\n const [drag, setDrag] = useState<{startY: number; currentY: number} | null>(\n null,\n );\n const plotRef = useRef<HTMLDivElement>(null);\n\n const {clientRef, state} = useBoxPlotClient({\n config: boxPlotConfig,\n coordinator,\n dataPolicy,\n params,\n runtimeIssueContext,\n runtimeIssueReporter,\n table,\n });\n\n const summaries = useMemo<PlotSummaryDatum[]>(\n () =>\n state.summaries.map((row) => ({\n ...row,\n categoryLabel: formatCategory(row.category),\n })),\n [state.summaries],\n );\n const outliers = useMemo<PlotOutlierDatum[]>(\n () =>\n state.outliers.map((row) => ({\n ...row,\n categoryLabel: formatCategory(row.category),\n })),\n [state.outliers],\n );\n const yDomain = useMemo(\n () => getYDomain(state.summaries, state.outliers),\n [state.outliers, state.summaries],\n );\n\n useEffect(() => {\n const container = plotRef.current;\n if (!container || !size || !boxPlotConfig) {\n return;\n }\n if (!summaries.length) {\n container.replaceChildren();\n return;\n }\n\n const plot = createBoxPlotElement({\n config: boxPlotConfig,\n domain: yDomain,\n outliers,\n size,\n summaries,\n });\n container.replaceChildren(plot);\n }, [boxPlotConfig, outliers, size, summaries, yDomain]);\n\n const getLocalY = useCallback((event: ReactPointerEvent<HTMLDivElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n return event.clientY - rect.top;\n }, []);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!size || !summaries.length) return;\n event.currentTarget.setPointerCapture(event.pointerId);\n const y = getLocalY(event);\n setDrag({currentY: y, startY: y});\n },\n [getLocalY, size, summaries.length],\n );\n\n const handlePointerMove = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!drag) return;\n setDrag({...drag, currentY: getLocalY(event)});\n },\n [drag, getLocalY],\n );\n\n const finishDrag = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!drag || !size) return;\n event.currentTarget.releasePointerCapture(event.pointerId);\n const currentY = getLocalY(event);\n const pixelDistance = Math.abs(currentY - drag.startY);\n setDrag(null);\n if (pixelDistance < DRAG_CLICK_THRESHOLD) {\n clientRef.current?.updateYBrush();\n return;\n }\n clientRef.current?.updateYBrush([\n yPixelToValue(drag.startY, size, yDomain),\n yPixelToValue(currentY, size, yDomain),\n ]);\n },\n [clientRef, drag, getLocalY, size, yDomain],\n );\n\n const brushStyle = useMemo(() => {\n const extent = drag\n ? [drag.startY, drag.currentY]\n : state.yBrush && size\n ? state.yBrush.map((value) => {\n const plotHeight = Math.max(\n 1,\n size.height - MARGINS.top - MARGINS.bottom,\n );\n const span = yDomain[1] - yDomain[0] || 1;\n const pixelPos =\n MARGINS.top + ((yDomain[1] - value) / span) * plotHeight;\n return Math.max(\n MARGINS.top,\n Math.min(MARGINS.top + plotHeight, pixelPos),\n );\n })\n : null;\n if (!extent) return undefined;\n const top = Math.max(MARGINS.top, Math.min(...extent));\n const bottom = Math.min(\n size?.height ? size.height - MARGINS.bottom : Number.POSITIVE_INFINITY,\n Math.max(...extent),\n );\n return {\n height: `${Math.max(0, bottom - top)}px`,\n left: `${MARGINS.left}px`,\n right: `${MARGINS.right}px`,\n top: `${top}px`,\n };\n }, [drag, size, state.yBrush, yDomain]);\n\n if (!config.settings.x || !config.settings.y) {\n return (\n <div className=\"flex h-full flex-col items-center justify-center\">\n <div className=\"text-center font-medium\">\n Configure chart to display visualization\n </div>\n <div className=\"text-center text-xs\">\n X and Y fields are required for box plot\n </div>\n </div>\n );\n }\n\n return (\n <BoxPlotErrorBoundary>\n <div className=\"h-full min-h-0 overflow-auto p-2\">\n <div className=\"bg-background text-foreground relative flex h-full min-h-[220px] w-full items-center justify-center rounded-md p-2\">\n {state.error ? (\n <div className=\"text-destructive flex h-full items-center justify-center p-4 text-sm\">\n {state.error.message}\n </div>\n ) : state.isLoading && !state.summaries.length ? (\n <SpinnerPane className=\"h-full w-full\" />\n ) : !state.summaries.length ? (\n <div className=\"text-muted-foreground flex h-full items-center justify-center text-sm\">\n No numeric values for this box plot\n </div>\n ) : (\n <ResponsivePlot\n onResize={setSize}\n className=\"relative h-full min-h-[220px] w-full\"\n >\n <div ref={plotRef} className=\"absolute inset-0\" />\n {brushStyle ? (\n <div\n className=\"bg-primary/15 border-primary/60 pointer-events-none absolute border\"\n style={brushStyle}\n />\n ) : null}\n <div\n className=\"absolute inset-0 cursor-crosshair touch-none\"\n onPointerCancel={finishDrag}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={finishDrag}\n />\n </ResponsivePlot>\n )}\n </div>\n </div>\n </BoxPlotErrorBoundary>\n );\n};\n"]}
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { Coordinator } from '@uwdata/mosaic-core';
|
|
2
2
|
import { BoxPlotClient, type BoxPlotState } from './BoxPlotClient';
|
|
3
3
|
import type { BrushSelectionParams } from '../../base-types';
|
|
4
|
+
import type { QualifiedTableName } from '@sqlrooms/duckdb';
|
|
4
5
|
import type { ChartDataPolicy, ChartRuntimeIssueContext, ChartRuntimeIssueReporter } from '../../../../chart-runtime';
|
|
5
6
|
import { BoxPlotChartSettings } from '../schema';
|
|
7
|
+
/**
|
|
8
|
+
* Creates and connects the Mosaic client used by the box plot renderer.
|
|
9
|
+
*
|
|
10
|
+
* @param args - Hook inputs including chart settings, Mosaic coordinator,
|
|
11
|
+
* optional dashboard services, and the resolved source table.
|
|
12
|
+
* @param args.table - Canonical `QualifiedTableName` for the source table. The
|
|
13
|
+
* hook passes this structured identity through to {@link BoxPlotClient}, where
|
|
14
|
+
* it is converted to a Mosaic SQL table reference at query-build time.
|
|
15
|
+
* @returns The active client ref and normalized renderer state.
|
|
16
|
+
*/
|
|
6
17
|
export declare function useBoxPlotClient(args: {
|
|
7
18
|
config: BoxPlotChartSettings | null;
|
|
8
19
|
coordinator: Coordinator;
|
|
@@ -10,7 +21,7 @@ export declare function useBoxPlotClient(args: {
|
|
|
10
21
|
params?: BrushSelectionParams;
|
|
11
22
|
runtimeIssueContext?: ChartRuntimeIssueContext;
|
|
12
23
|
runtimeIssueReporter?: ChartRuntimeIssueReporter;
|
|
13
|
-
|
|
24
|
+
table: QualifiedTableName;
|
|
14
25
|
}): {
|
|
15
26
|
clientRef: import("react").RefObject<BoxPlotClient | null>;
|
|
16
27
|
state: BoxPlotState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBoxPlotClient.d.ts","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/useBoxPlotClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAY,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAC,aAAa,EAAE,KAAK,YAAY,EAAC,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,oBAAoB,EAAC,MAAM,WAAW,CAAC;AAE/C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,mBAAmB,CAAC,EAAE,wBAAwB,CAAC;IAC/C,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;IACjD,
|
|
1
|
+
{"version":3,"file":"useBoxPlotClient.d.ts","sourceRoot":"","sources":["../../../../../src/charts/chart-types/box-plot/renderer/useBoxPlotClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAY,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAC,aAAa,EAAE,KAAK,YAAY,EAAC,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAC,oBAAoB,EAAC,MAAM,WAAW,CAAC;AAE/C;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,mBAAmB,CAAC,EAAE,wBAAwB,CAAC;IAC/C,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;IACjD,KAAK,EAAE,kBAAkB,CAAC;CAC3B;;;EAyEA"}
|