|
| 1 | +import { useState, useEffect } from "react" |
1 | 2 | import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" |
| 3 | +import { Button } from "@/components/ui/button" |
2 | 4 | import { |
3 | 5 | LineChart, |
4 | 6 | Line, |
@@ -55,6 +57,13 @@ function formatCellValue(col: string, val: unknown): string { |
55 | 57 | } |
56 | 58 |
|
57 | 59 | export function AnalysisResult({ result, plan }: AnalysisResultProps) { |
| 60 | + const [activeVizType, setActiveVizType] = useState<QueryPlan["vizType"]>(plan.vizType) |
| 61 | + |
| 62 | + // Reset to LLM's choice whenever a new query arrives |
| 63 | + useEffect(() => { |
| 64 | + setActiveVizType(plan.vizType) |
| 65 | + }, [plan.vizType]) |
| 66 | + |
58 | 67 | const renderDataTable = () => { |
59 | 68 | if (!result.data || result.data.length === 0) return null |
60 | 69 | const columns = Object.keys(result.data[0] || {}) |
@@ -98,7 +107,7 @@ export function AnalysisResult({ result, plan }: AnalysisResultProps) { |
98 | 107 | const groupByKey = plan.groupBy || dataKeys[0] |
99 | 108 | const metricKey = plan.metric || dataKeys.find(key => key !== groupByKey && typeof result.data[0][key] === 'number') || dataKeys[1] || 'count' |
100 | 109 |
|
101 | | - switch (plan.vizType) { |
| 110 | + switch (activeVizType) { |
102 | 111 | case "line": |
103 | 112 | return ( |
104 | 113 | <div className="overflow-visible"> |
@@ -258,8 +267,21 @@ export function AnalysisResult({ result, plan }: AnalysisResultProps) { |
258 | 267 | </CardDescription> |
259 | 268 | </CardHeader> |
260 | 269 | <CardContent> |
| 270 | + <div className="flex gap-1 mb-3 border-b border-border pb-2"> |
| 271 | + {(["table", "bar", "line", "pie", "kpi"] as const).map((type) => ( |
| 272 | + <Button |
| 273 | + key={type} |
| 274 | + variant={activeVizType === type ? "secondary" : "ghost"} |
| 275 | + size="sm" |
| 276 | + onClick={() => setActiveVizType(type)} |
| 277 | + disabled={!result.data?.length && type !== "table"} |
| 278 | + > |
| 279 | + {({ table: "Table", bar: "Bar", line: "Line", pie: "Pie", kpi: "KPI" } as const)[type]} |
| 280 | + </Button> |
| 281 | + ))} |
| 282 | + </div> |
261 | 283 | {renderVisualization()} |
262 | | - {plan.vizType !== "table" && result.data && result.data.length > 0 && ( |
| 284 | + {activeVizType !== "table" && result.data && result.data.length > 0 && ( |
263 | 285 | <div className="mt-4"> |
264 | 286 | <p className="text-xs text-muted-foreground mb-2">Raw data ({result.rowCount} rows)</p> |
265 | 287 | <div className="max-h-64 overflow-y-auto rounded-md border border-border"> |
|
0 commit comments