From 32f482b2327429746a9171eaae1af5a2c3da0c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E4=BA=86=E7=9D=A1=E5=A4=A7=E8=A7=89?= <64798754+stakeswky@users.noreply.github.com> Date: Mon, 4 Sep 2023 18:17:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9echarts=E5=9B=BE?= =?UTF-8?q?=E8=A1=A8=E7=9A=84=E6=94=AF=E6=8C=81=20(#249)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 增加对echarts图表的支持 * 增加对echarts的支持 --- client/data/config.json | 2 +- client/package.json | 1 + .../Markdown/img/EChartsCodeBlock.tsx | 26 ++++++++++++++ .../Markdown/img/EChartsRenderer.tsx | 35 +++++++++++++++++++ client/src/components/Markdown/index.tsx | 5 ++- client/src/types/echarts-gl.d.ts | 4 +++ 6 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 client/src/components/Markdown/img/EChartsCodeBlock.tsx create mode 100644 client/src/components/Markdown/img/EChartsRenderer.tsx create mode 100644 client/src/types/echarts-gl.d.ts diff --git a/client/data/config.json b/client/data/config.json index 2b6b5cd6e75..5bfd65fc15b 100644 --- a/client/data/config.json +++ b/client/data/config.json @@ -61,4 +61,4 @@ "maxToken": 16000, "price": 0 } -} +} \ No newline at end of file diff --git a/client/package.json b/client/package.json index 5a90764982b..6f0dea05f77 100644 --- a/client/package.json +++ b/client/package.json @@ -25,6 +25,7 @@ "date-fns": "^2.30.0", "dayjs": "^1.11.7", "echarts": "^5.4.1", + "echarts-gl": "^2.0.9", "formidable": "^2.1.1", "framer-motion": "^9.0.6", "hyperdown": "^2.4.29", diff --git a/client/src/components/Markdown/img/EChartsCodeBlock.tsx b/client/src/components/Markdown/img/EChartsCodeBlock.tsx new file mode 100644 index 00000000000..03274915327 --- /dev/null +++ b/client/src/components/Markdown/img/EChartsCodeBlock.tsx @@ -0,0 +1,26 @@ +// EChartsCodeBlock.tsx + +import React, { useMemo } from 'react'; +import EChartsRenderer from './EChartsRenderer'; +import * as echarts from 'echarts'; + + +interface EChartsCodeBlockProps { + code: string; +} + +const EChartsCodeBlock: React.FC = ({ code }) => { + const getOption = useMemo(() => { + try { + const optionFunction = new Function("echarts",'"use strict";' + code + '; return getChartOption;'); + return optionFunction(echarts); // 添加 echarts 参数 + } catch (error) { + console.error('Error parsing ECharts code:', '\n', error, '\n', 'Code:', code); + return null; + } + }, [code]); + + return getOption ? : null; +}; + +export default EChartsCodeBlock; diff --git a/client/src/components/Markdown/img/EChartsRenderer.tsx b/client/src/components/Markdown/img/EChartsRenderer.tsx new file mode 100644 index 00000000000..ff7a5c443a8 --- /dev/null +++ b/client/src/components/Markdown/img/EChartsRenderer.tsx @@ -0,0 +1,35 @@ +import React, { useRef, useEffect } from 'react'; +import { ECharts } from 'echarts'; + +interface EChartsRendererProps { + getOption: () => any; +} + + +const EChartsRenderer: React.FC = ({ getOption }) => { + const chartRef = useRef(null); + + useEffect(() => { + let chartInstance: ECharts | null = null; + + (async () => { + const echarts = await import('echarts'); + await import('echarts-gl'); + if (chartRef.current) { + chartInstance = echarts.init(chartRef.current, { renderer: 'svg', ssr: true }); + const option = getOption(); + chartInstance.setOption(option); + } + })(); + + return () => { + if (chartInstance) { + chartInstance.dispose(); + } + }; + }, [getOption]); + + return
; +}; + +export default EChartsRenderer; diff --git a/client/src/components/Markdown/index.tsx b/client/src/components/Markdown/index.tsx index 523b10d0adf..a2b4813358e 100644 --- a/client/src/components/Markdown/index.tsx +++ b/client/src/components/Markdown/index.tsx @@ -14,6 +14,7 @@ import CodeLight from './CodeLight'; const MermaidCodeBlock = dynamic(() => import('./img/MermaidCodeBlock')); const MdImage = dynamic(() => import('./img/Image')); const ChatGuide = dynamic(() => import('./chat/Guide')); +const EChartsCodeBlock = dynamic(() => import('./img/EChartsCodeBlock')); function Code({ inline, className, children }: any) { const match = /language-(\w+)/.exec(className || ''); @@ -26,7 +27,9 @@ function Code({ inline, className, children }: any) { if (codeType === 'guide') { return ; } - + if (codeType === 'echarts') { + return ; + } return ( {children} diff --git a/client/src/types/echarts-gl.d.ts b/client/src/types/echarts-gl.d.ts new file mode 100644 index 00000000000..2ec17990fcd --- /dev/null +++ b/client/src/types/echarts-gl.d.ts @@ -0,0 +1,4 @@ +declare module 'echarts-gl' { + export default echarts-gl + } +