| import React, { useEffect, useRef, useState } from 'react' | import React, { useEffect, useRef, useState } from 'react' | ||||
| import mermaid from 'mermaid' | import mermaid from 'mermaid' | ||||
| import { t } from 'i18next' | |||||
| import CryptoJS from 'crypto-js' | import CryptoJS from 'crypto-js' | ||||
| let mermaidAPI: any | let mermaidAPI: any | ||||
| const chartId = useRef(`flowchart_${CryptoJS.MD5(props.PrimitiveCode).toString()}`) | const chartId = useRef(`flowchart_${CryptoJS.MD5(props.PrimitiveCode).toString()}`) | ||||
| const [isRender, setIsRender] = useState(true) | const [isRender, setIsRender] = useState(true) | ||||
| const clearFlowchartCache = () => { | |||||
| for (let i = localStorage.length - 1; i >= 0; --i) { | |||||
| const key = localStorage.key(i) | |||||
| if (key && key.startsWith('flowchart_')) | |||||
| localStorage.removeItem(key) | |||||
| } | |||||
| } | |||||
| const renderFlowchart = async (PrimitiveCode: string) => { | const renderFlowchart = async (PrimitiveCode: string) => { | ||||
| try { | try { | ||||
| const cachedSvg: any = localStorage.getItem(chartId.current) | const cachedSvg: any = localStorage.getItem(chartId.current) | ||||
| const svgGraph = await mermaidAPI.render(chartId.current, PrimitiveCode) | const svgGraph = await mermaidAPI.render(chartId.current, PrimitiveCode) | ||||
| // eslint-disable-next-line @typescript-eslint/no-use-before-define | // eslint-disable-next-line @typescript-eslint/no-use-before-define | ||||
| const base64Svg: any = await svgToBase64(svgGraph.svg) | const base64Svg: any = await svgToBase64(svgGraph.svg) | ||||
| localStorage.setItem(chartId.current, base64Svg) | |||||
| setSvgCode(base64Svg) | setSvgCode(base64Svg) | ||||
| if (chartId.current && base64Svg) | |||||
| localStorage.setItem(chartId.current, base64Svg) | |||||
| } | } | ||||
| } | } | ||||
| catch (error) { | catch (error) { | ||||
| localStorage.clear() | |||||
| // eslint-disable-next-line @typescript-eslint/ban-ts-comment | |||||
| // @ts-expect-error | |||||
| console.error(error.toString()) | |||||
| clearFlowchartCache() | |||||
| // eslint-disable-next-line @typescript-eslint/no-use-before-define | |||||
| handleReRender() | |||||
| } | } | ||||
| } | } | ||||
| const handleReRender = () => { | const handleReRender = () => { | ||||
| setIsRender(false) | setIsRender(false) | ||||
| setSvgCode(null) | setSvgCode(null) | ||||
| localStorage.removeItem(chartId.current) | |||||
| if (chartId.current) | |||||
| localStorage.removeItem(chartId.current) | |||||
| setTimeout(() => { | setTimeout(() => { | ||||
| setIsRender(true) | setIsRender(true) | ||||
| renderFlowchart(props.PrimitiveCode) | renderFlowchart(props.PrimitiveCode) | ||||
| // @ts-expect-error | // @ts-expect-error | ||||
| <div ref={ref}> | <div ref={ref}> | ||||
| { | { | ||||
| isRender && <div id={chartId.current} className="mermaid" style={style}>{svgCode && (<img src={svgCode} style={{ width: '100%', height: 'auto' }} alt="Mermaid chart" />)}</div> | |||||
| isRender | |||||
| && <div id={chartId.current} className="mermaid" style={style}> | |||||
| {svgCode && <img src={svgCode} style={{ width: '100%', height: 'auto' }} alt="Mermaid chart" />} | |||||
| </div> | |||||
| } | } | ||||
| <button onClick={handleReRender}>{t('appApi.merMaind.rerender')}</button> | |||||
| </div> | </div> | ||||
| ) | ) | ||||
| }) | }) |