diff options
Diffstat (limited to 'src/client/views')
| -rw-r--r-- | src/client/views/nodes/DiagramBox.scss | 0 | ||||
| -rw-r--r-- | src/client/views/nodes/DiagramBox.tsx | 145 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 2 |
3 files changed, 147 insertions, 0 deletions
diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/client/views/nodes/DiagramBox.scss diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx new file mode 100644 index 000000000..3b9e9d952 --- /dev/null +++ b/src/client/views/nodes/DiagramBox.tsx @@ -0,0 +1,145 @@ +import { makeObservable, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; +import { StyleProp } from '../StyleProvider'; +import './DiagramBox.scss'; +import { FieldView, FieldViewProps } from './FieldView'; +import { PinProps, PresBox } from './trails'; +import mermaid from 'mermaid'; +import { Doc, DocListCast } from '../../../fields/Doc'; +import { List } from '../../../fields/List'; +import { RichTextField } from '../../../fields/RichTextField'; + +@observer +export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface { + + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(DiagramBox, fieldKey); + } + constructor(props: FieldViewProps) { + super(props); + makeObservable(this); + //this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; + } + + componentDidMount() { + this._props.setContentViewBox?.(this); + mermaid.initialize({ + securityLevel: "loose", + startOnLoad: true, + flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, + }); + + const renderMermaid = async (str: string) => { + try { + const { svg, bindFunctions } = await mermaidDiagram(str); + return { svg, bindFunctions }; + } catch (error) { + console.error("Error rendering mermaid diagram:", error); + return { svg: "", bindFunctions: undefined }; + } + }; + const mermaidDiagram = async (str: string) => { + return await mermaid.render("graph" + Date.now(), str); + }; + renderMermaid(this.createMermaidCode()).then(({ svg, bindFunctions }) => { + const dashDiv = document.getElementById('dashDiv'); + if (dashDiv) { + dashDiv.innerHTML = svg; + if (bindFunctions) { + bindFunctions(dashDiv); + } + } + }); + } + createMermaidCode = (): string => { + let mermaidCode = 'graph LR;'; + if (this.Document.data instanceof List) { + let docArray: Doc[] = DocListCast(this.Document.data); + let rectangleArray = docArray.filter(doc => doc.title == 'rectangle'||doc.title=='circle'); + let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke'); + let textArray=docArray.filter(doc=>doc.type=='rich text') + for (let i = 0; i < rectangleArray.length; i++) { + const rectangle = rectangleArray[i]; + for (let j = 0; j < lineArray.length; j++) { + const line = lineArray[j]; + if(this.isLineInFirstBox(rectangle,line)){ + for (let k = 0; k < rectangleArray.length; k++) { + const rectangle2 = rectangleArray[k]; + if (this.isLineInSecondBox(rectangle2, line)&& + typeof rectangle.x === 'number' && + typeof rectangle2.x === 'number') { + mermaidCode += Math.abs(rectangle.x) +this.getTextInBox(rectangle,textArray) + '---' + Math.abs(rectangle2.x)+ this.getTextInBox(rectangle2,textArray)+ ';'; + } + } + } + } + } + } + console.log(mermaidCode); + return mermaidCode; + } + getTextInBox=(box: Doc,richTextArray: Doc[]):string=>{ + for(let i=0;i<richTextArray.length;i++){ + let textDoc=richTextArray[i] + if(typeof textDoc.x==='number'&& + typeof textDoc.y==='number'&& + typeof box.x==='number'&& + typeof box.height==='number'&& + typeof box.width==='number'&& + typeof box.y==='number'){ + if(textDoc.x>box.x&&textDoc.x<box.x+box.width&&textDoc.y>box.y&&textDoc.y<box.y+box.height){ + if(box.title=='rectangle'){ + return "("+(textDoc.text as RichTextField)?.Text+")" + } + if(box.title=='circle'){ + return "(("+(textDoc.text as RichTextField)?.Text+"))" + } + } + } + } + return "( )"; + } + isLineInFirstBox=(box: Doc,line: Doc):boolean=>{ + if( + typeof line.x === 'number' && + typeof box.x === 'number' && + typeof box.width === 'number' && + typeof box.height === 'number' && + typeof box.y === 'number' && + typeof line.y === 'number') { + return line.x < box.x + box.width + (box.width + box.x) * 0.1 && + line.x > box.x && + line.y > box.y && + line.y < box.y + box.height + } + else{ + return false; + } + } + isLineInSecondBox=(box:Doc,line:Doc):boolean=>{ + if ( + typeof line.x === 'number' && + typeof line.width === 'number' && + typeof box.x === 'number' && + typeof box.width === 'number' && + typeof box.y === 'number' && + typeof box.height === 'number' && + typeof line.y === 'number') { + return line.x + line.width > box.x - (box.x - box.width) * 0.1 && + line.x + line.width < box.x + box.width && + line.y > box.y && + line.y < box.y + box.height; + } + else{ + return false; + } + } + render() { + return ( + <div id="dashDiv"></div> + ); + } +} + diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index e729e2fa2..f32466b8c 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -23,6 +23,7 @@ import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo'; import { YoutubeBox } from './../../apis/youtube/YoutubeBox'; import { AudioBox } from './AudioBox'; import { ComparisonBox } from './ComparisonBox'; +import { DiagramBox } from './DiagramBox'; import { DataVizBox } from './DataVizBox/DataVizBox'; import './DocumentView.scss'; import { EquationBox } from './EquationBox'; @@ -264,6 +265,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte DataVizBox, HTMLtag, ComparisonBox, + DiagramBox, LoadingBox, PhysicsSimulationBox, SchemaRowBox, |
