diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/StyleProvider.tsx | 3 | ||||
-rw-r--r-- | src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx | 458 |
2 files changed, 266 insertions, 195 deletions
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index bb0883cc0..e7275a913 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -62,8 +62,6 @@ export function border(doc: Doc, pw: number, ph: number, rad: number = 0, 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} @@ -212,7 +210,6 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & //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/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx index 27ffc63ef..5534fced3 100644 --- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx +++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx @@ -404,60 +404,180 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { testTemplate = () => { - 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 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 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); + // const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; + // mainCollection.addDocument(doc); + + const temp = TemplateLayouts.FourField002; + + const img: Col = {type: TemplateFieldType.VISUAL, title: 'Image', desc: '', size: FieldSize.LARGE}; + const capt1: Col = {type: TemplateFieldType.TEXT, title: 'Type', desc: '', size: FieldSize.TINY}; + const capt2: Col = {type: TemplateFieldType.TEXT, title: 'Locality', desc: '', size: FieldSize.TINY}; + const desc: Col = {type: TemplateFieldType.TEXT, title: 'Description', desc: '', size: FieldSize.LARGE}; - // setTimeout(() => image.borderWidth = '10', 1000); - // setTimeout(() => desc.borderWidth = '10', 1000); + const assignments = {'0': img, '1': capt1, '2': capt2, '3': desc} - // this._dataViz?.getRandomSample(); + this.createEmptyTemplate(temp, assignments); + } + @action addField = () => { + const newFields: Col[] = this._columns.concat([{title: '', type: TemplateFieldType.UNSET, desc: '', size: FieldSize.MEDIUM}]) + this._columns = newFields; + } + + @action removeField = (field: {title: string, type: string, desc: string}) => { + if (this._dataViz?.axes.includes(field.title)) { + this._dataViz.selectAxes(this._dataViz.axes.filter(col => col !== field.title)); + } else { + const toRemove = this._columns.filter(f => f === field); + if (!toRemove) return; + + if (toRemove.length > 1) { + while (toRemove.length > 1) { + toRemove.pop(); + } + } - // public static FourField001: TemplateDocInfos = { - // title: 'fourfield1', - // width: 450, - // height: 600, - // fields: [{ - // tl: [-.6, -.9], - // br: [.6, -.8], - // types: [TemplateFieldType.TEXT], - // sizes: [FieldSize.TINY], - // opts: { + if (this._columns.length === 1) { + this._columns = [] + } else { + this._columns.splice(this._columns.indexOf(toRemove[0]), 1); + } + } + } + + setFieldType = (column: Col, type: TemplateFieldType) => { + if (this.selectedFields.includes(column.title)) { + this._dataViz?.setFieldType(column.title, type); + } else { + column.type = type; + } + this.forceUpdate(); + } + + setFieldDesc = (column: Col, desc: string) => { + if (this.selectedFields.includes(column.title)) { + this._dataViz?.setFieldDesc(column.title, desc); + } else { + column.desc = desc; + } + this.forceUpdate(); + } + + matchesForTemplate = (template: TemplateDocInfos, cols: Col[]): number[][] => { + const colMatchesField = (col: Col, field : Field) => { return field.sizes?.includes(col.size) && field.types?.includes(col.type) }; + + const matches: number[][] = Array(template.fields.length).fill([]).map(() => []); + console.log(matches) + template.fields.forEach((field, i) => { + cols.forEach((col, v) => { + if (colMatchesField(col, field)) { + matches[i].push(v); + } + }); + }); + + return matches; + } + + maxMatches = (fieldsCt: number, matches: number[][]) => { + const used: boolean[] = Array(fieldsCt).fill(false); + const mt: number[] = Array(fieldsCt).fill(-1); + + const augmentingPath = (v: number): boolean => { + if (used[v]) return false; + used[v] = true; + for (const to of matches[v]) { + if (mt[to] === -1 || augmentingPath(mt[to])) { + mt[to] = v; + return true; + } + } + return false; + } - // tl: [-.9, -.7], - // br: [.9, .2], - // types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL], - // sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE], - - // 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: { - - - // 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])); + for (let v = 0; v < fieldsCt; ++v) { + used.fill(false); + augmentingPath(v); + } + + let count: number = 0; + + for (let i = 0; i < fieldsCt; ++i) { + if (mt[i] !== -1) ++count; + } + + return count; + } + + + findValidTemplates = (cols: Col[], templates: TemplateDocInfos[]) => { + const validTemplates: string[] = []; + templates.forEach(template => { + const numFields = template.fields.length; + const matches = this.matchesForTemplate(template, cols); + if (this.maxMatches(numFields, matches) === numFields) { + validTemplates.push(template.title); + } + }) + + 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)]; + console.log(field) + 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); + }); + + template.decorations.forEach(dec => { + const doc = FieldFuncs.FreeformField({ + tl: dec.tl, + br: dec.br }, + template.height, + template.width, + '', + '', + dec.opts, + ); + + fields.push(doc); + }); + + const renderedTemplate = Docs.Create.FreeformDocument(fields, { + _height: template.height, + _width: template.width, + title: template.title, + backgroundColor: template.opts.backgroundColor, + x: 400, + y: 400 + }); + + const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView; + mainCollection.addDocument(renderedTemplate); } + get templatesPreviewContents(){ const renderedTemplates: Doc[] = []; @@ -801,134 +921,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> { ); } - @action addField = () => { - const newFields: Col[] = this._columns.concat([{title: '', type: TemplateFieldType.UNSET, desc: '', size: FieldSize.MEDIUM}]) - this._columns = newFields; - } - - @action removeField = (field: {title: string, type: string, desc: string}) => { - if (this._dataViz?.axes.includes(field.title)) { - this._dataViz.selectAxes(this._dataViz.axes.filter(col => col !== field.title)); - } else { - const toRemove = this._columns.filter(f => f === field); - if (!toRemove) return; - - if (toRemove.length > 1) { - while (toRemove.length > 1) { - toRemove.pop(); - } - } - - if (this._columns.length === 1) { - this._columns = [] - } else { - this._columns.splice(this._columns.indexOf(toRemove[0]), 1); - } - } - } - - setFieldType = (column: Col, type: TemplateFieldType) => { - if (this.selectedFields.includes(column.title)) { - this._dataViz?.setFieldType(column.title, type); - } else { - column.type = type; - } - this.forceUpdate(); - } - - setFieldDesc = (column: Col, desc: string) => { - if (this.selectedFields.includes(column.title)) { - this._dataViz?.setFieldDesc(column.title, desc); - } else { - column.desc = desc; - } - this.forceUpdate(); - } - - matchesForTemplate = (template: TemplateDocInfos, cols: Col[]): number[][] => { - const colMatchesField = (col: Col, field : Field) => { return field.sizes?.includes(col.size) && field.types.includes(col.type) }; - - const matches: number[][] = Array(template.fields.length).fill([]).map(() => []); - console.log(matches) - template.fields.forEach((field, i) => { - cols.forEach((col, v) => { - if (colMatchesField(col, field)) { - matches[i].push(v); - } - }); - }); - - return matches; - } - - maxMatches = (fieldsCt: number, matches: number[][]) => { - const used: boolean[] = Array(fieldsCt).fill(false); - const mt: number[] = Array(fieldsCt).fill(-1); - - const augmentingPath = (v: number): boolean => { - if (used[v]) return false; - used[v] = true; - for (const to of matches[v]) { - if (mt[to] === -1 || augmentingPath(mt[to])) { - mt[to] = v; - return true; - } - } - return false; - } - - for (let v = 0; v < fieldsCt; ++v) { - used.fill(false); - augmentingPath(v); - } - - let count: number = 0; - - for (let i = 0; i < fieldsCt; ++i) { - if (mt[i] !== -1) ++count; - } - - return count; - } - - - findValidTemplates = (cols: Col[], templates: TemplateDocInfos[]) => { - const validTemplates: string[] = []; - templates.forEach(template => { - const numFields = template.fields.length; - const matches = this.matchesForTemplate(template, cols); - if (this.maxMatches(numFields, matches) === numFields) { - validTemplates.push(template.title); - } - }) - - 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 ( @@ -1115,16 +1107,24 @@ type Col = { type Field = { tl: [number, number], br: [number, number], - types: TemplateFieldType[], + types?: TemplateFieldType[], sizes?: FieldSize[], opts: FieldOpts; }; +type InkDecoration = { + +} + +type TemplateDecorations = Field | InkDecoration; + export interface TemplateDocInfos { title: string; height: number; width: number; + opts: TemplateOpts; fields: Field[]; + decorations: Field[]; } export interface FieldOpts { @@ -1142,6 +1142,10 @@ export interface FieldOpts { fontTransform?: 'toUpper' | 'toLower'; } +interface TemplateOpts extends 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}} => { @@ -1153,6 +1157,29 @@ export class FieldFuncs { return {width, height, coord}; } + public static FreeformField = (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 docWithBasicOpts = (Docs.Create.FreeformDocument)([], { + _height: height, + _width: width, + title: title, + x: coord.x, + y: coord.y, + _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 docWithBasicOpts; + } + public static TextField = (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); @@ -1217,6 +1244,7 @@ export class TemplateLayouts { title: 'fourfield1', width: 450, height: 600, + opts: {}, fields: [{ tl: [-.6, -.9], br: [.6, -.8], @@ -1249,46 +1277,92 @@ export class TemplateLayouts { opts: { } - }] + }], + decorations: [], }; public static FourField002: TemplateDocInfos = { title: 'fourfield2', width: 475, height: 870, + opts: { + backgroundColor: '#242425' + }, fields: [{ - tl: [-.95, -.83], - br: [-.15, .83], - types: [TemplateFieldType.VISUAL], + tl: [-.83, -.95], + br: [.83, -.2], + types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT], sizes: [FieldSize.MEDIUM, FieldSize.LARGE], opts: { - + borderWidth: '8', + borderColor: 'yellow', } }, { - tl: [-.9, -.7], - br: [.9, .2], - types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL], - sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE], + tl: [-.45, -.18], + br: [.45, 0], + types: [TemplateFieldType.TEXT], + sizes: [FieldSize.TINY, FieldSize.SMALL], opts: { - + backgroundColor: 'transparent', + color: 'white' } }, { - tl: [-.6, .3], - br: [.6, .4], + tl: [-.45, 0], + br: [.45, .18], types: [TemplateFieldType.TEXT], - sizes: [FieldSize.TINY], + sizes: [FieldSize.TINY, FieldSize.SMALL], opts: { - + backgroundColor: 'transparent', + color: 'white' } }, { - tl: [-.9, .5], - br: [.9, .9], + tl: [-.83, .2], + br: [.83, .95], types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL], sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE], opts: { - + borderWidth: '8', + borderColor: 'yellow', + } + }], + decorations: [{ + tl: [-.8, -.075], + br: [-.525, .075], + opts: { + backgroundColor: 'yellow', + rotation: 45 + } + }, { + tl: [-.3075, -.0245], + br: [-.2175, .0245], + opts: { + backgroundColor: 'yellow', + rotation: 45 + } + }, { + tl: [-.045, -.0245], + br: [.045, .0245], + opts: { + backgroundColor: 'yellow', + rotation: 45 + } + }, { + tl: [.2175, -.0245], + br: [.3075, .0245], + opts: { + backgroundColor: 'yellow', + rotation: 45 } - }] + }, { + tl: [.525, -.075], + br: [.8, .075], + opts: { + backgroundColor: 'yellow', + rotation: 45 + } + } + + ] }; // public static FourField002: TemplateDocInfos = { |