diff options
-rw-r--r-- | src/client/views/nodes/DiagramBox.tsx | 224 |
1 files changed, 155 insertions, 69 deletions
diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx index 068c92e6b..15e569949 100644 --- a/src/client/views/nodes/DiagramBox.tsx +++ b/src/client/views/nodes/DiagramBox.tsx @@ -1,3 +1,4 @@ +/* eslint-disable prettier/prettier */ /* eslint-disable jsx-a11y/control-has-associated-label */ import mermaid from 'mermaid'; import { action, makeObservable, observable, reaction } from 'mobx'; @@ -6,16 +7,18 @@ import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; import { RichTextField } from '../../../fields/RichTextField'; -import { DocCast } from '../../../fields/Types'; +import { DocCast,BoolCast } from '../../../fields/Types'; import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; import { DocumentType } from '../../documents/DocumentTypes'; import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { LinkManager } from '../../util/LinkManager'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; -import { InkingStroke } from '../InkingStroke'; +import { InkingStroke} from '../InkingStroke'; import './DiagramBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; +import { PointData } from '../../../pen-gestures/GestureTypes'; +import { InkField } from '../../../fields/InkField'; enum menuState { option, @@ -67,22 +70,22 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { if (typeof this.Document.drawingMermaidCode === 'string' && this.Document.menuState === 'drawing') { this.renderMermaidAsync(this.Document.drawingMermaidCode); } - console.log(this.Document.title); - // this.renderMermaidAsync(this.timeline); + this.renderMermaidAsync(this.timeline); // 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), - () => this.convertDrawingToMermaidCode(), - { fireImmediately: true } - ); - reaction( - () => - DocListCast(this.Document.data) - .filter(doc => doc.type === 'rich text') - .map(doc => (doc.text as RichTextField).Text), - () => this.convertDrawingToMermaidCode(), - { fireImmediately: true } - ); + // reaction( + // () => DocListCast(this.Document.data), + // () => this.lockInkStroke(), + // { fireImmediately: true } + // ); + // reaction( + // () => + // DocListCast(this.Document.data) + // .filter(doc => doc.type === 'rich text') + // .map(doc => (doc.text as RichTextField).Text), + // () => this.convertDrawingToMermaidCode(), + // { fireImmediately: true } + // ); + this.lockInkStroke(); } componentDidUpdate = () => { if (typeof this.Document.drawingMermaidCode === 'string' && this.Document.menuState === 'drawing') { @@ -109,7 +112,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { default: this.menuState = menuState.option; this.renderDiv = this.renderOption(); - console.log(this.renderDiv); } } renderMermaid = async (str: string) => { @@ -177,19 +179,13 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { 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.error('GPT call succeeded but invalid html; please try again.'); - this.errorMessage = 'GPT call succeeded but invalid html; please try again.'; - } + this.mermaidCode = res; + console.log('GPT call succeeded:' + res); + this.errorMessage = ''; } this.renderMermaidAsync.call(this, this.removeWords(this.mermaidCode)); this.Document.gptMermaidCode = this.removeWords(this.mermaidCode); } - isValidCode = (html: string) => true; removeWords(inputStrIn: string) { const inputStr = inputStrIn.replace('```mermaid', ''); return inputStr.replace('```', ''); @@ -203,21 +199,18 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const rectangleArray = docArray.filter(doc => doc.title === 'rectangle' || doc.title === 'circle'); const lineArray = docArray.filter(doc => doc.title === 'line' || doc.title === 'stroke'); const textArray = docArray.filter(doc => doc.type === 'rich text'); - this.isLeftRightDiagram(docArray); const timeoutPromise = () => new Promise(resolve => { setTimeout(resolve, 0); }); await timeoutPromise(); const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); - console.log(inkStrokeArray.length); - console.log(lineArray.length); if (inkStrokeArray[0] && inkStrokeArray.length === lineArray.length) { - if (this.isLeftRightDiagram(docArray)) { - mermaidCode = 'graph LR;'; - } else { - mermaidCode = 'graph TD;'; - } + // if (this.isLeftRightDiagram(docArray)) { + // mermaidCode = 'graph LR;'; + // } else { + // mermaidCode = 'graph TD;'; + // } const inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); for (let i = 0; i < rectangleArray.length; i++) { const rectangle = rectangleArray[i]; @@ -232,8 +225,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { ?.inkScaledData() .inkData.map(coord => coord.Y) .map(doc => doc * inkScaleY); - 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 const minX: number = Math.min(...inkStrokeXArray); const minY: number = Math.min(...inkStrokeYArray); @@ -247,7 +238,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { if (this.isPointInBox(rectangle2, [endX, endY]) && typeof rectangle.x === 'number' && typeof rectangle2.x === 'number') { diagramExists = true; const linkedDocs: Doc[] = LinkManager.Instance.getAllRelatedLinks(lineArray[j]).map(d => DocCast(LinkManager.getOppositeAnchor(d, lineArray[j]))); - console.log(linkedDocs.length); if (linkedDocs.length !== 0) { const 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) + ';'; @@ -268,39 +258,137 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } } } - isLeftRightDiagram = (docArray: Doc[]) => { - const filteredDocs = docArray.filter(doc => doc.title === 'rectangle' || doc.title === 'circle'); - const xDoc = filteredDocs.map(doc => doc.x) as number[]; - const minX = Math.min(...xDoc); - const xWidthDoc = filteredDocs.map(doc => { - if (typeof doc.x === 'number' && typeof doc.width === 'number') { - return doc.x + doc.width; - } - }) as number[]; - const maxX = Math.max(...xWidthDoc); - const yDoc = filteredDocs.map(doc => doc.y) as number[]; - const minY = Math.min(...yDoc); - const yHeightDoc = filteredDocs.map(doc => { - if (typeof doc.x === 'number' && typeof doc.width === 'number') { - return doc.x + doc.width; - } - }) as number[]; - const maxY = Math.max(...yHeightDoc); - if (maxX - minX > maxY - minY) { - return true; - } - return false; - }; - testInkingStroke = () => { + async lockInkStroke() { if (this.Document.data instanceof List) { const docArray: Doc[] = DocListCast(this.Document.data); + const rectangleArray = docArray.filter(doc => doc.title === 'rectangle' || doc.title === 'circle'); + if(rectangleArray[0]){ + console.log(rectangleArray[0].x) + } const lineArray = docArray.filter(doc => doc.title === 'line' || doc.title === 'stroke'); - setTimeout(() => { - const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); - console.log(inkStrokeArray); - }); + const timeoutPromise = () => + new Promise(resolve => { + setTimeout(resolve, 0); + }); + await timeoutPromise(); + const inkStrokeArray = lineArray.map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke); + const inkingStrokeArray = inkStrokeArray.map(stroke => stroke?.ComponentView); + for (let j = 0; j < lineArray.length; j++) { + const inkScaleX = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleX; + const inkScaleY = (inkingStrokeArray[j] as InkingStroke)?.inkScaledData().inkScaleY; + const inkStrokeXArray = (inkingStrokeArray[j] as InkingStroke) + ?.inkScaledData() + .inkData.map(coord => coord.X) + .map(doc => doc * inkScaleX); + const inkStrokeYArray = (inkingStrokeArray[j] as InkingStroke) + ?.inkScaledData() + .inkData.map(coord => coord.Y) + .map(doc => doc * inkScaleY); + // 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 + const minX: number = Math.min(...inkStrokeXArray); + const minY: number = Math.min(...inkStrokeYArray); + const startX = inkStrokeXArray[0] - minX + (lineArray[j]?.x as number); + const startY = inkStrokeYArray[0] - minY + (lineArray[j]?.y as number); + const endX = inkStrokeXArray[inkStrokeXArray.length - 1] - minX + (lineArray[j].x as number); + const endY = inkStrokeYArray[inkStrokeYArray.length - 1] - minY + (lineArray[j].y as number); + let closestStartRect:Doc=lineArray[0]; + let closestStartDistance=9999999; + let closestEndRect:Doc=lineArray[0]; + let closestEndDistance=9999999; + rectangleArray.forEach(rectangle => { + const midPoint=this.getMidPoint(rectangle) + if(this.euclideanDistance(midPoint.X,midPoint.Y,startX,startY)<closestStartDistance&&this.euclideanDistance(midPoint.X,midPoint.Y,endX,endY)<closestEndDistance){ + if(this.euclideanDistance(midPoint.X,midPoint.Y,startX,startY)<this.euclideanDistance(midPoint.X,midPoint.Y,endX,endY)){ + closestStartDistance=this.euclideanDistance(midPoint.X,midPoint.Y,startX,startY); + closestStartRect=rectangle + } + else{ + closestEndDistance=this.euclideanDistance(midPoint.X,midPoint.Y,startX,startY); + closestEndRect=rectangle + } + } + else if(this.euclideanDistance(midPoint.X,midPoint.Y,startX,startY)<closestStartDistance){ + closestStartDistance=this.euclideanDistance(midPoint.X,midPoint.Y,startX,startY); + closestStartRect=rectangle + } + else if(this.euclideanDistance(midPoint.X,midPoint.Y,endX,endY)<closestEndDistance){ + closestEndDistance=this.euclideanDistance(midPoint.X,midPoint.Y,startX,startY); + closestEndRect=rectangle + } + + }); + const inkToDelete:Doc=lineArray[j]; + if(typeof closestStartRect.x==='number'&&typeof closestStartRect.y==='number'&&typeof closestEndRect.x==='number'&&typeof closestEndRect.y==='number'&&typeof closestStartRect.width==='number'&&typeof closestStartRect.height==='number'){ + const points: PointData[] = [ + { X: closestStartRect.x, Y: closestStartRect.y }, + { X: closestStartRect.x, Y: closestStartRect.y }, + { X: closestEndRect.x, Y: closestEndRect.y }, + { X: closestEndRect.x, Y: closestEndRect.y } + ]; + const newInkDoc:Doc=Docs.Create.InkDocument( + points, + { title: 'stroke', + x: closestStartRect.x+closestStartRect.width/2, + y: closestStartRect.y+closestStartRect.height/2, + _width: closestStartRect.width, + _height: closestStartRect.height, + stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore + 1) + + DocumentManager.Instance.AddViewRenderedCb(this.Document, (docViewForYourCollection) => { + if (docViewForYourCollection && docViewForYourCollection.ComponentView) { + if (docViewForYourCollection.ComponentView.addDocument&&docViewForYourCollection.ComponentView.removeDocument) { + if(!inkToDelete.transformed){ + docViewForYourCollection.ComponentView?.removeDocument(inkToDelete) + docViewForYourCollection.ComponentView?.addDocument(newInkDoc); + newInkDoc.transformed=true; + + } + const bruh2= DocListCast(this.Document.data).filter(doc => doc.title === 'line' || doc.title === 'stroke').map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.())).filter(inkView => inkView?.ComponentView instanceof InkingStroke).map(stroke => stroke?.ComponentView); + console.log(bruh2) + console.log((bruh2[0] as InkingStroke)?.inkScaledData()) + } + } + }); + } + } } - }; + } + getMidPoint(rectangle:Doc){ + let midPoint={X:0,Y:0} + if(typeof rectangle.x ==='number' && typeof rectangle.width==='number'&&typeof rectangle.y ==='number' && typeof rectangle.height==='number'){ + midPoint={X:rectangle.x+rectangle.width/2,Y:rectangle.y+rectangle.height/2}; + } + return midPoint + } + euclideanDistance(x1: number, y1: number, x2: number, y2: number): number { + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return Math.sqrt(deltaX * deltaX + deltaY * deltaY); + } + // isLeftRightDiagram = (docArray: Doc[]) => { + // const filteredDocs = docArray.filter(doc => doc.title === 'rectangle' || doc.title === 'circle'); + // const xDoc = filteredDocs.map(doc => doc.x) as number[]; + // const minX = Math.min(...xDoc); + // const xWidthDoc = filteredDocs.map(doc => { + // if (typeof doc.x === 'number' && typeof doc.width === 'number') { + // return doc.x + doc.width; + // } + // }) as number[]; + // const maxX = Math.max(...xWidthDoc); + // const yDoc = filteredDocs.map(doc => doc.y) as number[]; + // const minY = Math.min(...yDoc); + // const yHeightDoc = filteredDocs.map(doc => { + // if (typeof doc.x === 'number' && typeof doc.width === 'number') { + // return doc.x + doc.width; + // } + // }) as number[]; + // const maxY = Math.max(...yHeightDoc); + // if (maxX - minX > maxY - minY) { + // return true; + // } + // return false; + // }; getTextInBox = (box: Doc, richTextArray: Doc[]): string => { for (let i = 0; i < richTextArray.length; i++) { const textDoc = richTextArray[i]; @@ -351,7 +439,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { ); } renderDrawing(): React.ReactNode { - console.log(this.Document.mermaidCode); return ( <div ref={this._dragRef} className="DiagramBox-wrapper"> <div className="content"> @@ -510,7 +597,6 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { if (typeof e.target.value === 'string') { this.createInputValue = e.target.value; this.renderMermaidAsync(e.target.value); - console.log('hellsad'); } }; timeline = `gantt |