@sqlrooms/vega 0.29.0-rc.1 → 0.29.0-rc.11
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/LICENSE.md +2 -1
- package/README.md +63 -1
- package/dist/ChartImageForMarkdownTool.d.ts +84 -0
- package/dist/ChartImageForMarkdownTool.d.ts.map +1 -0
- package/dist/ChartImageForMarkdownTool.js +287 -0
- package/dist/ChartImageForMarkdownTool.js.map +1 -0
- package/dist/VegaChartActions.js +1 -1
- package/dist/VegaChartActions.js.map +1 -1
- package/dist/VegaChartTool.d.ts +47 -26
- package/dist/VegaChartTool.d.ts.map +1 -1
- package/dist/VegaChartTool.js +61 -35
- package/dist/VegaChartTool.js.map +1 -1
- package/dist/VegaChartToolResult.d.ts +22 -18
- package/dist/VegaChartToolResult.d.ts.map +1 -1
- package/dist/VegaChartToolResult.js +8 -34
- package/dist/VegaChartToolResult.js.map +1 -1
- package/dist/VegaEditAction.d.ts +4 -9
- package/dist/VegaEditAction.d.ts.map +1 -1
- package/dist/VegaEditAction.js +9 -12
- package/dist/VegaEditAction.js.map +1 -1
- package/dist/VegaLiteArrowChart.d.ts.map +1 -1
- package/dist/VegaLiteArrowChart.js +23 -7
- package/dist/VegaLiteArrowChart.js.map +1 -1
- package/dist/VegaLiteSqlChart.js +1 -1
- package/dist/VegaLiteSqlChart.js.map +1 -1
- package/dist/chartSizing.d.ts +20 -0
- package/dist/chartSizing.d.ts.map +1 -0
- package/dist/chartSizing.js +103 -0
- package/dist/chartSizing.js.map +1 -0
- package/dist/editor/VegaChartDisplay.d.ts +9 -0
- package/dist/editor/VegaChartDisplay.d.ts.map +1 -1
- package/dist/editor/VegaChartDisplay.js +12 -3
- package/dist/editor/VegaChartDisplay.js.map +1 -1
- package/dist/editor/VegaCodeMirrorEditor.d.ts +15 -0
- package/dist/editor/VegaCodeMirrorEditor.d.ts.map +1 -0
- package/dist/editor/VegaCodeMirrorEditor.js +23 -0
- package/dist/editor/VegaCodeMirrorEditor.js.map +1 -0
- package/dist/editor/VegaMonacoEditor.d.ts +5 -0
- package/dist/editor/VegaMonacoEditor.d.ts.map +1 -1
- package/dist/editor/VegaMonacoEditor.js +2 -0
- package/dist/editor/VegaMonacoEditor.js.map +1 -1
- package/dist/editor/VegaSpecEditorPanel.d.ts.map +1 -1
- package/dist/editor/VegaSpecEditorPanel.js +11 -7
- package/dist/editor/VegaSpecEditorPanel.js.map +1 -1
- package/dist/editor/VegaSqlEditorPanel.d.ts +1 -1
- package/dist/editor/VegaSqlEditorPanel.d.ts.map +1 -1
- package/dist/editor/VegaSqlEditorPanel.js +9 -10
- package/dist/editor/VegaSqlEditorPanel.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/package.json +33 -26
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaLiteArrowChart.js","sourceRoot":"","sources":["../src/VegaLiteArrowChart.tsx"],"names":[],"mappings":"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","sourcesContent":["import {ToolErrorMessage} from '@sqlrooms/ai';\nimport {arrowTableToJson} from '@sqlrooms/duckdb';\nimport {\n AspectRatio,\n cn,\n useAspectRatioDimensions,\n useTheme,\n} from '@sqlrooms/ui';\nimport {safeJsonParse} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useVegaEmbed} from 'react-vega';\nimport {EmbedOptions, VisualizationSpec} from 'vega-embed';\nimport {Config} from 'vega-lite';\nimport {darkTheme} from './themes/darkTheme';\nimport {lightTheme} from './themes/lightTheme';\nimport {VegaChartActions} from './VegaChartActions';\nimport {VegaChartContextProvider} from './VegaChartContext';\nimport {VegaEditAction} from './VegaEditAction';\nimport {VegaExportAction} from './VegaExportAction';\n\nexport type VegaLiteArrowChartProps = {\n className?: string;\n width?: number | 'auto';\n height?: number | 'auto';\n aspectRatio?: number;\n spec: string | VisualizationSpec;\n options?: EmbedOptions;\n arrowTable: arrow.Table | undefined;\n /**\n * Children for composing actions and other elements.\n * Use VegaLiteArrowChart.Actions to add action buttons.\n *\n * @example\n * ```tsx\n * <VegaLiteArrowChart spec={spec} arrowTable={data}>\n * <VegaLiteArrowChart.Actions>\n * <VegaExportAction />\n * </VegaLiteArrowChart.Actions>\n * </VegaLiteArrowChart>\n * ```\n */\n children?: React.ReactNode;\n};\n\nexport function makeDefaultVegaLiteOptions(\n options?: EmbedOptions,\n): EmbedOptions {\n return {\n mode: 'vega-lite',\n theme: undefined,\n tooltip: true,\n actions: false,\n padding: {\n top: 20,\n right: 10,\n bottom: 10,\n left: 10,\n },\n ...options,\n };\n}\n\nconst VegaLiteArrowChartBase: React.FC<VegaLiteArrowChartProps> = ({\n className,\n aspectRatio = 16 / 9,\n spec,\n arrowTable,\n options: propsOptions,\n width = 'auto',\n height = 'auto',\n children,\n}) => {\n const {theme} = useTheme();\n\n const options = useMemo(\n () =>\n makeDefaultVegaLiteOptions({\n config: {\n ...(theme === 'dark' ? darkTheme : lightTheme),\n ...(typeof propsOptions?.config === 'object'\n ? (propsOptions.config as Config)\n : {}),\n },\n\n ...propsOptions,\n }),\n [theme, propsOptions],\n );\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [chartError, setChartError] = useState<Error | null>(null);\n\n const data = useMemo(() => {\n if (!arrowTable) return null;\n return {values: arrowTableToJson(arrowTable)};\n }, [arrowTable]);\n\n const specWithData = useMemo(() => {\n const parsed = typeof spec === 'string' ? safeJsonParse(spec) : spec;\n if (!parsed) {\n setChartError(new Error('Invalid Vega-Lite specification'));\n return null;\n }\n return {\n padding: 10,\n background: 'transparent',\n ...parsed,\n data: data,\n // Override the following props to ensure the chart is responsive\n width: 'container',\n height: 'container',\n autosize: {contains: 'padding'},\n } as VisualizationSpec;\n }, [spec, data]);\n\n // Reset chart error whenever spec or data changes\n useEffect(() => {\n setChartError(null);\n }, [spec, data]);\n\n const ref = useRef<HTMLDivElement>(null);\n const embed = useVegaEmbed({\n ref,\n spec: specWithData ?? '',\n onError: () => setChartError,\n options,\n });\n\n const dimensions = useAspectRatioDimensions({\n containerRef,\n width,\n height,\n aspectRatio,\n });\n const changeDimensions = useCallback(\n (width: number, height: number) => {\n embed?.view.width(width).height(height).runAsync();\n },\n [embed],\n );\n useEffect(() => {\n changeDimensions(dimensions.width, dimensions.height);\n }, [changeDimensions, dimensions.width, dimensions.height]);\n\n return (\n <VegaChartContextProvider value={{embed}}>\n <div\n ref={containerRef}\n className={cn('relative flex h-full w-full flex-col gap-2', className)}\n >\n <div className=\"peer relative\">\n {chartError ? (\n <ToolErrorMessage\n error={chartError}\n triggerLabel=\"Chart rendering failed\"\n title=\"Chart error\"\n align=\"start\"\n details={spec}\n />\n ) : (\n specWithData &&\n data && (\n <AspectRatio\n ratio={aspectRatio}\n className=\"overflow-visible\"\n asChild\n >\n <div ref={ref} className=\"[&_svg]:overflow-visible\" />\n </AspectRatio>\n )\n )}\n </div>\n {children}\n </div>\n </VegaChartContextProvider>\n );\n};\n\n/**\n * Composable Vega-Lite chart component with support for custom actions.\n *\n * @example\n * ```tsx\n * // Basic usage without actions (backwards compatible)\n * <VegaLiteArrowChart spec={spec} arrowTable={data} />\n *\n * // With export action\n * <VegaLiteArrowChart spec={spec} arrowTable={data}>\n * <VegaLiteArrowChart.Actions>\n * <VegaExportAction />\n * </VegaLiteArrowChart.Actions>\n * </VegaLiteArrowChart>\n *\n * // Custom actions with separator\n * <VegaLiteArrowChart spec={spec} arrowTable={data}>\n * <VegaLiteArrowChart.Actions>\n * <VegaExportAction pngScale={3} />\n * <Separator orientation=\"vertical\" className=\"h-4\" />\n * <Button size=\"xs\" variant=\"ghost\" onClick={handleRefresh}>\n * <RefreshCw className=\"h-4 w-4\" />\n * </Button>\n * </VegaLiteArrowChart.Actions>\n * </VegaLiteArrowChart>\n * ```\n */\nexport const VegaLiteArrowChart = Object.assign(VegaLiteArrowChartBase, {\n /**\n * Container for action buttons, positioned as an overlay\n */\n Actions: VegaChartActions,\n /**\n * Built-in export action with PNG/SVG download\n */\n ExportAction: VegaExportAction,\n /**\n * Built-in edit action with spec/SQL editor popover\n */\n EditAction: VegaEditAction,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"VegaLiteArrowChart.js","sourceRoot":"","sources":["../src/VegaLiteArrowChart.tsx"],"names":[],"mappings":"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","sourcesContent":["import {ToolErrorMessage} from '@sqlrooms/ai-core';\nimport {arrowTableToJson} from '@sqlrooms/duckdb';\nimport {cn, useAspectRatioDimensions, useTheme} from '@sqlrooms/ui';\nimport {safeJsonParse} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useVegaEmbed} from 'react-vega';\nimport {EmbedOptions, VisualizationSpec} from 'vega-embed';\nimport {Config} from 'vega-lite';\nimport {darkTheme} from './themes/darkTheme';\nimport {lightTheme} from './themes/lightTheme';\nimport {VegaChartActions} from './VegaChartActions';\nimport {VegaChartContextProvider} from './VegaChartContext';\nimport {VegaEditAction} from './VegaEditAction';\nimport {VegaExportAction} from './VegaExportAction';\n\nexport type VegaLiteArrowChartProps = {\n className?: string;\n width?: number | 'auto';\n height?: number | 'auto';\n aspectRatio?: number;\n spec: string | VisualizationSpec;\n options?: EmbedOptions;\n arrowTable: arrow.Table | undefined;\n /**\n * Children for composing actions and other elements.\n * Use VegaLiteArrowChart.Actions to add action buttons.\n *\n * @example\n * ```tsx\n * <VegaLiteArrowChart spec={spec} arrowTable={data}>\n * <VegaLiteArrowChart.Actions>\n * <VegaExportAction />\n * </VegaLiteArrowChart.Actions>\n * </VegaLiteArrowChart>\n * ```\n */\n children?: React.ReactNode;\n};\n\nexport function makeDefaultVegaLiteOptions(\n options?: EmbedOptions,\n): EmbedOptions {\n return {\n mode: 'vega-lite',\n renderer: 'svg',\n theme: undefined,\n tooltip: true,\n actions: false,\n padding: {\n top: 20,\n right: 10,\n bottom: 10,\n left: 10,\n },\n ...options,\n };\n}\n\nconst VegaLiteArrowChartBase: React.FC<VegaLiteArrowChartProps> = (props) => {\n const {\n className,\n spec,\n arrowTable,\n options: propsOptions,\n width = 'auto',\n height = 'auto',\n children,\n } = props;\n const aspectRatio = Object.hasOwn(props, 'aspectRatio')\n ? props.aspectRatio\n : 16 / 9;\n const {theme} = useTheme();\n\n const options = useMemo(\n () =>\n makeDefaultVegaLiteOptions({\n config: {\n ...(theme === 'dark' ? darkTheme : lightTheme),\n ...(typeof propsOptions?.config === 'object'\n ? (propsOptions.config as Config)\n : {}),\n },\n\n ...propsOptions,\n }),\n [theme, propsOptions],\n );\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [chartError, setChartError] = useState<Error | null>(null);\n\n const data = useMemo(() => {\n if (!arrowTable) return null;\n return {values: arrowTableToJson(arrowTable)};\n }, [arrowTable]);\n\n const specWithData = useMemo(() => {\n const parsed = typeof spec === 'string' ? safeJsonParse(spec) : spec;\n if (!parsed) {\n return null;\n }\n return {\n padding: 10,\n background: 'transparent',\n ...parsed,\n data: data,\n // Override the following props to ensure the chart is responsive\n width: 'container',\n height: 'container',\n autosize: {contains: 'padding'},\n } as VisualizationSpec;\n }, [spec, data]);\n const specError = specWithData\n ? null\n : new Error('Invalid Vega-Lite specification');\n const displayError = specError ?? chartError;\n\n // Reset chart error whenever spec or data changes\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setChartError(null);\n }, [spec, data]);\n\n const ref = useRef<HTMLDivElement>(null);\n const embed = useVegaEmbed({\n ref,\n spec: specWithData ?? '',\n onError: () => setChartError,\n options,\n });\n\n const dimensions = useAspectRatioDimensions({\n containerRef,\n width,\n height,\n aspectRatio:\n height === 'auto' || width !== 'auto' ? aspectRatio : undefined,\n });\n const changeDimensions = useCallback(\n (width: number, height: number) => {\n embed?.view.width(width).height(height).runAsync();\n },\n [embed],\n );\n useEffect(() => {\n changeDimensions(dimensions.width, dimensions.height);\n }, [changeDimensions, dimensions.width, dimensions.height]);\n\n return (\n <VegaChartContextProvider value={{embed}}>\n <div className={cn('relative flex w-full flex-col gap-2', className)}>\n <div\n className={cn(\n 'peer relative',\n height === 'auto' && aspectRatio === undefined && 'h-full',\n )}\n >\n {displayError ? (\n <ToolErrorMessage\n error={displayError}\n triggerLabel=\"Chart rendering failed\"\n title=\"Chart error\"\n align=\"start\"\n details={spec}\n />\n ) : (\n specWithData &&\n data && (\n <div\n ref={containerRef}\n style={{\n ...(height === 'auto' && aspectRatio !== undefined\n ? {aspectRatio}\n : height !== 'auto'\n ? {height}\n : {}),\n ...(width !== 'auto' ? {width} : {}),\n }}\n className={cn(\n 'overflow-visible',\n width === 'auto' && 'w-full',\n height === 'auto' && aspectRatio === undefined && 'h-full',\n )}\n >\n <div\n ref={ref}\n className=\"h-full w-full [&_svg]:overflow-visible\"\n />\n </div>\n )\n )}\n </div>\n {children}\n </div>\n </VegaChartContextProvider>\n );\n};\n\n/**\n * Composable Vega-Lite chart component with support for custom actions.\n *\n * @example\n * ```tsx\n * // Basic usage without actions (backwards compatible)\n * <VegaLiteArrowChart spec={spec} arrowTable={data} />\n *\n * // With export action\n * <VegaLiteArrowChart spec={spec} arrowTable={data}>\n * <VegaLiteArrowChart.Actions>\n * <VegaExportAction />\n * </VegaLiteArrowChart.Actions>\n * </VegaLiteArrowChart>\n *\n * // Custom actions with separator\n * <VegaLiteArrowChart spec={spec} arrowTable={data}>\n * <VegaLiteArrowChart.Actions>\n * <VegaExportAction pngScale={3} />\n * <Separator orientation=\"vertical\" className=\"h-4\" />\n * <Button size=\"xs\" variant=\"ghost\" onClick={handleRefresh}>\n * <RefreshCw className=\"h-4 w-4\" />\n * </Button>\n * </VegaLiteArrowChart.Actions>\n * </VegaLiteArrowChart>\n * ```\n */\nexport const VegaLiteArrowChart = Object.assign(VegaLiteArrowChartBase, {\n /**\n * Container for action buttons, positioned as an overlay\n */\n Actions: VegaChartActions,\n /**\n * Built-in export action with PNG/SVG download\n */\n ExportAction: VegaExportAction,\n /**\n * Built-in edit action with spec/SQL editor popover\n */\n EditAction: VegaEditAction,\n});\n"]}
|
package/dist/VegaLiteSqlChart.js
CHANGED
|
@@ -55,6 +55,6 @@ import { VegaLiteArrowChart, } from './VegaLiteArrowChart';
|
|
|
55
55
|
export const VegaLiteSqlChart = ({ className, sqlQuery, ...props }) => {
|
|
56
56
|
const result = useSql({ query: sqlQuery });
|
|
57
57
|
const arrowTable = result.data?.arrowTable;
|
|
58
|
-
return (_jsxs("div", { className: cn('flex h-full w-full flex-col gap-2 overflow-hidden', className), children: [result.error && (_jsx("div", { className: "
|
|
58
|
+
return (_jsxs("div", { className: cn('flex h-full w-full flex-col gap-2 overflow-hidden', className), children: [result.error && (_jsx("div", { className: "font-mono text-sm whitespace-pre-wrap text-red-500", children: result.error.message })), result.isLoading ? (_jsxs("div", { className: "text-muted-foreground align-center flex gap-2 px-2", children: [_jsx("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600" }), "Running query for chart data\u2026"] })) : (arrowTable && _jsx(VegaLiteArrowChart, { ...props, arrowTable: arrowTable }))] }));
|
|
59
59
|
};
|
|
60
60
|
//# sourceMappingURL=VegaLiteSqlChart.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaLiteSqlChart.js","sourceRoot":"","sources":["../src/VegaLiteSqlChart.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAChC,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAEzB,CAAC,EAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAC,EAAE,EAAE;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC;IAE3C,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,mDAAmD,EACnD,SAAS,CACV,aAEA,MAAM,CAAC,KAAK,IAAI,CACf,cAAK,SAAS,EAAC,oDAAoD,YAChE,MAAM,CAAC,KAAK,CAAC,OAAO,GACjB,CACP,EACA,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAClB,eAAK,SAAS,EAAC,oDAAoD,aACjE,cAAK,SAAS,EAAC,8EAA8E,GAAO,0CAEhG,CACP,CAAC,CAAC,CAAC,CACF,UAAU,IAAI,KAAC,kBAAkB,OAAK,KAAK,EAAE,UAAU,EAAE,UAAU,GAAI,CACxE,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {useSql} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {\n VegaLiteArrowChart,\n VegaLiteArrowChartProps,\n} from './VegaLiteArrowChart';\n\n/**\n * A component that renders a Vega-Lite chart with SQL data and responsive sizing.\n *\n * The chart can be sized in multiple ways:\n * - Fixed dimensions: Provide both width and height as numbers\n * - Fixed width, proportional height: Provide width as number, height as 'auto'\n * - Fixed height, proportional width: Provide height as number, width as 'auto'\n * - Fully responsive: Leave both as 'auto' (default), chart will fill container while maintaining aspect ratio\n *\n * @param props - The component props\n * @param {number | 'auto'} [props.width='auto'] - The chart width in pixels, or 'auto' to use container width\n * @param {number | 'auto'} [props.height='auto'] - The chart height in pixels, or 'auto' to calculate from aspect ratio\n * @param {number} [props.aspectRatio=3/2] - The desired width-to-height ratio when dimensions are auto-calculated\n * @param {string} props.sqlQuery - The SQL query to fetch data for the chart\n * @param {string | VisualizationSpec} props.spec - The Vega-Lite specification for the chart.\n * Can be either a JSON string or a VisualizationSpec object.\n * The data and size properties will be overridden by the component.\n *\n * @returns The rendered chart component\n *\n * @example\n * // Fixed size chart\n * <VegaLiteChart\n * width={600}\n * height={400}\n * sqlQuery=\"SELECT category, count(*) as count FROM sales GROUP BY category\"\n * spec={{\n * mark: 'bar',\n * encoding: {\n * x: {field: 'category', type: 'nominal'},\n * y: {field: 'count', type: 'quantitative'}\n * }\n * }}\n * />\n *\n * @example\n * // Responsive chart with 16:9 aspect ratio\n * <VegaLiteChart\n * className=\"max-w-[600px]\"\n * aspectRatio={16/9}\n * sqlQuery=\"SELECT date, value FROM metrics\"\n * spec={{\n * mark: 'line',\n * encoding: {\n * x: {field: 'date', type: 'temporal'},\n * y: {field: 'value', type: 'quantitative'}\n * }\n * }}\n * />\n */\nexport const VegaLiteSqlChart: React.FC<\n Omit<VegaLiteArrowChartProps, 'arrowTable'> & {sqlQuery: string}\n> = ({className, sqlQuery, ...props}) => {\n const result = useSql({query: sqlQuery});\n const arrowTable = result.data?.arrowTable;\n\n return (\n <div\n className={cn(\n 'flex h-full w-full flex-col gap-2 overflow-hidden',\n className,\n )}\n >\n {result.error && (\n <div className=\"
|
|
1
|
+
{"version":3,"file":"VegaLiteSqlChart.js","sourceRoot":"","sources":["../src/VegaLiteSqlChart.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAChC,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAEzB,CAAC,EAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAC,EAAE,EAAE;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC;IAE3C,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,mDAAmD,EACnD,SAAS,CACV,aAEA,MAAM,CAAC,KAAK,IAAI,CACf,cAAK,SAAS,EAAC,oDAAoD,YAChE,MAAM,CAAC,KAAK,CAAC,OAAO,GACjB,CACP,EACA,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAClB,eAAK,SAAS,EAAC,oDAAoD,aACjE,cAAK,SAAS,EAAC,8EAA8E,GAAO,0CAEhG,CACP,CAAC,CAAC,CAAC,CACF,UAAU,IAAI,KAAC,kBAAkB,OAAK,KAAK,EAAE,UAAU,EAAE,UAAU,GAAI,CACxE,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {useSql} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {\n VegaLiteArrowChart,\n VegaLiteArrowChartProps,\n} from './VegaLiteArrowChart';\n\n/**\n * A component that renders a Vega-Lite chart with SQL data and responsive sizing.\n *\n * The chart can be sized in multiple ways:\n * - Fixed dimensions: Provide both width and height as numbers\n * - Fixed width, proportional height: Provide width as number, height as 'auto'\n * - Fixed height, proportional width: Provide height as number, width as 'auto'\n * - Fully responsive: Leave both as 'auto' (default), chart will fill container while maintaining aspect ratio\n *\n * @param props - The component props\n * @param {number | 'auto'} [props.width='auto'] - The chart width in pixels, or 'auto' to use container width\n * @param {number | 'auto'} [props.height='auto'] - The chart height in pixels, or 'auto' to calculate from aspect ratio\n * @param {number} [props.aspectRatio=3/2] - The desired width-to-height ratio when dimensions are auto-calculated\n * @param {string} props.sqlQuery - The SQL query to fetch data for the chart\n * @param {string | VisualizationSpec} props.spec - The Vega-Lite specification for the chart.\n * Can be either a JSON string or a VisualizationSpec object.\n * The data and size properties will be overridden by the component.\n *\n * @returns The rendered chart component\n *\n * @example\n * // Fixed size chart\n * <VegaLiteChart\n * width={600}\n * height={400}\n * sqlQuery=\"SELECT category, count(*) as count FROM sales GROUP BY category\"\n * spec={{\n * mark: 'bar',\n * encoding: {\n * x: {field: 'category', type: 'nominal'},\n * y: {field: 'count', type: 'quantitative'}\n * }\n * }}\n * />\n *\n * @example\n * // Responsive chart with 16:9 aspect ratio\n * <VegaLiteChart\n * className=\"max-w-[600px]\"\n * aspectRatio={16/9}\n * sqlQuery=\"SELECT date, value FROM metrics\"\n * spec={{\n * mark: 'line',\n * encoding: {\n * x: {field: 'date', type: 'temporal'},\n * y: {field: 'value', type: 'quantitative'}\n * }\n * }}\n * />\n */\nexport const VegaLiteSqlChart: React.FC<\n Omit<VegaLiteArrowChartProps, 'arrowTable'> & {sqlQuery: string}\n> = ({className, sqlQuery, ...props}) => {\n const result = useSql({query: sqlQuery});\n const arrowTable = result.data?.arrowTable;\n\n return (\n <div\n className={cn(\n 'flex h-full w-full flex-col gap-2 overflow-hidden',\n className,\n )}\n >\n {result.error && (\n <div className=\"font-mono text-sm whitespace-pre-wrap text-red-500\">\n {result.error.message}\n </div>\n )}\n {result.isLoading ? (\n <div className=\"text-muted-foreground align-center flex gap-2 px-2\">\n <div className=\"h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600\"></div>\n Running query for chart data…\n </div>\n ) : (\n arrowTable && <VegaLiteArrowChart {...props} arrowTable={arrowTable} />\n )}\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type * as arrow from 'apache-arrow';
|
|
2
|
+
import type { VisualizationSpec } from 'vega-embed';
|
|
3
|
+
/** Height behavior for a Vega chart result. */
|
|
4
|
+
export type VegaChartHeight = number | 'auto';
|
|
5
|
+
/** Data available when resolving the height of a rendered Vega chart. */
|
|
6
|
+
export interface VegaChartSizingContext {
|
|
7
|
+
/** The parsed, responsive Vega-Lite specification. */
|
|
8
|
+
spec: VisualizationSpec;
|
|
9
|
+
/** The data loaded for the chart, when available. */
|
|
10
|
+
arrowTable: arrow.Table | undefined;
|
|
11
|
+
}
|
|
12
|
+
/** Resolves a chart height from its parsed specification and loaded data. */
|
|
13
|
+
export type VegaChartHeightResolver = (context: VegaChartSizingContext) => VegaChartHeight;
|
|
14
|
+
/**
|
|
15
|
+
* Computes a taller height for category-dense horizontal bar charts.
|
|
16
|
+
*
|
|
17
|
+
* Returns `'auto'` for other chart shapes so they retain aspect-ratio sizing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getCategoryAwareVegaChartHeight({ spec, arrowTable, }: VegaChartSizingContext): VegaChartHeight;
|
|
20
|
+
//# sourceMappingURL=chartSizing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chartSizing.d.ts","sourceRoot":"","sources":["../src/chartSizing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAElD,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9C,yEAAyE;AACzE,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,IAAI,EAAE,iBAAiB,CAAC;IACxB,qDAAqD;IACrD,UAAU,EAAE,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;CACrC;AAED,6EAA6E;AAC7E,MAAM,MAAM,uBAAuB,GAAG,CACpC,OAAO,EAAE,sBAAsB,KAC5B,eAAe,CAAC;AA8GrB;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,IAAI,EACJ,UAAU,GACX,EAAE,sBAAsB,GAAG,eAAe,CAmB1C"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const MIN_CATEGORY_COUNT = 12;
|
|
2
|
+
const MIN_AUTO_HEIGHT = 280;
|
|
3
|
+
const MAX_AUTO_HEIGHT = 800;
|
|
4
|
+
const CHART_VERTICAL_PADDING = 48;
|
|
5
|
+
const CATEGORY_ROW_HEIGHT = 22;
|
|
6
|
+
const MAX_MEANINGFUL_CATEGORY_COUNT = Math.ceil((MAX_AUTO_HEIGHT - CHART_VERTICAL_PADDING) / CATEGORY_ROW_HEIGHT);
|
|
7
|
+
/** Returns a JSON object value while excluding arrays and primitives. */
|
|
8
|
+
function asObject(value) {
|
|
9
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
10
|
+
? value
|
|
11
|
+
: undefined;
|
|
12
|
+
}
|
|
13
|
+
/** Extracts the Vega-Lite mark type from string and object mark definitions. */
|
|
14
|
+
function getMarkType(spec) {
|
|
15
|
+
if (typeof spec.mark === 'string') {
|
|
16
|
+
return spec.mark;
|
|
17
|
+
}
|
|
18
|
+
return asObject(spec.mark)?.type;
|
|
19
|
+
}
|
|
20
|
+
/** Checks for data/layout semantics that raw-table sizing cannot reproduce. */
|
|
21
|
+
function hasUnsupportedAutoSizingStructure(spec) {
|
|
22
|
+
if (Array.isArray(spec.transform) && spec.transform.length > 0) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
for (const key of ['concat', 'hconcat', 'vconcat']) {
|
|
26
|
+
if (Array.isArray(spec[key]))
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
const layers = spec.layer;
|
|
30
|
+
if (Array.isArray(layers) &&
|
|
31
|
+
layers.some((layer) => hasUnsupportedAutoSizingStructure(asObject(layer) ?? {}))) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
const nestedSpec = asObject(spec.spec);
|
|
35
|
+
return nestedSpec ? hasUnsupportedAutoSizingStructure(nestedSpec) : false;
|
|
36
|
+
}
|
|
37
|
+
/** Finds the discrete y field of a horizontal bar unit in a nested spec. */
|
|
38
|
+
function getHorizontalBarCategoryField(spec, inheritedEncoding = {}) {
|
|
39
|
+
const encoding = { ...inheritedEncoding, ...asObject(spec.encoding) };
|
|
40
|
+
const x = asObject(encoding.x);
|
|
41
|
+
const y = asObject(encoding.y);
|
|
42
|
+
const isAggregate = typeof x?.aggregate === 'string';
|
|
43
|
+
const isQuantitativeX = x?.type === 'quantitative' || isAggregate;
|
|
44
|
+
const isDiscreteY = y?.type === 'nominal' ||
|
|
45
|
+
y?.type === 'ordinal' ||
|
|
46
|
+
(isAggregate && y?.type === undefined);
|
|
47
|
+
if (getMarkType(spec) === 'bar' &&
|
|
48
|
+
isQuantitativeX &&
|
|
49
|
+
isDiscreteY &&
|
|
50
|
+
typeof y?.field === 'string') {
|
|
51
|
+
return y.field;
|
|
52
|
+
}
|
|
53
|
+
for (const key of ['layer', 'concat', 'hconcat', 'vconcat']) {
|
|
54
|
+
const children = spec[key];
|
|
55
|
+
if (!Array.isArray(children))
|
|
56
|
+
continue;
|
|
57
|
+
for (const child of children) {
|
|
58
|
+
const field = getHorizontalBarCategoryField(asObject(child) ?? {}, encoding);
|
|
59
|
+
if (field)
|
|
60
|
+
return field;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const nestedSpec = asObject(spec.spec);
|
|
64
|
+
return nestedSpec
|
|
65
|
+
? getHorizontalBarCategoryField(nestedSpec, encoding)
|
|
66
|
+
: undefined;
|
|
67
|
+
}
|
|
68
|
+
/** Counts distinct non-null field values up to the height saturation point. */
|
|
69
|
+
function countDistinctValues(table, field) {
|
|
70
|
+
const vector = table.getChild(field);
|
|
71
|
+
if (!vector)
|
|
72
|
+
return 0;
|
|
73
|
+
const values = new Set();
|
|
74
|
+
for (let index = 0; index < table.numRows; index += 1) {
|
|
75
|
+
const value = vector.get(index);
|
|
76
|
+
if (value !== null && value !== undefined) {
|
|
77
|
+
values.add(`${typeof value}:${String(value)}`);
|
|
78
|
+
if (values.size >= MAX_MEANINGFUL_CATEGORY_COUNT)
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return values.size;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Computes a taller height for category-dense horizontal bar charts.
|
|
86
|
+
*
|
|
87
|
+
* Returns `'auto'` for other chart shapes so they retain aspect-ratio sizing.
|
|
88
|
+
*/
|
|
89
|
+
export function getCategoryAwareVegaChartHeight({ spec, arrowTable, }) {
|
|
90
|
+
if (!arrowTable)
|
|
91
|
+
return 'auto';
|
|
92
|
+
const specObject = asObject(spec) ?? {};
|
|
93
|
+
if (hasUnsupportedAutoSizingStructure(specObject))
|
|
94
|
+
return 'auto';
|
|
95
|
+
const categoryField = getHorizontalBarCategoryField(specObject);
|
|
96
|
+
if (!categoryField)
|
|
97
|
+
return 'auto';
|
|
98
|
+
const categoryCount = countDistinctValues(arrowTable, categoryField);
|
|
99
|
+
if (categoryCount < MIN_CATEGORY_COUNT)
|
|
100
|
+
return 'auto';
|
|
101
|
+
return Math.min(MAX_AUTO_HEIGHT, Math.max(MIN_AUTO_HEIGHT, CHART_VERTICAL_PADDING + categoryCount * CATEGORY_ROW_HEIGHT));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=chartSizing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chartSizing.js","sourceRoot":"","sources":["../src/chartSizing.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as arrow from 'apache-arrow';\nimport type {VisualizationSpec} from 'vega-embed';\n\n/** Height behavior for a Vega chart result. */\nexport type VegaChartHeight = number | 'auto';\n\n/** Data available when resolving the height of a rendered Vega chart. */\nexport interface VegaChartSizingContext {\n /** The parsed, responsive Vega-Lite specification. */\n spec: VisualizationSpec;\n /** The data loaded for the chart, when available. */\n arrowTable: arrow.Table | undefined;\n}\n\n/** Resolves a chart height from its parsed specification and loaded data. */\nexport type VegaChartHeightResolver = (\n context: VegaChartSizingContext,\n) => VegaChartHeight;\n\nconst MIN_CATEGORY_COUNT = 12;\nconst MIN_AUTO_HEIGHT = 280;\nconst MAX_AUTO_HEIGHT = 800;\nconst CHART_VERTICAL_PADDING = 48;\nconst CATEGORY_ROW_HEIGHT = 22;\nconst MAX_MEANINGFUL_CATEGORY_COUNT = Math.ceil(\n (MAX_AUTO_HEIGHT - CHART_VERTICAL_PADDING) / CATEGORY_ROW_HEIGHT,\n);\n\ntype JsonObject = Record<string, unknown>;\n\n/** Returns a JSON object value while excluding arrays and primitives. */\nfunction asObject(value: unknown): JsonObject | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as JsonObject)\n : undefined;\n}\n\n/** Extracts the Vega-Lite mark type from string and object mark definitions. */\nfunction getMarkType(spec: JsonObject): string | undefined {\n if (typeof spec.mark === 'string') {\n return spec.mark;\n }\n return asObject(spec.mark)?.type as string | undefined;\n}\n\n/** Checks for data/layout semantics that raw-table sizing cannot reproduce. */\nfunction hasUnsupportedAutoSizingStructure(spec: JsonObject): boolean {\n if (Array.isArray(spec.transform) && spec.transform.length > 0) {\n return true;\n }\n\n for (const key of ['concat', 'hconcat', 'vconcat'] as const) {\n if (Array.isArray(spec[key])) return true;\n }\n\n const layers = spec.layer;\n if (\n Array.isArray(layers) &&\n layers.some((layer) =>\n hasUnsupportedAutoSizingStructure(asObject(layer) ?? {}),\n )\n ) {\n return true;\n }\n\n const nestedSpec = asObject(spec.spec);\n return nestedSpec ? hasUnsupportedAutoSizingStructure(nestedSpec) : false;\n}\n\n/** Finds the discrete y field of a horizontal bar unit in a nested spec. */\nfunction getHorizontalBarCategoryField(\n spec: JsonObject,\n inheritedEncoding: JsonObject = {},\n): string | undefined {\n const encoding = {...inheritedEncoding, ...asObject(spec.encoding)};\n const x = asObject(encoding.x);\n const y = asObject(encoding.y);\n const isAggregate = typeof x?.aggregate === 'string';\n const isQuantitativeX = x?.type === 'quantitative' || isAggregate;\n const isDiscreteY =\n y?.type === 'nominal' ||\n y?.type === 'ordinal' ||\n (isAggregate && y?.type === undefined);\n\n if (\n getMarkType(spec) === 'bar' &&\n isQuantitativeX &&\n isDiscreteY &&\n typeof y?.field === 'string'\n ) {\n return y.field;\n }\n\n for (const key of ['layer', 'concat', 'hconcat', 'vconcat'] as const) {\n const children = spec[key];\n if (!Array.isArray(children)) continue;\n for (const child of children) {\n const field = getHorizontalBarCategoryField(\n asObject(child) ?? {},\n encoding,\n );\n if (field) return field;\n }\n }\n\n const nestedSpec = asObject(spec.spec);\n return nestedSpec\n ? getHorizontalBarCategoryField(nestedSpec, encoding)\n : undefined;\n}\n\n/** Counts distinct non-null field values up to the height saturation point. */\nfunction countDistinctValues(table: arrow.Table, field: string): number {\n const vector = table.getChild(field);\n if (!vector) return 0;\n\n const values = new Set<string>();\n for (let index = 0; index < table.numRows; index += 1) {\n const value = vector.get(index);\n if (value !== null && value !== undefined) {\n values.add(`${typeof value}:${String(value)}`);\n if (values.size >= MAX_MEANINGFUL_CATEGORY_COUNT) break;\n }\n }\n return values.size;\n}\n\n/**\n * Computes a taller height for category-dense horizontal bar charts.\n *\n * Returns `'auto'` for other chart shapes so they retain aspect-ratio sizing.\n */\nexport function getCategoryAwareVegaChartHeight({\n spec,\n arrowTable,\n}: VegaChartSizingContext): VegaChartHeight {\n if (!arrowTable) return 'auto';\n\n const specObject = asObject(spec) ?? {};\n if (hasUnsupportedAutoSizingStructure(specObject)) return 'auto';\n\n const categoryField = getHorizontalBarCategoryField(specObject);\n if (!categoryField) return 'auto';\n\n const categoryCount = countDistinctValues(arrowTable, categoryField);\n if (categoryCount < MIN_CATEGORY_COUNT) return 'auto';\n\n return Math.min(\n MAX_AUTO_HEIGHT,\n Math.max(\n MIN_AUTO_HEIGHT,\n CHART_VERTICAL_PADDING + categoryCount * CATEGORY_ROW_HEIGHT,\n ),\n );\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { VegaChartHeight, VegaChartHeightResolver } from '../chartSizing';
|
|
2
3
|
export interface VegaChartDisplayProps {
|
|
3
4
|
/**
|
|
4
5
|
* Custom class name for the chart container
|
|
@@ -9,6 +10,14 @@ export interface VegaChartDisplayProps {
|
|
|
9
10
|
* @default 16/9
|
|
10
11
|
*/
|
|
11
12
|
aspectRatio?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Fixed outer chart height, or `'auto'` for category-aware sizing.
|
|
15
|
+
*/
|
|
16
|
+
height?: VegaChartHeight;
|
|
17
|
+
/**
|
|
18
|
+
* Optional height policy evaluated with the parsed spec and loaded data.
|
|
19
|
+
*/
|
|
20
|
+
getHeight?: VegaChartHeightResolver;
|
|
12
21
|
/**
|
|
13
22
|
* Children passed through to VegaLiteArrowChart (e.g., action components)
|
|
14
23
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaChartDisplay.d.ts","sourceRoot":"","sources":["../../src/editor/VegaChartDisplay.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"VegaChartDisplay.d.ts","sourceRoot":"","sources":["../../src/editor/VegaChartDisplay.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAC,eAAe,EAAE,uBAAuB,EAAC,MAAM,gBAAgB,CAAC;AAG7E,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;OAEG;IACH,SAAS,CAAC,EAAE,uBAAuB,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA6E5D,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ToolErrorMessage } from '@sqlrooms/ai';
|
|
2
|
+
import { ToolErrorMessage } from '@sqlrooms/ai-core';
|
|
3
3
|
import { useSql } from '@sqlrooms/duckdb';
|
|
4
4
|
import { cn } from '@sqlrooms/ui';
|
|
5
|
+
import React from 'react';
|
|
5
6
|
import { VegaLiteArrowChart } from '../VegaLiteArrowChart';
|
|
7
|
+
import { getCategoryAwareVegaChartHeight } from '../chartSizing';
|
|
6
8
|
import { useVegaEditorContext } from './VegaEditorContext';
|
|
7
9
|
/**
|
|
8
10
|
* Chart display subcomponent for VegaLiteChart.Container.
|
|
@@ -19,7 +21,7 @@ import { useVegaEditorContext } from './VegaEditorContext';
|
|
|
19
21
|
* </VegaLiteChart.Container>
|
|
20
22
|
* ```
|
|
21
23
|
*/
|
|
22
|
-
export const VegaChartDisplay = ({ className, aspectRatio = 16 / 9, children, }) => {
|
|
24
|
+
export const VegaChartDisplay = ({ className, aspectRatio = 16 / 9, height, getHeight, children, }) => {
|
|
23
25
|
const { state, arrowTable, options } = useVegaEditorContext();
|
|
24
26
|
// Use the applied SQL for chart rendering (updates when Apply is clicked)
|
|
25
27
|
const sqlQuery = state.appliedSql;
|
|
@@ -33,6 +35,13 @@ export const VegaChartDisplay = ({ className, aspectRatio = 16 / 9, children, })
|
|
|
33
35
|
// Use parsed spec for live preview, fall back to last valid spec if parse failed
|
|
34
36
|
// This ensures the chart keeps rendering during typing even with invalid JSON
|
|
35
37
|
const spec = state.parsedSpec ?? state.lastValidSpec;
|
|
38
|
+
const resolvedHeight = React.useMemo(() => {
|
|
39
|
+
const context = { spec, arrowTable: chartData };
|
|
40
|
+
const requestedHeight = getHeight?.(context) ?? height;
|
|
41
|
+
return requestedHeight === 'auto'
|
|
42
|
+
? getCategoryAwareVegaChartHeight(context)
|
|
43
|
+
: requestedHeight;
|
|
44
|
+
}, [chartData, getHeight, height, spec]);
|
|
36
45
|
// Show loading state
|
|
37
46
|
if (sqlQuery && !arrowTable && sqlResult.isLoading) {
|
|
38
47
|
return (_jsxs("div", { className: cn('text-muted-foreground flex items-center justify-center', className), children: [_jsx("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600" }), _jsx("span", { className: "ml-2 text-sm", children: "Loading data..." })] }));
|
|
@@ -41,6 +50,6 @@ export const VegaChartDisplay = ({ className, aspectRatio = 16 / 9, children, })
|
|
|
41
50
|
if (sqlQuery && !arrowTable && sqlResult.error) {
|
|
42
51
|
return (_jsx("div", { className: className, children: _jsx(ToolErrorMessage, { error: sqlResult.error, triggerLabel: "SQL query failed", title: "Query error", align: "start", details: sqlQuery }) }));
|
|
43
52
|
}
|
|
44
|
-
return (_jsx("div", { className: cn('relative', className), children: _jsx(VegaLiteArrowChart, { className: "w-full", spec: spec, arrowTable: chartData, aspectRatio: aspectRatio, options: options, children: children }) }));
|
|
53
|
+
return (_jsx("div", { className: cn('relative', className), children: _jsx(VegaLiteArrowChart, { className: "w-full", spec: spec, arrowTable: chartData, aspectRatio: aspectRatio, height: resolvedHeight, options: options, children: children }) }));
|
|
45
54
|
};
|
|
46
55
|
//# sourceMappingURL=VegaChartDisplay.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaChartDisplay.js","sourceRoot":"","sources":["../../src/editor/VegaChartDisplay.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"VegaChartDisplay.js","sourceRoot":"","sources":["../../src/editor/VegaChartDisplay.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,kBAAkB,EAAC,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAC,+BAA+B,EAAC,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AA0BzD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,SAAS,EACT,WAAW,GAAG,EAAE,GAAG,CAAC,EACpB,MAAM,EACN,SAAS,EACT,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,EAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAC,GAAG,oBAAoB,EAAE,CAAC;IAE5D,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC;IAElC,gDAAgD;IAChD,MAAM,SAAS,GAAG,MAAM,CAAC;QACvB,KAAK,EAAE,QAAQ,IAAI,EAAE;QACrB,OAAO,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,UAAU;KACnC,CAAC,CAAC;IAEH,wDAAwD;IACxD,MAAM,SAAS,GAAG,UAAU,IAAI,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC;IAE3D,iFAAiF;IACjF,8EAA8E;IAC9E,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,aAAa,CAAC;IAErD,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACxC,MAAM,OAAO,GAAG,EAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAC,CAAC;QAC9C,MAAM,eAAe,GAAG,SAAS,EAAE,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC;QACvD,OAAO,eAAe,KAAK,MAAM;YAC/B,CAAC,CAAC,+BAA+B,CAAC,OAAO,CAAC;YAC1C,CAAC,CAAC,eAAe,CAAC;IACtB,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEzC,qBAAqB;IACrB,IAAI,QAAQ,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QACnD,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,wDAAwD,EACxD,SAAS,CACV,aAED,cAAK,SAAS,EAAC,8EAA8E,GAAG,EAChG,eAAM,SAAS,EAAC,cAAc,gCAAuB,IACjD,CACP,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,IAAI,QAAQ,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,YACvB,KAAC,gBAAgB,IACf,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,YAAY,EAAC,kBAAkB,EAC/B,KAAK,EAAC,aAAa,EACnB,KAAK,EAAC,OAAO,EACb,OAAO,EAAE,QAAQ,GACjB,GACE,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,YACvC,KAAC,kBAAkB,IACjB,SAAS,EAAC,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,SAAS,EACrB,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,OAAO,YAEf,QAAQ,GACU,GACjB,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {ToolErrorMessage} from '@sqlrooms/ai-core';\nimport {useSql} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport React from 'react';\nimport {VegaLiteArrowChart} from '../VegaLiteArrowChart';\nimport {getCategoryAwareVegaChartHeight} from '../chartSizing';\nimport type {VegaChartHeight, VegaChartHeightResolver} from '../chartSizing';\nimport {useVegaEditorContext} from './VegaEditorContext';\n\nexport interface VegaChartDisplayProps {\n /**\n * Custom class name for the chart container\n */\n className?: string;\n /**\n * Aspect ratio for the chart\n * @default 16/9\n */\n aspectRatio?: number;\n /**\n * Fixed outer chart height, or `'auto'` for category-aware sizing.\n */\n height?: VegaChartHeight;\n /**\n * Optional height policy evaluated with the parsed spec and loaded data.\n */\n getHeight?: VegaChartHeightResolver;\n /**\n * Children passed through to VegaLiteArrowChart (e.g., action components)\n */\n children?: React.ReactNode;\n}\n\n/**\n * Chart display subcomponent for VegaLiteChart.Container.\n * Renders the Vega-Lite chart with data from SQL query or arrow table.\n *\n * Uses the parsed spec from the editor state for live preview during editing.\n *\n * Must be used within a VegaLiteChart.Container component.\n *\n * @example\n * ```tsx\n * <VegaLiteChart.Container spec={spec} sqlQuery={query}>\n * <VegaLiteChart.Chart />\n * </VegaLiteChart.Container>\n * ```\n */\nexport const VegaChartDisplay: React.FC<VegaChartDisplayProps> = ({\n className,\n aspectRatio = 16 / 9,\n height,\n getHeight,\n children,\n}) => {\n const {state, arrowTable, options} = useVegaEditorContext();\n\n // Use the applied SQL for chart rendering (updates when Apply is clicked)\n const sqlQuery = state.appliedSql;\n\n // Fetch data from SQL if no arrowTable provided\n const sqlResult = useSql({\n query: sqlQuery || '',\n enabled: !!sqlQuery && !arrowTable,\n });\n\n // Use arrow table if provided, otherwise use SQL result\n const chartData = arrowTable ?? sqlResult.data?.arrowTable;\n\n // Use parsed spec for live preview, fall back to last valid spec if parse failed\n // This ensures the chart keeps rendering during typing even with invalid JSON\n const spec = state.parsedSpec ?? state.lastValidSpec;\n\n const resolvedHeight = React.useMemo(() => {\n const context = {spec, arrowTable: chartData};\n const requestedHeight = getHeight?.(context) ?? height;\n return requestedHeight === 'auto'\n ? getCategoryAwareVegaChartHeight(context)\n : requestedHeight;\n }, [chartData, getHeight, height, spec]);\n\n // Show loading state\n if (sqlQuery && !arrowTable && sqlResult.isLoading) {\n return (\n <div\n className={cn(\n 'text-muted-foreground flex items-center justify-center',\n className,\n )}\n >\n <div className=\"h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-blue-600\" />\n <span className=\"ml-2 text-sm\">Loading data...</span>\n </div>\n );\n }\n\n // Show error state\n if (sqlQuery && !arrowTable && sqlResult.error) {\n return (\n <div className={className}>\n <ToolErrorMessage\n error={sqlResult.error}\n triggerLabel=\"SQL query failed\"\n title=\"Query error\"\n align=\"start\"\n details={sqlQuery}\n />\n </div>\n );\n }\n\n return (\n <div className={cn('relative', className)}>\n <VegaLiteArrowChart\n className=\"w-full\"\n spec={spec}\n arrowTable={chartData}\n aspectRatio={aspectRatio}\n height={resolvedHeight}\n options={options}\n >\n {children}\n </VegaLiteArrowChart>\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { JsonCodeMirrorEditorProps } from '@sqlrooms/codemirror';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface VegaCodeMirrorEditorProps extends Omit<JsonCodeMirrorEditorProps, 'schema'> {
|
|
4
|
+
/**
|
|
5
|
+
* Whether to enable Vega-Lite JSON schema validation
|
|
6
|
+
* @default true
|
|
7
|
+
*/
|
|
8
|
+
enableSchemaValidation?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A CodeMirror editor specialized for editing Vega-Lite specifications.
|
|
12
|
+
* Automatically loads and configures the Vega-Lite JSON schema for validation.
|
|
13
|
+
*/
|
|
14
|
+
export declare const VegaCodeMirrorEditor: React.FC<VegaCodeMirrorEditorProps>;
|
|
15
|
+
//# sourceMappingURL=VegaCodeMirrorEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VegaCodeMirrorEditor.d.ts","sourceRoot":"","sources":["../../src/editor/VegaCodeMirrorEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,yBAAyB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CACrD,yBAAyB,EACzB,QAAQ,CACT;IACC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA+BpE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { JsonCodeMirrorEditor, } from '@sqlrooms/codemirror';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { loadVegaLiteSchema } from '../schema/vegaLiteSchema';
|
|
5
|
+
/**
|
|
6
|
+
* A CodeMirror editor specialized for editing Vega-Lite specifications.
|
|
7
|
+
* Automatically loads and configures the Vega-Lite JSON schema for validation.
|
|
8
|
+
*/
|
|
9
|
+
export const VegaCodeMirrorEditor = ({ value, onChange, readOnly = false, className, enableSchemaValidation = true, ...props }) => {
|
|
10
|
+
const [schema, setSchema] = useState(null);
|
|
11
|
+
// Load Vega-Lite schema on mount
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (enableSchemaValidation) {
|
|
14
|
+
loadVegaLiteSchema().then((loadedSchema) => {
|
|
15
|
+
if (loadedSchema) {
|
|
16
|
+
setSchema(loadedSchema);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}, [enableSchemaValidation]);
|
|
21
|
+
return (_jsx(JsonCodeMirrorEditor, { value: value, onChange: onChange, schema: enableSchemaValidation ? (schema ?? undefined) : undefined, readOnly: readOnly, className: className, ...props }));
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=VegaCodeMirrorEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VegaCodeMirrorEditor.js","sourceRoot":"","sources":["../../src/editor/VegaCodeMirrorEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,oBAAoB,GAErB,MAAM,sBAAsB,CAAC;AAC9B,OAAc,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACjD,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAa5D;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAwC,CAAC,EACxE,KAAK,EACL,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,sBAAsB,GAAG,IAAI,EAC7B,GAAG,KAAK,EACT,EAAE,EAAE;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAE1D,iCAAiC;IACjC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,sBAAsB,EAAE,CAAC;YAC3B,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE;gBACzC,IAAI,YAAY,EAAE,CAAC;oBACjB,SAAS,CAAC,YAAY,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAE7B,OAAO,CACL,KAAC,oBAAoB,IACnB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAClE,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,KAChB,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n JsonCodeMirrorEditor,\n JsonCodeMirrorEditorProps,\n} from '@sqlrooms/codemirror';\nimport React, {useEffect, useState} from 'react';\nimport {loadVegaLiteSchema} from '../schema/vegaLiteSchema';\n\nexport interface VegaCodeMirrorEditorProps extends Omit<\n JsonCodeMirrorEditorProps,\n 'schema'\n> {\n /**\n * Whether to enable Vega-Lite JSON schema validation\n * @default true\n */\n enableSchemaValidation?: boolean;\n}\n\n/**\n * A CodeMirror editor specialized for editing Vega-Lite specifications.\n * Automatically loads and configures the Vega-Lite JSON schema for validation.\n */\nexport const VegaCodeMirrorEditor: React.FC<VegaCodeMirrorEditorProps> = ({\n value,\n onChange,\n readOnly = false,\n className,\n enableSchemaValidation = true,\n ...props\n}) => {\n const [schema, setSchema] = useState<object | null>(null);\n\n // Load Vega-Lite schema on mount\n useEffect(() => {\n if (enableSchemaValidation) {\n loadVegaLiteSchema().then((loadedSchema) => {\n if (loadedSchema) {\n setSchema(loadedSchema);\n }\n });\n }\n }, [enableSchemaValidation]);\n\n return (\n <JsonCodeMirrorEditor\n value={value}\n onChange={onChange}\n schema={enableSchemaValidation ? (schema ?? undefined) : undefined}\n readOnly={readOnly}\n className={className}\n {...props}\n />\n );\n};\n"]}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { MonacoEditorProps } from '@sqlrooms/monaco-editor';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use VegaCodeMirrorEditorProps instead. This interface is kept for backward compatibility.
|
|
5
|
+
*/
|
|
3
6
|
export interface VegaMonacoEditorProps extends Omit<MonacoEditorProps, 'language'> {
|
|
4
7
|
/**
|
|
5
8
|
* Whether to enable Vega-Lite JSON schema validation
|
|
@@ -10,6 +13,8 @@ export interface VegaMonacoEditorProps extends Omit<MonacoEditorProps, 'language
|
|
|
10
13
|
/**
|
|
11
14
|
* A Monaco editor specialized for editing Vega-Lite specifications.
|
|
12
15
|
* Automatically loads and configures the Vega-Lite JSON schema for validation.
|
|
16
|
+
*
|
|
17
|
+
* @deprecated Use VegaCodeMirrorEditor instead. This component is kept for backward compatibility.
|
|
13
18
|
*/
|
|
14
19
|
export declare const VegaMonacoEditor: React.FC<VegaMonacoEditorProps>;
|
|
15
20
|
//# sourceMappingURL=VegaMonacoEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaMonacoEditor.d.ts","sourceRoot":"","sources":["../../src/editor/VegaMonacoEditor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAA0B,MAAM,OAAO,CAAC;AAG/C,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,iBAAiB,EACjB,UAAU,CACX;IACC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED
|
|
1
|
+
{"version":3,"file":"VegaMonacoEditor.d.ts","sourceRoot":"","sources":["../../src/editor/VegaMonacoEditor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAA0B,MAAM,OAAO,CAAC;AAG/C;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,iBAAiB,EACjB,UAAU,CACX;IACC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAuE5D,CAAC"}
|
|
@@ -5,6 +5,8 @@ import { loadVegaLiteSchema } from '../schema/vegaLiteSchema';
|
|
|
5
5
|
/**
|
|
6
6
|
* A Monaco editor specialized for editing Vega-Lite specifications.
|
|
7
7
|
* Automatically loads and configures the Vega-Lite JSON schema for validation.
|
|
8
|
+
*
|
|
9
|
+
* @deprecated Use VegaCodeMirrorEditor instead. This component is kept for backward compatibility.
|
|
8
10
|
*/
|
|
9
11
|
export const VegaMonacoEditor = ({ value, onChange, readOnly = false, className, enableSchemaValidation = true, onMount, options, ...props }) => {
|
|
10
12
|
const monacoRef = useRef(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaMonacoEditor.js","sourceRoot":"","sources":["../../src/editor/VegaMonacoEditor.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,YAAY,EAAoB,MAAM,yBAAyB,CAAC;AACxE,OAAc,EAAC,SAAS,EAAE,MAAM,EAAC,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"VegaMonacoEditor.js","sourceRoot":"","sources":["../../src/editor/VegaMonacoEditor.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,YAAY,EAAoB,MAAM,yBAAyB,CAAC;AACxE,OAAc,EAAC,SAAS,EAAE,MAAM,EAAC,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAgB5D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,KAAK,EACL,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,sBAAsB,GAAG,IAAI,EAC7B,OAAO,EACP,OAAO,EACP,GAAG,KAAK,EACT,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,MAAM,CAAM,IAAI,CAAC,CAAC;IACpC,MAAM,mBAAmB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE1C,4BAA4B;IAC5B,SAAS,CAAC,GAAG,EAAE;QACb,IACE,sBAAsB;YACtB,SAAS,CAAC,OAAO;YACjB,CAAC,mBAAmB,CAAC,OAAO,EAC5B,CAAC;YACD,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBACnC,IAAI,SAAS,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC;oBAChC,mBAAmB,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC/C,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC;gBACrC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAE7B,MAAM,oBAAoB,GAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACvD,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;QAE3B,8CAA8C;QAC9C,IAAI,sBAAsB,EAAE,CAAC;YAC3B,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBACnC,IAAI,MAAM,EAAE,CAAC;oBACX,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBACpC,mBAAmB,CAAC,OAAO,GAAG,IAAI,CAAC;gBACrC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,yBAAyB;QACzB,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,SAAS,CAAC,8BAA8B,CAAC,EAAE,GAAG,EAAE,CAAC;QAC1D,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,wCAAwC;QACxC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,YAAY,IACX,QAAQ,EAAC,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE;YACP,aAAa,EAAE,IAAI;YACnB,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,IAAI;YACb,eAAe,EAAE,aAAa;YAC9B,WAAW,EAAE,KAAK;YAClB,oBAAoB,EAAE,KAAK;YAC3B,GAAG,OAAO;SACX,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,SAAS,mBAAmB,CAAC,MAAW,EAAE,MAAc;IACtD,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC;QACvD,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE;YACP;gBACE,GAAG,EAAE,iDAAiD;gBACtD,SAAS,EAAE,CAAC,GAAG,CAAC;gBAChB,MAAM,EAAE,MAAiC;aAC1C;SACF;QACD,mBAAmB,EAAE,KAAK;KAC3B,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {OnMount} from '@monaco-editor/react';\nimport {MonacoEditor, MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport React, {useEffect, useRef} from 'react';\nimport {loadVegaLiteSchema} from '../schema/vegaLiteSchema';\n\n/**\n * @deprecated Use VegaCodeMirrorEditorProps instead. This interface is kept for backward compatibility.\n */\nexport interface VegaMonacoEditorProps extends Omit<\n MonacoEditorProps,\n 'language'\n> {\n /**\n * Whether to enable Vega-Lite JSON schema validation\n * @default true\n */\n enableSchemaValidation?: boolean;\n}\n\n/**\n * A Monaco editor specialized for editing Vega-Lite specifications.\n * Automatically loads and configures the Vega-Lite JSON schema for validation.\n *\n * @deprecated Use VegaCodeMirrorEditor instead. This component is kept for backward compatibility.\n */\nexport const VegaMonacoEditor: React.FC<VegaMonacoEditorProps> = ({\n value,\n onChange,\n readOnly = false,\n className,\n enableSchemaValidation = true,\n onMount,\n options,\n ...props\n}) => {\n const monacoRef = useRef<any>(null);\n const schemaConfiguredRef = useRef(false);\n\n // Load and configure schema\n useEffect(() => {\n if (\n enableSchemaValidation &&\n monacoRef.current &&\n !schemaConfiguredRef.current\n ) {\n loadVegaLiteSchema().then((schema) => {\n if (monacoRef.current && schema) {\n configureJsonSchema(monacoRef.current, schema);\n schemaConfiguredRef.current = true;\n }\n });\n }\n }, [enableSchemaValidation]);\n\n const handleEditorDidMount: OnMount = (editor, monaco) => {\n monacoRef.current = monaco;\n\n // Configure JSON schema validation if enabled\n if (enableSchemaValidation) {\n loadVegaLiteSchema().then((schema) => {\n if (schema) {\n configureJsonSchema(monaco, schema);\n schemaConfiguredRef.current = true;\n }\n });\n }\n\n // Format on initial load\n setTimeout(() => {\n editor.getAction('editor.action.formatDocument')?.run();\n }, 100);\n\n // Call the original onMount if provided\n onMount?.(editor, monaco);\n };\n\n return (\n <MonacoEditor\n language=\"json\"\n value={value}\n onChange={onChange}\n onMount={handleEditorDidMount}\n className={className}\n readOnly={readOnly}\n options={{\n formatOnPaste: true,\n formatOnType: true,\n folding: true,\n foldingStrategy: 'indentation',\n lineNumbers: 'off',\n fixedOverflowWidgets: false,\n ...options,\n }}\n {...props}\n />\n );\n};\n\n/**\n * Configure Monaco JSON schema validation for Vega-Lite\n */\nfunction configureJsonSchema(monaco: any, schema: object) {\n monaco.languages.json.jsonDefaults.setDiagnosticsOptions({\n validate: true,\n schemas: [\n {\n uri: 'https://vega.github.io/schema/vega-lite/v5.json',\n fileMatch: ['*'],\n schema: schema as Record<string, unknown>,\n },\n ],\n enableSchemaRequest: false,\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaSpecEditorPanel.d.ts","sourceRoot":"","sources":["../../src/editor/VegaSpecEditorPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,
|
|
1
|
+
{"version":3,"file":"VegaSpecEditorPanel.d.ts","sourceRoot":"","sources":["../../src/editor/VegaSpecEditorPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAuDlE,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from '@sqlrooms/ui';
|
|
2
|
+
import { cn, CopyButton } from '@sqlrooms/ui';
|
|
3
3
|
import { AlertCircle } from 'lucide-react';
|
|
4
|
+
import { VegaCodeMirrorEditor } from './VegaCodeMirrorEditor';
|
|
4
5
|
import { useVegaEditorContext } from './VegaEditorContext';
|
|
5
|
-
import { VegaMonacoEditor } from './VegaMonacoEditor';
|
|
6
6
|
/**
|
|
7
7
|
* Spec editor panel subcomponent for VegaLiteChart.Container.
|
|
8
8
|
* Renders a Monaco editor with Vega-Lite JSON schema validation.
|
|
@@ -20,10 +20,14 @@ import { VegaMonacoEditor } from './VegaMonacoEditor';
|
|
|
20
20
|
export const VegaSpecEditorPanel = ({ className, title = 'Vega-Lite Spec', }) => {
|
|
21
21
|
const { state, actions, editable } = useVegaEditorContext();
|
|
22
22
|
const showHeader = title !== '';
|
|
23
|
-
return (_jsxs("div", { className: cn('flex h-full flex-col', className), children: [showHeader && (_jsxs("div", { className: "flex items-center justify-between border-b px-3 py-2", children: [_jsx("span", { className: "text-sm font-medium", children: title }), state.isSpecDirty && (_jsx("span", { className: "text-muted-foreground text-xs", children: "Modified" }))] })),
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
return (_jsxs("div", { className: cn('flex h-full flex-col', className), children: [showHeader && (_jsxs("div", { className: "flex items-center justify-between border-b px-3 py-2", children: [_jsx("span", { className: "text-sm font-medium", children: title }), state.isSpecDirty && (_jsx("span", { className: "text-muted-foreground text-xs", children: "Modified" }))] })), _jsxs("div", { className: "relative flex-1", children: [_jsx(VegaCodeMirrorEditor, { className: "absolute inset-0 h-full w-full", value: state.editedSpecString, onChange: (value) => {
|
|
24
|
+
if (value !== undefined) {
|
|
25
|
+
actions.setEditedSpec(value);
|
|
26
|
+
}
|
|
27
|
+
}, readOnly: !editable, options: {
|
|
28
|
+
lineNumbers: true,
|
|
29
|
+
lineWrapping: false,
|
|
30
|
+
foldGutter: true,
|
|
31
|
+
} }), _jsx("div", { className: "bg-background absolute top-2 right-2 rounded-md border", children: _jsx(CopyButton, { text: state.editedSpecString, size: "xs", tooltipLabel: "Copy spec", disabled: !state.editedSpecString.trim() }) })] }), state.specParseError && (_jsxs("div", { className: "bg-destructive/90 text-destructive-foreground flex items-center gap-2 px-3 py-2 backdrop-blur-sm", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "truncate text-xs", children: state.specParseError })] }))] }));
|
|
28
32
|
};
|
|
29
33
|
//# sourceMappingURL=VegaSpecEditorPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaSpecEditorPanel.js","sourceRoot":"","sources":["../../src/editor/VegaSpecEditorPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"VegaSpecEditorPanel.js","sourceRoot":"","sources":["../../src/editor/VegaSpecEditorPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,EAAE,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAczD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAuC,CAAC,EACtE,SAAS,EACT,KAAK,GAAG,gBAAgB,GACzB,EAAE,EAAE;IACH,MAAM,EAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAC,GAAG,oBAAoB,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAG,KAAK,KAAK,EAAE,CAAC;IAEhC,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,sBAAsB,EAAE,SAAS,CAAC,aAElD,UAAU,IAAI,CACb,eAAK,SAAS,EAAC,sDAAsD,aACnE,eAAM,SAAS,EAAC,qBAAqB,YAAE,KAAK,GAAQ,EACnD,KAAK,CAAC,WAAW,IAAI,CACpB,eAAM,SAAS,EAAC,+BAA+B,yBAAgB,CAChE,IACG,CACP,EAGD,eAAK,SAAS,EAAC,iBAAiB,aAC9B,KAAC,oBAAoB,IACnB,SAAS,EAAC,gCAAgC,EAC1C,KAAK,EAAE,KAAK,CAAC,gBAAgB,EAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4BAClB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gCACxB,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;4BAC/B,CAAC;wBACH,CAAC,EACD,QAAQ,EAAE,CAAC,QAAQ,EACnB,OAAO,EAAE;4BACP,WAAW,EAAE,IAAI;4BACjB,YAAY,EAAE,KAAK;4BACnB,UAAU,EAAE,IAAI;yBACjB,GACD,EACF,cAAK,SAAS,EAAC,wDAAwD,YACrE,KAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,gBAAgB,EAC5B,IAAI,EAAC,IAAI,EACT,YAAY,EAAC,WAAW,EACxB,QAAQ,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,GACxC,GACE,IACF,EAGL,KAAK,CAAC,cAAc,IAAI,CACvB,eAAK,SAAS,EAAC,kGAAkG,aAC/G,KAAC,WAAW,IAAC,SAAS,EAAC,kBAAkB,GAAG,EAC5C,eAAM,SAAS,EAAC,kBAAkB,YAAE,KAAK,CAAC,cAAc,GAAQ,IAC5D,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {cn, CopyButton} from '@sqlrooms/ui';\nimport {AlertCircle} from 'lucide-react';\nimport React from 'react';\nimport {VegaCodeMirrorEditor} from './VegaCodeMirrorEditor';\nimport {useVegaEditorContext} from './VegaEditorContext';\n\nexport interface VegaSpecEditorPanelProps {\n /**\n * Custom class name for the panel\n */\n className?: string;\n /**\n * Title shown in the panel header\n * @default \"Vega-Lite Spec\"\n */\n title?: string;\n}\n\n/**\n * Spec editor panel subcomponent for VegaLiteChart.Container.\n * Renders a Monaco editor with Vega-Lite JSON schema validation.\n *\n * Must be used within a VegaLiteChart.Container component.\n *\n * @example\n * ```tsx\n * <VegaLiteChart.Container spec={spec}>\n * <VegaLiteChart.Chart />\n * <VegaLiteChart.SpecEditor />\n * </VegaLiteChart.Container>\n * ```\n */\nexport const VegaSpecEditorPanel: React.FC<VegaSpecEditorPanelProps> = ({\n className,\n title = 'Vega-Lite Spec',\n}) => {\n const {state, actions, editable} = useVegaEditorContext();\n const showHeader = title !== '';\n\n return (\n <div className={cn('flex h-full flex-col', className)}>\n {/* Header - only show if title is provided */}\n {showHeader && (\n <div className=\"flex items-center justify-between border-b px-3 py-2\">\n <span className=\"text-sm font-medium\">{title}</span>\n {state.isSpecDirty && (\n <span className=\"text-muted-foreground text-xs\">Modified</span>\n )}\n </div>\n )}\n\n {/* Editor */}\n <div className=\"relative flex-1\">\n <VegaCodeMirrorEditor\n className=\"absolute inset-0 h-full w-full\"\n value={state.editedSpecString}\n onChange={(value) => {\n if (value !== undefined) {\n actions.setEditedSpec(value);\n }\n }}\n readOnly={!editable}\n options={{\n lineNumbers: true,\n lineWrapping: false,\n foldGutter: true,\n }}\n />\n <div className=\"bg-background absolute top-2 right-2 rounded-md border\">\n <CopyButton\n text={state.editedSpecString}\n size=\"xs\"\n tooltipLabel=\"Copy spec\"\n disabled={!state.editedSpecString.trim()}\n />\n </div>\n </div>\n\n {/* Spec parse error */}\n {state.specParseError && (\n <div className=\"bg-destructive/90 text-destructive-foreground flex items-center gap-2 px-3 py-2 backdrop-blur-sm\">\n <AlertCircle className=\"h-4 w-4 shrink-0\" />\n <span className=\"truncate text-xs\">{state.specParseError}</span>\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -17,7 +17,7 @@ export interface VegaSqlEditorPanelProps {
|
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* SQL editor panel subcomponent for VegaLiteChart.Container.
|
|
20
|
-
* Renders a
|
|
20
|
+
* Renders a CodeMirror editor with SQL syntax highlighting and a query preview.
|
|
21
21
|
*
|
|
22
22
|
* Must be used within a VegaLiteChart.Container component.
|
|
23
23
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VegaSqlEditorPanel.d.ts","sourceRoot":"","sources":["../../src/editor/VegaSqlEditorPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,
|
|
1
|
+
{"version":3,"file":"VegaSqlEditorPanel.d.ts","sourceRoot":"","sources":["../../src/editor/VegaSqlEditorPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA6FhE,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { Button, cn } from '@sqlrooms/ui';
|
|
2
|
+
import { SqlCodeMirrorEditor, SqlQueryPreview } from '@sqlrooms/sql-editor';
|
|
3
|
+
import { Button, cn, CopyButton } from '@sqlrooms/ui';
|
|
4
4
|
import { PlayIcon } from 'lucide-react';
|
|
5
5
|
import { useCallback, useState } from 'react';
|
|
6
6
|
import { useVegaEditorContext } from './VegaEditorContext';
|
|
7
7
|
/**
|
|
8
8
|
* SQL editor panel subcomponent for VegaLiteChart.Container.
|
|
9
|
-
* Renders a
|
|
9
|
+
* Renders a CodeMirror editor with SQL syntax highlighting and a query preview.
|
|
10
10
|
*
|
|
11
11
|
* Must be used within a VegaLiteChart.Container component.
|
|
12
12
|
*
|
|
@@ -29,13 +29,12 @@ export const VegaSqlEditorPanel = ({ className, title = 'SQL Query', maxPreviewR
|
|
|
29
29
|
const showHeader = title !== '';
|
|
30
30
|
return (_jsxs("div", { className: cn('flex h-full flex-col', className), children: [showHeader ? (_jsxs("div", { className: "flex items-center justify-between border-b px-3 py-2", children: [_jsx("span", { className: "text-sm font-medium", children: title }), _jsxs("div", { className: "flex items-center gap-2", children: [state.isSqlDirty && (_jsx("span", { className: "text-muted-foreground text-xs", children: "Modified" })), editable && (_jsxs(Button, { variant: "ghost", size: "xs", onClick: handleRunPreview, disabled: !state.editedSql.trim(), children: [_jsx(PlayIcon, { className: "mr-1 h-3 w-3" }), "Preview"] }))] })] })) : (
|
|
31
31
|
/* Toolbar when no header - just show preview button */
|
|
32
|
-
editable && (_jsx("div", { className: "flex items-center justify-end border-b px-2 py-1", children: _jsxs(Button, { variant: "ghost", size: "xs", onClick: handleRunPreview, disabled: !state.editedSql.trim(), children: [_jsx(PlayIcon, { className: "mr-1 h-3 w-3" }), "Preview"] }) }))),
|
|
33
|
-
if (value !== undefined) {
|
|
32
|
+
editable && (_jsx("div", { className: "flex items-center justify-end border-b px-2 py-1", children: _jsxs(Button, { variant: "ghost", size: "xs", onClick: handleRunPreview, disabled: !state.editedSql.trim(), children: [_jsx(PlayIcon, { className: "mr-1 h-3 w-3" }), "Preview"] }) }))), _jsxs("div", { className: "relative min-h-[100px] flex-1", children: [_jsx(SqlCodeMirrorEditor, { className: "absolute inset-0 h-full w-full", value: state.editedSql, onChange: (value) => {
|
|
34
33
|
actions.setEditedSql(value);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
}, options: {
|
|
35
|
+
lineNumbers: true,
|
|
36
|
+
lineWrapping: true,
|
|
37
|
+
foldGutter: true,
|
|
38
|
+
}, readOnly: !editable }), _jsx("div", { className: "bg-background absolute top-2 right-2 rounded-md border", children: _jsx(CopyButton, { text: state.editedSql, size: "xs", tooltipLabel: "Copy SQL", disabled: !state.editedSql.trim() }) })] }), previewQuery && showPreview && (_jsx("div", { className: "max-h-[200px] overflow-auto border-t", children: _jsx(SqlQueryPreview, { query: previewQuery, defaultLimit: maxPreviewRows, limitOptions: [100, 500, 1000] }) }))] }));
|
|
40
39
|
};
|
|
41
40
|
//# sourceMappingURL=VegaSqlEditorPanel.js.map
|