aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.tsx3
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx11
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes.tsx274
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx10
4 files changed, 218 insertions, 80 deletions
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 14e0a8e66..311a0ad65 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -32,11 +32,12 @@ import { DocumentView } from '../DocumentView';
import { FieldView, FieldViewProps } from '../FieldView';
import { FocusViewOptions } from '../FocusViewOptions';
import './DataVizBox.scss';
-import { Col, DataVizTemplateInfo, DocCreatorMenu, LayoutType, TemplateFieldSize, TemplateFieldType } from './DocCreatorMenu/DocCreatorMenu';
+import { Col, DataVizTemplateInfo, DocCreatorMenu, LayoutType} from './DocCreatorMenu/DocCreatorMenu';
import { Histogram } from './components/Histogram';
import { LineChart } from './components/LineChart';
import { PieChart } from './components/PieChart';
import { TableBox } from './components/TableBox';
+import { TemplateFieldSize, TemplateFieldType } from './DocCreatorMenu/TemplateBackend';
export enum DataVizView {
TABLE = 'table',
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index c34403e79..c86264716 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -379,8 +379,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
this._selectedTemplate = template;
MakeTemplate(template);
const templateInfo: DataVizTemplateInfo = { doc: template, layout: this._layout, referencePos: { x: this._pageX + 450, y: this._pageY }, columns: this.columnsCount };
- // this._fullyRenderedDocs = this._dataViz?.createDocsFromTemplate(templateInfo, true) ?? [];
- // this.updateRenderedDocCollection();
+ this._fullyRenderedDocs = this._dataViz?.createDocsFromTemplate(templateInfo, true) ?? [];
+ this.updateRenderedDocCollection();
}
};
@@ -724,7 +724,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
col.desc;
const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT);
- console.log(sysPrompt, prompt);
+ //console.log(sysPrompt, prompt);
return createGeneratedImage(fieldNum, col, prompt);
})
@@ -781,7 +781,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
});
template.decorations.forEach(dec => {
- const doc = FieldUtils.FreeformField(
+ console.log(dec);
+ const doc = FieldUtils.TextField(
{
tl: dec.tl,
br: dec.br,
@@ -1814,4 +1815,4 @@ export class FieldUtils {
return doc;
};
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes.tsx
index 119de88d0..f30183ed3 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/FieldTypes.tsx
@@ -1,8 +1,9 @@
import { Doc } from "../../../../../fields/Doc";
import { FieldType } from "../../../../../fields/ObjectField";
import { Docs, DocumentOptions } from "../../../../documents/Documents";
+import { Col } from "./DocCreatorMenu";
import { Template } from "./Template";
-import { TemplateFieldSize, TemplateFieldType } from "./TemplateBackend";
+import { TemplateDocInfos, TemplateFieldSize, TemplateFieldType } from "./TemplateBackend";
export enum FieldContentType {
STRING = 'string',
@@ -14,6 +15,12 @@ export enum ViewType {
FREEFORM = 'freeform',
}
+export type FieldDimensions = {
+ width: number;
+ height: number;
+ coord: {x: number, y: number};
+}
+
export interface FieldOpts {
backgroundColor?: string;
color?: string;
@@ -41,25 +48,37 @@ export type FieldSettings = {
description?: string;
};
-export class Field {
+export interface Field {
+ getContent: () => string;
+ setContent: (content: string) => void;
+ getDimensions: FieldDimensions;
+ getSubfields: Field[];
+ getAllSubfields: Field[];
+ setupSubfields: () => Field[];
+ renderedDoc: (content: string) => Doc;
+ matches: () => number[][];
+}
+
+export class StaticField {
private content: string;
private contentType: FieldContentType | undefined;
- private subfields: Field[] | undefined;
+ private subfields: Field[] = [];
private settings: FieldSettings;
- private parent: Field | Template;
- private dimensions: { width: number; height: number; coord: { x: number; y: number }};
+ private parent: Field;
+ private dimensions: FieldDimensions;
- constructor(settings: FieldSettings, parent: Field | Template) {
+ constructor(settings: FieldSettings, parent: Field, autoSetupFields: boolean = true) {
this.settings = settings;
this.parent = parent;
- this.dimensions = this.parent.getChildDimensions({tl: settings.tl, br: settings.br});
+ this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions);
this.content = '';
- this.setupSubfields();
- }
+ if (autoSetupFields) { this.subfields = this.setupSubfields(); }
+ };
get getSubfields(): Field[] { return this.subfields ?? []; };
+
get getAllSubfields(): Field[] {
const fields: Field[] = [];
this.subfields?.forEach(field => {
@@ -67,22 +86,33 @@ export class Field {
fields.concat(field.getAllSubfields)
});
return fields;
- }
+ };
+
+ get getDimensions() { return this.dimensions };
setContent = (newContent: string) => { this.content = newContent };
getContent() { return this.content };
- setupSubfields = () => {
+ setupSubfields = (): Field[] => {
+ const fields: Field[] = [];
this.settings.subfields?.forEach(fieldSettings => {
let field: Field;
const dynamicType = fieldSettings.dynamicType;
- if (dynamicType) { field = new DynamicField(fieldSettings, this, dynamicType); }
+ if (dynamicType) {
+ field = new DynamicField(fieldSettings, this, dynamicType);
+ } else {
+ field = new StaticField(fieldSettings, this);
+ }
- field = new Field(fieldSettings, this);
- this.subfields?.push(field);
+ fields.push(field);
});
- }
+ return fields;
+ };
+
+ matches = (): number[][] => {
+ return [];
+ };
renderedDoc = (content: string): Doc => {
const opts = this.settings.opts;
@@ -97,21 +127,72 @@ export class Field {
contentBold: opts.fontBold,
textTransform: opts.fontTransform,
color: opts.color,
- _text_fontSize: `${this.calculateFontSize(this.dimensions.width, this.dimensions.height, text, true)}`
+ _text_fontSize: `${FieldUtils.calculateFontSize(this.dimensions.width, this.dimensions.height, text, true)}`
});
- this.applyBasicOpts(textDoc);
+ FieldUtils.applyBasicOpts(textDoc, this.dimensions, this.settings);
return textDoc;
case FieldContentType.IMAGE:
const url = String(content);
const imgDoc = Docs.Create.ImageDocument(url, {
_layout_fitWidth: false,
});
- this.applyBasicOpts(imgDoc);
+ FieldUtils.applyBasicOpts(imgDoc, this.dimensions, this.settings);
return imgDoc;
}
+ };
+
+}
+
+class DynamicField implements Field {
+ private type: ViewType;
+ private subfields: Field[] = [];
+
+ private settings: FieldSettings;
+
+ private parent: Field;
+ private dimensions: FieldDimensions;
+
+ constructor(settings: FieldSettings, parent: Field, type: ViewType) {
+ this.type = type;
+ this.settings = settings;
+ this.parent = parent;
+ this.dimensions = FieldUtils.getLocalDimensions({tl: settings.tl, br: settings.br}, this.parent.getDimensions);
+ this.subfields = this.setupSubfields();
+ }
+
+ setContent = (content: string) => { return };
+ getContent = () => { return '' };
+
+ get getSubfields() { return this.subfields };
+ get getAllSubfields() {
+ const fields: Field[] = [];
+ this.subfields?.forEach(field => {
+ fields.push(field);
+ fields.concat(field.getAllSubfields)
+ });
+ return fields;
+ };
+
+ get getDimensions() { return this.dimensions };
+
+ matches = () => {
+ return [];
}
- getChildDimensions = (coords: { tl: [number, number]; br: [number, number] }): { width: number; height: number; coord: { x: number; y: number } } => {
+ setupSubfields = (): Field[] => {
+ this.settings.subfields?.forEach(fieldSettings => {
+ let field: Field;
+ const dynamicType = fieldSettings.dynamicType;
+
+ if (dynamicType) { field = new DynamicField(fieldSettings, this, dynamicType); }
+
+ field = new StaticField(fieldSettings, this);
+ this.subfields?.push(field);
+ });
+ return [];
+ }
+
+ getChildDimensions = (coords: { tl: [number, number]; br: [number, number] }): FieldDimensions => {
const l = (coords.tl[0] * this.dimensions.height) / 2;
const t = coords.tl[1] * this.dimensions.width / 2; //prettier-ignore
const r = (coords.br[0] * this.dimensions.height) / 2;
@@ -122,13 +203,113 @@ export class Field {
return { width, height, coord };
};
- applyBasicOpts = (doc: Doc) => {
- const opts = this.settings.opts;
+ renderedDoc = (): Doc => {
+ switch (this.type) {
+ case ViewType.CAROUSEL3D:
+ const carouselDoc = Docs.Create.Carousel3DDocument([], {
+ });
+ FieldUtils.applyBasicOpts(carouselDoc, this.dimensions, this.settings);
+ case ViewType.FREEFORM:
+ const freeformDoc = Docs.Create.FreeformDocument([], {
+ });
+ FieldUtils.applyBasicOpts(freeformDoc, this.dimensions, this.settings);
+ default:
+ return new Doc();
+ }
+ }
+
+}
+
+export class TemplateMatcher {
+
+ static matchesForTemplate = (field: FieldSettings, cols: Col[]): number[][] => {
+ const colMatchesField = (col: Col, field: FieldSettings) => {
+ return field.sizes?.some(size => col.sizes?.includes(size)) && field.types?.includes(col.type);
+ };
+
+ const matches: number[][] = Array(field.subfields?.length)
+ .fill([])
+ .map(() => []);
+
+ field.subfields?.forEach((field, i) => {
+ cols.forEach((col, v) => {
+ if (colMatchesField(col, field)) {
+ matches[i].push(v);
+ }
+ });
+ });
+
+ return matches;
+ };
+
+ static 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[]) => {
+ let validTemplates: any[] = [];
+ templates.forEach(template => {
+ const numFields = template.fields.length;
+ if (!(numFields === cols.length)) return;
+ const matches = this.matchesForTemplate(template, cols);
+ if (this.maxMatches(numFields, matches) === numFields) {
+ validTemplates.push(template.title);
+ }
+ });
+
+ validTemplates = validTemplates.map(title => TemplateLayouts.getTemplateByTitle(title));
+
+ return validTemplates;
+ };
+
+}
+
+
+export class FieldUtils {
+ public static getLocalDimensions = (coords: { tl: [number, number]; br: [number, number] }, parentDimensions: FieldDimensions): FieldDimensions => {
+ const l = (coords.tl[0] * parentDimensions.height) / 2;
+ const t = coords.tl[1] * parentDimensions.width / 2; //prettier-ignore
+ const r = (coords.br[0] * parentDimensions.height) / 2;
+ const b = coords.br[1] * parentDimensions.width / 2; //prettier-ignore
+ const width = r - l;
+ const height = b - t;
+ const coord = { x: l, y: t };
+ return { width, height, coord };
+ };
+
+ public static applyBasicOpts = (doc: Doc, parentDimensions: FieldDimensions, settings: FieldSettings) => {
+ const opts = settings.opts;
doc.isDefaultTemplateDoc = true,
- doc.x = this.dimensions.coord.x;
- doc.y = this.dimensions.coord.y;
- doc._height = this.dimensions.height;
- doc._width = this.dimensions.width;
+ doc.x = parentDimensions.coord.x;
+ doc.y = parentDimensions.coord.y;
+ doc._height = parentDimensions.height;
+ doc._width = parentDimensions.width;
doc.backgroundColor = opts.backgroundColor ?? '';
doc._layout_borderRounding = `${opts.cornerRounding ?? 0}px`;
doc.borderColor = opts.borderColor;
@@ -136,9 +317,9 @@ export class Field {
doc.opacity = opts.opacity;
doc._rotation = opts.rotation;
doc.hCentering = opts.contentXCentering;
- }
+ };
- calculateFontSize = (contWidth: number, contHeight: number, text: string, uppercase: boolean): number => {
+ public static calculateFontSize = (contWidth: number, contHeight: number, text: string, uppercase: boolean): number => {
const words: string[] = text.split(/\s+/).filter(Boolean);
let currFontSize = 1;
@@ -178,41 +359,4 @@ export class Field {
return currFontSize - 1;
};
-
-}
-
-class DynamicField extends Field {
- type: ViewType;
-
- constructor(settings: FieldSettings, parent: Field | Template, type: ViewType) {
- super(settings, parent);
- this.type = type;
- }
-
- renderedDoc = (): Doc => {
- switch (this.type) {
- case ViewType.CAROUSEL3D:
- const carouselDoc = Docs.Create.Carousel3DDocument([], {
- });
- this.applyBasicOpts(carouselDoc);
- case ViewType.FREEFORM:
- const freeformDoc = Docs.Create.FreeformDocument([], {
- });
- this.applyBasicOpts(freeformDoc);
- default:
- return new Doc();
- }
- }
-
-
-
-}
-
-
-type DecorationField = FieldSettings;
-
-type InkDecoration = {};
-
-type TemplateDecorations = FieldSettings | InkDecoration;
-
-interface TemplateOpts extends FieldOpts {}
+} \ No newline at end of file
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
index f9bf22047..57565906b 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/Template.tsx
@@ -6,23 +6,15 @@ import { TemplateDocInfos } from "./TemplateBackend";
export class Template {
+ mainField: Field;
width: number = 0;
height: number = 0;
fields: Field[] = [];
- mainDoc: Doc;
constructor(templateInfo: TemplateDocInfos) {
this.width = templateInfo.width;
this.height = templateInfo.height;
this.fields = templateInfo.fields.map(settings => new Field(settings, this));
- this.mainDoc = this.setupMainDoc();
- }
-
- setupMainDoc = (): Doc => {
- Docs.Create.FreeformDocument(, ){
-
- }
- return new Doc;
}
get childFields(): Field[] {