From ed5a7755eba7563c01bc3cc40840d0ebb6cd8826 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Wed, 6 Mar 2024 19:46:09 -0500 Subject: add diagram document --- src/client/views/nodes/DiagramBox.tsx | 86 +++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/client/views/nodes/DiagramBox.tsx (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx new file mode 100644 index 000000000..e2af0b670 --- /dev/null +++ b/src/client/views/nodes/DiagramBox.tsx @@ -0,0 +1,86 @@ +import { action, computed, makeObservable, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { emptyFunction, setupMoveUpEvents } from '../../../Utils'; +import { Doc, Opt } from '../../../fields/Doc'; +import { DocCast, NumCast, StrCast } from '../../../fields/Types'; +import { Docs } from '../../documents/Documents'; +import { DragManager } from '../../util/DragManager'; +import { undoBatch } from '../../util/UndoManager'; +import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; +import { StyleProp } from '../StyleProvider'; +import './ComparisonBox.scss'; +import { FieldView, FieldViewProps } from './FieldView'; +import { PinProps, PresBox } from './trails'; +import mermaid from 'mermaid'; + +interface MermaidProps { + chart: String; + } + +class Mermaid extends React.Component { + componentDidMount() { + mermaid.contentLoaded(); + } + render() { + return
{this.props.chart}
; + } + } + +@observer +export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { + + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(DiagramBox, fieldKey); + } + constructor(props: FieldViewProps) { + super(props); + makeObservable(this); + mermaid.initialize({ startOnLoad: true }); + } + + @observable _animating = ''; + + @computed get clipWidth() { + return NumCast(this.layoutDoc[this.clipWidthKey], 50); + } + get clipWidthKey() { + return '_' + this._props.fieldKey + '_clipWidth'; + } + + componentDidMount() { + this._props.setContentViewBox?.(this); + } + getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { + const anchor = Docs.Create.ConfigDocument({ + title: 'CompareAnchor:' + this.Document.title, + // set presentation timing properties for restoring view + presentation_transition: 1000, + annotationOn: this.Document, + }); + if (anchor) { + if (!addAsAnnotation) anchor.backgroundColor = 'transparent'; + /* addAsAnnotation &&*/ this.addDocument(anchor); + PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), clippable: true } }, this.Document); + return anchor; + } + return this.Document; + }; + docStyleProvider = (doc: Opt, props: Opt, property: string): any => { + if (property === StyleProp.PointerEvents) return 'none'; + return this._props.styleProvider?.(doc, props, property); + }; + _closeRef = React.createRef(); + render() { + return ( +
+ B; + B-->C; + B-->D[hi]; + `}/> +
+ ); + } +} -- cgit v1.2.3-70-g09d2 From ec89fe170a810c0a83b9347ec9f024e0ff9c2568 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Sun, 10 Mar 2024 13:10:43 -0400 Subject: test --- src/client/documents/Documents.ts | 1 + src/client/util/CurrentUserUtils.ts | 5 +- src/client/views/nodes/DiagramBox.tsx | 88 ++++++++++++++++------------------- 3 files changed, 45 insertions(+), 49 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ade5e718c..a6e229ba7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -252,6 +252,7 @@ export class DocumentOptions { layout_hideLinkButton?: BOOLt = new BoolInfo('whether the blue link counter button should be hidden'); layout_hideDecorationTitle?: BOOLt = new BoolInfo('whether to suppress the document decortations title when selected'); _layout_hideContextMenu?: BOOLt = new BoolInfo('whether the context menu can be shown'); + layout_diagramEditor?: STRt = new StrInfo("specify the JSX string for a diagram editor view") layout_borderRounding?: string; _layout_modificationDate?: DATEt = new DateInfo('last modification date of doc layout', false); _layout_nativeDimEditable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 8275ec6b8..0279ca2c4 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -31,6 +31,7 @@ import { ScriptingGlobals } from "./ScriptingGlobals"; import { ColorScheme } from "./SettingsManager"; import { SnappingManager } from "./SnappingManager"; import { UndoManager } from "./UndoManager"; +import { CollectionView } from "../views/collections/CollectionView"; interface Button { // DocumentOptions fields a button can set @@ -248,7 +249,7 @@ export class CurrentUserUtils { {key: "Collection", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 150, _height: 100, _layout_fitWidth: true }}, {key: "Webpage", creator: opts => Docs.Create.WebDocument("",opts), opts: { _width: 400, _height: 512, _nativeWidth: 850, data_useCors: true, }}, {key: "Comparison", creator: Docs.Create.ComparisonDocument, opts: { _width: 300, _height: 300 }}, - {key: "Diagram", creator: Docs.Create.DiagramDocument, opts: { _width: 300, _height: 300 }}, + {key: "Diagram", creator: Docs.Create.DiagramDocument, opts: { _width: 300, _height: 300, _type_collection: CollectionViewType.Freeform, layout_diagramEditor: CollectionView.LayoutString("data") }, scripts: { onPaint: `toggleDetail(documentView, "diagramEditor","")`}}, {key: "Audio", creator: opts => Docs.Create.AudioDocument(nullAudio, opts),opts: { _width: 200, _height: 100, }}, {key: "Map", creator: opts => Docs.Create.MapDocument([], opts), opts: { _width: 800, _height: 600, _layout_fitWidth: true, }}, {key: "Screengrab", creator: Docs.Create.ScreenshotDocument, opts: { _width: 400, _height: 200 }}, @@ -281,7 +282,7 @@ export class CurrentUserUtils { { toolTip: "Tap or drag to create a collection", title: "Col", icon: "folder", dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)}, { toolTip: "Tap or drag to create a webpage", title: "Web", icon: "globe-asia", dragFactory: doc.emptyWebpage as Doc, clickFactory: DocCast(doc.emptyWebpage)}, { toolTip: "Tap or drag to create a comparison box", title: "Compare", icon: "columns", dragFactory: doc.emptyComparison as Doc, clickFactory: DocCast(doc.emptyComparison)}, - { toolTip: "Tap or drag to create a diagram", title: "Diagram", icon: "circle", dragFactory: doc.emptyDiagram as Doc, clickFactory: DocCast(doc.emptyDiagram)}, + { toolTip: "Tap or drag to create a diagram", title: "Diagram", icon: "tree", dragFactory: doc.emptyDiagram as Doc, clickFactory: DocCast(doc.emptyDiagram)}, { toolTip: "Tap or drag to create an audio recorder", title: "Audio", icon: "microphone", dragFactory: doc.emptyAudio as Doc, clickFactory: DocCast(doc.emptyAudio), openFactoryLocation: OpenWhere.overlay}, { toolTip: "Tap or drag to create a map", title: "Map", icon: "map-marker-alt", dragFactory: doc.emptyMap as Doc, clickFactory: DocCast(doc.emptyMap)}, { toolTip: "Tap or drag to create a screen grabber", title: "Grab", icon: "photo-video", dragFactory: doc.emptyScreengrab as Doc, clickFactory: DocCast(doc.emptyScreengrab), openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}}, diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index e2af0b670..376dff15d 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,85 +1,79 @@ -import { action, computed, makeObservable, observable } from 'mobx'; +import { makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { emptyFunction, setupMoveUpEvents } from '../../../Utils'; -import { Doc, Opt } from '../../../fields/Doc'; -import { DocCast, NumCast, StrCast } from '../../../fields/Types'; -import { Docs } from '../../documents/Documents'; -import { DragManager } from '../../util/DragManager'; -import { undoBatch } from '../../util/UndoManager'; import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; import './ComparisonBox.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'; interface MermaidProps { - chart: String; - } + chart: String; +} class Mermaid extends React.Component { componentDidMount() { - mermaid.contentLoaded(); + mermaid.contentLoaded(); } render() { - return
{this.props.chart}
; + return
{this.props.chart}
; } - } +} @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { - + @observable chartContent: string = ''; + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DiagramBox, fieldKey); } constructor(props: FieldViewProps) { super(props); makeObservable(this); - mermaid.initialize({ startOnLoad: true }); + //this.createMermaidCode(); + this.chartContent = 'graph LR;A-->B;B-->C; B-->D[hello];'; } - @observable _animating = ''; - - @computed get clipWidth() { - return NumCast(this.layoutDoc[this.clipWidthKey], 50); - } - get clipWidthKey() { - return '_' + this._props.fieldKey + '_clipWidth'; - } - componentDidMount() { this._props.setContentViewBox?.(this); + mermaid.initialize({ startOnLoad: true }); } - getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { - const anchor = Docs.Create.ConfigDocument({ - title: 'CompareAnchor:' + this.Document.title, - // set presentation timing properties for restoring view - presentation_transition: 1000, - annotationOn: this.Document, - }); - if (anchor) { - if (!addAsAnnotation) anchor.backgroundColor = 'transparent'; - /* addAsAnnotation &&*/ this.addDocument(anchor); - PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), clippable: true } }, this.Document); - return anchor; + createMermaidCode = (): void => { + if (this.Document.data instanceof List) { + let docArray: Doc[] = DocListCast(this.Document.data); + let mermaidCode = 'graph LR;'; + docArray.map(doc => { + if (doc.title == 'rectangle') { + DocListCast(this.Document.data).map(lineDoc => { + if ((lineDoc.title == 'stroke' || lineDoc.title == 'line') && typeof lineDoc.x === 'number' && typeof doc.x === 'number' && typeof doc.width === 'number'&& typeof doc.height === 'number'&& typeof doc.y === 'number'&& typeof lineDoc.y === 'number') { + if (lineDoc.x < doc.x + doc.width + (doc.width + doc.x) * 0.1 && lineDoc.x > doc.x&&lineDoc.y>doc.y&&lineDoc.y { + if (doc2.title == 'rectangle' && typeof lineDoc.x === 'number' && typeof lineDoc.width === 'number' && typeof doc2.x === 'number' && typeof doc2.width === 'number'&& typeof doc2.y === 'number'&& typeof doc2.height === 'number'&& typeof lineDoc.y === 'number') { + if (lineDoc.x + lineDoc.width > doc2.x - (doc2.x - doc2.width) * 0.1 && lineDoc.x + lineDoc.width < doc2.x + doc2.width &&lineDoc.y>doc2.y&&lineDoc.y' + doc2.title + Math.floor(doc2.x).toString() + ';'; + const indexToRemove = docArray.findIndex(doc => doc === lineDoc); + if (indexToRemove !== -1) { + docArray.splice(indexToRemove, 1); + } + } + } + }); + } + } + }); + } + this.chartContent = mermaidCode; + }); } - return this.Document; - }; - docStyleProvider = (doc: Opt, props: Opt, property: string): any => { - if (property === StyleProp.PointerEvents) return 'none'; - return this._props.styleProvider?.(doc, props, property); }; - _closeRef = React.createRef(); render() { + console.log(this.chartContent) return (
- B; - B-->C; - B-->D[hi]; - `}/> +
); } -- cgit v1.2.3-70-g09d2 From 84e75f944a45c3b98ec70c75d2abc47051b10b03 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Tue, 12 Mar 2024 16:28:39 -0400 Subject: test --- src/client/views/nodes/DiagramBox.tsx | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 376dff15d..9ff2d27d2 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -48,11 +48,35 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im docArray.map(doc => { if (doc.title == 'rectangle') { DocListCast(this.Document.data).map(lineDoc => { - if ((lineDoc.title == 'stroke' || lineDoc.title == 'line') && typeof lineDoc.x === 'number' && typeof doc.x === 'number' && typeof doc.width === 'number'&& typeof doc.height === 'number'&& typeof doc.y === 'number'&& typeof lineDoc.y === 'number') { - if (lineDoc.x < doc.x + doc.width + (doc.width + doc.x) * 0.1 && lineDoc.x > doc.x&&lineDoc.y>doc.y&&lineDoc.y doc.x && lineDoc.y > doc.y && lineDoc.y < doc.y + doc.height) { DocListCast(this.Document.data).map(doc2 => { - if (doc2.title == 'rectangle' && typeof lineDoc.x === 'number' && typeof lineDoc.width === 'number' && typeof doc2.x === 'number' && typeof doc2.width === 'number'&& typeof doc2.y === 'number'&& typeof doc2.height === 'number'&& typeof lineDoc.y === 'number') { - if (lineDoc.x + lineDoc.width > doc2.x - (doc2.x - doc2.width) * 0.1 && lineDoc.x + lineDoc.width < doc2.x + doc2.width &&lineDoc.y>doc2.y&&lineDoc.y doc2.x - (doc2.x - doc2.width) * 0.1 && + lineDoc.x + lineDoc.width < doc2.x + doc2.width && + lineDoc.y > doc2.y && + lineDoc.y < doc2.y + doc2.height && + typeof doc.x === 'number' && + typeof doc.width === 'number' + ) { mermaidCode += doc.title + Math.floor(doc.x).toString() + '-->' + doc2.title + Math.floor(doc2.x).toString() + ';'; const indexToRemove = docArray.findIndex(doc => doc === lineDoc); if (indexToRemove !== -1) { @@ -70,7 +94,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } }; render() { - console.log(this.chartContent) + console.log(this.ScreenToLocalBoxXf().scale(2)); return (
-- cgit v1.2.3-70-g09d2 From 2ca4e70cd030fb9199d149060adf1b1d7c07857c Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Tue, 12 Mar 2024 16:40:40 -0400 Subject: fix --- src/client/documents/Documents.ts | 1 + src/client/util/CurrentUserUtils.ts | 2 ++ src/client/views/nodes/DiagramBox.scss | 3 +++ src/client/views/nodes/DiagramBox.tsx | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 src/client/views/nodes/DiagramBox.scss (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 2f177b62a..96f4e4597 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -276,6 +276,7 @@ export class DocumentOptions { layout_hideDecorationTitle?: BOOLt = new BoolInfo('whether to suppress the document decortations title when selected'); _layout_hideContextMenu?: BOOLt = new BoolInfo('whether the context menu can be shown'); layout_diagramEditor?: STRt = new StrInfo("specify the JSX string for a diagram editor view") + layout_hideContextMenu?: BOOLt = new BoolInfo('whether the context menu can be shown'); layout_borderRounding?: string; _layout_modificationDate?: DATEt = new DateInfo('last modification date of doc layout', false); _layout_nativeDimEditable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index a41fd8796..18b37ffd1 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -33,6 +33,8 @@ import { ColorScheme } from "./SettingsManager"; import { SnappingManager } from "./SnappingManager"; import { UndoManager } from "./UndoManager"; import { CollectionView } from "../views/collections/CollectionView"; +import { LabelBox } from "../views/nodes/LabelBox"; +import { ImageBox } from "../views/nodes/ImageBox"; interface Button { // DocumentOptions fields a button can set diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss new file mode 100644 index 000000000..50d9a6573 --- /dev/null +++ b/src/client/views/nodes/DiagramBox.scss @@ -0,0 +1,3 @@ +.mermaid{ + width:100%; +} \ No newline at end of file diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 9ff2d27d2..e162360f8 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -3,7 +3,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; -import './ComparisonBox.scss'; +import './DiagramBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; import { PinProps, PresBox } from './trails'; import mermaid from 'mermaid'; -- cgit v1.2.3-70-g09d2 From 868668efbdbfaa50c0203d133cd2401e65ec5281 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Sun, 17 Mar 2024 12:50:32 -0400 Subject: fix bug with mermaid diagram changing scale on zoom --- package-lock.json | 3 ++- src/client/views/nodes/DiagramBox.scss | 12 ++++++++--- src/client/views/nodes/DiagramBox.tsx | 39 ++++++++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 10 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/package-lock.json b/package-lock.json index 7b86365c2..253356c07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32257,7 +32257,8 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/textarea-caret": { "version": "3.1.0", diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss index 50d9a6573..9ceac15df 100644 --- a/src/client/views/nodes/DiagramBox.scss +++ b/src/client/views/nodes/DiagramBox.scss @@ -1,3 +1,9 @@ -.mermaid{ - width:100%; -} \ No newline at end of file +.mermaid { + svg { + g { + g{ + + } + } + } +} diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index e162360f8..a2fb7e2c8 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -34,12 +34,41 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im super(props); makeObservable(this); //this.createMermaidCode(); - this.chartContent = 'graph LR;A-->B;B-->C; B-->D[hello];'; + this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; } componentDidMount() { this._props.setContentViewBox?.(this); - mermaid.initialize({ startOnLoad: true }); + // (window as any)["callb"] = (x: any) => { + // alert(x); + // }; + mermaid.initialize({ + securityLevel: "loose", + startOnLoad: true, + flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, + }); + + const renderMermaid = async (str: string) => { + try { + const { svg, bindFunctions } = await mermaid2(str); + return { svg, bindFunctions }; + } catch (error) { + console.error("Error rendering mermaid diagram:", error); + return { svg: "", bindFunctions: undefined }; + } + }; + const mermaid2 = async (str: string) => { + return await mermaid.render("graph" + Date.now(), str); + }; + renderMermaid(this.chartContent).then(({ svg, bindFunctions }) => { + const dashDiv = document.getElementById('dashDiv'); + if (dashDiv) { + dashDiv.innerHTML = svg; + if (bindFunctions) { + bindFunctions(dashDiv); + } + } + }); } createMermaidCode = (): void => { if (this.Document.data instanceof List) { @@ -94,11 +123,9 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } }; render() { - console.log(this.ScreenToLocalBoxXf().scale(2)); + console.log(this.ScreenToLocalBoxXf().Scale); return ( -
- -
+
); } } -- cgit v1.2.3-70-g09d2 From dc0ee4595e37042db3adf60b002d7baf77cb24ae Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Tue, 2 Apr 2024 16:34:11 -0400 Subject: test --- src/client/views/nodes/DiagramBox.scss | 9 -- src/client/views/nodes/DiagramBox.tsx | 152 ++++++++++++++++++--------------- 2 files changed, 83 insertions(+), 78 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss index 9ceac15df..e69de29bb 100644 --- a/src/client/views/nodes/DiagramBox.scss +++ b/src/client/views/nodes/DiagramBox.scss @@ -1,9 +0,0 @@ -.mermaid { - svg { - g { - g{ - - } - } - } -} diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index a2fb7e2c8..3b9e9d952 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -9,23 +9,10 @@ import { PinProps, PresBox } from './trails'; import mermaid from 'mermaid'; import { Doc, DocListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; - -interface MermaidProps { - chart: String; -} - -class Mermaid extends React.Component { - componentDidMount() { - mermaid.contentLoaded(); - } - render() { - return
{this.props.chart}
; - } -} +import { RichTextField } from '../../../fields/RichTextField'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { - @observable chartContent: string = ''; public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DiagramBox, fieldKey); @@ -33,15 +20,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im constructor(props: FieldViewProps) { super(props); makeObservable(this); - //this.createMermaidCode(); - this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; + //this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; } componentDidMount() { this._props.setContentViewBox?.(this); - // (window as any)["callb"] = (x: any) => { - // alert(x); - // }; mermaid.initialize({ securityLevel: "loose", startOnLoad: true, @@ -50,17 +33,17 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im const renderMermaid = async (str: string) => { try { - const { svg, bindFunctions } = await mermaid2(str); + const { svg, bindFunctions } = await mermaidDiagram(str); return { svg, bindFunctions }; } catch (error) { console.error("Error rendering mermaid diagram:", error); return { svg: "", bindFunctions: undefined }; } }; - const mermaid2 = async (str: string) => { + const mermaidDiagram = async (str: string) => { return await mermaid.render("graph" + Date.now(), str); }; - renderMermaid(this.chartContent).then(({ svg, bindFunctions }) => { + renderMermaid(this.createMermaidCode()).then(({ svg, bindFunctions }) => { const dashDiv = document.getElementById('dashDiv'); if (dashDiv) { dashDiv.innerHTML = svg; @@ -70,62 +53,93 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } }); } - createMermaidCode = (): void => { + createMermaidCode = (): string => { + let mermaidCode = 'graph LR;'; if (this.Document.data instanceof List) { let docArray: Doc[] = DocListCast(this.Document.data); - let mermaidCode = 'graph LR;'; - docArray.map(doc => { - if (doc.title == 'rectangle') { - DocListCast(this.Document.data).map(lineDoc => { - if ( - (lineDoc.title == 'stroke' || lineDoc.title == 'line') && - typeof lineDoc.x === 'number' && - typeof doc.x === 'number' && - typeof doc.width === 'number' && - typeof doc.height === 'number' && - typeof doc.y === 'number' && - typeof lineDoc.y === 'number' - ) { - if (lineDoc.x < doc.x + doc.width + (doc.width + doc.x) * 0.1 && lineDoc.x > doc.x && lineDoc.y > doc.y && lineDoc.y < doc.y + doc.height) { - DocListCast(this.Document.data).map(doc2 => { - if ( - doc2.title == 'rectangle' && - typeof lineDoc.x === 'number' && - typeof lineDoc.width === 'number' && - typeof doc2.x === 'number' && - typeof doc2.width === 'number' && - typeof doc2.y === 'number' && - typeof doc2.height === 'number' && - typeof lineDoc.y === 'number' - ) { - if ( - lineDoc.x + lineDoc.width > doc2.x - (doc2.x - doc2.width) * 0.1 && - lineDoc.x + lineDoc.width < doc2.x + doc2.width && - lineDoc.y > doc2.y && - lineDoc.y < doc2.y + doc2.height && - typeof doc.x === 'number' && - typeof doc.width === 'number' - ) { - mermaidCode += doc.title + Math.floor(doc.x).toString() + '-->' + doc2.title + Math.floor(doc2.x).toString() + ';'; - const indexToRemove = docArray.findIndex(doc => doc === lineDoc); - if (indexToRemove !== -1) { - docArray.splice(indexToRemove, 1); - } - } - } - }); + 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)+ ';'; } } - }); + } } - this.chartContent = mermaidCode; - }); + } } - }; + console.log(mermaidCode); + return mermaidCode; + } + getTextInBox=(box: Doc,richTextArray: Doc[]):string=>{ + for(let i=0;ibox.x&&textDoc.xbox.y&&textDoc.y{ + 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() { - console.log(this.ScreenToLocalBoxXf().Scale); return (
); } } + -- cgit v1.2.3-70-g09d2 From 1809abeb1cb837ef9d43d19b7cf286b33ad8789d Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Thu, 4 Apr 2024 13:47:40 -0400 Subject: add ai mermaids --- src/client/apis/gpt/GPT.ts | 6 +- src/client/views/nodes/DiagramBox.tsx | 207 ++++++++++++++++++++-------------- 2 files changed, 128 insertions(+), 85 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index fb51278ae..49c56f04e 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -4,6 +4,7 @@ enum GPTCallType { SUMMARY = 'summary', COMPLETION = 'completion', EDIT = 'edit', + MERMAID='mermaid' } type GPTCallOpts = { @@ -17,8 +18,10 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { summary: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Summarize this text in simpler terms: ' }, edit: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Reword this: ' }, completion: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: '' }, + mermaid:{model:'gpt-3.5-turbo-instruct',maxTokens:256,temp:0,prompt:"Write this in mermaid code (keep in note thatPut this at the end of the code to add colors heres an example and be very care about the order:pie title Example Pie Chart \"Red\" : 25 \"Blue\" : 75%%{init: {'theme': 'base', 'themeVariables': { 'pie1': '#0000FF', 'pie2': '#FF0000'}}}%%): "} }; + /** * Calls the OpenAI API. * @@ -30,7 +33,7 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => { const opts: GPTCallOpts = callTypeMap[callType]; try { const configuration: ClientOptions = { - apiKey: process.env.OPENAI_KEY, + apiKey: "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", dangerouslyAllowBrowser: true, }; const openai = new OpenAI(configuration); @@ -39,6 +42,7 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => { max_tokens: opts.maxTokens, temperature: opts.temp, prompt: `${opts.prompt}${inputText}`, + }); return response.choices[0].text; } catch (err) { diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 3b9e9d952..64d0d6d78 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,4 +1,4 @@ -import { makeObservable, observable } from 'mobx'; +import { makeObservable, observable, action } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; @@ -10,10 +10,11 @@ import mermaid from 'mermaid'; import { Doc, DocListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { RichTextField } from '../../../fields/RichTextField'; +import { ContextMenu } from '../ContextMenu'; +import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DiagramBox, fieldKey); } @@ -26,7 +27,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im componentDidMount() { this._props.setContentViewBox?.(this); mermaid.initialize({ - securityLevel: "loose", + securityLevel: 'loose', startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); @@ -36,110 +37,148 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im const { svg, bindFunctions } = await mermaidDiagram(str); return { svg, bindFunctions }; } catch (error) { - console.error("Error rendering mermaid diagram:", error); - return { svg: "", bindFunctions: undefined }; + console.error('Error rendering mermaid diagram:', error); + return { svg: '', bindFunctions: undefined }; } }; const mermaidDiagram = async (str: string) => { - return await mermaid.render("graph" + Date.now(), str); + 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); + async function renderMermaidAsync(this: DiagramBox) { + try { + const mermaidCode: string = await this.createMermaidCode(); + const { svg, bindFunctions } = await renderMermaid(mermaidCode); + const dashDiv = document.getElementById('dashDiv'); + if (dashDiv) { + dashDiv.innerHTML = svg; + if (bindFunctions) { + bindFunctions(dashDiv); + } } + } catch (error) { + console.error('Error rendering Mermaid:', error); } - }); + } + + renderMermaidAsync.call(this); } - 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)+ ';'; + + askGPT = async (): Promise => { + try { + let notes = 'mermaid syntax for pie charts do not include %'; + let text = notes + (DocListCast(this.Document.data)[0].text as RichTextField)?.Text; + if (!text) { + console.error('Text extraction failed'); + return; + } + + let res = await gptAPICall(text, GPTCallType.MERMAID); + if (!res) { + console.error('GPT call failed'); + return; + } else { + console.log(res) + return this.removeWords(res); + } + } catch (err) { + console.error('Error:', err); + return; + } + }; + + removeWords(inputStr:string) { + let presetArray=["pie","flowchart","diagramChart","graph TD","flowchart TD","flowchart LR","graph LR"] + const lines = inputStr.split('\n'); + let foundPresetWord = false; + let result = ''; + + for (const line of lines) { + if (!foundPresetWord) { + for (const word of presetArray) { + if (line.toLowerCase().includes(word.toLowerCase())) { + foundPresetWord = true; + result += line + '\n'; + break; + } + } + } else { + result += line + '\n'; + } + } + + return result; + } + + createMermaidCode = async (): Promise => { + let mermaidCode = ''; + let docArray: Doc[] = DocListCast(this.Document.data); + if (docArray.length === 1) { + if (docArray[0].type == 'rich text') { + const gptResponse = await this.askGPT(); + console.log(gptResponse); + if (gptResponse) { + mermaidCode = gptResponse; + } + } + } else { + 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); + //console.log(mermaidCode); return mermaidCode; - } - getTextInBox=(box: Doc,richTextArray: Doc[]):string=>{ - for(let i=0;ibox.x&&textDoc.xbox.y&&textDoc.y { + 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+"))" + 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 '( )'; + }; + 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{ + }; + 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 ( -
- ); + return
; } } - -- cgit v1.2.3-70-g09d2 From 8f388d6f7cba5964547fd6a401b4a6c661cf76dc Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Tue, 30 Apr 2024 14:55:36 -0400 Subject: ui changes for ai mermaid --- src/client/apis/gpt/GPT.ts | 21 ++-- src/client/views/nodes/DiagramBox.scss | 88 +++++++++++++++ src/client/views/nodes/DiagramBox.tsx | 192 +++++++++++++++++---------------- 3 files changed, 202 insertions(+), 99 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 49c56f04e..027c10e28 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -1,4 +1,5 @@ import { ClientOptions, OpenAI } from 'openai'; +import { ChatCompletionMessageParam } from 'openai/resources'; enum GPTCallType { SUMMARY = 'summary', @@ -18,11 +19,11 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { summary: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Summarize this text in simpler terms: ' }, edit: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Reword this: ' }, completion: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: '' }, - mermaid:{model:'gpt-3.5-turbo-instruct',maxTokens:256,temp:0,prompt:"Write this in mermaid code (keep in note thatPut this at the end of the code to add colors heres an example and be very care about the order:pie title Example Pie Chart \"Red\" : 25 \"Blue\" : 75%%{init: {'theme': 'base', 'themeVariables': { 'pie1': '#0000FF', 'pie2': '#FF0000'}}}%%): "} + mermaid:{model:'gpt-4-turbo',maxTokens:2048,temp:0,prompt:"Write this in mermaid code and only give me the mermaid code (Heres an example of changing color of a pie chart to help you pie title Example \"Red\": 20 \"Blue\": 50 \"Green\": 30 %%{init: {'theme': 'base', 'themeVariables': {'pie1': '#0000FF', 'pie2': '#00FF00', 'pie3': '#FF0000'}}}%% keep in mind that pie1 is the highest since its sorted in descending order. Heres an example of a mindmap: mindmap root((mindmap)) Origins Long history ::icon(fa fa-book) Popularisation British popular psychology author Tony Buzan Research On effectivness
and features On Automatic creation Uses Creative techniques Strategic planning Argument mapping Tools Pen and paper Mermaid. "} }; -/** +/**` * Calls the OpenAI API. * * @param inputText Text to process @@ -37,14 +38,20 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => { dangerouslyAllowBrowser: true, }; const openai = new OpenAI(configuration); - const response = await openai.completions.create({ + + let messages: ChatCompletionMessageParam[] = [ + { role: 'system', content: opts.prompt }, + { role: 'user', content: inputText }, + ]; + + const response = await openai.chat.completions.create({ model: opts.model, - max_tokens: opts.maxTokens, + messages: messages, temperature: opts.temp, - prompt: `${opts.prompt}${inputText}`, - + max_tokens: opts.maxTokens, }); - return response.choices[0].text; + const content = response.choices[0].message.content; + return content; } catch (err) { console.log(err); return 'Error connecting with API.'; diff --git a/src/client/views/nodes/DiagramBox.scss b/src/client/views/nodes/DiagramBox.scss index e69de29bb..d2749f1ad 100644 --- a/src/client/views/nodes/DiagramBox.scss +++ b/src/client/views/nodes/DiagramBox.scss @@ -0,0 +1,88 @@ +.DIYNodeBox { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + .DIYNodeBox-wrapper { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + .DIYNodeBox { + /* existing code */ + + .DIYNodeBox-iframe { + height: 100%; + width: 100%; + border: none; + + } + } + + .search-bar { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + padding: 10px; + + input[type="text"] { + flex: 1; + margin-right: 10px; + } + + button { + padding: 5px 10px; + } + } + + .content { + flex: 1; + display: flex; + justify-content: center; + align-items: center; + width:100%; + height:100%; + .diagramBox{ + flex: 1; + display: flex; + justify-content: center; + align-items: center; + width:100%; + height:100%; + svg{ + flex: 1; + display: flex; + justify-content: center; + align-items: center; + width:100%; + height:100%; + } + } + } + + .loading-circle { + position: relative; + width: 50px; + height: 50px; + border-radius: 50%; + border: 3px solid #ccc; + border-top-color: #333; + animation: spin 1s infinite linear; + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + } +} \ No newline at end of file diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 64d0d6d78..902134fb7 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -12,18 +12,30 @@ import { List } from '../../../fields/List'; import { RichTextField } from '../../../fields/RichTextField'; import { ContextMenu } from '../ContextMenu'; import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT'; +import { ChatCompletionMessageParam } from 'openai/resources/chat/completions'; +import OpenAI, { ClientOptions } from 'openai'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DiagramBox, fieldKey); } + private _ref: React.RefObject = React.createRef(); + private _dragRef = React.createRef(); constructor(props: FieldViewProps) { super(props); makeObservable(this); //this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; } + @observable inputValue = ''; + @observable loading = false; + @observable errorMessage = ''; + @observable mermaidCode = ''; + + @action handleInputChange = (e: React.ChangeEvent) => { + this.inputValue = e.target.value; + }; componentDidMount() { this._props.setContentViewBox?.(this); mermaid.initialize({ @@ -31,112 +43,91 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); + } + renderMermaid = async (str:string) => { + try { + const { svg, bindFunctions } = await this.mermaidDiagram(str); + return { svg, bindFunctions }; + } catch (error) { + console.error('Error rendering mermaid diagram:', error); + return { svg: '', bindFunctions: undefined }; + } + }; + mermaidDiagram = async (str:string) => { + return await mermaid.render('graph' + Date.now(), str); + }; - 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); - }; - async function renderMermaidAsync(this: DiagramBox) { - try { - const mermaidCode: string = await this.createMermaidCode(); - const { svg, bindFunctions } = await renderMermaid(mermaidCode); - const dashDiv = document.getElementById('dashDiv'); - if (dashDiv) { - dashDiv.innerHTML = svg; - if (bindFunctions) { - bindFunctions(dashDiv); - } + async renderMermaidAsync(mermaidCode:string) { + try { + const { svg, bindFunctions } = await this.renderMermaid(mermaidCode); + const dashDiv = document.getElementById('dashDiv'); + if (dashDiv) { + dashDiv.innerHTML = svg; + if (bindFunctions) { + bindFunctions(dashDiv); } - } catch (error) { - console.error('Error rendering Mermaid:', error); } + } catch (error) { + console.error('Error rendering Mermaid:', error); } - - renderMermaidAsync.call(this); } + @action handleRenderClick = () => { + // Call the GPT model and get the HTML output + // const modelOutput = getHtmlOutput(this.inputValue); + // this.htmlCode = modelOutput; + this.generateMermaidCode(); + }; + @action generateMermaidCode=async()=>{ + console.log('Generating Mermaid Code'); + this.loading = true; - askGPT = async (): Promise => { - try { - let notes = 'mermaid syntax for pie charts do not include %'; - let text = notes + (DocListCast(this.Document.data)[0].text as RichTextField)?.Text; - if (!text) { - console.error('Text extraction failed'); - return; - } - - let res = await gptAPICall(text, GPTCallType.MERMAID); - if (!res) { - console.error('GPT call failed'); - return; + let res = await gptAPICall(this.inputValue, GPTCallType.MERMAID); + this.loading = false; + if (res == 'Error connecting with API.') { + // If GPT call failed + console.error('GPT call failed'); + this.errorMessage = 'GPT call failed; please try again.'; + } else if(res!=null){ + // If GPT call succeeded, set htmlCode;;; TODO: check if valid html + if (this.isValidCode(res)) { + this.mermaidCode = res; + console.log('GPT call succeeded:' + res); + this.errorMessage = ''; } else { - console.log(res) - return this.removeWords(res); + console.error('GPT call succeeded but invalid html; please try again.'); + this.errorMessage = 'GPT call succeeded but invalid html; please try again.'; } - } catch (err) { - console.error('Error:', err); - return; } + this.renderMermaidAsync.call(this,this.removeWords(this.mermaidCode)); + this.loading = false; + } + isValidCode = (html: string) => { + return true; }; + removeWords(inputStr:string) { - let presetArray=["pie","flowchart","diagramChart","graph TD","flowchart TD","flowchart LR","graph LR"] - const lines = inputStr.split('\n'); - let foundPresetWord = false; - let result = ''; - - for (const line of lines) { - if (!foundPresetWord) { - for (const word of presetArray) { - if (line.toLowerCase().includes(word.toLowerCase())) { - foundPresetWord = true; - result += line + '\n'; - break; - } - } - } else { - result += line + '\n'; - } - } - - return result; + inputStr=inputStr.replace("```mermaid","") + return inputStr.replace("```",""); } + createMermaidCode = async (): Promise => { - let mermaidCode = ''; - let docArray: Doc[] = DocListCast(this.Document.data); - if (docArray.length === 1) { - if (docArray[0].type == 'rich text') { - const gptResponse = await this.askGPT(); - console.log(gptResponse); - if (gptResponse) { - mermaidCode = gptResponse; - } - } - } else { - 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) + ';'; - } + 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) + ';'; } } } @@ -179,6 +170,23 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im }; render() { - return
; + console.log(this.loading) + return( +
+
+
+ + +
+
+ {this.mermaidCode ? ( +
+ ) : ( +
{this.loading ?
:
{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}
}
+ )} +
+
+
+ ); } } -- cgit v1.2.3-70-g09d2 From becb6c46c176acf57fe24315f45ffe99f3ed0c76 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Wed, 1 May 2024 21:02:48 -0400 Subject: asd --- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 ++ src/client/views/nodes/DiagramBox.tsx | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 791124f50..a0c878ee6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1495,6 +1495,8 @@ export class CollectionFreeFormView extends CollectionSubView (this._layoutElements = this.doLayoutComputation(computation.newPool, computation.computedElementData)), { fireImmediately: true } ); + console.log("Asdasdasda"+this.childDocs) + console.log(DocListCast(this.Document.data)); } static replaceCanvases(oldDiv: HTMLElement, newDiv: HTMLElement) { diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 902134fb7..2e77d1796 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -14,6 +14,10 @@ import { ContextMenu } from '../ContextMenu'; import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT'; import { ChatCompletionMessageParam } from 'openai/resources/chat/completions'; import OpenAI, { ClientOptions } from 'openai'; +import { line } from 'd3'; +import { InkingStroke } from '../InkingStroke'; +import { DocumentManager } from '../../util/DocumentManager'; +import { C } from '@fullcalendar/core/internal-common'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { @@ -22,10 +26,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } private _ref: React.RefObject = React.createRef(); private _dragRef = React.createRef(); + private chartContent:string constructor(props: FieldViewProps) { super(props); makeObservable(this); - //this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; + this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; } @observable inputValue = ''; @@ -43,6 +48,10 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); + this.renderMermaidAsync.call(this,this.chartContent); + this.mermaidCode=this.chartContent + this.createMermaidCode() + } renderMermaid = async (str:string) => { try { @@ -119,6 +128,10 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im 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'); + console.log(docArray) + console.log(this.childDocs + .map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))); + console.log(this.Document.data.filter(inkView => inkView?.ComponentView instanceof InkingStroke)) for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; for (let j = 0; j < lineArray.length; j++) { @@ -170,7 +183,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im }; render() { - console.log(this.loading) return(
-- cgit v1.2.3-70-g09d2 From c6512a23a4eeba55115c5538bdb5b00a5b3d1848 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 1 May 2024 21:22:41 -0400 Subject: quick fix to documentView problem --- src/client/views/nodes/DiagramBox.tsx | 89 +++++++++++++++++------------------ 1 file changed, 44 insertions(+), 45 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 2e77d1796..efec9c7e2 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -26,7 +26,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } private _ref: React.RefObject = React.createRef(); private _dragRef = React.createRef(); - private chartContent:string + private chartContent: string; constructor(props: FieldViewProps) { super(props); makeObservable(this); @@ -48,12 +48,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); - this.renderMermaidAsync.call(this,this.chartContent); - this.mermaidCode=this.chartContent - this.createMermaidCode() - + this.renderMermaidAsync.call(this, this.chartContent); + this.mermaidCode = this.chartContent; + this.createMermaidCode(); } - renderMermaid = async (str:string) => { + renderMermaid = async (str: string) => { try { const { svg, bindFunctions } = await this.mermaidDiagram(str); return { svg, bindFunctions }; @@ -62,11 +61,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im return { svg: '', bindFunctions: undefined }; } }; - mermaidDiagram = async (str:string) => { + mermaidDiagram = async (str: string) => { return await mermaid.render('graph' + Date.now(), str); }; - async renderMermaidAsync(mermaidCode:string) { + async renderMermaidAsync(mermaidCode: string) { try { const { svg, bindFunctions } = await this.renderMermaid(mermaidCode); const dashDiv = document.getElementById('dashDiv'); @@ -86,7 +85,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im // this.htmlCode = modelOutput; this.generateMermaidCode(); }; - @action generateMermaidCode=async()=>{ + @action generateMermaidCode = async () => { console.log('Generating Mermaid Code'); this.loading = true; @@ -96,7 +95,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im // If GPT call failed console.error('GPT call failed'); this.errorMessage = 'GPT call failed; please try again.'; - } else if(res!=null){ + } else if (res != null) { // If GPT call succeeded, set htmlCode;;; TODO: check if valid html if (this.isValidCode(res)) { this.mermaidCode = res; @@ -107,20 +106,18 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im this.errorMessage = 'GPT call succeeded but invalid html; please try again.'; } } - this.renderMermaidAsync.call(this,this.removeWords(this.mermaidCode)); + this.renderMermaidAsync.call(this, this.removeWords(this.mermaidCode)); this.loading = false; - } + }; isValidCode = (html: string) => { return true; }; - - removeWords(inputStr:string) { - inputStr=inputStr.replace("```mermaid","") - return inputStr.replace("```",""); + removeWords(inputStr: string) { + inputStr = inputStr.replace('```mermaid', ''); + return inputStr.replace('```', ''); } - createMermaidCode = async (): Promise => { let mermaidCode = 'graph LR;'; if (this.Document.data instanceof List) { @@ -128,24 +125,26 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im 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'); - console.log(docArray) - console.log(this.childDocs - .map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))); - console.log(this.Document.data.filter(inkView => inkView?.ComponentView instanceof InkingStroke)) - 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(docArray); + setTimeout(() => { + console.log(docArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))); + console.log(docArray.filter(inkView => inkView?.ComponentView instanceof InkingStroke)); + + 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; @@ -183,22 +182,22 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im }; render() { - return( -
-
-
- - -
-
- {this.mermaidCode ? ( -
- ) : ( -
{this.loading ?
:
{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}
}
- )} + return ( +
+
+
+ + +
+
+ {this.mermaidCode ? ( +
+ ) : ( +
{this.loading ?
:
{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}
}
+ )} +
-
); } } -- cgit v1.2.3-70-g09d2 From 90dd101b601add39b2e03a2e1235a74e45c69d5c Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Thu, 2 May 2024 01:48:47 -0400 Subject: change algorithm to include stroke points --- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 - src/client/views/nodes/DiagramBox.tsx | 57 ++++++++++++++-------- 2 files changed, 37 insertions(+), 22 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a0c878ee6..791124f50 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1495,8 +1495,6 @@ export class CollectionFreeFormView extends CollectionSubView (this._layoutElements = this.doLayoutComputation(computation.newPool, computation.computedElementData)), { fireImmediately: true } ); - console.log("Asdasdasda"+this.childDocs) - console.log(DocListCast(this.Document.data)); } static replaceCanvases(oldDiv: HTMLElement, newDiv: HTMLElement) { diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index efec9c7e2..5254a4fe0 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -50,7 +50,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im }); this.renderMermaidAsync.call(this, this.chartContent); this.mermaidCode = this.chartContent; - this.createMermaidCode(); + this.chartContent= this.createMermaidCode(); } renderMermaid = async (str: string) => { try { @@ -118,26 +118,50 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im return inputStr.replace('```', ''); } - createMermaidCode = async (): Promise => { + createMermaidCode() { 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'); - console.log(docArray); setTimeout(() => { - console.log(docArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))); - console.log(docArray.filter(inkView => inkView?.ComponentView instanceof InkingStroke)); - - for (let i = 0; i < rectangleArray.length; i++) { + let inkStrokeArray=lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())) + .filter(inkView => inkView?.ComponentView instanceof InkingStroke) + console.log(inkStrokeArray.length) + let inkingStrokeArray=inkStrokeArray.map(stroke=>stroke?.ComponentView) + 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)) { + let inkStrokeXArray=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord=>coord.X) + let inkStrokeYArray=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord=>coord.Y) + let minX=Math.min(...inkStrokeXArray) + let minY=Math.min(...inkStrokeYArray) + let inkScaleX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX + let inkScaleY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY + let StartX:number=0 + let StartY:number=0 + let EndX:number=0 + let EndY:number=0 + if(typeof docArray[j].x==='number'&&typeof docArray[j].y==='number'&&typeof (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j]==='number'){ + StartX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].X*inkScaleX-minX*inkScaleX + StartY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].Y*inkScaleY-minY*inkScaleY+lineArray[j]?.y + EndX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].X*inkScaleX-minX*inkScaleX+docArray[j].x + EndY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].Y*inkScaleY-minY*inkScaleY+docArray[j].y + } + console.log((inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData) + console.log((inkingStrokeArray[j] as InkingStroke)?.inkScaledData()) + console.log(EndX) + console.log(EndY) + console.log(docArray[j].title) + console.log(docArray[j].x) + console.log(docArray[j].y) + console.log(docArray[j].width) + console.log(docArray[j].height) + if (this.isPointInBox(rectangle, [StartX,StartY])) { 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') { + if (this.isPointInBox(rectangle2, [EndX,EndY]) && 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) + ';'; } } @@ -166,16 +190,9 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } 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; + isPointInBox = (box: Doc, line: number[]): boolean => { + if (typeof line[0] === 'number' && typeof box.x === 'number' && typeof box.width === 'number' && typeof box.height === 'number' && typeof box.y === 'number' && typeof line[1] === 'number') { + return line[0] < box.x + box.width&& line[0] > box.x && line[1] > box.y && line[1] < box.y + box.height; } else { return false; } -- cgit v1.2.3-70-g09d2 From c32c2b48258c0d104921ecdbd6eeb514a814595e Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Mon, 6 May 2024 18:39:52 -0400 Subject: fix mermaid code generator from drawing, does not render --- src/client/views/nodes/DiagramBox.tsx | 77 +++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 31 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 5254a4fe0..27f9d2a86 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -18,6 +18,7 @@ import { line } from 'd3'; import { InkingStroke } from '../InkingStroke'; import { DocumentManager } from '../../util/DocumentManager'; import { C } from '@fullcalendar/core/internal-common'; +import { Docs } from '../../documents/Documents'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { @@ -26,11 +27,10 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } private _ref: React.RefObject = React.createRef(); private _dragRef = React.createRef(); - private chartContent: string; + private chartContent: string="graph L;"; constructor(props: FieldViewProps) { super(props); makeObservable(this); - this.chartContent = 'flowchart LR;A-->B:::wide;B-->C:::wide; B-->D[hello];'; } @observable inputValue = ''; @@ -41,16 +41,21 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im @action handleInputChange = (e: React.ChangeEvent) => { this.inputValue = e.target.value; }; - componentDidMount() { + async componentDidMount() { + console.log(this.chartContent) this._props.setContentViewBox?.(this); mermaid.initialize({ securityLevel: 'loose', startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); - this.renderMermaidAsync.call(this, this.chartContent); - this.mermaidCode = this.chartContent; - this.chartContent= this.createMermaidCode(); + this.mermaidCode = "asdasdasd"; + if(this.chartContent!="graph LR;"){ + this.chartContent=await this.createMermaidCode() + //console.log(this.chartContent) + } + this.renderMermaidAsync(this.chartContent) + this.testInkingStroke() } renderMermaid = async (str: string) => { try { @@ -112,66 +117,76 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im isValidCode = (html: string) => { return true; }; + testInkingStroke=()=>{ + if (this.Document.data instanceof List) { + let docArray: Doc[] = DocListCast(this.Document.data); + let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke'); + setTimeout(() => { + let inkStrokeArray=lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())) + .filter(inkView => inkView?.ComponentView instanceof InkingStroke) + console.log(inkStrokeArray) + }); + } + } removeWords(inputStr: string) { inputStr = inputStr.replace('```mermaid', ''); return inputStr.replace('```', ''); } - createMermaidCode() { + async createMermaidCode() { 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'); - setTimeout(() => { - let inkStrokeArray=lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())) - .filter(inkView => inkView?.ComponentView instanceof InkingStroke) - console.log(inkStrokeArray.length) + const timeoutPromise = () => new Promise(resolve => { + setTimeout(resolve, 0); + }); + await timeoutPromise(); + let inkStrokeArray=lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())) + .filter(inkView => inkView?.ComponentView instanceof InkingStroke) + if(inkStrokeArray[0]){ let inkingStrokeArray=inkStrokeArray.map(stroke=>stroke?.ComponentView) for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; for (let j = 0; j < lineArray.length; j++) { let inkStrokeXArray=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord=>coord.X) let inkStrokeYArray=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord=>coord.Y) - let minX=Math.min(...inkStrokeXArray) - let minY=Math.min(...inkStrokeYArray) + let minX:number=Math.min(...inkStrokeXArray) + let minY:number=Math.min(...inkStrokeYArray) let inkScaleX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX let inkScaleY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY let StartX:number=0 let StartY:number=0 let EndX:number=0 let EndY:number=0 - if(typeof docArray[j].x==='number'&&typeof docArray[j].y==='number'&&typeof (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j]==='number'){ - StartX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].X*inkScaleX-minX*inkScaleX - StartY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].Y*inkScaleY-minY*inkScaleY+lineArray[j]?.y - EndX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].X*inkScaleX-minX*inkScaleX+docArray[j].x - EndY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].Y*inkScaleY-minY*inkScaleY+docArray[j].y - } - console.log((inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData) - console.log((inkingStrokeArray[j] as InkingStroke)?.inkScaledData()) - console.log(EndX) - console.log(EndY) - console.log(docArray[j].title) - console.log(docArray[j].x) - console.log(docArray[j].y) - console.log(docArray[j].width) - console.log(docArray[j].height) + StartX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].X*inkScaleX-minX*inkScaleX+(lineArray[j]?.x as number) + StartY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].Y*inkScaleY-minY*inkScaleY+(lineArray[j]?.y as number) + EndX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].X*inkScaleX-minX*inkScaleX+(lineArray[j].x as number) + EndY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].Y*inkScaleY-minY*inkScaleY+(lineArray[j].y as number) if (this.isPointInBox(rectangle, [StartX,StartY])) { for (let k = 0; k < rectangleArray.length; k++) { const rectangle2 = rectangleArray[k]; if (this.isPointInBox(rectangle2, [EndX,EndY]) && 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) } } } } } - }); + } + } - //console.log(mermaidCode); - return mermaidCode; + console.log(this) + this.addDocument(Docs.Create.TextDocument("asd", { title:"hellotitle", x: 0, y: 0 })); + let docArray: Doc[] = DocListCast(this.Document.data); + console.log(docArray.length) + //console.log(mermaidCode) + return mermaidCode }; getTextInBox = (box: Doc, richTextArray: Doc[]): string => { -- cgit v1.2.3-70-g09d2 From db9b7f9282a0fd921a45275c3bb0cfe7e1d055f9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 6 May 2024 19:20:00 -0400 Subject: fixed adding collection from DiagramBox --- src/client/views/nodes/DiagramBox.tsx | 85 +++++++++++++++++------------------ 1 file changed, 40 insertions(+), 45 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 27f9d2a86..8a31f634b 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -19,6 +19,7 @@ import { InkingStroke } from '../InkingStroke'; import { DocumentManager } from '../../util/DocumentManager'; import { C } from '@fullcalendar/core/internal-common'; import { Docs } from '../../documents/Documents'; +import { NumCast } from '../../../fields/Types'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { @@ -27,7 +28,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } private _ref: React.RefObject = React.createRef(); private _dragRef = React.createRef(); - private chartContent: string="graph L;"; + private chartContent: string = 'graph L;'; constructor(props: FieldViewProps) { super(props); makeObservable(this); @@ -42,20 +43,20 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im this.inputValue = e.target.value; }; async componentDidMount() { - console.log(this.chartContent) + console.log(this.chartContent); this._props.setContentViewBox?.(this); mermaid.initialize({ securityLevel: 'loose', startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); - this.mermaidCode = "asdasdasd"; - if(this.chartContent!="graph LR;"){ - this.chartContent=await this.createMermaidCode() + this.mermaidCode = 'asdasdasd'; + if (this.chartContent != 'graph LR;') { + this.chartContent = await this.createMermaidCode(); //console.log(this.chartContent) } - this.renderMermaidAsync(this.chartContent) - this.testInkingStroke() + this.renderMermaidAsync(this.chartContent); + this.testInkingStroke(); } renderMermaid = async (str: string) => { try { @@ -117,17 +118,16 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im isValidCode = (html: string) => { return true; }; - testInkingStroke=()=>{ + testInkingStroke = () => { if (this.Document.data instanceof List) { let docArray: Doc[] = DocListCast(this.Document.data); let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke'); setTimeout(() => { - let inkStrokeArray=lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())) - .filter(inkView => inkView?.ComponentView instanceof InkingStroke) - console.log(inkStrokeArray) + let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); + console.log(inkStrokeArray); }); } - } + }; removeWords(inputStr: string) { inputStr = inputStr.replace('```mermaid', ''); @@ -141,36 +141,35 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im 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'); - const timeoutPromise = () => new Promise(resolve => { - setTimeout(resolve, 0); - }); + const timeoutPromise = () => + new Promise(resolve => { + setTimeout(resolve, 0); + }); await timeoutPromise(); - let inkStrokeArray=lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())) - .filter(inkView => inkView?.ComponentView instanceof InkingStroke) - if(inkStrokeArray[0]){ - let inkingStrokeArray=inkStrokeArray.map(stroke=>stroke?.ComponentView) - for (let i = 0; i < rectangleArray.length; i++) { + let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); + if (inkStrokeArray[0]) { + let inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); + for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; for (let j = 0; j < lineArray.length; j++) { - let inkStrokeXArray=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord=>coord.X) - let inkStrokeYArray=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord=>coord.Y) - let minX:number=Math.min(...inkStrokeXArray) - let minY:number=Math.min(...inkStrokeYArray) - let inkScaleX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX - let inkScaleY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY - let StartX:number=0 - let StartY:number=0 - let EndX:number=0 - let EndY:number=0 - StartX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].X*inkScaleX-minX*inkScaleX+(lineArray[j]?.x as number) - StartY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].Y*inkScaleY-minY*inkScaleY+(lineArray[j]?.y as number) - EndX=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].X*inkScaleX-minX*inkScaleX+(lineArray[j].x as number) - EndY=(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length-1].Y*inkScaleY-minY*inkScaleY+(lineArray[j].y as number) - if (this.isPointInBox(rectangle, [StartX,StartY])) { + let inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.X); + let inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.Y); + let minX: number = Math.min(...inkStrokeXArray); + let minY: number = Math.min(...inkStrokeYArray); + let inkScaleX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX; + let inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY; + let StartX: number = 0; + let StartY: number = 0; + let EndX: number = 0; + let EndY: number = 0; + StartX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].X * inkScaleX - minX * inkScaleX + (lineArray[j]?.x as number); + StartY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].Y * inkScaleY - minY * inkScaleY + (lineArray[j]?.y as number); + EndX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length - 1].X * inkScaleX - minX * inkScaleX + (lineArray[j].x as number); + EndY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length - 1].Y * inkScaleY - minY * inkScaleY + (lineArray[j].y as number); + if (this.isPointInBox(rectangle, [StartX, StartY])) { for (let k = 0; k < rectangleArray.length; k++) { const rectangle2 = rectangleArray[k]; - if (this.isPointInBox(rectangle2, [EndX,EndY]) && typeof rectangle.x === 'number' && typeof rectangle2.x === 'number') { - + if (this.isPointInBox(rectangle2, [EndX, EndY]) && 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) } @@ -179,15 +178,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } } } - } - console.log(this) - this.addDocument(Docs.Create.TextDocument("asd", { title:"hellotitle", x: 0, y: 0 })); - let docArray: Doc[] = DocListCast(this.Document.data); - console.log(docArray.length) + this._props.addDocument?.(Docs.Create.TextDocument('asd', { title: 'hellotitle', x: NumCast(this.Document.x) + NumCast(this.layoutDoc._width), y: NumCast(this.Document.y) })); //console.log(mermaidCode) - return mermaidCode - }; + return mermaidCode; + } getTextInBox = (box: Doc, richTextArray: Doc[]): string => { for (let i = 0; i < richTextArray.length; i++) { @@ -207,7 +202,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im }; isPointInBox = (box: Doc, line: number[]): boolean => { if (typeof line[0] === 'number' && typeof box.x === 'number' && typeof box.width === 'number' && typeof box.height === 'number' && typeof box.y === 'number' && typeof line[1] === 'number') { - return line[0] < box.x + box.width&& line[0] > box.x && line[1] > box.y && line[1] < box.y + box.height; + return line[0] < box.x + box.width && line[0] > box.x && line[1] > box.y && line[1] < box.y + box.height; } else { return false; } -- cgit v1.2.3-70-g09d2 From d1c053e3630cab14647af65db05fffc18a7efef3 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Tue, 7 May 2024 17:01:08 -0400 Subject: add saving of mermaid diagram code with text box --- src/client/views/nodes/DiagramBox.tsx | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 8a31f634b..c45b9a8be 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -28,7 +28,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } private _ref: React.RefObject = React.createRef(); private _dragRef = React.createRef(); - private chartContent: string = 'graph L;'; constructor(props: FieldViewProps) { super(props); makeObservable(this); @@ -43,7 +42,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im this.inputValue = e.target.value; }; async componentDidMount() { - console.log(this.chartContent); this._props.setContentViewBox?.(this); mermaid.initialize({ securityLevel: 'loose', @@ -51,11 +49,12 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); this.mermaidCode = 'asdasdasd'; - if (this.chartContent != 'graph LR;') { - this.chartContent = await this.createMermaidCode(); - //console.log(this.chartContent) + await this.createMermaidCode(); + let docArray: Doc[] = DocListCast(this.Document.data); + let mermaidCodeDoc = docArray.filter(doc => doc.title == 'mermaidCodeTitle') + if(mermaidCodeDoc[0]){ + this.renderMermaidAsync((mermaidCodeDoc[0].text as RichTextField).Text); } - this.renderMermaidAsync(this.chartContent); this.testInkingStroke(); } renderMermaid = async (str: string) => { @@ -135,7 +134,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } async createMermaidCode() { - 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'); @@ -148,6 +146,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im await timeoutPromise(); let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); if (inkStrokeArray[0]) { + let mermaidCode = 'graph LR;'; let inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; @@ -177,13 +176,28 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } } } + DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { + if (docViewForYourCollection && docViewForYourCollection.ComponentView) { + if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { + let docArray: Doc[] = DocListCast(this.Document.data); + let mermaidCodeDoc = docArray.filter(doc => doc.title == 'mermaidCodeTitle') + if(mermaidCodeDoc[0]){ + console.log(mermaidCodeDoc[0].title) + } + docViewForYourCollection.ComponentView?.removeDocument(mermaidCodeDoc) + let newDoc=Docs.Create.TextDocument(mermaidCode, { title: 'mermaidCodeTitle', x: NumCast(this.Document.x) + NumCast(this.layoutDoc._width), y: NumCast(this.Document.y) }) + docViewForYourCollection.ComponentView?.addDocument(newDoc) + } + } + }); } } - this._props.addDocument?.(Docs.Create.TextDocument('asd', { title: 'hellotitle', x: NumCast(this.Document.x) + NumCast(this.layoutDoc._width), y: NumCast(this.Document.y) })); + let docArray: Doc[] = DocListCast(this._props.Document.data) + console.log(docArray.length) + this.Document.data //console.log(mermaidCode) - return mermaidCode; - } + } getTextInBox = (box: Doc, richTextArray: Doc[]): string => { for (let i = 0; i < richTextArray.length; i++) { let textDoc = richTextArray[i]; -- cgit v1.2.3-70-g09d2 From 33fabe4ae82a697e753953af471abdd3aa34e2a2 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Wed, 8 May 2024 10:39:13 -0400 Subject: change to saving mermaid code in text box title --- src/client/views/nodes/DiagramBox.tsx | 51 ++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index c45b9a8be..553d55ac4 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,4 +1,4 @@ -import { makeObservable, observable, action } from 'mobx'; +import { makeObservable, observable, action ,reaction} from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; @@ -49,13 +49,25 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, }); this.mermaidCode = 'asdasdasd'; - await this.createMermaidCode(); let docArray: Doc[] = DocListCast(this.Document.data); let mermaidCodeDoc = docArray.filter(doc => doc.title == 'mermaidCodeTitle') if(mermaidCodeDoc[0]){ this.renderMermaidAsync((mermaidCodeDoc[0].text as RichTextField).Text); } - this.testInkingStroke(); + else{ + DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { + if (docViewForYourCollection && docViewForYourCollection.ComponentView) { + if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { + let newDoc=Docs.Create.TextDocument("mermaidCodeTitle", { title: "", x: 9999 + NumCast(this.layoutDoc._width), y: 9999 }) + docViewForYourCollection.ComponentView?.addDocument(newDoc) + } + } + }); + } + reaction(() => DocListCast(this.Document.data), + docs=> this.createMermaidCode(), + {fireImmediately: true} + ) } renderMermaid = async (str: string) => { try { @@ -134,6 +146,9 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } async createMermaidCode() { + console.log("i just ran") + let mermaidCode="" + let diagramExists=false if (this.Document.data instanceof List) { let docArray: Doc[] = DocListCast(this.Document.data); let rectangleArray = docArray.filter(doc => doc.title == 'rectangle' || doc.title == 'circle'); @@ -146,7 +161,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im await timeoutPromise(); let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); if (inkStrokeArray[0]) { - let mermaidCode = 'graph LR;'; + mermaidCode = 'graph LR;'; let inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; @@ -169,6 +184,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im for (let k = 0; k < rectangleArray.length; k++) { const rectangle2 = rectangleArray[k]; if (this.isPointInBox(rectangle2, [EndX, EndY]) && typeof rectangle.x === 'number' && typeof rectangle2.x === 'number') { + diagramExists=true mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '---' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';'; //console.log(mermaidCode) } @@ -176,25 +192,24 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } } } - DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { - if (docViewForYourCollection && docViewForYourCollection.ComponentView) { - if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { - let docArray: Doc[] = DocListCast(this.Document.data); - let mermaidCodeDoc = docArray.filter(doc => doc.title == 'mermaidCodeTitle') - if(mermaidCodeDoc[0]){ - console.log(mermaidCodeDoc[0].title) - } - docViewForYourCollection.ComponentView?.removeDocument(mermaidCodeDoc) - let newDoc=Docs.Create.TextDocument(mermaidCode, { title: 'mermaidCodeTitle', x: NumCast(this.Document.x) + NumCast(this.layoutDoc._width), y: NumCast(this.Document.y) }) - docViewForYourCollection.ComponentView?.addDocument(newDoc) + } + } + if(diagramExists){ + DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { + if (docViewForYourCollection && docViewForYourCollection.ComponentView) { + if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { + let docArray: Doc[] = DocListCast(this.Document.data); + docArray=docArray.filter(doc => doc.type == 'rich text') + let mermaidCodeDoc = docArray.filter(doc => (doc.text as RichTextField).Text == 'mermaidCodeTitle') + if(mermaidCodeDoc[0]){ + mermaidCodeDoc[0].title=mermaidCode } } - }); - } + } + }); } let docArray: Doc[] = DocListCast(this._props.Document.data) console.log(docArray.length) - this.Document.data //console.log(mermaidCode) } -- cgit v1.2.3-70-g09d2 From 1af901727a79a6d132875f2468fa25dabbbae894 Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Wed, 8 May 2024 18:16:13 -0400 Subject: fix bug with generation of wrong mermaid code --- package-lock.json | 32 +++++++++++-- package.json | 2 +- src/client/views/nodes/DiagramBox.tsx | 85 +++++++++++++++++++++-------------- 3 files changed, 81 insertions(+), 38 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/package-lock.json b/package-lock.json index 49ff43210..2e191b933 100644 --- a/package-lock.json +++ b/package-lock.json @@ -128,7 +128,7 @@ "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", - "mermaid": "^10.8.0", + "mermaid": "^10.9.0", "mobile-detect": "^1.4.5", "mobx": "^6.12.0", "mobx-react": "^9.1.0", @@ -22598,6 +22598,29 @@ "node": ">=12.0.0" } }, + "node_modules/katex": { + "version": "0.16.10", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz", + "integrity": "sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, "node_modules/kdbush": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", @@ -23562,9 +23585,9 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "node_modules/mermaid": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.8.0.tgz", - "integrity": "sha512-9CzfSreRjdDJxX796+jW4zjEq0DVw5xVF0nWsqff8OTbrt+ml0TZ5PyYUjjUZJa2NYxYJZZXewEquxGiM8qZEA==", + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.0.tgz", + "integrity": "sha512-swZju0hFox/B/qoLKK0rOxxgh8Cf7rJSfAUc1u8fezVihYMvrJAS45GzAxTVf4Q+xn9uMgitBcmWk7nWGXOs/g==", "dependencies": { "@braintree/sanitize-url": "^6.0.1", "@types/d3-scale": "^4.0.3", @@ -23577,6 +23600,7 @@ "dayjs": "^1.11.7", "dompurify": "^3.0.5", "elkjs": "^0.9.0", + "katex": "^0.16.9", "khroma": "^2.0.0", "lodash-es": "^4.17.21", "mdast-util-from-markdown": "^1.3.0", diff --git a/package.json b/package.json index ca48bfd0e..78b556fac 100644 --- a/package.json +++ b/package.json @@ -211,7 +211,7 @@ "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", - "mermaid": "^10.8.0", + "mermaid": "^10.9.0", "mobile-detect": "^1.4.5", "mobx": "^6.12.0", "mobx-react": "^9.1.0", diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 553d55ac4..1b8290652 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -50,9 +50,15 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im }); this.mermaidCode = 'asdasdasd'; let docArray: Doc[] = DocListCast(this.Document.data); - let mermaidCodeDoc = docArray.filter(doc => doc.title == 'mermaidCodeTitle') + let mermaidCodeDoc = docArray.filter(doc => doc.type == 'rich text') + mermaidCodeDoc=mermaidCodeDoc.filter(doc=>(doc.text as RichTextField).Text=='mermaidCodeTitle') if(mermaidCodeDoc[0]){ - this.renderMermaidAsync((mermaidCodeDoc[0].text as RichTextField).Text); + if(typeof mermaidCodeDoc[0].title=='string'){ + console.log(mermaidCodeDoc[0].title) + if(mermaidCodeDoc[0].title!=""){ + this.renderMermaidAsync(mermaidCodeDoc[0].title); + } + } } else{ DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { @@ -64,10 +70,15 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } }); } - reaction(() => DocListCast(this.Document.data), - docs=> this.createMermaidCode(), - {fireImmediately: true} - ) + reaction( + () => DocListCast(this.Document.data), + docs => { + console.log("reaction happened") + this.createMermaidCode(); + + }, + { fireImmediately: true } + ); } renderMermaid = async (str: string) => { try { @@ -146,7 +157,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } async createMermaidCode() { - console.log("i just ran") let mermaidCode="" let diagramExists=false if (this.Document.data instanceof List) { @@ -159,34 +169,40 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im setTimeout(resolve, 0); }); await timeoutPromise(); + lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).forEach(inkView => { + const componentView = inkView?.ComponentView; + if (componentView) { + console.log(componentView.constructor.name, componentView); // Print instance type and object + } + }); let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); + console.log(lineArray.length) + console.log(inkStrokeArray.length) if (inkStrokeArray[0]) { mermaidCode = 'graph LR;'; let inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; for (let j = 0; j < lineArray.length; j++) { - let inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.X); - let inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.Y); - let minX: number = Math.min(...inkStrokeXArray); - let minY: number = Math.min(...inkStrokeYArray); let inkScaleX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX; let inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY; - let StartX: number = 0; - let StartY: number = 0; - let EndX: number = 0; - let EndY: number = 0; - StartX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].X * inkScaleX - minX * inkScaleX + (lineArray[j]?.x as number); - StartY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[j].Y * inkScaleY - minY * inkScaleY + (lineArray[j]?.y as number); - EndX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length - 1].X * inkScaleX - minX * inkScaleX + (lineArray[j].x as number); - EndY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData[(inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.length - 1].Y * inkScaleY - minY * inkScaleY + (lineArray[j].y as number); - if (this.isPointInBox(rectangle, [StartX, StartY])) { + let inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.X).map(doc=>doc*inkScaleX); + let inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.Y).map(doc=>doc*inkScaleY); + //console.log(inkingStrokeArray.length) + //console.log(lineArray.length) + let minX: number = Math.min(...inkStrokeXArray); + let minY: number = Math.min(...inkStrokeYArray); + let startX = inkStrokeXArray[0] - minX + (lineArray[j]?.x as number); + let startY = inkStrokeYArray[0] - minY + (lineArray[j]?.y as number); + let endX = inkStrokeXArray[inkStrokeXArray.length - 1]- minX + (lineArray[j].x as number); + let endY = inkStrokeYArray[inkStrokeYArray.length - 1]- minY + (lineArray[j].y as number); + if (this.isPointInBox(rectangle, [startX, startY])) { for (let k = 0; k < rectangleArray.length; k++) { const rectangle2 = rectangleArray[k]; - if (this.isPointInBox(rectangle2, [EndX, EndY]) && typeof rectangle.x === 'number' && typeof rectangle2.x === 'number') { + if (this.isPointInBox(rectangle2, [endX, endY]) && typeof rectangle.x === 'number' && typeof rectangle2.x === 'number') { diagramExists=true mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '---' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';'; - //console.log(mermaidCode) + } } } @@ -194,25 +210,28 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } } } - if(diagramExists){ - DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { - if (docViewForYourCollection && docViewForYourCollection.ComponentView) { - if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { - let docArray: Doc[] = DocListCast(this.Document.data); - docArray=docArray.filter(doc => doc.type == 'rich text') - let mermaidCodeDoc = docArray.filter(doc => (doc.text as RichTextField).Text == 'mermaidCodeTitle') - if(mermaidCodeDoc[0]){ + DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { + if (docViewForYourCollection && docViewForYourCollection.ComponentView) { + if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { + let docArray: Doc[] = DocListCast(this.Document.data); + docArray=docArray.filter(doc => doc.type == 'rich text') + let mermaidCodeDoc = docArray.filter(doc => (doc.text as RichTextField).Text == 'mermaidCodeTitle') + if(mermaidCodeDoc[0]){ + if(diagramExists){ mermaidCodeDoc[0].title=mermaidCode } + else{ + mermaidCodeDoc[0].title="" + } } } - }); - } + } + }); let docArray: Doc[] = DocListCast(this._props.Document.data) - console.log(docArray.length) //console.log(mermaidCode) } + getTextInBox = (box: Doc, richTextArray: Doc[]): string => { for (let i = 0; i < richTextArray.length; i++) { let textDoc = richTextArray[i]; -- cgit v1.2.3-70-g09d2 From bd82ad3ebefebd4e8354007568ca27f3e2f13a9b Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Fri, 10 May 2024 13:05:24 -0400 Subject: small change in gpt prompty --- src/client/apis/gpt/GPT.ts | 2 +- src/client/views/nodes/DiagramBox.tsx | 38 ++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 027c10e28..cde408382 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -19,7 +19,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { summary: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Summarize this text in simpler terms: ' }, edit: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: 'Reword this: ' }, completion: { model: 'gpt-3.5-turbo-instruct', maxTokens: 256, temp: 0.5, prompt: '' }, - mermaid:{model:'gpt-4-turbo',maxTokens:2048,temp:0,prompt:"Write this in mermaid code and only give me the mermaid code (Heres an example of changing color of a pie chart to help you pie title Example \"Red\": 20 \"Blue\": 50 \"Green\": 30 %%{init: {'theme': 'base', 'themeVariables': {'pie1': '#0000FF', 'pie2': '#00FF00', 'pie3': '#FF0000'}}}%% keep in mind that pie1 is the highest since its sorted in descending order. Heres an example of a mindmap: mindmap root((mindmap)) Origins Long history ::icon(fa fa-book) Popularisation British popular psychology author Tony Buzan Research On effectivness
and features On Automatic creation Uses Creative techniques Strategic planning Argument mapping Tools Pen and paper Mermaid. "} + mermaid:{model:'gpt-4-turbo',maxTokens:2048,temp:0,prompt:"(Heres an example of changing color of a pie chart to help you pie title Example \"Red\": 20 \"Blue\": 50 \"Green\": 30 %%{init: {'theme': 'base', 'themeVariables': {'pie1': '#0000FF', 'pie2': '#00FF00', 'pie3': '#FF0000'}}}%% keep in mind that pie1 is the highest since its sorted in descending order. Heres an example of a mindmap: mindmap root((mindmap)) Origins Long history ::icon(fa fa-book) Popularisation British popular psychology author Tony Buzan Research On effectivness
and features On Automatic creation Uses Creative techniques Strategic planning Argument mapping Tools Pen and paper Mermaid. "} }; diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 1b8290652..1813e6097 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -113,11 +113,43 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im // this.htmlCode = modelOutput; this.generateMermaidCode(); }; - @action generateMermaidCode = async () => { + printTitle(){ + let docArray: Doc[] = DocListCast(this.Document.data); + let mermaidCodeDoc = docArray.filter(doc => doc.type == 'rich text') + mermaidCodeDoc=mermaidCodeDoc.filter(doc=>(doc.text as RichTextField).Text=='mermaidCodeTitle') + console.log(mermaidCodeDoc[0].title) + if(mermaidCodeDoc[0]){ + console.log(mermaidCodeDoc[0].title) + if(typeof mermaidCodeDoc[0].title=='string'){ + console.log(mermaidCodeDoc[0].title) + if(mermaidCodeDoc[0].title!=""){ + console.log("you have to see me") + } + } + } + } + @action async generateMermaidCode() { console.log('Generating Mermaid Code'); this.loading = true; - - let res = await gptAPICall(this.inputValue, GPTCallType.MERMAID); + let prompt="" + // let docArray: Doc[] = DocListCast(this.Document.data); + // let mermaidCodeDoc = docArray.filter(doc => doc.type == 'rich text') + // mermaidCodeDoc=mermaidCodeDoc.filter(doc=>(doc.text as RichTextField).Text=='mermaidCodeTitle') + // if(mermaidCodeDoc[0]){ + // console.log(mermaidCodeDoc[0].title) + // if(typeof mermaidCodeDoc[0].title=='string'){ + // console.log(mermaidCodeDoc[0].title) + // if(mermaidCodeDoc[0].title!=""){ + // prompt="Edit this code "+this.inputValue+": "+mermaidCodeDoc[0].title + // console.log("you have to see me") + // } + // } + // } + // else{ + prompt="Write this in mermaid code and only give me the mermaid code: "+this.inputValue + console.log("there is no text save") + //} + let res = await gptAPICall(prompt, GPTCallType.MERMAID); this.loading = false; if (res == 'Error connecting with API.') { // If GPT call failed -- cgit v1.2.3-70-g09d2 From 8c1b420a143e4b72ec551277887c211ca6ca003b Mon Sep 17 00:00:00 2001 From: Zachary Zhang Date: Wed, 15 May 2024 15:26:39 -0400 Subject: add feature to add text onto line --- src/client/views/nodes/DiagramBox.tsx | 122 +++++++++++++++------------------- 1 file changed, 54 insertions(+), 68 deletions(-) (limited to 'src/client/views/nodes/DiagramBox.tsx') diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 1813e6097..c69c3d683 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -20,6 +20,8 @@ import { DocumentManager } from '../../util/DocumentManager'; import { C } from '@fullcalendar/core/internal-common'; import { Docs } from '../../documents/Documents'; import { NumCast } from '../../../fields/Types'; +import { LinkManager } from '../../util/LinkManager'; +import { CsvCast, DocCast, StrCast } from '../../../fields/Types'; @observer export class DiagramBox extends ViewBoxAnnotatableComponent() implements ViewBoxInterface { @@ -60,6 +62,8 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } } } + //this will create a text doc far away where the user cant to save the mermaid code, where it will then be accessed when flipped to the diagram box side + //the code is stored in the title since it is much easier to change than in the text else{ DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { if (docViewForYourCollection && docViewForYourCollection.ComponentView) { @@ -70,12 +74,13 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } }); } + console.log(this.Document.title) + //this is so that ever time a new doc, text node or ink node, is created, this.createMermaidCode will run which will create a save reaction( () => DocListCast(this.Document.data), docs => { console.log("reaction happened") - this.createMermaidCode(); - + this.convertDrawingToMermaidCode(); }, { fireImmediately: true } ); @@ -96,7 +101,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im async renderMermaidAsync(mermaidCode: string) { try { const { svg, bindFunctions } = await this.renderMermaid(mermaidCode); - const dashDiv = document.getElementById('dashDiv'); + const dashDiv = document.getElementById('dashDiv'+this.Document.title); if (dashDiv) { dashDiv.innerHTML = svg; if (bindFunctions) { @@ -108,26 +113,8 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im } } @action handleRenderClick = () => { - // Call the GPT model and get the HTML output - // const modelOutput = getHtmlOutput(this.inputValue); - // this.htmlCode = modelOutput; this.generateMermaidCode(); }; - printTitle(){ - let docArray: Doc[] = DocListCast(this.Document.data); - let mermaidCodeDoc = docArray.filter(doc => doc.type == 'rich text') - mermaidCodeDoc=mermaidCodeDoc.filter(doc=>(doc.text as RichTextField).Text=='mermaidCodeTitle') - console.log(mermaidCodeDoc[0].title) - if(mermaidCodeDoc[0]){ - console.log(mermaidCodeDoc[0].title) - if(typeof mermaidCodeDoc[0].title=='string'){ - console.log(mermaidCodeDoc[0].title) - if(mermaidCodeDoc[0].title!=""){ - console.log("you have to see me") - } - } - } - } @action async generateMermaidCode() { console.log('Generating Mermaid Code'); this.loading = true; @@ -172,23 +159,12 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im isValidCode = (html: string) => { return true; }; - testInkingStroke = () => { - if (this.Document.data instanceof List) { - let docArray: Doc[] = DocListCast(this.Document.data); - let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke'); - setTimeout(() => { - let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); - console.log(inkStrokeArray); - }); - } - }; - removeWords(inputStr: string) { inputStr = inputStr.replace('```mermaid', ''); return inputStr.replace('```', ''); } - - async createMermaidCode() { + //method to convert the drawings on collection node side the mermaid code + async convertDrawingToMermaidCode() { let mermaidCode="" let diagramExists=false if (this.Document.data instanceof List) { @@ -201,17 +177,11 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im setTimeout(resolve, 0); }); await timeoutPromise(); - lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).forEach(inkView => { - const componentView = inkView?.ComponentView; - if (componentView) { - console.log(componentView.constructor.name, componentView); // Print instance type and object - } - }); let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); - console.log(lineArray.length) console.log(inkStrokeArray.length) - if (inkStrokeArray[0]) { - mermaidCode = 'graph LR;'; + console.log(lineArray.length) + if (inkStrokeArray[0]&&inkStrokeArray.length==lineArray.length) { + mermaidCode = 'graph TD;'; let inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; @@ -220,8 +190,9 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im let inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY; let inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.X).map(doc=>doc*inkScaleX); let inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkData.map(coord => coord.Y).map(doc=>doc*inkScaleY); - //console.log(inkingStrokeArray.length) - //console.log(lineArray.length) + console.log(inkingStrokeArray.length) + console.log(lineArray.length) + //need to minX and minY to since the inkStroke.x and.y is not relative to the doc. so I have to do some calcluations let minX: number = Math.min(...inkStrokeXArray); let minY: number = Math.min(...inkStrokeYArray); let startX = inkStrokeXArray[0] - minX + (lineArray[j]?.x as number); @@ -233,37 +204,52 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im const rectangle2 = rectangleArray[k]; if (this.isPointInBox(rectangle2, [endX, endY]) && typeof rectangle.x === 'number' && typeof rectangle2.x === 'number') { diagramExists=true - mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '---' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';'; - + const linkedDocs:Doc[] = LinkManager.Instance.getAllRelatedLinks(lineArray[j]) + .map(d => DocCast(LinkManager.getOppositeAnchor(d, lineArray[j]))) + console.log(linkedDocs.length) + if(linkedDocs.length!=0){ + let linkedText=((linkedDocs[0].text as RichTextField).Text) + mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '-->|'+linkedText+"|" + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';'; + } + else{ + mermaidCode += Math.abs(rectangle.x) + this.getTextInBox(rectangle, textArray) + '-->' + Math.abs(rectangle2.x) + this.getTextInBox(rectangle2, textArray) + ';'; + } } } } } } - } - } - DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { - if (docViewForYourCollection && docViewForYourCollection.ComponentView) { - if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { - let docArray: Doc[] = DocListCast(this.Document.data); - docArray=docArray.filter(doc => doc.type == 'rich text') - let mermaidCodeDoc = docArray.filter(doc => (doc.text as RichTextField).Text == 'mermaidCodeTitle') - if(mermaidCodeDoc[0]){ - if(diagramExists){ - mermaidCodeDoc[0].title=mermaidCode - } - else{ - mermaidCodeDoc[0].title="" + //this will save the text + DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { + if (docViewForYourCollection && docViewForYourCollection.ComponentView) { + if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { + let docArray: Doc[] = DocListCast(this.Document.data); + docArray=docArray.filter(doc => doc.type == 'rich text') + let mermaidCodeDoc = docArray.filter(doc => (doc.text as RichTextField).Text == 'mermaidCodeTitle') + if(mermaidCodeDoc[0]){ + if(diagramExists){ + mermaidCodeDoc[0].title=mermaidCode + } + else{ + mermaidCodeDoc[0].title="" + } + } } } - } + }); } - }); - let docArray: Doc[] = DocListCast(this._props.Document.data) - //console.log(mermaidCode) - + } } - + testInkingStroke = () => { + if (this.Document.data instanceof List) { + let docArray: Doc[] = DocListCast(this.Document.data); + let lineArray = docArray.filter(doc => doc.title == 'line' || doc.title == 'stroke'); + setTimeout(() => { + let inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); + console.log(inkStrokeArray); + }); + } + }; getTextInBox = (box: Doc, richTextArray: Doc[]): string => { for (let i = 0; i < richTextArray.length; i++) { let textDoc = richTextArray[i]; @@ -298,7 +284,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent() im
{this.mermaidCode ? ( -
+
) : (
{this.loading ?
:
{this.errorMessage ? this.errorMessage : 'Insert prompt to generate diagram'}
}
)} -- cgit v1.2.3-70-g09d2