feat(web): AI对话框增加图表显示

支持Mermaid、EChart、Chart.js
This commit is contained in:
2025-06-08 02:42:05 +08:00
parent 4fe21f3d8b
commit c04269c3fa
6 changed files with 1775 additions and 1 deletions

View File

@@ -14,15 +14,21 @@
"@ant-design/x": "^1.4.0",
"@echofly/fetch-event-source": "^3.0.2",
"@fortawesome/fontawesome-free": "^6.7.2",
"@lightenna/react-mermaid-diagram": "^1.0.20",
"@tinyflow-ai/react": "^0.1.10",
"ahooks": "^3.8.5",
"amis": "^6.12.0",
"antd": "^5.25.3",
"axios": "^1.9.0",
"chart.js": "^4.4.9",
"echarts-for-react": "^3.0.2",
"licia": "^1.48.0",
"markdown-it": "^14.1.0",
"mermaid": "^11.6.0",
"react": "^18.3.1",
"react-chartjs-2": "^5.3.0",
"react-dom": "^18.3.1",
"react-markdown": "^10.1.0",
"react-router": "^7.6.1",
"styled-components": "^6.1.18"
},

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,129 @@
import MarkdownRender from '../util/Markdown.tsx'
import {useState} from 'react'
// language=Markdown
const markdownText = `### Hello
world
tony
jenny
\`\`\`javascript
console.log('hello')
\`\`\`
\`\`\`mermaid
graph TD
a-->b;
\`\`\`
\`\`\`mermaid
graph TD
c-->d;
\`\`\`
\`\`\`chartjs
{
type: 'bar',
data: {
labels: ['苹果', '香蕉', '橙子', '葡萄', '菠萝'],
datasets: [{
label: '水果销量',
data: [43, 32, 56, 29, 38],
}]
},
options: {
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: '水果店周销量数据'
}
}
}
}
\`\`\`
\`\`\`chartjs
{
type: 'bar',
data: {
labels: ['苹果', '香蕉', '橙子', '葡萄', '菠萝'],
datasets: [{
label: '水果销量',
data: [43, 32, 56, 29, 38],
}]
},
options: {
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: '水果店周销量数据'
}
}
}
}
\`\`\`
\`\`\`echart
{
grid: { top: 8, right: 8, bottom: 24, left: 36 },
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
smooth: true,
},
],
tooltip: {
trigger: 'axis',
},
}
\`\`\`
\`\`\`echart
{
grid: { top: 8, right: 8, bottom: 24, left: 36 },
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
smooth: true,
},
],
tooltip: {
trigger: 'axis',
},
}
\`\`\``
function Test() {
const [value, setValue] = useState<string>(markdownText)
return (
<>
<button onClick={() => setValue('hahaha\n' + markdownText)}>Button</button>
<MarkdownRender content={value}/>
</>
)
}
export default Test

View File

@@ -30,6 +30,7 @@ import Version from './pages/overview/Version.tsx'
import Yarn from './pages/overview/Yarn.tsx'
import YarnCluster from './pages/overview/YarnCluster.tsx'
import {commonInfo} from './util/amis.tsx'
import Test from './pages/Test.tsx'
export const routes: RouteObject[] = [
{
@@ -109,6 +110,10 @@ export const routes: RouteObject[] = [
},
],
},
{
path: 'test',
Component: Test,
}
],
},
]

View File

@@ -0,0 +1,50 @@
import 'chart.js/auto'
import {trim} from 'licia'
import {MermaidDiagram} from '@lightenna/react-mermaid-diagram'
import {Chart} from 'react-chartjs-2'
import EChartsReact from 'echarts-for-react'
import Markdown from 'react-markdown'
type MarkdownOptions = {
content: string
}
function MarkdownRender(options: MarkdownOptions) {
return (
<Markdown
children={options.content}
components={{
code: ({children, className, node, ...rest}) => {
switch (trim(className || '')) {
case 'language-mermaid':
return (
<MermaidDiagram
children={children as string}
/>
)
case 'language-chartjs':
let chartjsData = eval(`(${children as string})`)
return (
<Chart
{...chartjsData}
/>
)
case 'language-echart':
let echartData = eval(`(${children as string})`)
return (
<EChartsReact option={echartData}/>
)
default:
return (
<code {...rest} className={className}>
{children}
</code>
)
}
}
}}
/>
)
}
export default MarkdownRender

View File

@@ -1 +0,0 @@
/// <reference types="vite/client" />