mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-03 10:05:13 +00:00
feat(web): 🎨 Unified color theme, AntV light/dark theme switching, Antd first-screen style loading. (#1020)
Co-authored-by: 黄振洪 <hzh01509324@alibaba-inc.com> Co-authored-by: Aralhi <xiaoping0501@gmail.com>
This commit is contained in:
@@ -1,19 +1,21 @@
|
||||
import { Empty, Row, Col, Select, Tooltip } from 'antd';
|
||||
import { Advice, Advisor } from '@antv/ava';
|
||||
import { Chart } from '@berryv/g2-react';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import i18n from '@/app/i18n';
|
||||
import { customizeAdvisor, getVisAdvices } from './advisor/pipeline';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { defaultAdvicesFilter } from './advisor/utils';
|
||||
import { AutoChartProps, ChartType, CustomAdvisorConfig, CustomChart, Specification } from './types';
|
||||
import { customCharts } from './charts';
|
||||
import { ChatContext } from '@/app/chat-context';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
export const AutoChart = (props: AutoChartProps) => {
|
||||
const { data, chartType, scopeOfCharts, ruleConfig } = props;
|
||||
|
||||
const { mode } = useContext(ChatContext);
|
||||
|
||||
const [advisor, setAdvisor] = useState<Advisor>();
|
||||
const [advices, setAdvices] = useState<Advice[]>([]);
|
||||
const [renderChartType, setRenderChartType] = useState<ChartType>();
|
||||
@@ -54,7 +56,15 @@ export const AutoChart = (props: AutoChartProps) => {
|
||||
const chartTypeInput = renderChartType ?? advices[0].type;
|
||||
const spec: Specification = advices?.find((item: Advice) => item.type === chartTypeInput)?.spec ?? undefined;
|
||||
if (spec) {
|
||||
return <Chart key={chartTypeInput} options={spec} />;
|
||||
return (
|
||||
<Chart
|
||||
key={chartTypeInput}
|
||||
options={{
|
||||
...spec,
|
||||
theme: mode,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [advices, renderChartType]);
|
||||
@@ -62,13 +72,13 @@ export const AutoChart = (props: AutoChartProps) => {
|
||||
if (renderChartType) {
|
||||
return (
|
||||
<div>
|
||||
<Row justify="start">
|
||||
<Row justify="start" className="mb-2">
|
||||
<Col>{i18n.t('Advices')}</Col>
|
||||
<Col style={{ marginLeft: 24 }}>
|
||||
<Select
|
||||
className="w-52"
|
||||
value={renderChartType}
|
||||
placeholder={'Chart Switcher'}
|
||||
style={{ width: '180px' }}
|
||||
onChange={(value) => setRenderChartType(value)}
|
||||
size={'small'}
|
||||
>
|
||||
@@ -78,10 +88,7 @@ export const AutoChart = (props: AutoChartProps) => {
|
||||
return (
|
||||
<Option key={item.type} value={item.type}>
|
||||
<Tooltip title={name} placement={'right'}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<DownOutlined />
|
||||
<div style={{ marginLeft: '2px' }}>{name}</div>
|
||||
</div>
|
||||
<div>{name}</div>
|
||||
</Tooltip>
|
||||
</Option>
|
||||
);
|
||||
|
@@ -1,36 +1,34 @@
|
||||
import { ChatContext } from '@/app/chat-context';
|
||||
import { ChartData } from '@/types/chat';
|
||||
import { Chart } from '@berryv/g2-react';
|
||||
import { Card, CardContent, Typography } from '@mui/joy';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export default function BarChart({ chart }: { key: string; chart: ChartData }) {
|
||||
const { mode } = useContext(ChatContext);
|
||||
|
||||
return (
|
||||
<div className="flex-1 min-w-0">
|
||||
<Card className="h-full" sx={{ background: 'transparent' }}>
|
||||
<CardContent className="h-full">
|
||||
<Typography gutterBottom component="div">
|
||||
{chart.chart_name}
|
||||
</Typography>
|
||||
<Typography gutterBottom level="body3">
|
||||
{chart.chart_desc}
|
||||
</Typography>
|
||||
<div className="h-[300px]">
|
||||
<Chart
|
||||
style={{ height: '100%' }}
|
||||
options={{
|
||||
autoFit: true,
|
||||
type: 'interval',
|
||||
data: chart.values,
|
||||
encode: { x: 'name', y: 'value', color: 'type' },
|
||||
axis: {
|
||||
x: {
|
||||
labelAutoRotate: false,
|
||||
},
|
||||
<div className="flex-1 min-w-0 p-4 bg-white dark:bg-theme-dark-container rounded">
|
||||
<div className="h-full">
|
||||
<div className="mb-2">{chart.chart_name}</div>
|
||||
<div className="opacity-80 text-sm mb-2">{chart.chart_desc}</div>
|
||||
<div className="h-[300px]">
|
||||
<Chart
|
||||
style={{ height: '100%' }}
|
||||
options={{
|
||||
autoFit: true,
|
||||
theme: mode,
|
||||
type: 'interval',
|
||||
data: chart.values,
|
||||
encode: { x: 'name', y: 'value', color: 'type' },
|
||||
axis: {
|
||||
x: {
|
||||
labelAutoRotate: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -1,59 +1,57 @@
|
||||
import { ChartData } from '@/types/chat';
|
||||
import { Card, CardContent, Typography } from '@mui/joy';
|
||||
import { Chart } from '@berryv/g2-react';
|
||||
import { useContext } from 'react';
|
||||
import { ChatContext } from '@/app/chat-context';
|
||||
|
||||
export default function LineChart({ chart }: { chart: ChartData }) {
|
||||
const { mode } = useContext(ChatContext);
|
||||
|
||||
return (
|
||||
<div className="flex-1 min-w-0">
|
||||
<Card className="h-full" sx={{ background: 'transparent' }}>
|
||||
<CardContent className="h-full">
|
||||
<Typography gutterBottom component="div">
|
||||
{chart.chart_name}
|
||||
</Typography>
|
||||
<Typography gutterBottom level="body3">
|
||||
{chart.chart_desc}
|
||||
</Typography>
|
||||
<div className="h-[300px]">
|
||||
<Chart
|
||||
style={{ height: '100%' }}
|
||||
options={{
|
||||
autoFit: true,
|
||||
type: 'view',
|
||||
data: chart.values,
|
||||
children: [
|
||||
{
|
||||
type: 'line',
|
||||
encode: {
|
||||
x: 'name',
|
||||
y: 'value',
|
||||
color: 'type',
|
||||
shape: 'smooth',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'area',
|
||||
encode: {
|
||||
x: 'name',
|
||||
y: 'value',
|
||||
color: 'type',
|
||||
shape: 'smooth',
|
||||
},
|
||||
legend: false,
|
||||
style: {
|
||||
fillOpacity: 0.15,
|
||||
},
|
||||
},
|
||||
],
|
||||
axis: {
|
||||
x: {
|
||||
labelAutoRotate: false,
|
||||
<div className="flex-1 min-w-0 p-4 bg-white dark:bg-theme-dark-container rounded">
|
||||
<div className="h-full">
|
||||
<div className="mb-2">{chart.chart_name}</div>
|
||||
<div className="opacity-80 text-sm mb-2">{chart.chart_desc}</div>
|
||||
<div className="h-[300px]">
|
||||
<Chart
|
||||
style={{ height: '100%' }}
|
||||
options={{
|
||||
autoFit: true,
|
||||
theme: mode,
|
||||
type: 'view',
|
||||
data: chart.values,
|
||||
children: [
|
||||
{
|
||||
type: 'line',
|
||||
encode: {
|
||||
x: 'name',
|
||||
y: 'value',
|
||||
color: 'type',
|
||||
shape: 'smooth',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
{
|
||||
type: 'area',
|
||||
encode: {
|
||||
x: 'name',
|
||||
y: 'value',
|
||||
color: 'type',
|
||||
shape: 'smooth',
|
||||
},
|
||||
legend: false,
|
||||
style: {
|
||||
fillOpacity: 0.15,
|
||||
},
|
||||
},
|
||||
],
|
||||
axis: {
|
||||
x: {
|
||||
labelAutoRotate: false,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -1,41 +1,36 @@
|
||||
import { ChartData } from '@/types/chat';
|
||||
import { Card, CardContent, Typography, Table } from '@mui/joy';
|
||||
import { Table } from '@mui/joy';
|
||||
import { groupBy } from 'lodash';
|
||||
|
||||
export default function TableChart({ chart }: { key: string; chart: ChartData }) {
|
||||
const data = groupBy(chart.values, 'type');
|
||||
|
||||
return (
|
||||
<div className="flex-1 min-w-0">
|
||||
<Card className="h-full overflow-auto" sx={{ background: 'transparent' }}>
|
||||
<CardContent className="h-full">
|
||||
<Typography gutterBottom component="div">
|
||||
{chart.chart_name}
|
||||
</Typography>
|
||||
<Typography gutterBottom level="body3">
|
||||
{chart.chart_desc}
|
||||
</Typography>
|
||||
<div className="flex-1">
|
||||
<Table aria-label="basic table" stripe="odd" hoverRow borderAxis="bothBetween">
|
||||
<thead>
|
||||
<tr>
|
||||
{Object.keys(data).map((key) => (
|
||||
<th key={key}>{key}</th>
|
||||
<div className="flex-1 min-w-0 p-4 bg-white dark:bg-theme-dark-container rounded">
|
||||
<div className="h-full">
|
||||
<div className="mb-2">{chart.chart_name}</div>
|
||||
<div className="opacity-80 text-sm mb-2">{chart.chart_desc}</div>
|
||||
<div className="flex-1">
|
||||
<Table aria-label="basic table" stripe="odd" hoverRow borderAxis="bothBetween">
|
||||
<thead>
|
||||
<tr>
|
||||
{Object.keys(data).map((key) => (
|
||||
<th key={key}>{key}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Object.values(data)?.[0]?.map((value, i) => (
|
||||
<tr key={i}>
|
||||
{Object.keys(data)?.map((k) => (
|
||||
<td key={k}>{data?.[k]?.[i].value || ''}</td>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Object.values(data)?.[0]?.map((value, i) => (
|
||||
<tr key={i}>
|
||||
{Object.keys(data)?.map((k) => (
|
||||
<td key={k}>{data?.[k]?.[i].value || ''}</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user