mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-01 11:58:38 +00:00
@@ -1,62 +1,89 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import * as echarts from 'echarts';
|
||||
import type { ECharts } from 'echarts';
|
||||
import { Box, Skeleton } from '@chakra-ui/react';
|
||||
import json5 from 'json5';
|
||||
import { useMount } from 'ahooks';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { useScreen } from '@fastgpt/web/hooks/useScreen';
|
||||
|
||||
const EChartsCodeBlock = ({ code }: { code: string }) => {
|
||||
const chartRef = useRef<HTMLDivElement>(null);
|
||||
const eChart = useRef<ECharts>();
|
||||
const { isPc } = useSystem();
|
||||
const [option, setOption] = useState<any>();
|
||||
const [width, setWidth] = useState(400);
|
||||
|
||||
useEffect(() => {
|
||||
const clientWidth = document.getElementById('chat-container')?.clientWidth || 500;
|
||||
setWidth(clientWidth * 0.9);
|
||||
setTimeout(() => {
|
||||
eChart.current?.resize();
|
||||
}, 100);
|
||||
}, []);
|
||||
const findMarkdownDom = useCallback(() => {
|
||||
if (!chartRef.current) return;
|
||||
|
||||
useEffect(() => {
|
||||
let option;
|
||||
try {
|
||||
option = JSON.parse(code.trim());
|
||||
option = {
|
||||
...option,
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
saveAsImage: {}
|
||||
// 一直找到 parent = markdown 的元素
|
||||
let parent = chartRef.current?.parentElement;
|
||||
while (parent && !parent.className.includes('chat-box-card')) {
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
|
||||
const ChatItemDom = parent?.parentElement;
|
||||
const clientWidth = ChatItemDom?.clientWidth ? ChatItemDom.clientWidth - (isPc ? 90 : 60) : 500;
|
||||
setWidth(clientWidth);
|
||||
return parent?.parentElement;
|
||||
}, [isPc]);
|
||||
|
||||
useMount(() => {
|
||||
// @ts-ignore
|
||||
import('echarts-gl');
|
||||
});
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const option = (() => {
|
||||
try {
|
||||
const parse = {
|
||||
...json5.parse(code.trim()),
|
||||
toolbox: {
|
||||
// show: true,
|
||||
feature: {
|
||||
saveAsImage: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
setOption(option);
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
return parse;
|
||||
} catch (error) {}
|
||||
})();
|
||||
|
||||
setOption(option ?? {});
|
||||
|
||||
if (!option) return;
|
||||
|
||||
(async () => {
|
||||
// @ts-ignore
|
||||
await import('echarts-gl');
|
||||
})();
|
||||
|
||||
if (chartRef.current) {
|
||||
eChart.current = echarts.init(chartRef.current);
|
||||
eChart.current.setOption(option);
|
||||
eChart.current?.resize();
|
||||
}
|
||||
|
||||
findMarkdownDom();
|
||||
|
||||
return () => {
|
||||
if (eChart.current) {
|
||||
eChart.current.dispose();
|
||||
}
|
||||
};
|
||||
}, [code]);
|
||||
}, [code, findMarkdownDom]);
|
||||
|
||||
const { screenWidth } = useScreen();
|
||||
useEffect(() => {
|
||||
findMarkdownDom();
|
||||
}, [screenWidth]);
|
||||
|
||||
useEffect(() => {
|
||||
eChart.current?.resize();
|
||||
}, [width]);
|
||||
|
||||
return (
|
||||
<Box overflowX={'auto'}>
|
||||
<Box h={'400px'} minW={'400px'} w={`${width}px`} ref={chartRef} />
|
||||
{!option && <Skeleton isLoaded={true} fadeDuration={2} h={'400px'} w={`400px`}></Skeleton>}
|
||||
<Box overflowX={'auto'} bg={'white'} borderRadius={'md'}>
|
||||
<Box h={'400px'} w={`${width}px`} ref={chartRef} />
|
||||
{!option && (
|
||||
<Skeleton isLoaded={true} fadeDuration={2} h={'400px'} w={`${width}px`}></Skeleton>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@@ -139,9 +139,8 @@ const ChatItem = ({
|
||||
)}
|
||||
</Flex>
|
||||
{/* content */}
|
||||
<Box mt={['6px', 2]} textAlign={styleMap.textAlign}>
|
||||
<Box mt={['6px', 2]} className="chat-box-card" textAlign={styleMap.textAlign}>
|
||||
<Card
|
||||
className="markdown"
|
||||
{...MessageCardStyle}
|
||||
bg={styleMap.bg}
|
||||
borderRadius={styleMap.borderRadius}
|
||||
|
Reference in New Issue
Block a user