diff options
author | bob <bcz@cs.brown.edu> | 2019-03-26 13:56:50 -0400 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-03-26 13:56:50 -0400 |
commit | b9d23e5adde2da01708cc8501ca375726d232d06 (patch) | |
tree | d6619061e76d95dfa1a355219af146471f09f9bb | |
parent | 8335f0ba0b780a0ed0619e52076f051f122e4865 (diff) |
some filtering
-rw-r--r-- | src/client/northstar/core/filter/FilterModel.ts | 48 | ||||
-rw-r--r-- | src/client/northstar/core/filter/IBaseFilterConsumer.ts | 4 | ||||
-rw-r--r-- | src/client/northstar/operations/BaseOperation.ts | 2 | ||||
-rw-r--r-- | src/client/northstar/operations/HistogramOperation.ts | 57 | ||||
-rw-r--r-- | src/client/views/nodes/HistogramBox.tsx | 35 |
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); } |