From 9a16849391913a397bc4ddad52311df0f93b580e Mon Sep 17 00:00:00 2001 From: Jan Bicker Date: Tue, 29 Jan 2019 09:36:53 +0000 Subject: [PATCH] Changes regarding chart scaling --- .../src/components/time-graph-axis-scale.ts | 2 +- .../src/components/time-graph-component.ts | 6 ++- .../src/components/time-graph-row-element.ts | 43 +++++++++------ .../src/components/time-graph-row.ts | 15 +++++- timeline-chart/src/layer/time-graph-chart.ts | 52 ++++++++++++++++--- timeline-chart/src/layer/time-graph-layer.ts | 14 +++-- .../src/time-graph-unit-controller.ts | 1 + 7 files changed, 100 insertions(+), 33 deletions(-) diff --git a/timeline-chart/src/components/time-graph-axis-scale.ts b/timeline-chart/src/components/time-graph-axis-scale.ts index 3f76663..cd4261b 100644 --- a/timeline-chart/src/components/time-graph-axis-scale.ts +++ b/timeline-chart/src/components/time-graph-axis-scale.ts @@ -53,7 +53,7 @@ export class TimeGraphAxisScale extends TimeGraphComponent { const logRounded = Math.round(log); const normalizedStepLength = Math.pow(10, logRounded); const residual = realStepLength / normalizedStepLength; - const steps = [1, 1.5, 2, 2.5, 5, 10]; + const steps = this.unitController.scaleSteps || [1, 1.5, 2, 2.5, 5, 10]; const normStepLength = steps.find(s => s > residual); const stepLength = normalizedStepLength * (normStepLength || 1); return stepLength; diff --git a/timeline-chart/src/components/time-graph-component.ts b/timeline-chart/src/components/time-graph-component.ts index ed70694..c846bd9 100644 --- a/timeline-chart/src/components/time-graph-component.ts +++ b/timeline-chart/src/components/time-graph-component.ts @@ -30,6 +30,10 @@ export type TimeGraphStyledRect = TimeGraphRect & TimeGraphElementStyle; export type TimeGraphHorizontalLine = TimeGraphHorizontalElement & TimeGraphLineStyle; export type TimeGraphVerticalLine = TimeGraphVerticalElement & TimeGraphLineStyle; +export interface TimeGraphParentComponent { + addChild(child: TimeGraphComponent): void; +} + export abstract class TimeGraphComponent { protected _displayObject: PIXI.Graphics; protected _options: TimeGraphComponentOptions; @@ -90,4 +94,4 @@ export abstract class TimeGraphComponent { } }).bind(this)); } -} \ No newline at end of file +} diff --git a/timeline-chart/src/components/time-graph-row-element.ts b/timeline-chart/src/components/time-graph-row-element.ts index c472b6c..1e9970c 100644 --- a/timeline-chart/src/components/time-graph-row-element.ts +++ b/timeline-chart/src/components/time-graph-row-element.ts @@ -1,4 +1,4 @@ -import { TimeGraphComponent, TimeGraphStyledRect } from "./time-graph-component"; +import { TimeGraphComponent, TimeGraphStyledRect, TimeGraphElementPosition } from "./time-graph-component"; import { TimeGraphRow } from "./time-graph-row"; import { TimelineChart } from "../time-graph-model"; @@ -11,27 +11,30 @@ export interface TimeGraphRowElementStyle { export class TimeGraphRowElement extends TimeGraphComponent { - protected rectangleOptions: TimeGraphStyledRect; + height: number; + position: TimeGraphElementPosition; + + protected _options: TimeGraphStyledRect; constructor( id: string, - protected _options: TimelineChart.TimeGraphRowElementModel, + protected _model: TimelineChart.TimeGraphRowElementModel, protected range: TimelineChart.TimeGraphRange, protected _row: TimeGraphRow, style: TimeGraphRowElementStyle = { color: 0xfffa66, height: 14 }, - displayObject?:PIXI.Graphics + displayObject?: PIXI.Graphics ) { super(id, displayObject); - const height = style.height || 14; - const position = { + this.height = style.height || 14; + this.position = { x: this.range.start, - y: this._row.position.y + ((this.row.height - height) / 2) + y: this._row.position.y + ((this.row.height - this.height) / 2) }; const width = this.range.end - this.range.start; - this.rectangleOptions = { + this._options = { color: style.color, - height, - position, + height: this.height, + position: this.position, width, borderRadius: 2, borderWidth: style.borderWidth || 0 @@ -39,7 +42,7 @@ export class TimeGraphRowElement extends TimeGraphComponent { } get model(): TimelineChart.TimeGraphRowElementModel { - return this._options; + return this._model; } get row(): TimeGraphRow { @@ -48,21 +51,29 @@ export class TimeGraphRowElement extends TimeGraphComponent { set style(style: TimeGraphRowElementStyle) { if (style.color !== undefined) { - this.rectangleOptions.color = style.color; + this._options.color = style.color; } if (style.height !== undefined) { - this.rectangleOptions.height = style.height; + this._options.height = style.height; } if (style.borderColor !== undefined) { - this.rectangleOptions.borderColor = style.color; + this._options.borderColor = style.color; } if (style.borderWidth !== undefined) { - this.rectangleOptions.borderWidth = style.borderWidth; + this._options.borderWidth = style.borderWidth; } this.update(); } + update(opts?: TimeGraphStyledRect) { + if(opts){ + this._options.position = opts.position; + this._options.width = opts.width; + } + super.update(); + } + render() { - this.rect(this.rectangleOptions); + this.rect(this._options); } } \ No newline at end of file diff --git a/timeline-chart/src/components/time-graph-row.ts b/timeline-chart/src/components/time-graph-row.ts index c2a1f67..8b95bc8 100644 --- a/timeline-chart/src/components/time-graph-row.ts +++ b/timeline-chart/src/components/time-graph-row.ts @@ -1,5 +1,6 @@ -import { TimeGraphComponent, TimeGraphElementPosition, TimeGraphRect } from "./time-graph-component"; +import { TimeGraphComponent, TimeGraphElementPosition, TimeGraphRect, TimeGraphParentComponent } from "./time-graph-component"; import { TimelineChart } from "../time-graph-model"; +import { TimeGraphRowElement } from "./time-graph-row-element"; export interface TimeGraphRowStyle { backgroundColor?: number @@ -9,7 +10,9 @@ export interface TimeGraphRowStyle { lineOpacity?: number } -export class TimeGraphRow extends TimeGraphComponent { +export class TimeGraphRow extends TimeGraphComponent implements TimeGraphParentComponent{ + + protected rowElements: TimeGraphRowElement[] = []; constructor( id: string, @@ -44,6 +47,8 @@ export class TimeGraphRow extends TimeGraphComponent { }); } + + get position(): TimeGraphElementPosition { return this._options.position; } @@ -51,4 +56,10 @@ export class TimeGraphRow extends TimeGraphComponent { get height(): number { return this._options.height; } + + // Gets called by TimeGraphLayer. Don't call it unless you know what you are doing. + addChild(rowElement: TimeGraphRowElement){ + this.rowElements.push(rowElement); + this._displayObject.addChild(rowElement.displayObject); + } } \ No newline at end of file diff --git a/timeline-chart/src/layer/time-graph-chart.ts b/timeline-chart/src/layer/time-graph-chart.ts index 2526179..392e77b 100644 --- a/timeline-chart/src/layer/time-graph-chart.ts +++ b/timeline-chart/src/layer/time-graph-chart.ts @@ -1,7 +1,7 @@ import { TimeGraphRowElement, TimeGraphRowElementStyle } from "../components/time-graph-row-element"; import { TimeGraphRow, TimeGraphRowStyle } from "../components/time-graph-row"; import { TimelineChart } from "../time-graph-model"; -import { TimeGraphComponent } from "../components/time-graph-component"; +import { TimeGraphComponent, TimeGraphRect, TimeGraphStyledRect } from "../components/time-graph-component"; import { TimeGraphChartLayer } from "./time-graph-chart-layer"; import { TimeGraphRowController } from "../time-graph-row-controller"; @@ -24,6 +24,8 @@ export type TimeGraphRowStyleHook = (row: TimelineChart.TimeGraphRowModel) => Ti export class TimeGraphChart extends TimeGraphChartLayer { protected rows: TimelineChart.TimeGraphRowModel[]; + protected rowComponents: Map; + protected rowElementComponents: Map protected rowElementMouseInteractions: TimeGraphRowElementMouseInteractions; protected selectedElementModel: TimelineChart.TimeGraphRowElementModel; protected selectedElementChangedHandler: ((el: TimelineChart.TimeGraphRowElementModel) => void)[] = []; @@ -107,7 +109,6 @@ export class TimeGraphChart extends TimeGraphChartLayer { } }); if (this.unitController.viewRangeLength) { - this.updateScaleAndPosition(); this.maybeFetchNewData(); } } @@ -128,6 +129,7 @@ export class TimeGraphChart extends TimeGraphChartLayer { this.providedResolution = rowData.resolution; this.providedRange = rowData.range; this.setRowModel(rowData.rows); + this.removeChildren(); this.addRows(this.rows, this.rowController.rowHeight); } this.fetching = false; @@ -135,8 +137,38 @@ export class TimeGraphChart extends TimeGraphChartLayer { } protected updateScaleAndPosition() { - this.layer.position.x = -(this.unitController.viewRange.start * this.stateController.zoomFactor); - this.layer.scale.x = this.stateController.zoomFactor; + if (this.rows) { + this.rows.forEach((row: TimelineChart.TimeGraphRowModel) => { + const comp = this.rowComponents.get(row); + if (comp) { + const opts: TimeGraphRect = { + height: this.rowController.rowHeight, + position: { + x: (row.range.start - this.unitController.viewRange.start) * this.stateController.zoomFactor, + y: comp.position.y + }, + width: (row.range.end - row.range.start) * this.stateController.zoomFactor + } + comp.update(opts); + } + row.states.forEach((rowElementModel: TimelineChart.TimeGraphRowElementModel, elementIndex: number) => { + const el = this.rowElementComponents.get(rowElementModel); + if (el) { + const start = rowElementModel.range.start; + const end = rowElementModel.range.end; + const opts: TimeGraphStyledRect = { + height: el.height, + position: { + x: (start - this.unitController.viewRange.start) * this.stateController.zoomFactor, + y: el.position.y + }, + width: (end - start) * this.stateController.zoomFactor + } + el.update(opts); + } + }); + }); + } } protected handleSelectedRowElementChange() { @@ -149,10 +181,10 @@ export class TimeGraphChart extends TimeGraphChartLayer { const rowStyle = this.providers.rowStyleProvider ? this.providers.rowStyleProvider(row) : undefined; const rowComponent = new TimeGraphRow(rowId, { position: { - x: row.range.start, + x: row.range.start * this.stateController.zoomFactor, y: (height * rowIndex) }, - width: length, + width: length * this.stateController.zoomFactor, height }, rowIndex, row, rowStyle); rowComponent.displayObject.interactive = true; @@ -160,15 +192,17 @@ export class TimeGraphChart extends TimeGraphChartLayer { this.selectRow(row); }).bind(this)); this.addChild(rowComponent); + this.rowComponents.set(row, rowComponent); row.states.forEach((rowElementModel: TimelineChart.TimeGraphRowElementModel, elementIndex: number) => { - const start = rowElementModel.range.start; - const end = rowElementModel.range.end; + const start = rowElementModel.range.start * this.stateController.zoomFactor; + const end = rowElementModel.range.end * this.stateController.zoomFactor; const range: TimelineChart.TimeGraphRange = { start, end }; const elementStyle = this.providers.rowElementStyleProvider ? this.providers.rowElementStyleProvider(rowElementModel) : undefined; const el = new TimeGraphRowElement(rowElementModel.id, rowElementModel, range, rowComponent, elementStyle); + this.rowElementComponents.set(rowElementModel, el); this.addElementInteractions(el); this.addChild(el); }); @@ -208,6 +242,8 @@ export class TimeGraphChart extends TimeGraphChartLayer { if (!this.stateController) { throw ('Add this TimeGraphChart to a container before adding rows.'); } + this.rowComponents = new Map(); + this.rowElementComponents = new Map(); this.rowController.rowHeight = height; rows.forEach((row: TimelineChart.TimeGraphRowModel, index: number) => { this.addRow(row, height, index); diff --git a/timeline-chart/src/layer/time-graph-layer.ts b/timeline-chart/src/layer/time-graph-layer.ts index cc7a264..fd849d1 100644 --- a/timeline-chart/src/layer/time-graph-layer.ts +++ b/timeline-chart/src/layer/time-graph-layer.ts @@ -1,4 +1,4 @@ -import { TimeGraphComponent } from "../components/time-graph-component"; +import { TimeGraphComponent, TimeGraphParentComponent } from "../components/time-graph-component"; import { TimeGraphUnitController } from "../time-graph-unit-controller"; import { TimeGraphStateController } from "../time-graph-state-controller"; @@ -15,13 +15,17 @@ export abstract class TimeGraphLayer { this.layer = new PIXI.Container; } - protected addChild(child: TimeGraphComponent) { + protected addChild(child: TimeGraphComponent, parent?: TimeGraphParentComponent) { if (!this.canvas) { throw ("Layers must be added to a container before components can be added."); } child.render(); - this.layer.addChild(child.displayObject); - this.children.push(child); + if (parent) { + parent.addChild(child); + } else { + this.layer.addChild(child.displayObject); + this.children.push(child); + } } /** @@ -45,7 +49,7 @@ export abstract class TimeGraphLayer { this.children = []; } - protected removeChild(child:TimeGraphComponent){ + protected removeChild(child: TimeGraphComponent) { this.layer.removeChild(child.displayObject); } diff --git a/timeline-chart/src/time-graph-unit-controller.ts b/timeline-chart/src/time-graph-unit-controller.ts index 5bddff2..827a042 100644 --- a/timeline-chart/src/time-graph-unit-controller.ts +++ b/timeline-chart/src/time-graph-unit-controller.ts @@ -8,6 +8,7 @@ export class TimeGraphUnitController { protected _selectionRange?: TimelineChart.TimeGraphRange; numberTranslator?: (theNumber: number) => string; + scaleSteps?: number[] constructor(public absoluteRange: number, viewRange?: TimelineChart.TimeGraphRange) { this.viewRangeChangedHandlers = [];