| import { |
| Bar, |
| BarChart, |
| CartesianGrid, |
| Legend, |
| Line, |
| LineChart, |
| ResponsiveContainer, |
| Scatter, |
| ScatterChart, |
| Tooltip, |
| XAxis, |
| YAxis, |
| } from "recharts"; |
| import type { ChatResult } from "./types"; |
|
|
| const seriesColors = ["#36589f", "#6379ad", "#8e9bc0", "#203968"]; |
|
|
| function formatValue(value: unknown) { |
| if (typeof value === "number") { |
| return new Intl.NumberFormat("en-IN", { maximumFractionDigits: 2 }).format(value); |
| } |
| return String(value ?? ""); |
| } |
|
|
| export function AnalysisChart({ result }: { result: ChatResult }) { |
| if ( |
| result.visualization === "none" || |
| !result.rows.length || |
| !result.x_key || |
| !result.y_keys.length |
| ) { |
| return null; |
| } |
|
|
| const common = ( |
| <> |
| <CartesianGrid stroke="#d9d8d1" strokeDasharray="3 5" vertical={false} /> |
| <XAxis |
| dataKey={result.x_key} |
| tick={{ fill: "#62625e", fontSize: 11 }} |
| tickLine={false} |
| axisLine={{ stroke: "#c4c3bc" }} |
| interval="preserveStartEnd" |
| minTickGap={18} |
| /> |
| <YAxis |
| tick={{ fill: "#62625e", fontSize: 11 }} |
| tickLine={false} |
| axisLine={false} |
| tickFormatter={formatValue} |
| width={54} |
| /> |
| <Tooltip |
| formatter={formatValue} |
| contentStyle={{ |
| background: "#fcfbf8", |
| border: "1px solid #d9d8d1", |
| borderRadius: "8px", |
| boxShadow: "0 12px 34px rgba(30, 42, 67, 0.12)", |
| fontSize: "12px", |
| }} |
| /> |
| {result.y_keys.length > 1 ? ( |
| <Legend wrapperStyle={{ fontSize: "12px", paddingTop: "12px" }} /> |
| ) : null} |
| </> |
| ); |
|
|
| return ( |
| <figure className="analysis-chart" aria-label={result.title || "Analysis chart"}> |
| {result.title ? <figcaption>{result.title}</figcaption> : null} |
| <div className="chart-frame"> |
| <ResponsiveContainer width="100%" height="100%"> |
| {result.visualization === "bar" ? ( |
| <BarChart data={result.rows} margin={{ top: 10, right: 14, left: 0, bottom: 8 }}> |
| {common} |
| {result.y_keys.map((key, index) => ( |
| <Bar |
| key={key} |
| dataKey={key} |
| fill={seriesColors[index % seriesColors.length]} |
| radius={[4, 4, 0, 0]} |
| maxBarSize={44} |
| /> |
| ))} |
| </BarChart> |
| ) : result.visualization === "scatter" ? ( |
| <ScatterChart margin={{ top: 10, right: 14, left: 0, bottom: 8 }}> |
| <CartesianGrid stroke="#d9d8d1" strokeDasharray="3 5" /> |
| <XAxis |
| type="number" |
| dataKey={result.x_key} |
| name={result.x_key} |
| tick={{ fill: "#62625e", fontSize: 11 }} |
| tickFormatter={formatValue} |
| /> |
| <YAxis |
| type="number" |
| dataKey={result.y_keys[0]} |
| name={result.y_keys[0]} |
| tick={{ fill: "#62625e", fontSize: 11 }} |
| tickFormatter={formatValue} |
| width={54} |
| /> |
| <Tooltip cursor={{ strokeDasharray: "3 3" }} formatter={formatValue} /> |
| <Scatter data={result.rows} fill={seriesColors[0]} /> |
| </ScatterChart> |
| ) : ( |
| <LineChart data={result.rows} margin={{ top: 10, right: 14, left: 0, bottom: 8 }}> |
| {common} |
| {result.y_keys.map((key, index) => ( |
| <Line |
| key={key} |
| type="monotone" |
| dataKey={key} |
| stroke={seriesColors[index % seriesColors.length]} |
| strokeWidth={2.25} |
| dot={result.rows.length < 20 ? { r: 2.5 } : false} |
| activeDot={{ r: 4 }} |
| /> |
| ))} |
| </LineChart> |
| )} |
| </ResponsiveContainer> |
| </div> |
| </figure> |
| ); |
| } |
|
|