aboutsummaryrefslogtreecommitdiff
path: root/src/client/northstar/model/binRanges
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/northstar/model/binRanges')
-rw-r--r--src/client/northstar/model/binRanges/AlphabeticVisualBinRange.ts52
-rw-r--r--src/client/northstar/model/binRanges/DateTimeVisualBinRange.ts105
-rw-r--r--src/client/northstar/model/binRanges/NominalVisualBinRange.ts52
-rw-r--r--src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts90
-rw-r--r--src/client/northstar/model/binRanges/VisualBinRange.ts36
-rw-r--r--src/client/northstar/model/binRanges/VisualBinRangeHelper.ts71
6 files changed, 406 insertions, 0 deletions
diff --git a/src/client/northstar/model/binRanges/AlphabeticVisualBinRange.ts b/src/client/northstar/model/binRanges/AlphabeticVisualBinRange.ts
new file mode 100644
index 000000000..995bf4e0b
--- /dev/null
+++ b/src/client/northstar/model/binRanges/AlphabeticVisualBinRange.ts
@@ -0,0 +1,52 @@
+import { AlphabeticBinRange, BinLabel } from '../../model/idea/idea'
+import { VisualBinRange } from './VisualBinRange'
+
+export class AlphabeticVisualBinRange extends VisualBinRange {
+ public DataBinRange: AlphabeticBinRange;
+
+ constructor(dataBinRange: AlphabeticBinRange) {
+ super();
+ this.DataBinRange = dataBinRange;
+ }
+
+ public AddStep(value: number): number {
+ return value + 1;
+ }
+
+ public GetValueFromIndex(index: number): number {
+ return index;
+ }
+
+ public GetBins(): number[] {
+ var bins = new Array<number>();
+ var idx = 0;
+ for (var key in this.DataBinRange.labelsValue) {
+ if (this.DataBinRange.labelsValue.hasOwnProperty(key)) {
+ bins.push(idx);
+ idx++;
+ }
+ }
+ return bins;
+ }
+
+ public GetLabel(value: number): string {
+ return this.DataBinRange.prefix + this.DataBinRange.valuesLabel![value];
+ }
+
+ public GetLabels(): Array<BinLabel> {
+ var labels = new Array<BinLabel>();
+ var count = 0;
+ for (var key in this.DataBinRange.valuesLabel) {
+ if (this.DataBinRange.valuesLabel.hasOwnProperty(key)) {
+ var value = this.DataBinRange.valuesLabel[key];
+ labels.push(new BinLabel({
+ value: parseFloat(key),
+ minValue: count++,
+ maxValue: count,
+ label: this.DataBinRange.prefix + value
+ }));
+ }
+ }
+ return labels;
+ }
+} \ No newline at end of file
diff --git a/src/client/northstar/model/binRanges/DateTimeVisualBinRange.ts b/src/client/northstar/model/binRanges/DateTimeVisualBinRange.ts
new file mode 100644
index 000000000..9313fb1a7
--- /dev/null
+++ b/src/client/northstar/model/binRanges/DateTimeVisualBinRange.ts
@@ -0,0 +1,105 @@
+import { DateTimeBinRange, DateTimeStep, DateTimeStepGranularity } from '../idea/idea'
+import { VisualBinRange } from './VisualBinRange'
+
+export class DateTimeVisualBinRange extends VisualBinRange {
+ public DataBinRange: DateTimeBinRange;
+
+ constructor(dataBinRange: DateTimeBinRange) {
+ super();
+ this.DataBinRange = dataBinRange;
+ }
+
+ public AddStep(value: number): number {
+ return DateTimeVisualBinRange.AddToDateTimeTicks(value, this.DataBinRange.step!);
+ }
+
+ public GetValueFromIndex(index: number): number {
+ var v = this.DataBinRange.minValue!;
+ for (var i = 0; i < index; i++) {
+ v = this.AddStep(v);
+ }
+ return v;
+ }
+
+ public GetBins(): number[] {
+ var bins = new Array<number>();
+ for (var v: number = this.DataBinRange.minValue!;
+ v < this.DataBinRange.maxValue!;
+ v = DateTimeVisualBinRange.AddToDateTimeTicks(v, this.DataBinRange.step!)) {
+ bins.push(v);
+ }
+ return bins;
+ }
+
+ private pad(n: number, size: number) {
+ var sign = n < 0 ? '-' : '';
+ return sign + new Array(size).concat([Math.abs(n)]).join('0').slice(-size);
+ }
+
+
+ public GetLabel(value: number): string {
+ var dt = DateTimeVisualBinRange.TicksToDate(value);
+ if (this.DataBinRange.step!.dateTimeStepGranularity == DateTimeStepGranularity.Second ||
+ this.DataBinRange.step!.dateTimeStepGranularity == DateTimeStepGranularity.Minute) {
+ return ("" + this.pad(dt.getMinutes(), 2) + ":" + this.pad(dt.getSeconds(), 2));
+ //return dt.ToString("mm:ss");
+ }
+ else if (this.DataBinRange.step!.dateTimeStepGranularity == DateTimeStepGranularity.Hour) {
+ return (this.pad(dt.getHours(), 2) + ":" + this.pad(dt.getMinutes(), 2));
+ //return dt.ToString("HH:mm");
+ }
+ else if (this.DataBinRange.step!.dateTimeStepGranularity == DateTimeStepGranularity.Day) {
+ return ((dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear());
+ //return dt.ToString("MM/dd/yyyy");
+ }
+ else if (this.DataBinRange.step!.dateTimeStepGranularity == DateTimeStepGranularity.Month) {
+ //return dt.ToString("MM/yyyy");
+ return ((dt.getMonth() + 1) + "/" + dt.getFullYear());
+ }
+ else if (this.DataBinRange.step!.dateTimeStepGranularity == DateTimeStepGranularity.Year) {
+ return "" + dt.getFullYear();
+ }
+ return "n/a";
+ }
+
+ public static TicksToDate(ticks: number): Date {
+ var dd = new Date((ticks - 621355968000000000) / 10000);
+ dd.setMinutes(dd.getMinutes() + dd.getTimezoneOffset());
+ return dd;
+ }
+
+
+ public static DateToTicks(date: Date): number {
+ var copiedDate = new Date(date.getTime());
+ copiedDate.setMinutes(copiedDate.getMinutes() - copiedDate.getTimezoneOffset());
+ var t = copiedDate.getTime() * 10000 + 621355968000000000;
+ /*var dd = new Date((ticks - 621355968000000000) / 10000);
+ dd.setMinutes(dd.getMinutes() + dd.getTimezoneOffset());
+ return dd;*/
+ return t;
+ }
+
+ public static AddToDateTimeTicks(ticks: number, dateTimeStep: DateTimeStep): number {
+ var copiedDate = DateTimeVisualBinRange.TicksToDate(ticks);
+ var returnDate: Date = new Date(Date.now());
+ if (dateTimeStep.dateTimeStepGranularity == DateTimeStepGranularity.Second) {
+ returnDate = new Date(copiedDate.setSeconds(copiedDate.getSeconds() + dateTimeStep.dateTimeStepValue!));
+ }
+ else if (dateTimeStep.dateTimeStepGranularity == DateTimeStepGranularity.Minute) {
+ returnDate = new Date(copiedDate.setMinutes(copiedDate.getMinutes() + dateTimeStep.dateTimeStepValue!));
+ }
+ else if (dateTimeStep.dateTimeStepGranularity == DateTimeStepGranularity.Hour) {
+ returnDate = new Date(copiedDate.setHours(copiedDate.getHours() + dateTimeStep.dateTimeStepValue!));
+ }
+ else if (dateTimeStep.dateTimeStepGranularity == DateTimeStepGranularity.Day) {
+ returnDate = new Date(copiedDate.setDate(copiedDate.getDate() + dateTimeStep.dateTimeStepValue!));
+ }
+ else if (dateTimeStep.dateTimeStepGranularity == DateTimeStepGranularity.Month) {
+ returnDate = new Date(copiedDate.setMonth(copiedDate.getMonth() + dateTimeStep.dateTimeStepValue!));
+ }
+ else if (dateTimeStep.dateTimeStepGranularity == DateTimeStepGranularity.Year) {
+ returnDate = new Date(copiedDate.setFullYear(copiedDate.getFullYear() + dateTimeStep.dateTimeStepValue!));
+ }
+ return DateTimeVisualBinRange.DateToTicks(returnDate);
+ }
+} \ No newline at end of file
diff --git a/src/client/northstar/model/binRanges/NominalVisualBinRange.ts b/src/client/northstar/model/binRanges/NominalVisualBinRange.ts
new file mode 100644
index 000000000..407ff3ea6
--- /dev/null
+++ b/src/client/northstar/model/binRanges/NominalVisualBinRange.ts
@@ -0,0 +1,52 @@
+import { NominalBinRange, BinLabel } from '../../model/idea/idea'
+import { VisualBinRange } from './VisualBinRange'
+
+export class NominalVisualBinRange extends VisualBinRange {
+ public DataBinRange: NominalBinRange;
+
+ constructor(dataBinRange: NominalBinRange) {
+ super();
+ this.DataBinRange = dataBinRange;
+ }
+
+ public AddStep(value: number): number {
+ return value + 1;
+ }
+
+ public GetValueFromIndex(index: number): number {
+ return index;
+ }
+
+ public GetBins(): number[] {
+ var bins = new Array<number>();
+ var idx = 0;
+ for (var key in this.DataBinRange.labelsValue) {
+ if (this.DataBinRange.labelsValue.hasOwnProperty(key)) {
+ bins.push(idx);
+ idx++;
+ }
+ }
+ return bins;
+ }
+
+ public GetLabel(value: number): string {
+ return this.DataBinRange.valuesLabel![value];
+ }
+
+ public GetLabels(): Array<BinLabel> {
+ var labels = new Array<BinLabel>();
+ var count = 0;
+ for (var key in this.DataBinRange.valuesLabel) {
+ if (this.DataBinRange.valuesLabel.hasOwnProperty(key)) {
+ var value = this.DataBinRange.valuesLabel[key];
+ labels.push(new BinLabel({
+ value: parseFloat(key),
+ minValue: count++,
+ maxValue: count,
+ label: value
+ }));
+ }
+ }
+ return labels;
+ }
+} \ No newline at end of file
diff --git a/src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts b/src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts
new file mode 100644
index 000000000..80886416b
--- /dev/null
+++ b/src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts
@@ -0,0 +1,90 @@
+import { QuantitativeBinRange } from '../idea/idea'
+import { VisualBinRange } from './VisualBinRange';
+import { format } from "d3-format";
+
+export class QuantitativeVisualBinRange extends VisualBinRange {
+
+ public DataBinRange: QuantitativeBinRange;
+
+ constructor(dataBinRange: QuantitativeBinRange) {
+ super();
+ this.DataBinRange = dataBinRange;
+ }
+
+ public AddStep(value: number): number {
+ return value + this.DataBinRange.step!;
+ }
+
+ public GetValueFromIndex(index: number): number {
+ return this.DataBinRange.minValue! + (index * this.DataBinRange.step!);
+ }
+
+ public GetLabel(value: number): string {
+ return QuantitativeVisualBinRange.NumberFormatter(value);
+ }
+
+ public static NumberFormatter(val: number): string {
+ if (val === 0) {
+ return "0";
+ }
+ if (val < 1) {
+ /*if (val < Math.abs(0.001)) {
+ return val.toExponential(2);
+ }*/
+ return format(".3")(val);
+ }
+ return format("~s")(val);
+ }
+
+ public GetBins(): number[] {
+ let bins = new Array<number>();
+
+ for (let v: number = this.DataBinRange.minValue!; v < this.DataBinRange.maxValue!; v += this.DataBinRange.step!) {
+ bins.push(v);
+ }
+ return bins;
+ }
+
+ public static Initialize(dataMinValue: number, dataMaxValue: number, targetBinNumber: number, isIntegerRange: boolean): QuantitativeVisualBinRange {
+ let extent = QuantitativeVisualBinRange.getExtent(dataMinValue, dataMaxValue, targetBinNumber, isIntegerRange);
+ let dataBinRange = new QuantitativeBinRange();
+ dataBinRange.minValue = extent[0];
+ dataBinRange.maxValue = extent[1];
+ dataBinRange.step = extent[2];
+
+ return new QuantitativeVisualBinRange(dataBinRange);
+ }
+
+ private static getExtent(dataMin: number, dataMax: number, m: number, isIntegerRange: boolean): number[] {
+ if (dataMin === dataMax) {
+ // dataMin -= 0.1;
+ dataMax += 0.1;
+ }
+ let span = dataMax - dataMin;
+
+ let step = Math.pow(10, Math.floor(Math.log10(span / m)));
+ let err = m / span * step;
+
+ if (err <= .15) {
+ step *= 10;
+ }
+ else if (err <= .35) {
+ step *= 5;
+ }
+ else if (err <= .75) {
+ step *= 2;
+ }
+
+ if (isIntegerRange) {
+ step = Math.ceil(step);
+ }
+ let ret: number[] = new Array<number>(3);
+ let minDivStep = Math.floor(dataMin / step);
+ let maxDivStep = Math.floor(dataMax / step);
+ ret[0] = minDivStep * step; // Math.floor(Math.Round(dataMin, 8)/step)*step;
+ ret[1] = maxDivStep * step + step; // Math.floor(Math.Round(dataMax, 8)/step)*step + step;
+ ret[2] = step;
+
+ return ret;
+ }
+} \ No newline at end of file
diff --git a/src/client/northstar/model/binRanges/VisualBinRange.ts b/src/client/northstar/model/binRanges/VisualBinRange.ts
new file mode 100644
index 000000000..f53008f9a
--- /dev/null
+++ b/src/client/northstar/model/binRanges/VisualBinRange.ts
@@ -0,0 +1,36 @@
+import { BinLabel } from '../../model/idea/idea'
+
+export abstract class VisualBinRange {
+
+ constructor() {
+
+ }
+
+ public abstract AddStep(value: number): number;
+
+ public abstract GetValueFromIndex(index: number): number;
+
+ public abstract GetBins(): Array<number>;
+
+ public GetLabel(value: number): string {
+ return value.toString();
+ }
+
+ public GetLabels(): Array<BinLabel> {
+ var labels = new Array<BinLabel>();
+ var bins = this.GetBins();
+ bins.forEach(b => {
+ labels.push(new BinLabel({
+ value: b,
+ minValue: b,
+ maxValue: this.AddStep(b),
+ label: this.GetLabel(b)
+ }));
+ });
+ return labels;
+ }
+}
+
+export enum ChartType {
+ HorizontalBar = 0, VerticalBar = 1, HeatMap = 2, SinglePoint = 3
+} \ No newline at end of file
diff --git a/src/client/northstar/model/binRanges/VisualBinRangeHelper.ts b/src/client/northstar/model/binRanges/VisualBinRangeHelper.ts
new file mode 100644
index 000000000..9eae39800
--- /dev/null
+++ b/src/client/northstar/model/binRanges/VisualBinRangeHelper.ts
@@ -0,0 +1,71 @@
+import { BinRange, NominalBinRange, QuantitativeBinRange, Exception, AlphabeticBinRange, DateTimeBinRange, AggregateBinRange, DoubleValueAggregateResult, HistogramResult } from "../idea/idea";
+import { VisualBinRange, ChartType } from "./VisualBinRange";
+import { NominalVisualBinRange } from "./NominalVisualBinRange";
+import { QuantitativeVisualBinRange } from "./QuantitativeVisualBinRange";
+import { AlphabeticVisualBinRange } from "./AlphabeticVisualBinRange";
+import { DateTimeVisualBinRange } from "./DateTimeVisualBinRange";
+import { Settings } from "../../manager/Gateway";
+import { ModelHelpers } from "../ModelHelpers";
+import { AttributeTransformationModel } from "../../core/attribute/AttributeTransformationModel";
+
+export const SETTINGS_X_BINS = 15;
+export const SETTINGS_Y_BINS = 15;
+export const SETTINGS_SAMPLE_SIZE = 100000;
+
+export class VisualBinRangeHelper {
+
+ public static GetNonAggregateVisualBinRange(dataBinRange: BinRange): VisualBinRange {
+ if (dataBinRange instanceof NominalBinRange) {
+ return new NominalVisualBinRange(dataBinRange as NominalBinRange);
+ }
+ else if (dataBinRange instanceof QuantitativeBinRange) {
+ return new QuantitativeVisualBinRange(dataBinRange as QuantitativeBinRange);
+ }
+ else if (dataBinRange instanceof AlphabeticBinRange) {
+ return new AlphabeticVisualBinRange(dataBinRange as AlphabeticBinRange);
+ }
+ else if (dataBinRange instanceof DateTimeBinRange) {
+ return new DateTimeVisualBinRange(dataBinRange as DateTimeBinRange);
+ }
+ throw new Exception()
+ }
+
+ public static GetVisualBinRange(dataBinRange: BinRange, histoResult: HistogramResult, attr: AttributeTransformationModel, chartType: ChartType): VisualBinRange {
+
+ if (!(dataBinRange instanceof AggregateBinRange)) {
+ return VisualBinRangeHelper.GetNonAggregateVisualBinRange(dataBinRange);
+ }
+ else {
+ var aggregateKey = ModelHelpers.CreateAggregateKey(attr, histoResult, ModelHelpers.AllBrushIndex(histoResult));
+ var minValue = Number.MAX_VALUE;
+ var maxValue = Number.MIN_VALUE;
+ for (var b = 0; b < histoResult.brushes!.length; b++) {
+ var brush = histoResult.brushes![b];
+ aggregateKey.brushIndex = brush.brushIndex;
+ for (var key in histoResult.bins) {
+ if (histoResult.bins.hasOwnProperty(key)) {
+ var bin = histoResult.bins[key];
+ var res = <DoubleValueAggregateResult>ModelHelpers.GetAggregateResult(bin, aggregateKey);
+ if (res && res.hasResult && res.result) {
+ minValue = Math.min(minValue, res.result);
+ maxValue = Math.max(maxValue, res.result);
+ }
+ }
+ }
+ };
+
+ let visualBinRange = QuantitativeVisualBinRange.Initialize(minValue, maxValue, 10, false);
+
+ if (chartType == ChartType.HorizontalBar || chartType == ChartType.VerticalBar) {
+ visualBinRange = QuantitativeVisualBinRange.Initialize(Math.min(0, minValue),
+ Math.max(0, (visualBinRange as QuantitativeVisualBinRange).DataBinRange.maxValue!),
+ SETTINGS_X_BINS, false);
+ }
+ else if (chartType == ChartType.SinglePoint) {
+ visualBinRange = QuantitativeVisualBinRange.Initialize(Math.min(0, minValue), Math.max(0, maxValue),
+ SETTINGS_X_BINS, false);
+ }
+ return visualBinRange;
+ }
+ }
+}