From 78fa358233003f75c79096209dda6de508c94ac8 Mon Sep 17 00:00:00 2001 From: Jan Bicker Date: Fri, 21 Dec 2018 17:07:44 +0000 Subject: [PATCH] some more improvements --- example/src/index.ts | 30 +++++---- example/src/test-data-provider.ts | 2 - timeline-chart/package.json | 6 +- .../src/components/time-graph-cursor.ts | 4 +- .../src/layer/time-graph-axis-cursors.ts | 2 +- .../src/layer/time-graph-chart-arrows.ts | 4 +- .../src/layer/time-graph-chart-cursors.ts | 58 ++++------------- .../src/layer/time-graph-chart-layer.ts | 10 +++ .../layer/time-graph-chart-selection-range.ts | 48 ++++++++++++++ timeline-chart/src/layer/time-graph-chart.ts | 65 ++++++------------- .../layer/time-graph-vertical-scrollbar.ts | 42 ++++-------- timeline-chart/src/time-graph-model.ts | 4 +- .../src/time-graph-row-controller.ts | 44 +++++++++++++ .../src/time-graph-unit-controller.ts | 2 +- 14 files changed, 172 insertions(+), 149 deletions(-) create mode 100644 timeline-chart/src/layer/time-graph-chart-layer.ts create mode 100644 timeline-chart/src/layer/time-graph-chart-selection-range.ts create mode 100644 timeline-chart/src/time-graph-row-controller.ts diff --git a/example/src/index.ts b/example/src/index.ts index 43b26f4..969a740 100644 --- a/example/src/index.ts +++ b/example/src/index.ts @@ -1,9 +1,11 @@ import { TimeGraphAxis } from "timeline-chart/lib/layer/time-graph-axis"; import { TimeGraphChart } from "timeline-chart/lib/layer/time-graph-chart"; import { TimeGraphUnitController } from "timeline-chart/lib/time-graph-unit-controller"; +import { TimeGraphRowController } from "timeline-chart/lib/time-graph-row-controller"; import { TimeGraphNavigator } from "timeline-chart/lib/layer/time-graph-navigator"; import { TimeGraphContainer } from "timeline-chart/lib/time-graph-container"; import { TimeGraphChartCursors } from "timeline-chart/lib/layer/time-graph-chart-cursors"; +import { TimeGraphChartSelectionRange } from "timeline-chart/lib/layer/time-graph-chart-selection-range"; import { TimeGraphAxisCursors } from "timeline-chart/lib/layer/time-graph-axis-cursors"; // import { timeGraph } from "timeline-chart/lib/test-data"; import { TimeGraphRowElementModel, TimeGraphRowModel, TimeGraphRange } from "timeline-chart/lib/time-graph-model"; @@ -34,6 +36,10 @@ const testDataProvider = new TestDataProvider(styleConfig.mainWidth); let timeGraph = testDataProvider.getData(); const unitController = new TimeGraphUnitController(timeGraph.totalRange); +const rowHeight = 16; +const totalHeight = timeGraph.rows.length * rowHeight; +const rowController = new TimeGraphRowController(rowHeight, totalHeight); + const axisHTMLContainer = document.createElement('div'); axisHTMLContainer.id = 'main_axis'; container.appendChild(axisHTMLContainer); @@ -68,12 +74,10 @@ const timeGraphChartContainer = new TimeGraphContainer({ }, unitController); chartHTMLContainer.appendChild(timeGraphChartContainer.canvas); -const rowHeight = 16; - const timeGraphChartGridLayer = new TimeGraphChartGrid('timeGraphGrid', rowHeight); timeGraphChartContainer.addLayer(timeGraphChartGridLayer); -const timeGraphChartLayer = new TimeGraphChart('timeGraphChart', { +const timeGraphChart = new TimeGraphChart('timeGraphChart', { dataProvider: (range: TimeGraphRange, resolution: number) => { timeGraph = testDataProvider.getData(range); if (selectedElement) { @@ -126,10 +130,10 @@ const timeGraphChartLayer = new TimeGraphChart('timeGraphChart', { lineThickness: row.data && row.data.hasStates ? 1 : 3 } } -}, rowHeight); -timeGraphChartContainer.addLayer(timeGraphChartLayer); +}, rowController); +timeGraphChartContainer.addLayer(timeGraphChart); -timeGraphChartLayer.registerRowElementMouseInteractions({ +timeGraphChart.registerRowElementMouseInteractions({ click: el => { console.log(el.model.label); if (el.model.data) { @@ -138,8 +142,8 @@ timeGraphChartLayer.registerRowElementMouseInteractions({ } }); let selectedElement: TimeGraphRowElement; -timeGraphChartLayer.onSelectedRowElementChanged((model) => { - const el = timeGraphChartLayer.getElementById(model.id); +timeGraphChart.onSelectedRowElementChanged((model) => { + const el = timeGraphChart.getElementById(model.id); if (el) { selectedElement = el; } @@ -151,7 +155,9 @@ timeGraphChartLayer.onSelectedRowElementChanged((model) => { const timeAxisCursors = new TimeGraphAxisCursors('timeGraphAxisCursors', { color: styleConfig.cursorColor }); timeGraphAxisContainer.addLayer(timeAxisCursors); -const timeGraphChartCursors = new TimeGraphChartCursors('chart-cursors', timeGraphChartLayer, { color: styleConfig.cursorColor }); +const timeGraphSelectionRange = new TimeGraphChartSelectionRange('chart-selection-range', { color: styleConfig.cursorColor } ); +timeGraphChartContainer.addLayer(timeGraphSelectionRange); +const timeGraphChartCursors = new TimeGraphChartCursors('chart-cursors', timeGraphChart, rowController, { color: styleConfig.cursorColor }); timeGraphChartContainer.addLayer(timeGraphChartCursors); const cursorReset = document.getElementById('cursor-reset'); @@ -182,11 +188,7 @@ if (vscrollElement) { id: 'vscroll', backgroundColor: styleConfig.naviBackgroundColor }, unitController); - const vscroll = new TimeGraphVerticalScrollbar('timeGraphVerticalScrollbar', (timeGraph.rows.length * rowHeight)); + const vscroll = new TimeGraphVerticalScrollbar('timeGraphVerticalScrollbar', rowController); verticalScrollContainer.addLayer(vscroll); - vscroll.onVerticalPositionChanged(ypos => { - timeGraphChartLayer.setVerticalPositionOffset(ypos); - }); - timeGraphChartLayer.onVerticalPositionChanged((verticalChartPosition: number) => vscroll.setVerticalPosition(verticalChartPosition)); vscrollElement.appendChild(verticalScrollContainer.canvas); } \ No newline at end of file diff --git a/example/src/test-data-provider.ts b/example/src/test-data-provider.ts index e507538..eb4c3b5 100644 --- a/example/src/test-data-provider.ts +++ b/example/src/test-data-provider.ts @@ -176,7 +176,6 @@ export class TestDataProvider { states.push({ id: 'el_' + rowIndex + '_' + stateIndex, label: state.label, - selected: false, range: { start, end }, data: { value: state.value, timeRange: { startTime: state.startTime, endTime: (state.startTime + state.duration) } } }); @@ -191,7 +190,6 @@ export class TestDataProvider { end: entry.endTime - entry.startTime }, states, - selected: false, data: { type: entry.type, hasStates diff --git a/timeline-chart/package.json b/timeline-chart/package.json index 3d73dbd..0b7201a 100644 --- a/timeline-chart/package.json +++ b/timeline-chart/package.json @@ -5,11 +5,9 @@ "build": "tsc", "watch": "tsc --watch" }, - "devDependencies": { - "@types/lodash.throttle": "^4.1.4", - "@types/pixi.js": "^4.8.2" - }, "dependencies": { + "@types/lodash.throttle": "^4.1.4", + "@types/pixi.js": "^4.8.2", "lodash.throttle": "^4.1.1", "pixi.js": "^4.8.2" } diff --git a/timeline-chart/src/components/time-graph-cursor.ts b/timeline-chart/src/components/time-graph-cursor.ts index 8caadaa..372f236 100644 --- a/timeline-chart/src/components/time-graph-cursor.ts +++ b/timeline-chart/src/components/time-graph-cursor.ts @@ -4,6 +4,7 @@ export interface TimeGraphCursorOptions { height: number position: TimeGraphElementPosition color: number + thickness?: number } export class TimeGraphCursor extends TimeGraphComponent{ @@ -12,8 +13,9 @@ export class TimeGraphCursor extends TimeGraphComponent{ this._options = opts; } render(): void { - const {color, height, position} = this._options as TimeGraphCursorOptions; + const {color, height, position, thickness} = this._options as TimeGraphCursorOptions; this.vline({ + thickness, color, height, position diff --git a/timeline-chart/src/layer/time-graph-axis-cursors.ts b/timeline-chart/src/layer/time-graph-axis-cursors.ts index 4ee4934..cea38a4 100644 --- a/timeline-chart/src/layer/time-graph-axis-cursors.ts +++ b/timeline-chart/src/layer/time-graph-axis-cursors.ts @@ -15,8 +15,8 @@ export class TimeGraphAxisCursors extends TimeGraphLayer { } afterAddToContainer() { - this.unitController.onSelectionRangeChange(() => this.update()); this.unitController.onViewRangeChanged(() => this.update()); + this.unitController.onSelectionRangeChange(() => this.update()); } update(): void { diff --git a/timeline-chart/src/layer/time-graph-chart-arrows.ts b/timeline-chart/src/layer/time-graph-chart-arrows.ts index aeffb8f..f5d3ad4 100644 --- a/timeline-chart/src/layer/time-graph-chart-arrows.ts +++ b/timeline-chart/src/layer/time-graph-chart-arrows.ts @@ -1,10 +1,10 @@ -import { TimeGraphLayer } from "./time-graph-layer"; import { TimeGraphArrowComponent, TimeGraphArrowHead } from "../components/time-graph-arrow"; import { TimeGraphElementPosition } from "../components/time-graph-component"; import { TimeGraphArrow } from "../time-graph-model"; +import { TimeGraphChartLayer } from "./time-graph-chart-layer"; // import ArrowHead from "./arrowhead.png"; -export class TimeGraphChartArrows extends TimeGraphLayer { +export class TimeGraphChartArrows extends TimeGraphChartLayer { protected rowHeight: number; protected arrows: TimeGraphArrow[]; diff --git a/timeline-chart/src/layer/time-graph-chart-cursors.ts b/timeline-chart/src/layer/time-graph-chart-cursors.ts index 346241c..3c96705 100644 --- a/timeline-chart/src/layer/time-graph-chart-cursors.ts +++ b/timeline-chart/src/layer/time-graph-chart-cursors.ts @@ -1,31 +1,24 @@ import { TimeGraphCursor } from "../components/time-graph-cursor"; -import { TimeGraphRectangle } from "../components/time-graph-rectangle"; -import { TimeGraphLayer } from "./time-graph-layer"; -import { TimeGraphChart } from "./time-graph-chart"; import { TimeGraphRowElementModel } from "../time-graph-model"; +import { TimeGraphChartLayer } from "./time-graph-chart-layer"; +import { TimeGraphRowController } from "../time-graph-row-controller"; +import { TimeGraphChart } from "./time-graph-chart"; -export class TimeGraphChartCursors extends TimeGraphLayer { +export class TimeGraphChartCursors extends TimeGraphChartLayer { protected mouseIsDown: boolean; protected shiftKeyDown: boolean; protected firstCursor: TimeGraphCursor; protected secondCursor: TimeGraphCursor; - protected selectionRange: TimeGraphRectangle; protected color: number = 0x0000ff; - constructor(id: string, protected chartLayer: TimeGraphChart, style?: { color?: number }) { - super(id); + constructor(id: string, protected chartLayer: TimeGraphChart, protected rowController: TimeGraphRowController, style?: { color?: number }) { + super(id, rowController); if (style && style.color) { this.color = style.color; } } - protected updateScaleAndPosition() { - this.layer.position.x = -(this.unitController.viewRange.start * this.stateController.zoomFactor); - this.layer.scale.x = this.stateController.zoomFactor; - } - protected afterAddToContainer() { - this.addBackground(); this.mouseIsDown = false; this.shiftKeyDown = false this.stage.interactive = true; @@ -44,7 +37,6 @@ export class TimeGraphChartCursors extends TimeGraphLayer { this.mouseIsDown = true; const mouseX = event.data.global.x; const xpos = this.unitController.viewRange.start + (mouseX / this.stateController.zoomFactor); - console.log("SET CURSOR AT", xpos); if (this.shiftKeyDown) { const start = this.unitController.selectionRange ? this.unitController.selectionRange.start : 0; this.unitController.selectionRange = { @@ -75,12 +67,8 @@ export class TimeGraphChartCursors extends TimeGraphLayer { this.stage.on('mouseupoutside', (event: PIXI.interaction.InteractionEvent) => { this.mouseIsDown = false; }); - this.unitController.onViewRangeChanged(() => { - this.updateScaleAndPosition(); - }); - this.updateScaleAndPosition(); + this.unitController.onViewRangeChanged(() => this.update()); this.unitController.onSelectionRangeChange(() => this.update()); - // this.unitController.onViewRangeChanged(() => this.update()); } protected maybeCenterCursor() { @@ -92,7 +80,7 @@ export class TimeGraphChartCursors extends TimeGraphLayer { }; protected navigateOrSelectLeft() { - const row = this.chartLayer.getSelectedRow(); + const row = this.rowController.selectedRow; const states = row.states; const nextIndex = states.findIndex((rowElementModel: TimeGraphRowElementModel) => { const selStart = this.unitController.selectionRange ? (this.shiftKeyDown ? this.unitController.selectionRange.end : this.unitController.selectionRange.start) : 0; @@ -116,7 +104,7 @@ export class TimeGraphChartCursors extends TimeGraphLayer { } protected navigateOrSelectRight() { - const row = this.chartLayer.getSelectedRow(); + const row = this.rowController.selectedRow; const states = row.states; const nextIndex = states.findIndex((rowElementModel: TimeGraphRowElementModel) => { const cursorPosition = this.unitController.selectionRange ? (this.shiftKeyDown ? this.unitController.selectionRange.end : this.unitController.selectionRange.start) : 0; @@ -134,17 +122,6 @@ export class TimeGraphChartCursors extends TimeGraphLayer { this.chartLayer.selectRowElement(states[nextIndex]); } - // this background is needed because an empty stage, or a point at that stage which is not actually an displayObject, wont react on mouse events. - protected addBackground() { - const background = new TimeGraphRectangle({ - position: { x: 0, y: 0 }, - height: this.stateController.canvasDisplayHeight, - width: this.stateController.canvasDisplayWidth, - opacity: 0 - }); - this.addChild(background); - } - centerCursor() { if (this.unitController.selectionRange) { const cursorPosition = this.unitController.selectionRange.start; @@ -162,10 +139,9 @@ export class TimeGraphChartCursors extends TimeGraphLayer { update() { this.removeChildren(); - this.addBackground(); if (this.unitController.selectionRange) { - const firstCursorPosition = this.unitController.selectionRange.start;//(this.unitController.selectionRange.start - this.unitController.viewRange.start) * this.stateController.zoomFactor; - const secondCursorPosition = this.unitController.selectionRange.end;//(this.unitController.selectionRange.end - this.unitController.viewRange.start) * this.stateController.zoomFactor; + const firstCursorPosition = (this.unitController.selectionRange.start - this.unitController.viewRange.start) * this.stateController.zoomFactor; + const secondCursorPosition = (this.unitController.selectionRange.end - this.unitController.viewRange.start) * this.stateController.zoomFactor; const firstCursorOptions = { color: this.color, height: this.stateController.canvasDisplayHeight, @@ -187,18 +163,6 @@ export class TimeGraphChartCursors extends TimeGraphLayer { }; this.secondCursor = new TimeGraphCursor(secondCursorOptions); this.addChild(this.secondCursor); - - const selectionRange = new TimeGraphRectangle({ - color: this.color, - opacity: 0.2, - position: { - x: firstCursorPosition, - y: 0 - }, - height: this.stateController.canvasDisplayHeight, - width: secondCursorPosition - firstCursorPosition - }); - this.addChild(selectionRange); } } } diff --git a/timeline-chart/src/layer/time-graph-chart-layer.ts b/timeline-chart/src/layer/time-graph-chart-layer.ts new file mode 100644 index 0000000..372cdce --- /dev/null +++ b/timeline-chart/src/layer/time-graph-chart-layer.ts @@ -0,0 +1,10 @@ +import { TimeGraphLayer } from "./time-graph-layer"; +import { TimeGraphRowController } from "../time-graph-row-controller"; + +export abstract class TimeGraphChartLayer extends TimeGraphLayer { + + constructor(id: string, protected rowController: TimeGraphRowController){ + super(id); + } + +} \ No newline at end of file diff --git a/timeline-chart/src/layer/time-graph-chart-selection-range.ts b/timeline-chart/src/layer/time-graph-chart-selection-range.ts new file mode 100644 index 0000000..f3937d4 --- /dev/null +++ b/timeline-chart/src/layer/time-graph-chart-selection-range.ts @@ -0,0 +1,48 @@ +import { TimeGraphRectangle } from "../components/time-graph-rectangle"; +import { TimeGraphLayer } from "./time-graph-layer"; + +export class TimeGraphChartSelectionRange extends TimeGraphLayer { + protected selectionRange: TimeGraphRectangle; + protected color: number = 0x0000ff; + + constructor(id: string, style?: { color?: number }) { + super(id); + if (style && style.color) { + this.color = style.color; + } + } + + protected updateScaleAndPosition() { + this.layer.position.x = -(this.unitController.viewRange.start * this.stateController.zoomFactor); + this.layer.scale.x = this.stateController.zoomFactor; + } + + protected afterAddToContainer() { + this.unitController.onViewRangeChanged(() => { + this.updateScaleAndPosition(); + }); + this.updateScaleAndPosition(); + this.unitController.onSelectionRangeChange(() => this.update()); + } + + update() { + this.removeChildren(); + if (this.unitController.selectionRange) { + const firstCursorPosition = this.unitController.selectionRange.start; + const secondCursorPosition = this.unitController.selectionRange.end; + if (secondCursorPosition !== firstCursorPosition) { + this.selectionRange = new TimeGraphRectangle({ + color: this.color, + opacity: 0.2, + position: { + x: firstCursorPosition, + y: 0 + }, + height: this.stateController.canvasDisplayHeight, + width: secondCursorPosition - firstCursorPosition + }); + this.addChild(this.selectionRange); + } + } + } +} \ 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 426e0e4..719131a 100644 --- a/timeline-chart/src/layer/time-graph-chart.ts +++ b/timeline-chart/src/layer/time-graph-chart.ts @@ -1,9 +1,10 @@ import { TimeGraphRowElement, TimeGraphRowElementStyle } from "../components/time-graph-row-element"; import { TimeGraphRow, TimeGraphRowStyle } from "../components/time-graph-row"; import { TimeGraphRowModel, TimeGraphRowElementModel, TimeGraphRange } from "../time-graph-model"; -import { TimeGraphLayer } from "./time-graph-layer"; import { TimeGraphComponent } from "../components/time-graph-component"; import * as _ from "lodash"; +import { TimeGraphChartLayer } from "./time-graph-chart-layer"; +import { TimeGraphRowController } from "../time-graph-row-controller"; export interface TimeGraphRowElementMouseInteractions { click?: (el: TimeGraphRowElement, ev: PIXI.interaction.InteractionEvent) => void @@ -21,36 +22,34 @@ export interface TimeGraphChartProviders { export type TimeGraphRowStyleHook = (row: TimeGraphRowModel) => TimeGraphRowStyle | undefined; -export class TimeGraphChart extends TimeGraphLayer { +export class TimeGraphChart extends TimeGraphChartLayer { protected rows: TimeGraphRowModel[]; protected rowElementMouseInteractions: TimeGraphRowElementMouseInteractions; protected selectedElementModel: TimeGraphRowElementModel; protected selectedElementChangedHandler: ((el: TimeGraphRowElementModel) => void)[] = []; - protected selectedRow: TimeGraphRowModel; - protected selectedRowChangedHandler: ((el: TimeGraphRowModel) => void)[] = []; - protected verticalPositionChangedHandler: ((verticalChartPosition: number) => void)[] = []; - protected totalHeight: number; - constructor(id: string, protected providers: TimeGraphChartProviders, protected rowHeight: number) { - super(id); + constructor(id: string, protected providers: TimeGraphChartProviders, protected rowController: TimeGraphRowController) { + super(id, rowController); } protected afterAddToContainer() { this.onCanvasEvent('mousewheel', (ev: WheelEvent) => { const shiftStep = ev.deltaY; - let verticalOffset = this.stateController.positionOffset.y + shiftStep; + let verticalOffset = this.rowController.verticalOffset + shiftStep; if (verticalOffset < 0) { verticalOffset = 0; } - if (this.totalHeight - verticalOffset <= this.stateController.canvasDisplayHeight) { - verticalOffset = this.totalHeight - this.stateController.canvasDisplayHeight; + if (this.rowController.totalHeight - verticalOffset <= this.stateController.canvasDisplayHeight) { + verticalOffset = this.rowController.totalHeight - this.stateController.canvasDisplayHeight; } - this.stateController.positionOffset.y = verticalOffset; + this.rowController.verticalOffset = verticalOffset; + ev.preventDefault(); + }); + + this.rowController.onVerticalOffsetChangedHandler(verticalOffset => { this.layer.position.y = -verticalOffset; - this.handleVerticalPositionChange(); - return false; }); this.unitController.onViewRangeChanged(() => { @@ -61,7 +60,7 @@ export class TimeGraphChart extends TimeGraphLayer { // lets fetch everything const rowData = this.providers.dataProvider({ start: 0, end: this.unitController.absoluteRange }, 1); this.setRowModel(rowData.rows); - this.addRows(this.rows, this.rowHeight); + this.addRows(this.rows, this.rowController.rowHeight); } update() { } @@ -71,18 +70,10 @@ export class TimeGraphChart extends TimeGraphLayer { this.layer.scale.x = this.stateController.zoomFactor; } - protected handleVerticalPositionChange() { - this.verticalPositionChangedHandler.forEach(handler => handler(this.stateController.positionOffset.y)); - } - protected handleSelectedRowElementChange() { this.selectedElementChangedHandler.forEach(handler => handler(this.selectedElementModel)); } - protected handleSelectedRowChange() { - this.selectedRowChangedHandler.forEach(handler => handler(this.selectedRow)); - } - protected addRow(row: TimeGraphRowModel, height: number, rowIndex: number) { const rowId = 'row_' + rowIndex; const length = row.range.end - row.range.start; @@ -148,8 +139,7 @@ export class TimeGraphChart extends TimeGraphLayer { if (!this.stateController) { throw ('Add this TimeGraphChart to a container before adding rows.'); } - this.rowHeight = height; - this.totalHeight = rows.length * height; + this.rowController.rowHeight = height; rows.forEach((row: TimeGraphRowModel, index: number) => { this.addRow(row, height, index); }); @@ -167,14 +157,6 @@ export class TimeGraphChart extends TimeGraphLayer { this.selectedElementChangedHandler.push(handler); } - onSelectedRowChanged(handler: (row: TimeGraphRowModel) => void) { - this.selectedRowChangedHandler.push(handler); - } - - onVerticalPositionChanged(handler: (verticalChartPosition: number) => void) { - this.verticalPositionChangedHandler.push(handler); - } - getRowModels(): TimeGraphRowModel[] { return this.rows; } @@ -186,17 +168,12 @@ export class TimeGraphChart extends TimeGraphLayer { return element as TimeGraphRowElement; } - getSelectedRow(): TimeGraphRowModel { - return this.selectedRow; - } - selectRow(row: TimeGraphRowModel) { - if (this.selectedRow) { - this.selectedRow.selected = false; + if (this.rowController.selectedRow) { + delete this.rowController.selectedRow.selected; } - this.selectedRow = row; + this.rowController.selectedRow = row; row.selected = true; - this.handleSelectedRowChange(); } getSelectedRowElement(): TimeGraphRowElementModel { @@ -205,7 +182,7 @@ export class TimeGraphChart extends TimeGraphLayer { selectRowElement(model: TimeGraphRowElementModel) { if (this.selectedElementModel) { - this.selectedElementModel.selected = false; + delete this.selectedElementModel.selected; } this.selectedElementModel = model; model.selected = true; @@ -215,8 +192,4 @@ export class TimeGraphChart extends TimeGraphLayer { } this.handleSelectedRowElementChange(); } - - setVerticalPositionOffset(ypos: number) { - this.stateController.positionOffset.y = ypos; - } } \ No newline at end of file diff --git a/timeline-chart/src/layer/time-graph-vertical-scrollbar.ts b/timeline-chart/src/layer/time-graph-vertical-scrollbar.ts index 5885849..0a55261 100644 --- a/timeline-chart/src/layer/time-graph-vertical-scrollbar.ts +++ b/timeline-chart/src/layer/time-graph-vertical-scrollbar.ts @@ -1,46 +1,30 @@ import { TimeGraphComponent, TimeGraphInteractionHandler, TimeGraphElementPosition } from "../components/time-graph-component"; import { TimeGraphStateController } from "../time-graph-state-controller"; import { TimeGraphRectangle } from "../components/time-graph-rectangle"; -import { TimeGraphLayer } from "./time-graph-layer"; +import { TimeGraphChartLayer } from "./time-graph-chart-layer"; +import { TimeGraphRowController } from "../time-graph-row-controller"; -export class TimeGraphVerticalScrollbar extends TimeGraphLayer { +export class TimeGraphVerticalScrollbar extends TimeGraphChartLayer { protected navigatorHandle: TimeGraphVerticalScrollbarHandle; protected selectionRange?: TimeGraphRectangle; protected factor: number; - protected verticalPositionChangedHandler: ((ypos: number) => void)[]; - - constructor(id: string, protected totalHeight: number) { - super(id); - this.verticalPositionChangedHandler = []; + constructor(id: string, protected rowController: TimeGraphRowController) { + super(id, rowController); } protected afterAddToContainer() { - this.factor = this.totalHeight / this.stateController.canvasDisplayHeight; - this.navigatorHandle = new TimeGraphVerticalScrollbarHandle(this.stateController, this.factor); + this.factor = this.stateController.canvasDisplayHeight / this.rowController.totalHeight; + this.navigatorHandle = new TimeGraphVerticalScrollbarHandle(this.rowController, this.stateController, this.factor); this.addChild(this.navigatorHandle); - this.stateController.onPositionChanged(() => this.update()); - } - - protected handleVerticalPositionChange(ypos: number) { - this.verticalPositionChangedHandler.forEach(handler => handler(ypos)); - } - - onVerticalPositionChanged(handler: (ypos: number) => void) { - this.verticalPositionChangedHandler.push(handler); - } - - setVerticalPosition(verticalPosition: number){ - this.stateController.positionOffset.y = verticalPosition / this.factor; - this.update(); + this.rowController.onVerticalOffsetChangedHandler(() => this.update()); } update() { this.navigatorHandle.clear(); this.navigatorHandle.render(); - this.handleVerticalPositionChange(this.stateController.positionOffset.y * this.factor); } } @@ -53,11 +37,11 @@ export class TimeGraphVerticalScrollbarHandle extends TimeGraphComponent { protected height: number; protected position: TimeGraphElementPosition; - constructor(protected stateController: TimeGraphStateController, protected factor: number) { + constructor(protected rowController: TimeGraphRowController, protected stateController: TimeGraphStateController, protected factor: number) { super('vscroll_handle'); this.addEvent('mousedown', event => { this.mouseStartY = event.data.global.y; - this.oldVerticalOffset = this.stateController.positionOffset.y + this.oldVerticalOffset = this.rowController.verticalOffset this.mouseIsDown = true; }, this._displayObject); this.addEvent('mousemove', event => { @@ -65,7 +49,7 @@ export class TimeGraphVerticalScrollbarHandle extends TimeGraphComponent { const delta = event.data.global.y - this.mouseStartY; let ypos = this.oldVerticalOffset + delta; if (ypos >= 0 && (ypos + this.height) <= this.stateController.canvasDisplayHeight) { - this.stateController.positionOffset = { x: 0, y: ypos }; + this.rowController.verticalOffset = ypos/this.factor; } } }, this._displayObject); @@ -77,8 +61,8 @@ export class TimeGraphVerticalScrollbarHandle extends TimeGraphComponent { } render(): void { - this.position = { x: 0, y: this.stateController.positionOffset.y }; - this.height = this.stateController.canvasDisplayHeight / this.factor; + this.position = { x: 0, y: this.rowController.verticalOffset * this.factor }; + this.height = this.stateController.canvasDisplayHeight * this.factor; this.rect({ height: this.height, position: this.position, diff --git a/timeline-chart/src/time-graph-model.ts b/timeline-chart/src/time-graph-model.ts index 0641c0b..c6fdc59 100644 --- a/timeline-chart/src/time-graph-model.ts +++ b/timeline-chart/src/time-graph-model.ts @@ -15,7 +15,7 @@ export interface TimeGraphRowModel { name: string range: TimeGraphRange states: TimeGraphRowElementModel[] - selected: boolean + selected?: boolean readonly data?: {[key:string]:any} } @@ -23,7 +23,7 @@ export interface TimeGraphRowElementModel { readonly id: string readonly range: TimeGraphRange readonly label: string - selected: boolean + selected?: boolean readonly data?: {[key:string]:any} } diff --git a/timeline-chart/src/time-graph-row-controller.ts b/timeline-chart/src/time-graph-row-controller.ts new file mode 100644 index 0000000..c4790d5 --- /dev/null +++ b/timeline-chart/src/time-graph-row-controller.ts @@ -0,0 +1,44 @@ +import { TimeGraphRowModel } from "./time-graph-model"; + +export class TimeGraphRowController { + private _selectedRow: TimeGraphRowModel; + private _verticalOffset: number; + protected selectedRowChangedHandler: ((row: TimeGraphRowModel) => void)[] = []; + protected verticalOffsetChangedHandler: ((verticalOffset: number) => void)[] = []; + + constructor(public rowHeight: number, public totalHeight: number) { + this._verticalOffset = 0; + } + + protected handleVerticalOffsetChanged(){ + this.verticalOffsetChangedHandler.forEach(h=>h(this._verticalOffset)); + } + + protected handleSelectedRowChanged(){ + this.selectedRowChangedHandler.forEach(h=>h(this._selectedRow)); + } + + onSelectedRowChangedHandler(handler: (row: TimeGraphRowModel) => void) { + this.selectedRowChangedHandler.push(handler); + } + + onVerticalOffsetChangedHandler(handler: (verticalOffset: number) => void) { + this.verticalOffsetChangedHandler.push(handler); + } + + get verticalOffset(): number { + return this._verticalOffset; + } + set verticalOffset(value: number) { + this._verticalOffset = value; + this.handleVerticalOffsetChanged(); + } + + get selectedRow(): TimeGraphRowModel { + return this._selectedRow; + } + set selectedRow(value: TimeGraphRowModel) { + this._selectedRow = value; + this.handleSelectedRowChanged(); + } +} \ No newline at end of file diff --git a/timeline-chart/src/time-graph-unit-controller.ts b/timeline-chart/src/time-graph-unit-controller.ts index bad6475..5bd6bb9 100644 --- a/timeline-chart/src/time-graph-unit-controller.ts +++ b/timeline-chart/src/time-graph-unit-controller.ts @@ -35,7 +35,7 @@ export class TimeGraphUnitController { } set viewRange(newRange: TimeGraphRange) { if (newRange.end > newRange.start) { - this._viewRange = { start: Math.round(newRange.start), end: Math.round(newRange.end) }; + this._viewRange = { start: newRange.start, end: newRange.end }; } if (newRange.start < 0) { this._viewRange.start = 0;