Merge branch 'staging' into big-nate/bus-939-create-new-structure-for-chats

This commit is contained in:
Nate Kelley 2025-02-06 13:01:19 -07:00
commit a2f07161f8
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
7 changed files with 202 additions and 7 deletions

View File

@ -367,7 +367,7 @@ pub async fn modify_visualization_agent(
let (
format_labels_result,
configure_charts_result,
global_styling_result,
mut global_styling_result,
stylize_columns_result,
) = tokio::join!(
async {
@ -400,6 +400,29 @@ pub async fn modify_visualization_agent(
}
);
let time_unit = match configure_charts_result.clone() {
Some(mut result) => {
// Try to get and remove from bar_line_chart first
if let Some(Value::String(time_unit)) = result.bar_line_chart.as_object_mut().and_then(|obj| obj.remove("x_axis_time_unit")) {
time_unit
} else {
// If not found in bar_line_chart, try combo_chart
if let Some(Value::String(time_unit)) = result.combo_chart.as_object_mut().and_then(|obj| obj.remove("x_axis_time_unit")) {
time_unit
} else {
String::new()
}
}
},
None => String::new(),
};
if !time_unit.is_empty() {
global_styling_result = Some(json!({
"xAxisTimeInterval": time_unit
}));
}
// Transform format_labels_result into columnLabelFormats
let column_label_formats = match format_labels_result {
Some(result) => result,

View File

@ -1,4 +1,6 @@
pub fn bar_line_chart_system_prompt() -> String {
// time_unit: 'day' | 'week' | 'month' | 'quarter' | 'year' | null; //OPTIONAL: default is null. This will only apply if the x axis is a date column. This will convert the date to the specified time unit.
String::from(
r#" ## TYPESCRIPT CONFIGS
@ -8,6 +10,7 @@ pub fn bar_line_chart_system_prompt() -> String {
type BarAndLineAxis = {
x: string[]; //the column names to use for the x axis. If multiple columns are provided, they will be grouped together and summed. The LLM should NEVER set multiple x axis columns. Only the user can set this.
y: string[]; //the column names to use for the y axis. These columns MUST be numerical column type and should NEVER be ID columns. If there is not matching, then this can be empty. If multiple columns are provided, they will be grouped together and summed. The LLM should NEVER set multiple y axis columns. Only the user can set this.
x_axis_time_unit?: 'day' | 'week' | 'month' | 'quarter' | 'year' | null; // OPTIONAL: default is null if not selected. If the sql query is grouping by a specific interval, you MUST match the interval to the x_axis_time_unit.
category?: string[]; // OPTIONAL: the column names to use for the category axis. This is optional and should only be used if the user needs to group or stack their data. This should likely not be the same as the x axis column. The category is ALMOST ALWAYS a string type column.
tooltip?: string[] | null; //OPTIONAL: if null the y axis will automatically be used
};

View File

@ -9,6 +9,7 @@ type ComboChartAxis = {
x: string[]; //the column names to use for the x axis. If multiple columns are provided, they will be grouped together and summed. The LLM should NEVER set multiple x axis columns. Only the user can set this.
y: string[]; //the column names to use for the y axis. These columns MUST be numerical column type and should NEVER be ID columns. If there is not matching, then this can be empty. If multiple columns are provided, they will be grouped together and summed. The LLM should NEVER set multiple y axis columns. Only the user can set this.
y2?: string[]; //the column names to use for the second y axis. These columns MUST be numerical column type and should NEVER be ID columns. The y2 axis is often called the "right axes". The y2 is also what makes this a dual axes chart.
x_axis_time_unit?: 'day' | 'week' | 'month' | 'quarter' | 'year' | null; // OPTIONAL: default is null if not selected. If the sql query is grouping by a specific interval, you MUST match the interval to the x_axis_time_unit.
category?: string[] | null; //the column names to use for the category axis. This is optional and should only be used if the user needs to group or stack their data. This should likely not be the same as the x axis column. The category is ALMOST ALWAYS a string type column.
tooltip?: string[] | null; //if null the y axis will automatically be used
};

View File

@ -22,7 +22,7 @@ type BusterChartLabelFormatCurrency = {
} & ColumnLabelFormatBase;
type BusterChartLabelFormatDate = {
dateFormat?: 'auto' | string; //OPTIONAL: default is 'LL'. This will only apply if the format is set to 'date'. This will convert the date to the specified format. This MUST BE IN dayjs format. If you determine that a column type is a date column, you should specify it's date format here.
dateFormat?: 'auto' | string; //OPTIONAL: The default to 'auto'. Only specify the day.js string format if the user asks for it.
useRelativeTime?: boolean;
isUTC?: boolean;
// This is useful if a date column is actually returned as a number. For example, if the column is the day of the week (1-7) or month of the year (1-12), then you should set this to 'day_of_week' or 'month_of_year'.

View File

@ -0,0 +1,160 @@
'use client';
import { ColumnMetaData, DEFAULT_COLUMN_SETTINGS } from '@/api/buster_rest';
import {
BusterChart,
BusterChartProps,
ChartType,
IColumnLabelFormat,
ViewType
} from '@/components/charts';
import { faker } from '@faker-js/faker';
import { Button, Checkbox, Select, Slider } from 'antd';
import { useMemo, useState } from 'react';
const chartData = [
{ date: '2024-01-01', sales: 100 },
{ date: '2024-02-01', sales: 200 },
{ date: '2024-03-01', sales: 300 },
{ date: '2024-04-01', sales: 250 },
{ date: '2024-05-01', sales: 400 },
{ date: '2024-06-01', sales: 350 },
{ date: '2024-07-01', sales: 450 },
{ date: '2024-08-01', sales: 500 },
{ date: '2024-09-01', sales: 550 },
{ date: '2024-10-01', sales: 600 },
{ date: '2024-11-01', sales: 650 },
{ date: '2024-12-01', sales: 700 }
];
const barAndLineAxis = {
x: ['date'],
y: ['sales'],
category: []
};
const pieConfig = {
x: ['date'],
y: ['sales']
};
const scatterAxis = {
x: ['date'],
y: ['sales']
};
const comboConfig = {
x: ['date'],
y: ['sales'],
y2: []
};
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
sales: {
style: 'currency',
currency: 'USD',
columnType: 'number'
// displayName: 'This is a display that is really long just for testing to make sure it works'
},
date: { style: 'date', dateFormat: undefined, columnType: 'date' }
};
const columnSettings: BusterChartProps['columnSettings'] = {
sales: {
...DEFAULT_COLUMN_SETTINGS,
// columnVisualization: 'bar',
// showDataLabels: false,
// barRoundness: 7,
// showDataLabelsAsPercentage: false,
lineSymbolSize: 3
// lineStyle: 'line',
// lineType: 'normal',
// lineWidth: 2
}
};
const columnMetadata: ColumnMetaData[] = Object.entries({
...chartData[0]
}).map(([key, value]) => ({
name: key,
min_value: 100,
max_value: 190,
unique_values: 1000,
simple_type: typeof value === 'number' ? 'number' : 'text',
type: typeof value as 'text'
}));
export default function ChartjsFixedLine() {
const [numberOfPoints, setNumberOfPoints] = useState(10);
const [useGeneratedData, setUseGeneratedData] = useState<'static' | 'generated' | 'multi-year'>(
'static'
);
const [rerenderNumber, setRerenderNumber] = useState(1);
const data = useMemo(() => {
if (useGeneratedData === 'generated') {
return Array.from({ length: numberOfPoints }, (_, index) => ({
date: faker.date.past({ years: 1 }).toISOString(),
sales: faker.number.int({ min: 590 + index, max: index + 10 + 590 })
}));
}
if (useGeneratedData === 'multi-year') {
return Array.from({ length: numberOfPoints }, (_, index) => ({
date: faker.date.past({ years: 5 }).toISOString(),
sales: faker.number.int({ min: 590 + index, max: index + 10 + 590 })
}));
}
return chartData;
}, [numberOfPoints, useGeneratedData]);
return (
<div className="flex h-[1000px] w-[75vw] flex-col rounded bg-white">
<div className="h-[500px] w-full p-3">
<BusterChart
key={rerenderNumber}
data={data}
selectedChartType={ChartType.Line}
selectedView={ViewType.Chart}
loading={false}
barAndLineAxis={barAndLineAxis}
pieChartAxis={pieConfig}
scatterAxis={scatterAxis}
comboChartAxis={comboConfig}
columnLabelFormats={columnLabelFormats}
columnSettings={columnSettings}
metricColumnId="sales"
columnMetadata={columnMetadata}
renderType="chartjs"
/>
</div>
<div className="flex w-full flex-col space-y-2 p-3">
<Select
value={useGeneratedData}
onChange={setUseGeneratedData}
options={[
{ label: 'Use 12 Month Interval Data', value: 'static' },
{ label: 'Use Multi-Year Data', value: 'multi-year' },
{ label: 'Use Random Same Year Data', value: 'generated' }
]}
/>
<div className="flex w-full items-center space-x-2">
<div>{numberOfPoints}</div>
<Slider
className="w-full"
value={numberOfPoints}
onChange={setNumberOfPoints}
min={1}
max={100}
/>
</div>
<Button onClick={() => setRerenderNumber(rerenderNumber + 1)}>
Rerender {rerenderNumber}
</Button>
</div>
</div>
);
}

View File

@ -101,7 +101,6 @@ export const useOptions = ({
columnSettings,
selectedAxis,
selectedChartType,
columnMetadata,
xAxisLabelRotation,
xAxisShowAxisLabel,
gridLines,

View File

@ -20,7 +20,6 @@ export const useXAxis = ({
columnLabelFormats,
selectedAxis,
selectedChartType,
columnMetadata,
columnSettings,
xAxisLabelRotation,
xAxisShowAxisLabel,
@ -34,7 +33,6 @@ export const useXAxis = ({
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
selectedAxis: ChartEncodes;
selectedChartType: ChartType;
columnMetadata: NonNullable<BusterChartProps['columnMetadata']>;
xAxisLabelRotation: NonNullable<BusterChartProps['xAxisLabelRotation']>;
xAxisShowAxisLabel: NonNullable<BusterChartProps['xAxisShowAxisLabel']>;
gridLines: NonNullable<BusterChartProps['gridLines']>;
@ -148,6 +146,13 @@ export const useXAxis = ({
const timeUnit = useMemo(() => {
if (type === 'time' && xAxisTimeInterval) {
const arrayOfValidTimeUnits: XAxisConfig['xAxisTimeInterval'][] = [
'day',
'week',
'month',
'quarter',
'year'
];
const isValidTimeUnit = arrayOfValidTimeUnits.includes(xAxisTimeInterval);
return isValidTimeUnit ? xAxisTimeInterval : false;
}
@ -157,7 +162,6 @@ export const useXAxis = ({
const memoizedXAxisOptions: DeepPartial<ScaleChartOptions<'bar'>['scales']['x']> | undefined =
useMemo(() => {
if (isPieChart) return undefined;
return {
type,
offset: !isScatterChart,
@ -166,17 +170,21 @@ export const useXAxis = ({
text: title
},
stacked,
time: {
unit: xAxisTimeInterval ? xAxisTimeInterval : false
},
ticks: {
...rotation,
sampleSize: type === 'time' ? 24 : undefined,
display: xAxisShowAxisLabel,
callback: useTickCallback ? tickCallback : null,
autoSkip: true,
autoSkipPadding: 3,
align: 'center',
time: {
unit: timeUnit
},
includeBounds: true,
autoSkipPadding: 4, // 17,
source: 'auto'
},
display: true,
@ -186,6 +194,7 @@ export const useXAxis = ({
grid
} as DeepPartial<ScaleChartOptions<'bar'>['scales']['x']>;
}, [
timeUnit,
title,
isScatterChart,
isPieChart,