diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 3 | ||||
-rw-r--r-- | src/client/views/StyleProvider.tsx | 5 | ||||
-rw-r--r-- | src/client/views/nodes/DataVizBox/DataVizBox.tsx | 18 | ||||
-rw-r--r-- | src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 149 | ||||
-rw-r--r-- | src/client/views/nodes/DataVizBox/components/TableBox.tsx | 13 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 1 |
6 files changed, 137 insertions, 52 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a4ba2978c..723f851c6 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -178,6 +178,7 @@ export class DocumentOptions { map_bearing?: NUMt = new NumInfo('bearing of a map view', false); map_style?: STRt = new StrInfo('mapbox style for a map view', false); identifier?: STRt = new StrInfo('documentIcon displayed for each doc as "d[x]"', false); + _rotation?: NUMt = new NumInfo('Amount of rotation on a document in degrees', false); date_range?: STRt = new StrInfo('date range for calendar', false); @@ -237,7 +238,7 @@ export class DocumentOptions { dataViz?: string; dataViz_savedTemplates?: LISTt; - borderWidth?: NUMt = new NumInfo('Width of user-added border', false); + borderWidth?: STRt = new StrInfo('Width of user-added border', false); borderColor?: STRt = new StrInfo('Color of user-added border', false); layout?: string | Doc; // default layout string or template document diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 3ecb101f8..bb0883cc0 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -56,11 +56,14 @@ export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: nu } export function border(doc: Doc, pw: number, ph: number, rad: number = 0, inset: number = 0) { + if (!rad) rad = 0; const width = pw * inset; const height = ph * inset; const radius = Math.min(rad, (pw - 2 * width) / 2, (ph - 2 * height) / 2); + console.log(pw, ph, rad, inset) + return ` M ${width + radius} ${height} L ${pw - width - radius} ${height} @@ -206,8 +209,10 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & case StyleProp.BorderPath: { const docWidth = Number(doc?._width); const borderWidth = Number(StrCast(doc?.borderWidth)); + //console.log(borderWidth); const ratio = borderWidth / docWidth; const borderRadius = Number(StrCast(layoutDoc?._layout_borderRounding).replace('px', '')); + console.log(StrCast(layoutDoc?._layout_borderRounding), borderRadius, typeof borderRadius) const radiusRatio = borderRadius / docWidth; const radius = radiusRatio * ((2 * borderWidth) + docWidth); diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index 8e9680e38..82df141fa 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -53,6 +53,7 @@ export enum DataVizView { @observer export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { + private _urlError: boolean = false; private _mainCont: React.RefObject<HTMLDivElement> = React.createRef(); private _marqueeref = React.createRef<MarqueeAnnotator>(); private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef(); @@ -116,8 +117,17 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // all CSV records in the dataset (that aren't an empty row) @computed.struct get records() { - const records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href); - return records?.filter(record => Object.keys(record).some(key => record[key])) ?? []; + try { + const records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href); + this._urlError = false; + return records?.filter(record => Object.keys(record).some(key => record[key])) ?? []; + } catch (e){ + this._urlError = true; + const data: { [key: string]: string; }[] = [ + { error: "Data not found"}, + ]; + return data; + } } // currently chosen visualization type: line, pie, histogram, table @@ -133,8 +143,6 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } selectAxes = (axes: string[]) => { this.layoutDoc._dataViz_axes = new List<string>(axes); - //axes.forEach(axis => console.log(axis)) - //DocCreatorMenu.Instance.generateTemplates(''); }; @computed.struct get titleCol() { return StrCast(this.layoutDoc._dataViz_titleCol); @@ -315,7 +323,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { componentDidMount() { this._props.setContentViewBox?.(this); - if (!DataVizBox.dataset.has(CsvCast(this.dataDoc[this.fieldKey]).url.href)) this.fetchData(); + if (!this._urlError) { if (!DataVizBox.dataset.has(CsvCast(this.dataDoc[this.fieldKey]).url.href)) this.fetchData() }; this._disposers.datavis = reaction( () => { if (this.layoutDoc.dataViz_schemaLive === undefined) this.layoutDoc.dataViz_schemaLive = true; diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 43cf57167..27ffc63ef 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -404,21 +404,21 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { testTemplate = () => { - // const temp = TemplateLayouts.TwoFieldPlusCarousel; - // const title = new TemplateDocTextField({tl: temp.fields[0].tl, br: temp.fields[0].br}); - // const title1 = new TemplateDocTextField({tl: temp.fields[0].tl, br: temp.fields[0].br}); - // const title2 = new TemplateDocTextField({tl: temp.fields[0].tl, br: temp.fields[0].br}); - // const title3 = new TemplateDocTextField({tl: temp.fields[0].tl, br: temp.fields[0].br}); - // const focus = new TemplateDocCarouselField({tl: temp.fields[1].tl, br: temp.fields[1].br}, temp.width, temp.height, '', [title1, title2, title3].map(field => field.getDoc(temp.width, temp.height, 'hey now', ''))); - // const caption = new TemplateDocTextField({tl: temp.fields[2].tl, br: temp.fields[2].br}); - // let fields = [title, caption].map(field => field.getDoc(temp.width, temp.height, 'hey now', '')); - // fields = fields.concat(focus.getDoc()); - // console.log(temp.height, temp.width) - // const doc = Docs.Create.StackingDocument(fields, { _height: temp.height, _width: temp.width, title: 'hey', x: 400, y: 400 }); - - // const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; - // mainCollection.addDocument(doc); - //this._dataViz?.getRandomSample(); + const temp = TemplateLayouts.FourField001; + const title: Doc = FieldFuncs.TextField({tl: temp.fields[0].tl, br: temp.fields[0].br}, temp.height, temp.width, 'title', 'Title', {backgroundColor: 'transparent'}); + const image: Doc = FieldFuncs.ImageField({tl: temp.fields[1].tl, br: temp.fields[1].br}, temp.height, temp.width, 'title', '', {borderColor: '#159fe4', borderWidth: '10', cornerRounding: 10, rotation: 40}); + const caption: Doc = FieldFuncs.TextField({tl: temp.fields[2].tl, br: temp.fields[2].br}, temp.height, temp.width, 'title', 'Caption', {backgroundColor: 'transparent'}); + const desc: Doc = FieldFuncs.TextField({tl: temp.fields[3].tl, br: temp.fields[3].br}, temp.height, temp.width, 'title', '', {backgroundColor: 'lightblue', borderColor: '#159fe4', borderWidth: '10', cornerRounding: 10}); + + const doc = Docs.Create.FreeformDocument([title, image, caption, desc], { _height: temp.height, _width: temp.width, title: 'hey', x: 400, y: 400 }); + + const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; + mainCollection.addDocument(doc); + + // setTimeout(() => image.borderWidth = '10', 1000); + // setTimeout(() => desc.borderWidth = '10', 1000); + + // this._dataViz?.getRandomSample(); // public static FourField001: TemplateDocInfos = { @@ -450,12 +450,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { // opts: { - const field1: Col = {title: 'hey', type: TemplateFieldType.TEXT, size: FieldSize.HUGE, desc: ''} - const field2: Col = {title: 'heyo', type: TemplateFieldType.TEXT, size: FieldSize.TINY, desc: ''} - const field3: Col = {title: 'heya', type: TemplateFieldType.VISUAL, size: FieldSize.LARGE, desc: ''} - const field4: Col = {title: 'heyy', type: TemplateFieldType.TEXT, size: FieldSize.MEDIUM, desc: ''} + // const field1: Col = {title: 'hey', type: TemplateFieldType.TEXT, size: FieldSize.HUGE, desc: ''} + // const field2: Col = {title: 'heyo', type: TemplateFieldType.TEXT, size: FieldSize.TINY, desc: ''} + // const field3: Col = {title: 'heya', type: TemplateFieldType.VISUAL, size: FieldSize.LARGE, desc: ''} + // const field4: Col = {title: 'heyy', type: TemplateFieldType.TEXT, size: FieldSize.MEDIUM, desc: ''} - console.log(this.findValidTemplates([field1, field2, field3, field4], [TemplateLayouts.FourField001])); + // console.log(this.findValidTemplates([field1, field2, field3, field4], [TemplateLayouts.FourField001])); } get templatesPreviewContents(){ @@ -609,9 +609,9 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { } } - doc = () => { - return Docs.Create.FreeformDocument([], { _height: 200, _width: 200, title: 'title'}); - } + // doc = () => { + // return Docs.Create.FreeformDocument([], { _height: 200, _width: 200, title: 'title'}); + // } screenToLocalTransform = () => this._props @@ -802,7 +802,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { } @action addField = () => { - const newFields: Col[] = this._columns.concat([{title: '', type: TemplateFieldType.TEXT, desc: '', size: FieldSize.MEDIUM}]) + const newFields: Col[] = this._columns.concat([{title: '', type: TemplateFieldType.UNSET, desc: '', size: FieldSize.MEDIUM}]) this._columns = newFields; } @@ -822,9 +822,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { if (this._columns.length === 1) { this._columns = [] } else { - console.log(this._columns) this._columns.splice(this._columns.indexOf(toRemove[0]), 1); - console.log(this._columns) } } } @@ -899,7 +897,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { templates.forEach(template => { const numFields = template.fields.length; const matches = this.matchesForTemplate(template, cols); - console.log(matches) if (this.maxMatches(numFields, matches) === numFields) { validTemplates.push(template.title); } @@ -908,7 +905,32 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { return validTemplates; } + createEmptyTemplate = (template: TemplateDocInfos, assignments: {[field: number]: Col}) => { + const fields: Doc[] = []; + + Object.entries(assignments).forEach(([f, col]) => { + const field: Field = template.fields[Number(f)]; + const doc = (col.type === TemplateFieldType.VISUAL ? FieldFuncs.ImageField : FieldFuncs.TextField)({ + tl: field.tl, + br: field.br }, + template.height, + template.width, + col.title, + '', + field.opts + ); + + fields.push(doc); + }); + + const renderedTemplate = Docs.Create.FreeformDocument(fields, { _height: template.height, _width: template.width, title: template.title, x: 400, y: 400 }); + + const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; + mainCollection.addDocument(renderedTemplate); + } + get dashboardContents(){ + return ( <div className='docCreatorMenu-dashboard-view'> <div className='topbar'> @@ -919,10 +941,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { {this.fieldsInfos.map((field, index) => <div className='field-panel' id={`${index}`}> <div className='properties-wrapper'> - <input className='field-property-container' id={`${Math.random() * 100}`} defaultValue={field.title} placeholder={'Enter title'} style={{width: field.title === '' ? '30%' : ''}}/> + <input className='field-property-container' id={`${Math.random() * 100}`} defaultValue={field.title} placeholder={'Enter title'}/> <div className='field-type-selection-container'> - {field.type ? null : <span className='placeholder'>Select media type</span>} - <span className='type-display'>{field.type ? field.type === 'text' ? 'Text Field' : 'File Field' : ''}</span> + {field.type === TemplateFieldType.UNSET ? <span className='placeholder'>Select media type</span> : null} + <span className='type-display'>{field.type === TemplateFieldType.TEXT ? 'Text Field' : field.type === TemplateFieldType.VISUAL ? 'File Field' : ''}</span> <div className='bubbles'> <input className='bubble' type="radio" name="type" onClick={() => {this.setFieldType(field, TemplateFieldType.TEXT)}}/> <div className='text'>Text</div> @@ -930,15 +952,13 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { <div className='text'>File</div> </div> </div> + <input className='field-property-container' id={`${Math.random() * 100}`} placeholder={'Choose size'} style={{width: field.title === '' ? '30%' : ''}}/> </div> <textarea className='field-description-container' onChange={(e) => this._dataViz?.setFieldDesc(field.title, e.target.value)} defaultValue={field.desc === this._dataViz?.GPTSummary?.get(field.title) ? '' : field.desc } placeholder={this._dataViz?.GPTSummary?.get(field.title) ?? 'Add a description to help with template generation.'} /> <div> <button className='docCreatorMenu-menu-button section-reveal-options top-right' onPointerDown={e => this.setUpButtonClick(e, () => this.removeField(field))}> <FontAwesomeIcon icon='trash'/> </button> - {/* <button className='docCreatorMenu-menu-button section-reveal-options top-right' onPointerDown={e => this.setUpButtonClick(e, () => this.removeField(field))}> - <FontAwesomeIcon icon='lightbulb'/> - </button> */} </div> </div> )} @@ -1111,7 +1131,7 @@ export interface FieldOpts { backgroundColor?: string; color?: string; cornerRounding?: number; - borderWidth?: number; + borderWidth?: string; borderColor?: string; contentXCentering?: 'left' | 'center' | 'right'; contentYCentering?: 'top' | 'center' | 'bottom'; @@ -1125,8 +1145,8 @@ export interface FieldOpts { export class FieldFuncs { private static getDimensions = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number): {width: number, height: number, coord: {x: number, y: number}} => { - const l = coords.tl[0] * parentWidth / 2; const t = coords.tl[1] * parentHeight / 2; //prettier-ignore - const r = coords.br[0] * parentWidth / 2; const b = coords.br[1] * parentHeight / 2; //prettier-ignore + const l = coords.tl[0] * parentHeight / 2; const t = coords.tl[1] * parentWidth / 2; //prettier-ignore + const r = coords.br[0] * parentHeight / 2; const b = coords.br[1] * parentWidth / 2; //prettier-ignore const width = r - l; const height = b - t; const coord = {x: l, y: t}; @@ -1147,17 +1167,18 @@ export class FieldFuncs { _text_fontSize: `${height/2}` , backgroundColor: opts.backgroundColor ?? '', color: opts.color, - _layout_borderRounding: `${opts.cornerRounding}`, - borderWidth: opts.borderWidth, + _layout_borderRounding: `${opts.cornerRounding}px` ?? '0px', borderColor: opts.borderColor, + borderWidth: opts.borderWidth, opacity: opts.opacity, _layout_centered: opts.contentXCentering === 'center' ? true : false, + _rotation: opts.rotation, }); return docWithBasicOpts; } - public static ImageField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string) => { + public static ImageField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => { const {width, height, coord} = FieldFuncs.getDimensions(coords, parentWidth, parentHeight); const doc = Docs.Create.ImageDocument(content, { @@ -1166,7 +1187,16 @@ export class FieldFuncs { title: title, x: coord.x, y: coord.y, - _text_fontSize: `${height/2}` }) + _text_fontSize: `${height/2}` , + backgroundColor: opts.backgroundColor ?? '', + color: opts.color, + _layout_borderRounding: `${opts.cornerRounding}px` ?? '0px', + borderColor: opts.borderColor, + borderWidth: opts.borderWidth, + opacity: opts.opacity, + _layout_centered: opts.contentXCentering === 'center' ? true : false, + _rotation: opts.rotation, + }); return doc; } @@ -1222,6 +1252,45 @@ export class TemplateLayouts { }] }; + public static FourField002: TemplateDocInfos = { + title: 'fourfield2', + width: 475, + height: 870, + fields: [{ + tl: [-.95, -.83], + br: [-.15, .83], + types: [TemplateFieldType.VISUAL], + sizes: [FieldSize.MEDIUM, FieldSize.LARGE], + opts: { + + } + }, { + tl: [-.9, -.7], + br: [.9, .2], + types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL], + sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE], + opts: { + + } + }, { + tl: [-.6, .3], + br: [.6, .4], + types: [TemplateFieldType.TEXT], + sizes: [FieldSize.TINY], + opts: { + + } + }, { + tl: [-.9, .5], + br: [.9, .9], + types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL], + sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE], + opts: { + + } + }] + }; + // public static FourField002: TemplateDocInfos = { // width: 450, // height: 600, diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index 559b8507c..6d800bc19 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -178,7 +178,6 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { } else { const newAxes = this._props.axes; if (newAxes.includes(col)) newAxes.splice(newAxes.indexOf(col), 1); - else if (newAxes.length > 2) newAxes[newAxes.length - 1] = col; else newAxes.push(col); this._props.selectAxes(newAxes); } @@ -410,11 +409,13 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { color: this._props.axes.slice().reverse().lastElement() === col ? 'darkgreen' - : this._props.axes.length > 2 && this._props.axes.lastElement() === col + : this._props.axes.length > 3 && this._props.axes.lastElement() === col ? 'darkred' - : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col) + : this._props.axes.length > 3 && this._props.axes[1] === col ? 'darkblue' - : undefined, + : this._props.axes.lastElement() === col || (this._props.axes.length > 3 && this._props.axes[2] === col) + ? 'darkcyan' + : undefined, background: this.settingTitle ? 'lightgrey' : this._props.axes.slice().reverse().lastElement() === col @@ -423,7 +424,9 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> { ? '#Fbdbdb' : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col) ? '#c6ebf7' - : undefined, + : this._props.axes.lastElement() === col || (this._props.axes.length > 3 && this._props.axes[2] === col) + ? '#c2f0f4' + : undefined, fontWeight: 'bolder', border: '3px solid black', }} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5af6e65de..79a2def87 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1444,7 +1444,6 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { render() { TraceMobx(); const borderWidth = 50/*Number(StrCast(this.layoutDoc.layout_borderWidth).replace('px', ''))*/; - console.log(this._props.PanelWidth(), borderWidth) const xshift = Math.abs(this.Xshift) <= 0.001 ? this._props.PanelWidth() : undefined; const yshift = Math.abs(this.Yshift) <= 0.001 ? this._props.PanelHeight() : undefined; |