Skip to content

Commit

Permalink
增加对echarts图表的支持 (#249)
Browse files Browse the repository at this point in the history
* 增加对echarts图表的支持

* 增加对echarts的支持
  • Loading branch information
stakeswky authored Sep 4, 2023
1 parent 5d596bd commit 32f482b
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 2 deletions.
2 changes: 1 addition & 1 deletion client/data/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@
"maxToken": 16000,
"price": 0
}
}
}
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
26 changes: 26 additions & 0 deletions client/src/components/Markdown/img/EChartsCodeBlock.tsx
Original file line number Diff line number Diff line change
@@ -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<EChartsCodeBlockProps> = ({ 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 ? <EChartsRenderer getOption={getOption} /> : null;
};

export default EChartsCodeBlock;
35 changes: 35 additions & 0 deletions client/src/components/Markdown/img/EChartsRenderer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useRef, useEffect } from 'react';
import { ECharts } from 'echarts';

interface EChartsRendererProps {
getOption: () => any;
}


const EChartsRenderer: React.FC<EChartsRendererProps> = ({ getOption }) => {
const chartRef = useRef<HTMLDivElement>(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 <div style={{ width: '100%', height: '400px', minWidth: '600px' }} ref={chartRef} />;
};

export default EChartsRenderer;
5 changes: 4 additions & 1 deletion client/src/components/Markdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 || '');
Expand All @@ -26,7 +27,9 @@ function Code({ inline, className, children }: any) {
if (codeType === 'guide') {
return <ChatGuide text={String(children)} />;
}

if (codeType === 'echarts') {
return <EChartsCodeBlock code={String(children)} />;
}
return (
<CodeLight className={className} inline={inline} match={match}>
{children}
Expand Down
4 changes: 4 additions & 0 deletions client/src/types/echarts-gl.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module 'echarts-gl' {
export default echarts-gl
}

0 comments on commit 32f482b

Please sign in to comment.