aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2019-03-26 13:56:50 -0400
committerbob <bcz@cs.brown.edu>2019-03-26 13:56:50 -0400
commitb9d23e5adde2da01708cc8501ca375726d232d06 (patch)
treed6619061e76d95dfa1a355219af146471f09f9bb
parent8335f0ba0b780a0ed0619e52076f051f122e4865 (diff)
some filtering
-rw-r--r--src/client/northstar/core/filter/FilterModel.ts48
-rw-r--r--src/client/northstar/core/filter/IBaseFilterConsumer.ts4
-rw-r--r--src/client/northstar/operations/BaseOperation.ts2
-rw-r--r--src/client/northstar/operations/HistogramOperation.ts57
-rw-r--r--src/client/views/nodes/HistogramBox.tsx35
5 files changed, 110 insertions, 36 deletions
diff --git a/src/client/northstar/core/filter/FilterModel.ts b/src/client/northstar/core/filter/FilterModel.ts
index 01bf2a809..a9c79d245 100644
--- a/src/client/northstar/core/filter/FilterModel.ts
+++ b/src/client/northstar/core/filter/FilterModel.ts
@@ -1,8 +1,13 @@
import { ValueComparison } from "./ValueComparision";
import { Utils } from "../../utils/Utils";
-import { IBaseFilterProvider } from "./IBaseFilterProvider";
+import { IBaseFilterProvider, instanceOfIBaseFilterProvider } from "./IBaseFilterProvider";
import { BaseOperation } from "../../operations/BaseOperation";
import { FilterOperand } from "./FilterOperand";
+import { HistogramField } from "../../../../fields/HistogramField";
+import { KeyStore } from "../../../../fields/KeyStore";
+import { filter } from "bluebird";
+import { FieldWaiting } from "../../../../fields/Field";
+import { Document } from "../../../../fields/Document";
export class FilterModel {
public ValueComparisons: ValueComparison[];
@@ -38,6 +43,47 @@ export class FilterModel {
let ret = filters.filter(f => f !== "").join(" && ");
return ret;
}
+ public static GetFilterModelsRecursive(baseOperation: IBaseFilterProvider, visitedFilterProviders: Set<IBaseFilterProvider>, filterModels: FilterModel[], isFirst: boolean): string {
+ let ret = "";
+ visitedFilterProviders.add(baseOperation);
+ let filtered = baseOperation.FilterModels.filter(fm => fm && fm.ValueComparisons.length > 0);
+ if (!isFirst && filtered.length > 0) {
+ filterModels.push(...filtered);
+ ret = "(" + baseOperation.FilterModels.filter(fm => fm != null).map(fm => fm.ToPythonString()).join(" || ") + ")";
+ }
+ if (Utils.isBaseFilterConsumer(baseOperation) && baseOperation.Links) {
+ let children = new Array<string>();
+ let linkedGraphNodes = baseOperation.Links;
+ linkedGraphNodes.map(linkVm => {
+ let filterDoc = linkVm.Get(KeyStore.LinkedFromDocs);
+ if (filterDoc && filterDoc != FieldWaiting && filterDoc instanceof Document) {
+ let filterHistogram = filterDoc.GetT(KeyStore.Data, HistogramField);
+ if (filterHistogram && filterHistogram != FieldWaiting) {
+ if (!visitedFilterProviders.has(filterHistogram.Data)) {
+ let child = FilterModel.GetFilterModelsRecursive(filterHistogram.Data, visitedFilterProviders, filterModels, false);
+ if (child !== "") {
+ // if (linkVm.IsInverted) {
+ // child = "! " + child;
+ // }
+ children.push(child);
+ }
+ }
+ }
+ }
+ });
+
+ let childrenJoined = children.join(baseOperation.FilterOperand === FilterOperand.AND ? " && " : " || ");
+ if (children.length > 0) {
+ if (ret !== "") {
+ ret = "(" + ret + " && (" + childrenJoined + "))";
+ }
+ else {
+ ret = "(" + childrenJoined + ")";
+ }
+ }
+ }
+ return ret;
+ }
// public static GetFilterModelsRecursive(baseOperation: BaseOperation,
// visitedFilterProviders: Set<IBaseFilterProvider>, filterModels: FilterModel[], isFirst: boolean): string {
diff --git a/src/client/northstar/core/filter/IBaseFilterConsumer.ts b/src/client/northstar/core/filter/IBaseFilterConsumer.ts
index 3eb32b6db..93f66a154 100644
--- a/src/client/northstar/core/filter/IBaseFilterConsumer.ts
+++ b/src/client/northstar/core/filter/IBaseFilterConsumer.ts
@@ -1,10 +1,10 @@
import { FilterOperand } from '../filter/FilterOperand'
import { IEquatable } from '../../utils/IEquatable'
-import { IBaseFilterProvider } from './IBaseFilterProvider';
+import { Document } from "../../../../fields/Document";
export interface IBaseFilterConsumer extends IEquatable {
FilterOperand: FilterOperand;
- Links: IBaseFilterProvider[];
+ Links: Document[];
}
export function instanceOfIBaseFilterConsumer(object: any): object is IBaseFilterConsumer {
diff --git a/src/client/northstar/operations/BaseOperation.ts b/src/client/northstar/operations/BaseOperation.ts
index 4c0303a48..4bc8873d5 100644
--- a/src/client/northstar/operations/BaseOperation.ts
+++ b/src/client/northstar/operations/BaseOperation.ts
@@ -25,6 +25,8 @@ export abstract class BaseOperation {
@computed
public get FilterString(): string {
+ // let filterModels: FilterModel[] = [];
+ // return FilterModel.GetFilterModelsRecursive(this, new Set<GraphNode<BaseOperationViewModel, FilterLinkViewModel>>(), filterModels, true)
// if (this.OverridingFilters.length > 0) {
// return "(" + this.OverridingFilters.filter(fm => fm != null).map(fm => fm.ToPythonString()).join(" || ") + ")";
// }
diff --git a/src/client/northstar/operations/HistogramOperation.ts b/src/client/northstar/operations/HistogramOperation.ts
index 0c38679e5..93946b296 100644
--- a/src/client/northstar/operations/HistogramOperation.ts
+++ b/src/client/northstar/operations/HistogramOperation.ts
@@ -1,23 +1,24 @@
-import { reaction, computed, action, observable } from "mobx";
-import { Attribute, DataType, QuantitativeBinRange, HistogramOperationParameters, AggregateParameters, AggregateFunction, AverageAggregateParameters } from "../model/idea/idea";
-import { ArrayUtil } from "../utils/ArrayUtil";
-import { CalculatedAttributeManager } from "../core/attribute/CalculatedAttributeModel";
-import { ModelHelpers } from "../model/ModelHelpers";
-import { SETTINGS_X_BINS, SETTINGS_Y_BINS, SETTINGS_SAMPLE_SIZE } from "../model/binRanges/VisualBinRangeHelper";
-import { AttributeTransformationModel } from "../core/attribute/AttributeTransformationModel";
-import { BaseOperation } from "./BaseOperation";
+import { action, computed, observable } from "mobx";
+import { Document } from "../../../fields/Document";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
-import { FilterModel } from "../core/filter/FilterModel";
+import { ColumnAttributeModel } from "../core/attribute/AttributeModel";
+import { AttributeTransformationModel } from "../core/attribute/AttributeTransformationModel";
+import { CalculatedAttributeManager } from "../core/attribute/CalculatedAttributeModel";
import { BrushLinkModel } from "../core/brusher/BrushLinkModel";
-import { IBaseFilterConsumer } from "../core/filter/IBaseFilterConsumer";
+import { FilterModel } from "../core/filter/FilterModel";
import { FilterOperand } from "../core/filter/FilterOperand";
+import { IBaseFilterConsumer } from "../core/filter/IBaseFilterConsumer";
import { IBaseFilterProvider } from "../core/filter/IBaseFilterProvider";
-import { AttributeModel, ColumnAttributeModel } from "../core/attribute/AttributeModel";
+import { SETTINGS_SAMPLE_SIZE, SETTINGS_X_BINS, SETTINGS_Y_BINS } from "../model/binRanges/VisualBinRangeHelper";
+import { AggregateFunction, AggregateParameters, Attribute, AverageAggregateParameters, DataType, HistogramOperationParameters, QuantitativeBinRange } from "../model/idea/idea";
+import { ModelHelpers } from "../model/ModelHelpers";
+import { ArrayUtil } from "../utils/ArrayUtil";
+import { BaseOperation } from "./BaseOperation";
export class HistogramOperation extends BaseOperation implements IBaseFilterConsumer, IBaseFilterProvider {
@observable public FilterOperand: FilterOperand = FilterOperand.AND;
- @observable public Links: IBaseFilterProvider[] = [];
+ @observable public Links: Document[] = [];
@observable public BrushColors: number[] = [];
@observable public Normalization: number = -1;
@observable public FilterModels: FilterModel[] = [];
@@ -27,6 +28,15 @@ export class HistogramOperation extends BaseOperation implements IBaseFilterCons
@observable public BrusherModels: BrushLinkModel<HistogramOperation>[] = [];
@observable public BrushableModels: BrushLinkModel<HistogramOperation>[] = [];
+ @action
+ public AddFilterModels(filterModels: FilterModel[]): void {
+ filterModels.filter(f => f !== null).forEach(fm => this.FilterModels.push(fm));
+ }
+ @action
+ public RemoveFilterModels(filterModels: FilterModel[]): void {
+ ArrayUtil.RemoveMany(this.FilterModels, filterModels);
+ }
+
public static Empty = new HistogramOperation(new AttributeTransformationModel(new ColumnAttributeModel(new Attribute())), new AttributeTransformationModel(new ColumnAttributeModel(new Attribute())), new AttributeTransformationModel(new ColumnAttributeModel(new Attribute())));
Equals(other: Object): boolean {
@@ -41,6 +51,19 @@ export class HistogramOperation extends BaseOperation implements IBaseFilterCons
this.Normalization = normalized ? normalized : -1;
}
+ @computed
+ public get FilterString(): string {
+ let filterModels: FilterModel[] = [];
+ let fstring = FilterModel.GetFilterModelsRecursive(this, new Set<IBaseFilterProvider>(), filterModels, true)
+ console.log("Filter string " + this.X.AttributeModel.DisplayName + " = " + fstring);
+ return fstring;
+ }
+ @computed
+ public get OutputFilterString(): string {
+ let filterModels: FilterModel[] = [];
+ return FilterModel.GetFilterModelsRecursive(this, new Set<IBaseFilterProvider>(), filterModels, false)
+ }
+
@computed.struct
public get BrushString() {
return [];
@@ -59,11 +82,11 @@ export class HistogramOperation extends BaseOperation implements IBaseFilterCons
}
- // @computed.struct
- // public get SelectionString() {
- // let filterModels = new Array<FilterModel>();
- // return FilterModel.GetFilterModelsRecursive(this, new Set<GraphNode<BaseOperationViewModel, FilterLinkViewModel>>(), filterModels, false);
- // }
+ @computed.struct
+ public get SelectionString() {
+ let filterModels = new Array<FilterModel>();
+ return FilterModel.GetFilterModelsRecursive(this, new Set<IBaseFilterProvider>(), filterModels, false);
+ }
GetAggregateParameters(histoX: AttributeTransformationModel, histoY: AttributeTransformationModel, histoValue: AttributeTransformationModel) {
let allAttributes = new Array<AttributeTransformationModel>(histoX, histoY, histoValue);
diff --git a/src/client/views/nodes/HistogramBox.tsx b/src/client/views/nodes/HistogramBox.tsx
index 73d3f3bc3..e21054e15 100644
--- a/src/client/views/nodes/HistogramBox.tsx
+++ b/src/client/views/nodes/HistogramBox.tsx
@@ -1,17 +1,19 @@
import React = require("react")
-import { computed, observable, reaction, runInAction, action, observe } from "mobx";
+import { computed, observable, reaction, runInAction, trace } from "mobx";
import { observer } from "mobx-react";
import Measure from "react-measure";
import { Dictionary } from "typescript-collections";
+import { Document } from "../../../fields/Document";
+import { Opt } from "../../../fields/Field";
+import { HistogramField } from "../../../fields/HistogramField";
+import { KeyStore } from "../../../fields/KeyStore";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { Utils as DashUtils } from '../../../Utils';
-import { ColumnAttributeModel, AttributeModel } from "../../northstar/core/attribute/AttributeModel";
-import { AttributeTransformationModel } from "../../northstar/core/attribute/AttributeTransformationModel";
import { FilterModel } from '../../northstar/core/filter/FilterModel';
import { NominalVisualBinRange } from "../../northstar/model/binRanges/NominalVisualBinRange";
import { ChartType, VisualBinRange } from '../../northstar/model/binRanges/VisualBinRange';
import { VisualBinRangeHelper } from "../../northstar/model/binRanges/VisualBinRangeHelper";
-import { AggregateBinRange, AggregateFunction, Bin, Brush, DoubleValueAggregateResult, HistogramResult, MarginAggregateParameters, MarginAggregateResult, Attribute, BinRange } from "../../northstar/model/idea/idea";
+import { AggregateBinRange, AggregateFunction, Bin, BinRange, Brush, DoubleValueAggregateResult, HistogramResult, MarginAggregateParameters, MarginAggregateResult } from "../../northstar/model/idea/idea";
import { ModelHelpers } from "../../northstar/model/ModelHelpers";
import { HistogramOperation } from "../../northstar/operations/HistogramOperation";
import { ArrayUtil } from "../../northstar/utils/ArrayUtil";
@@ -21,11 +23,6 @@ import { SizeConverter } from "../../northstar/utils/SizeConverter";
import { StyleConstants } from "../../northstar/utils/StyleContants";
import { FieldView, FieldViewProps } from './FieldView';
import "./HistogramBox.scss";
-import { KeyStore } from "../../../fields/KeyStore";
-import { ListField } from "../../../fields/ListField";
-import { Document } from "../../../fields/Document"
-import { HistogramField } from "../../../fields/HistogramField";
-import { FieldWaiting, Opt } from "../../../fields/Field";
@observer
export class HistogramBox extends React.Component<FieldViewProps> {
@@ -92,12 +89,13 @@ export class HistogramBox extends React.Component<FieldViewProps> {
if (histoOp) {
runInAction(() => this.HistoOp = histoOp.Data);
this.HistoOp!.Update();
- reaction(() => this.createOperationParamsCache, () => this.HistoOp!.Update());
+ reaction(
+ () => this.createOperationParamsCache,
+ () => this.HistoOp!.Update();
reaction(() => this.props.doc.GetList(KeyStore.LinkedFromDocs, []),
- () => {
- let linkFrom: Document[] = this.props.doc.GetData(KeyStore.LinkedFromDocs, ListField, []);
+ (docs: Document[]) => {
this.HistoOp!.Links.length = 0;
- linkFrom.map(l => this.HistoOp!.Links.push(l.GetData(KeyStore.Data, HistogramField, HistogramOperation.Empty)));
+ this.HistoOp!.Links.push(...docs);
},
{ fireImmediately: true }
);
@@ -172,7 +170,6 @@ export class HistogramBox extends React.Component<FieldViewProps> {
let filterModel = ModelHelpers.GetBinFilterModel(this.HistoOp.Result.bins![key], allBrushIndex, this.HistoOp.Result, this.HistoOp.X, this.HistoOp.Y);
-
this.HitTargets.setValue(drawPrims.HitGeom, filterModel);
if (ArrayUtil.Contains(this.HistoOp.FilterModels, filterModel)) {
@@ -180,8 +177,13 @@ export class HistogramBox extends React.Component<FieldViewProps> {
}
drawPrims.BinPrimitives.filter(bp => bp.DataValue && bp.BrushIndex !== allBrushIndex).map(binPrimitive => {
- prims.push(this.drawRect(binPrimitive.Rect, binPrimitive.Color, () => { console.log("FM = " + filterModel.ToPythonString()) }));
- prims.push(this.drawRect(binPrimitive.MarginRect, StyleConstants.MARGIN_BARS_COLOR, () => { console.log("FM = " + filterModel.ToPythonString()) }));
+ let toggleFilter = () => {
+ if ([filterModel].filter(h => ArrayUtil.Contains(this.HistoOp!.FilterModels, h)).length > 0)
+ this.HistoOp!.RemoveFilterModels([filterModel]);
+ else this.HistoOp!.AddFilterModels([filterModel]);
+ }
+ prims.push(this.drawRect(binPrimitive.Rect, binPrimitive.Color, () => runInAction(toggleFilter)));
+ prims.push(this.drawRect(binPrimitive.MarginRect, StyleConstants.MARGIN_BARS_COLOR, () => runInAction(toggleFilter)));
});
}
}
@@ -189,6 +191,7 @@ export class HistogramBox extends React.Component<FieldViewProps> {
}
render() {
+ trace();
if (!this.binPrimitives || !this.VisualBinRanges.length) {
return (null);
}