aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/Main.tsx45
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx4
-rw-r--r--src/client/views/nodes/FieldView.tsx7
-rw-r--r--src/client/views/nodes/HistogramBox.scss8
-rw-r--r--src/client/views/nodes/HistogramBox.tsx67
5 files changed, 120 insertions, 11 deletions
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index b0ca347df..d79907518 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -1,4 +1,4 @@
-import { action, configure, observable, runInAction, trace, computed } from 'mobx';
+import { action, configure, observable, runInAction, trace, computed, reaction } from 'mobx';
import "normalize.css";
import * as React from 'react';
import * as ReactDOM from 'react-dom';
@@ -22,7 +22,6 @@ import "./Main.scss";
import { observer } from 'mobx-react';
import { InkingControl } from './InkingControl';
import { RouteStore } from '../../server/RouteStore';
-import { json } from 'body-parser';
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFont } from '@fortawesome/free-solid-svg-icons';
@@ -36,15 +35,17 @@ import { faRedoAlt } from '@fortawesome/free-solid-svg-icons';
import { faPenNib } from '@fortawesome/free-solid-svg-icons';
import { faFilm } from '@fortawesome/free-solid-svg-icons';
import { faMusic } from '@fortawesome/free-solid-svg-icons';
+import { faTree } from '@fortawesome/free-solid-svg-icons';
import Measure from 'react-measure';
import { DashUserModel } from '../../server/authentication/models/user_model';
import { ServerUtils } from '../../server/ServerUtil';
import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
import { Field, Opt } from '../../fields/Field';
import { ListField } from '../../fields/ListField';
-import { map } from 'bluebird';
import { Gateway, Settings } from '../northstar/manager/Gateway';
-import { Catalog } from '../northstar/model/idea/idea';
+import { Catalog, Schema, Attribute, AttributeGroup } from '../northstar/model/idea/idea';
+import { ArrayUtil } from '../northstar/utils/ArrayUtil';
+import '../northstar/model/ModelExtensions'
@observer
export class Main extends React.Component {
@@ -85,20 +86,50 @@ export class Main extends React.Component {
library.add(faPenNib);
library.add(faFilm);
library.add(faMusic);
+ library.add(faTree);
this.initEventListeners();
Documents.initProtos(() => this.initAuthenticationRouters());
+
+ reaction(() => [this.mainContainer, this.ActiveSchema],
+ () => {
+ if (this.mainContainer && this.ActiveSchema) {
+ if (!this.mainContainer!.GetTAsync(KeyStore.ActiveDB, ListField, field => this.NorthstarCatalog = field!.Data as Document[])) {
+ this.NorthstarCatalog = this.GetAllAttributes().map(a => Documents.HistogramDocument({ width: 200, height: 200, title: a.displayName! }));
+ this.mainContainer!.SetData(KeyStore.ActiveDB, this.NorthstarCatalog, ListField);
+ }
+ }
+ })
}
+ NorthstarCatalog: Document[] = [];
+ @observable ActiveSchema: Schema | undefined;
@action SetNorthstarCatalog(ctlog: Catalog) {
this._northstarCatalog = ctlog;
- if (this._northstarCatalog) {
+ if (this._northstarCatalog && this._northstarCatalog.schemas) {
console.log("CATALOG " + this._northstarCatalog.schemas);
+ this.ActiveSchema = ArrayUtil.FirstOrDefault<Schema>(this._northstarCatalog.schemas!, (s: Schema) => s.displayName === "mimic");
+ }
+ }
+ public GetAllAttributes() {
+ if (!this.ActiveSchema || !this.ActiveSchema.rootAttributeGroup) {
+ return [];
}
+ const recurs = (attrs: Attribute[], g: AttributeGroup) => {
+ if (g.attributes) {
+ attrs.push.apply(attrs, g.attributes);
+ if (g.attributeGroups) {
+ g.attributeGroups.forEach(ng => recurs(attrs, ng));
+ }
+ }
+ };
+ const allAttributes: Attribute[] = new Array<Attribute>();
+ recurs(allAttributes, this.ActiveSchema.rootAttributeGroup);
+ return allAttributes;
}
async initializeNorthstar(): Promise<void> {
- let envPath = "assets/env.json";
+ let envPath = "/assets/env.json";
const response = await fetch(envPath, {
redirect: "follow",
method: "GET",
@@ -253,6 +284,7 @@ export class Main extends React.Component {
let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" }))
let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
let addSchemaNode = action(() => Documents.SchemaDocument([], { width: 200, height: 200, title: "a schema collection" }));
+ let addTreeNode = action(() => Documents.TreeDocument(this.NorthstarCatalog, { width: 200, height: 200, title: "a tree collection" }));
let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, height: 200, title: "video node" }));
let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, height: 200, title: "a schema collection" }));
let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
@@ -267,6 +299,7 @@ export class Main extends React.Component {
[React.createRef<HTMLDivElement>(), "music", "Add Audio", addAudioNode],
[React.createRef<HTMLDivElement>(), "globe-asia", "Add Web Clipping", addWebNode],
[React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
+ [React.createRef<HTMLDivElement>(), "tree", "Add Tree", addTreeNode],
[React.createRef<HTMLDivElement>(), "table", "Add Schema", addSchemaNode],
]
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index ce72ab64b..2f0459f88 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -19,6 +19,7 @@ import { KeyValueBox } from "./KeyValueBox";
import { PDFBox } from "./PDFBox";
import { VideoBox } from "./VideoBox";
import { WebBox } from "./WebBox";
+import { HistogramBox } from "./HistogramBox";
import React = require("react");
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
@@ -47,8 +48,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
render() {
return <JsxParser
- components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
- bindings={this.CreateBindings()}
+ components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }} bindings={this.CreateBindings()}
jsx={this.layout}
showWarnings={true}
onError={(test: any) => { console.log(test) }}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index b6d50bffb..f6343c631 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -7,7 +7,6 @@ import { TextField } from "../../../fields/TextField";
import { NumberField } from "../../../fields/NumberField";
import { RichTextField } from "../../../fields/RichTextField";
import { ImageField } from "../../../fields/ImageField";
-import { WebField } from "../../../fields/WebField";
import { VideoField } from "../../../fields/VideoField"
import { Key } from "../../../fields/Key";
import { FormattedTextBox } from "./FormattedTextBox";
@@ -64,9 +63,11 @@ export class FieldView extends React.Component<FieldViewProps> {
}
else if (field instanceof AudioField) {
return <AudioBox {...this.props} />
- } else if (field instanceof Document) {
+ }
+ else if (field instanceof Document) {
return <div>{field.Title}</div>
- } else if (field instanceof ListField) {
+ }
+ else if (field instanceof ListField) {
return (<div>
{(field as ListField<Field>).Data.map(f => {
return f instanceof Document ? f.Title : f.GetValue().toString();
diff --git a/src/client/views/nodes/HistogramBox.scss b/src/client/views/nodes/HistogramBox.scss
new file mode 100644
index 000000000..04bf1d732
--- /dev/null
+++ b/src/client/views/nodes/HistogramBox.scss
@@ -0,0 +1,8 @@
+.histogrambox-container {
+ padding: 0vw;
+ position: relative;
+ text-align: center;
+ width: 100%;
+ height: 100%;
+ }
+ \ No newline at end of file
diff --git a/src/client/views/nodes/HistogramBox.tsx b/src/client/views/nodes/HistogramBox.tsx
new file mode 100644
index 000000000..0fcc25e66
--- /dev/null
+++ b/src/client/views/nodes/HistogramBox.tsx
@@ -0,0 +1,67 @@
+import React = require("react")
+import { observer } from "mobx-react";
+import { FieldView, FieldViewProps } from './FieldView';
+import "./VideoBox.scss";
+import { observable, reaction } from "mobx";
+import { HistogramOperation } from "../../northstar/operations/HistogramOperation";
+import { Main } from "../Main";
+import { ColumnAttributeModel } from "../../northstar/core/attribute/AttributeModel";
+import { AttributeTransformationModel } from "../../northstar/core/attribute/AttributeTransformationModel";
+import { AggregateFunction, HistogramResult, DoubleValueAggregateResult } from "../../northstar/model/idea/idea";
+import { ModelHelpers } from "../../northstar/model/ModelHelpers";
+
+@observer
+export class HistogramBox extends React.Component<FieldViewProps> {
+
+ public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(HistogramBox, fieldStr) }
+
+ constructor(props: FieldViewProps) {
+ super(props);
+ }
+
+ @observable _histoResult?: HistogramResult;
+ _histoOp?: HistogramOperation;
+
+ componentDidMount() {
+ Main.Instance.GetAllAttributes().map(a => {
+ if (a.displayName == this.props.doc.Title) {
+ var atmod = new ColumnAttributeModel(a);
+ this._histoOp = new HistogramOperation(new AttributeTransformationModel(atmod, AggregateFunction.None),
+ new AttributeTransformationModel(atmod, AggregateFunction.Count),
+ new AttributeTransformationModel(atmod, AggregateFunction.Count));
+ reaction(() => [this._histoOp && this._histoOp.Result],
+ () => this._histoResult = this._histoOp ? this._histoOp.Result as HistogramResult : undefined
+ );
+ this._histoOp.Update();
+ }
+ })
+ }
+
+ twoString() {
+ let str = "";
+ if (this._histoResult && !this._histoResult.isEmpty) {
+ for (let key in this._histoResult.bins) {
+ if (this._histoResult.bins.hasOwnProperty(key)) {
+ let bin = this._histoResult.bins[key];
+ str += JSON.stringify(bin.binIndex!.toJSON()) + " = ";
+ let valueAggregateKey = ModelHelpers.CreateAggregateKey(this._histoOp!.V, this._histoResult, ModelHelpers.AllBrushIndex(this._histoResult));
+ let value = ModelHelpers.GetAggregateResult(bin, valueAggregateKey) as DoubleValueAggregateResult;
+ if (value && value.hasResult && value.result) {
+ str += value.result;
+ }
+ }
+ }
+ }
+ return str;
+ }
+
+ render() {
+ if (!this._histoResult)
+ return (null);
+ return (
+ <div className="histogrambox-container">
+ `HISTOGRAM RESULT : ${this.twoString()}`
+ </div>
+ )
+ }
+} \ No newline at end of file