mirror of
https://github.com/vercel-labs/natural-language-postgres.git
synced 2026-11-04 08:10:38 +00:00
clean up
This commit is contained in:
1 parent
3602e229ec
commit
9a941df84f
3 files changed
+6
-183
No files matched your search
+1
-169
@@ -138,35 +138,7 @@ export const explainQuery = async (input: string, sqlQuery: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const generateAChart = async (results: Result[], userQuery: string) => {
|
||||
"use server";
|
||||
try {
|
||||
const result = await generateObject({
|
||||
model: openai("gpt-4o"),
|
||||
system: `You are a data visualization expert. Your job is to suggest the best chart type to represent the given data and provide the necessary information for rendering the chart. Consider the number of data points, the types of variables, and the relationships between them.`,
|
||||
prompt: `Given the following data from a SQL query result, suggest the best chart type to visualize this information. Provide the columns to use, labels for the chart, and the relevant data points. Also, give a brief explanation for your choice.
|
||||
Use the right chart type for the user query. For example, if the data is about which country has the most unicorns, you might suggest a pie chart. Or for growth rate, you might suggest a line chart. Show multiple lines where necessary.
|
||||
In your description, be sure to explain the biggest takeaway from the chart. You can refactor the data and format to fit the chart type and desired takeaway.
|
||||
|
||||
You can take liberty with long tail of data if it is not relevant to the chart type. For example, if the user asks for a pie chart of the top 5 countries with the most unicorns, you can ignore the rest of the data.
|
||||
|
||||
User Query:
|
||||
${userQuery}
|
||||
|
||||
Data:
|
||||
${JSON.stringify(results, null, 2)}`,
|
||||
schema: z.object({ generation: chartGenerationSchema }),
|
||||
output: "object",
|
||||
});
|
||||
return result.object;
|
||||
} catch (e) {
|
||||
// @ts-expect-error e
|
||||
console.error(e.message);
|
||||
throw new Error("Failed to generate chart suggestion");
|
||||
}
|
||||
};
|
||||
|
||||
export const generateChart = async (results: Result[], userQuery: string) => {
|
||||
export const generateChartConfig = async (results: Result[], userQuery: string) => {
|
||||
"use server";
|
||||
const system = `You are a data visualization expert. `;
|
||||
|
||||
@@ -211,143 +183,3 @@ export const generateChart = async (results: Result[], userQuery: string) => {
|
||||
throw new Error("Failed to generate chart suggestion");
|
||||
}
|
||||
};
|
||||
|
||||
export const streamChartData = async (
|
||||
config: Config,
|
||||
results: Unicorn[],
|
||||
userQuery: string,
|
||||
) => {
|
||||
const stream = createStreamableValue<string[]>([]);
|
||||
try {
|
||||
(async () => {
|
||||
const { object: dataObj, elementStream } = await streamObject({
|
||||
model: openai("gpt-4o"),
|
||||
system: `You are a data visualization expert.`,
|
||||
prompt: `Given the following available data from a SQL query result, generate the datapoints (in csv format) that best visualises the data and answers the users query.
|
||||
|
||||
Here is an example complete data:
|
||||
month,sales,profit,expenses
|
||||
January,1000,200,800
|
||||
February,1200,250,950
|
||||
March,1500,300,1200
|
||||
April,1800,350,1450
|
||||
May,2000,400,1600
|
||||
June,2200,450,1750
|
||||
|
||||
User Query:
|
||||
${userQuery}
|
||||
|
||||
Available Data:
|
||||
${JSON.stringify(results, null, 2)}
|
||||
|
||||
Chart Config to Use to Guide Data Generation:
|
||||
${JSON.stringify(config)}
|
||||
|
||||
Return only the data.
|
||||
`,
|
||||
schema: z
|
||||
.string()
|
||||
.describe("CSV formatted data points for a chart with a header row"),
|
||||
output: "array",
|
||||
});
|
||||
let items = [];
|
||||
for await (const el of elementStream) {
|
||||
items.push(el);
|
||||
stream.update(items);
|
||||
}
|
||||
stream.done(items);
|
||||
})();
|
||||
return stream.value;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw Error();
|
||||
}
|
||||
};
|
||||
|
||||
export const generateChartData = async (
|
||||
config: Config,
|
||||
results: Unicorn[],
|
||||
userQuery: string,
|
||||
) => {
|
||||
try {
|
||||
const { object: dataObj } = await generateObject({
|
||||
model: openai("gpt-4o-mini"),
|
||||
system: `You are a data visualization expert.`,
|
||||
prompt: `Given the following available data from a SQL query result, generate the datapoints (in csv format) that best visualises the data and answers the users query.
|
||||
|
||||
Here is an example complete data:
|
||||
month,sales,profit,expenses
|
||||
January,1000,200,800
|
||||
February,1200,250,950
|
||||
March,1500,300,1200
|
||||
April,1800,350,1450
|
||||
May,2000,400,1600
|
||||
June,2200,450,1750
|
||||
|
||||
User Query:
|
||||
${userQuery}
|
||||
|
||||
Available Data:
|
||||
${JSON.stringify(results, null, 2)}
|
||||
|
||||
Chart Config to Use to Guide Data Generation:
|
||||
${JSON.stringify(config)}
|
||||
|
||||
Return only the data.
|
||||
`,
|
||||
schema: z
|
||||
.object({ data: z.string() })
|
||||
.describe("CSV formatted data points for a chart with a header row"),
|
||||
});
|
||||
return dataObj;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw Error();
|
||||
}
|
||||
};
|
||||
|
||||
export const generateChartConfig = async (results: Result[], userQuery: string) => {
|
||||
"use server";
|
||||
const system = `You are a SQL and data visualization expert.`;
|
||||
|
||||
try {
|
||||
const { object: config } = await generateObject({
|
||||
model: openai("gpt-4o"),
|
||||
system,
|
||||
prompt: `Given the following data from a SQL query result, generate the chart config that could visualises the data and answers the users query without any data modification.
|
||||
For multiple groups use multi-lines.
|
||||
|
||||
Here is an example complete config:
|
||||
export const chartConfig = {
|
||||
type: "pie",
|
||||
xKey: "month",
|
||||
yKeys: ["sales", "profit", "expenses"],
|
||||
colors: {
|
||||
sales: "#4CAF50", // Green for sales
|
||||
profit: "#2196F3", // Blue for profit
|
||||
expenses: "#F44336" // Red for expenses
|
||||
},
|
||||
legend: true
|
||||
}
|
||||
|
||||
User Query:
|
||||
${userQuery}
|
||||
|
||||
Data:
|
||||
${JSON.stringify(results, null, 2)}`,
|
||||
schema: configSchema,
|
||||
});
|
||||
|
||||
const colors: Record<string, string> = {};
|
||||
config.yKeys.forEach((key, index) => {
|
||||
colors[key] = `hsl(var(--chart-${index+1}))`;
|
||||
});
|
||||
|
||||
const updatedConfig: Config = { ...config, colors };
|
||||
return { config: updatedConfig };
|
||||
} catch (e) {
|
||||
// @ts-expect-errore
|
||||
console.error(e.message);
|
||||
throw new Error("Failed to generate chart suggestion");
|
||||
}
|
||||
};
|
||||
+4
-7
@@ -14,14 +14,11 @@ import {
|
||||
} from "@/components/ui/table";
|
||||
import {
|
||||
explainQuery,
|
||||
generateAChart,
|
||||
generateChart,
|
||||
generateChartData,
|
||||
generateChartConfig,
|
||||
generateQuery,
|
||||
getCompanies,
|
||||
streamChartData,
|
||||
} from "./actions";
|
||||
import { Config, Data, QueryExplanation, Unicorn } from "@/lib/types";
|
||||
import { Config, QueryExplanation, Unicorn } from "@/lib/types";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Info, X, Search, Sparkles, Loader2, BarChart2 } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
@@ -105,7 +102,7 @@ export default function Component() {
|
||||
setResults(companies);
|
||||
setColumns(columns);
|
||||
setLoading(false);
|
||||
const generation = await generateChart(companies, inputValue);
|
||||
const generation = await generateChartConfig(companies, inputValue);
|
||||
setChartConfig(generation.config);
|
||||
};
|
||||
|
||||
@@ -167,7 +164,7 @@ export default function Component() {
|
||||
const handleGenerateChart = async () => {
|
||||
setIsGeneratingChart(true);
|
||||
try {
|
||||
const generation = await generateChart(results, inputValue);
|
||||
const generation = await generateChartConfig(results, inputValue);
|
||||
setChartConfig(generation.config);
|
||||
setIsChartModalOpen(true);
|
||||
} catch (error) {
|
||||
|
||||
@@ -14,20 +14,14 @@ import {
|
||||
XAxis,
|
||||
YAxis,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
Legend,
|
||||
ResponsiveContainer,
|
||||
} from "recharts";
|
||||
import {
|
||||
ChartContainer,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from "@/components/ui/chart";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { generateChart } from "@/app/actions";
|
||||
import { Config, Data, Unicorn } from "@/lib/types";
|
||||
import { Config, Data } from "@/lib/types";
|
||||
import { Label } from "recharts";
|
||||
import { transformDataForMultiLineChart } from "@/lib/rechart-format";
|
||||
|
||||
|
||||
Reference in new issue
Block a user