diff --git a/example/index.html b/example/index.html
index 8e238f7..b3eeab9 100644
--- a/example/index.html
+++ b/example/index.html
@@ -4,12 +4,18 @@
diff --git a/src/index.ts b/src/index.ts
index 57a3ec3..3e1c6e5 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,7 @@
-import { TimeGraph, TimeGraphModel } from "./time-graph";
-// import { TimeAxis } from "./time-axis";
+import { TimeGraph } from "./time-graph";
+import { TimeGraphModel } from "./time-graph-model";
+import { TimeGraphAxis } from "./time-graph-axis";
+import { TimeGraphChart } from "./time-graph-chart";
// const timeGraphSimple: TimeGraphModel = {
// id: 'test1',
@@ -112,26 +114,30 @@ const timeGraph: TimeGraphModel = {
]
},
{
+ range: {
+ start: 1000,
+ end: 2000
+ },
states: [
{
label: 'state2.1',
range: {
- start: 145,
- end: 255
+ start: 1145,
+ end: 1255
}
},
{
label: 'state2.2',
range: {
- start: 265,
- end: 275
+ start: 1265,
+ end: 1275
}
},
{
label: 'state2.3',
range: {
- start: 365,
- end: 555
+ start: 1365,
+ end: 1555
}
}
]
@@ -139,38 +145,28 @@ const timeGraph: TimeGraphModel = {
]
}
+const tg = new TimeGraph('main', timeGraph);
+const timeAxis = new TimeGraphAxis({
+ id: 'timeGraphAxis',
+ height: 30,
+ width: 500
+}, timeGraph.range, tg.controller);
-// const tg = new TimeGraph('main');
-
-// const timeAxis = new TimeAxis({
-// id: 'timeAxis',
-// height: 30,
-// width: 6000
-// });
-// tg.setTimeAxis(timeAxis)
-
-// r1 = new TimeGraphRow(row-config)
-// r2 = new TimeGraphRow(row-config)
-
-// tg.addRows([r1, r2])
-// tg.removeRows([r2])
-
-// s1 = new TimeGraphState(state-config)
-// s2 = new TimeGraphState(state-config)
-
-// r = tg.findRow(row-id)
-// r.addStates([s1])
-// r1.addStates([s2])
-
-const chart = new TimeGraph('main', timeGraph);
-chart.render();
+const timeGraphChart = new TimeGraphChart({
+ id: timeGraph.id + '_chart',
+ height: 300,
+ width: 500
+}, timeGraph.range, tg.controller);
+timeGraphChart.addRows(timeGraph.rows);
+tg.timeGraphAxis = timeAxis;
+tg.timeGraphChart = timeGraphChart;
export type TestFieldId = 'test0' | 'test1' | 'test2' | 'test3' | 'test4' | 'test5' | 'test6' | 'test7' | 'test8' | 'test9';
-export function tgTest(id: TestFieldId, val:string){
+export function tgTest(id: TestFieldId, val: string) {
const f = document.getElementById(id);
- if(f){
+ if (f) {
f.innerHTML = val;
}
}
\ No newline at end of file
diff --git a/src/time-axis-controller.ts b/src/time-axis-controller.ts
deleted file mode 100644
index 5e66a18..0000000
--- a/src/time-axis-controller.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { TimeAxisScale } from "./time-axis-scale";
-import { TimeGraphRange } from "./time-graph";
-
-export class TimeAxisController {
-
- protected totalRange: TimeGraphRange;
- protected visibleRange: TimeGraphRange;
-
- constructor(protected timeAxis: TimeAxisScale) {
-
- }
-}
\ No newline at end of file
diff --git a/src/time-axis.ts b/src/time-axis.ts
deleted file mode 100644
index afed534..0000000
--- a/src/time-axis.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { TimeGraphContextOptions, TimeGraphContainer } from "./time-graph";
-
-export class TimeAxis {
-
- protected application: PIXI.Application;
-
- constructor(config: TimeGraphContextOptions) {
- const canvas: HTMLCanvasElement = document.createElement('canvas');
- canvas.width = config.width;
- canvas.height = config.height;
- canvas.id = config.id;
- canvas.className = 'time-graph-canvas';
- this.application = new PIXI.Application({
- width: config.width,
- height: config.height,
- view: canvas,
- backgroundColor: config.backgroundColor || 0x000000
- });
-
- }
-
- getViewElement(): HTMLCanvasElement {
- return this.application.view;
- }
-
- getStage(): TimeGraphContainer {
- return this.application.stage;
- }
-
-
-}
\ No newline at end of file
diff --git a/src/time-cursor.ts b/src/time-cursor.ts
deleted file mode 100644
index b723814..0000000
--- a/src/time-cursor.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { TimeGraphComponent } from "./time-graph-component";
-
-export class TimeCursor extends TimeGraphComponent {
-
- render(): void {
- throw new Error("Method not implemented.");
- }
-
-}
\ No newline at end of file
diff --git a/src/time-graph-axis-scale.ts b/src/time-graph-axis-scale.ts
new file mode 100644
index 0000000..bd4bb19
--- /dev/null
+++ b/src/time-graph-axis-scale.ts
@@ -0,0 +1,19 @@
+import { TimeGraphComponent, TimeGraphRect } from "./time-graph-component";
+
+export class TimeGraphAxisScale extends TimeGraphComponent {
+
+ constructor(id: string, protected options: TimeGraphRect) {
+ super(id);
+ }
+
+ render() {
+ this.rect({
+ color: 0xFF0000,
+ height: this.options.height,
+ width: this.options.width,
+ position: this.options.position
+ });
+ console.log("render axis", this.options.width);
+ }
+
+}
\ No newline at end of file
diff --git a/src/time-graph-axis.ts b/src/time-graph-axis.ts
new file mode 100644
index 0000000..a35a48e
--- /dev/null
+++ b/src/time-graph-axis.ts
@@ -0,0 +1,34 @@
+import { TimeGraphAxisScale } from "./time-graph-axis-scale";
+import { TimeGraphContainer, TimeGraphContainerOptions } from "./time-graph-container";
+import { TimeGraphRange } from "./time-graph-model";
+import { TimeGraphStateController } from "./time-graph-state-controller";
+
+export class TimeGraphAxis extends TimeGraphContainer {
+
+ constructor(protected canvasOpts: TimeGraphContainerOptions, protected range: TimeGraphRange, protected controller: TimeGraphStateController) {
+ super({
+ id: canvasOpts.id,
+ height: canvasOpts.height,
+ width: canvasOpts.width,
+ backgroundColor: 0xAA30f0
+ }, controller);
+
+ this.update();
+ this.controller.zoomAndPanController.addMousewheelZoomAndPan(this.canvas);
+ }
+
+ update() {
+ this.stage.removeChildren();
+ const scaleComponent = new TimeGraphAxisScale(this.canvasOpts.id + '_scale', {
+ height: 30,
+ width: (this.range.end - this.range.start) * this._controller.zoomFactor,
+ position: {
+ x: this._controller.positionOffset.x,
+ y: 0
+ }
+ });
+
+ this.addChild(scaleComponent);
+ this.controller.zoomAndPanController.addDnDZoomAndPan(scaleComponent.displayObject);
+ }
+}
\ No newline at end of file
diff --git a/src/time-graph-chart.ts b/src/time-graph-chart.ts
new file mode 100644
index 0000000..98c4ac1
--- /dev/null
+++ b/src/time-graph-chart.ts
@@ -0,0 +1,59 @@
+import { TimeGraphContainer, TimeGraphContainerOptions } from "./time-graph-container";
+import { TimeGraphRowElement } from "./time-graph-row-element";
+import { TimeGraphRow } from "./time-graph-row";
+import { TimeGraphRowModel, TimeGraphRowElementModel, TimeGraphRange } from "./time-graph-model";
+import { TimeGraphStateController } from "./time-graph-state-controller";
+
+export class TimeGraphChart extends TimeGraphContainer {
+
+ protected rows: TimeGraphRowModel[];
+
+ constructor(canvasOpts: TimeGraphContainerOptions, protected range: TimeGraphRange, controller: TimeGraphStateController) {
+ super({
+ id: canvasOpts.id,
+ height: canvasOpts.height,
+ width: canvasOpts.width,
+ backgroundColor: 0xFFFFFF
+ }, controller);
+ this.rows = [];
+ }
+
+ addRow(row: TimeGraphRowModel) {
+ const height = 20;
+ const rowId = 'row_' + this._stage.children.length;
+ const rowComponent = new TimeGraphRow(rowId, {
+ position: {
+ x: 0, // TODO must be calculated by zoom and pan
+ y: (height * this.rows.length) + height / 2
+ },
+ width: this.range.end
+ });
+ this.addChild(rowComponent);
+ this.rows.push(row);
+
+ row.states.forEach((rowElement: TimeGraphRowElementModel, idx: number) => {
+ const newRowElement: TimeGraphRowElementModel = {
+ label: rowElement.label,
+ range: {
+ start: (rowElement.range.start * this._controller.zoomFactor) + this._controller.positionOffset.x,
+ end: (rowElement.range.end * this._controller.zoomFactor) + this._controller.positionOffset.x
+ }
+ }
+ const el = new TimeGraphRowElement(rowId + '_el_' + idx, newRowElement, rowComponent);
+ this.addChild(el);
+ });
+ }
+
+ addRows(rows: TimeGraphRowModel[]) {
+ this.rows = [];
+ rows.forEach(row => {
+ this.addRow(row);
+ })
+ }
+
+ update() {
+ this.stage.removeChildren();
+ this.addRows(this.rows);
+ }
+
+}
\ No newline at end of file
diff --git a/src/time-graph-component.ts b/src/time-graph-component.ts
index 166e070..5c9a4f6 100644
--- a/src/time-graph-component.ts
+++ b/src/time-graph-component.ts
@@ -1,91 +1,69 @@
-import { TimeGraphContainer, TimeGraphApplication } from "./time-graph";
-import { TimeGraphController } from "./time-graph-controller";
-
export type TimeGraphInteractionType = 'mouseover' | 'mouseout' | 'mousemove' | 'mousedown' | 'mouseup' | 'mouseupoutside' | 'click';
export type TimeGraphInteractionHandler = (event: PIXI.interaction.InteractionEvent) => void;
-export type TimeGraphInteractionHandlerMap = Map
-export interface TimeGraphDisplayObject {
+export interface TimeGraphElementStyle {
color?: number
opacity?: number
}
-
-export interface TimeGraphRect extends TimeGraphDisplayObject {
+export interface TimeGraphElementPosition {
x: number
y: number
- w: number
- h: number
}
-
-export interface TimeGraphLine extends TimeGraphDisplayObject {
- start: {
- x: number
- y: number
- }
- end: {
- x: number
- y: number
- }
- width?: number
+export interface TimeGraphHorizontalElement {
+ position: TimeGraphElementPosition
+ width: number
}
+export interface TimeGraphVerticalElement {
+ position: TimeGraphElementPosition
+ height: number
+}
+export interface TimeGraphLineStyle extends TimeGraphElementStyle {
+ thickness?: number
+}
+export type TimeGraphRect = TimeGraphHorizontalElement & TimeGraphVerticalElement;
+export type TimeGraphStyledRect = TimeGraphRect & TimeGraphElementStyle;
+export type TimeGraphHorizontalLine = TimeGraphHorizontalElement & TimeGraphLineStyle;
+export type TimeGraphVerticalLine = TimeGraphVerticalElement & TimeGraphLineStyle;
export abstract class TimeGraphComponent {
+ protected _displayObject: PIXI.Graphics;
- protected _ctx: TimeGraphContainer;
- protected _id: string;
- protected _controller: TimeGraphController;
- protected displayObject: PIXI.Graphics;
- protected options: TimeGraphDisplayObject;
-
- constructor(id: string, protected app: TimeGraphApplication, timeGraphController: TimeGraphController) {
- this._id = id;
- this._ctx = app.stage;
- this._controller = timeGraphController;
- this.displayObject = new PIXI.Graphics();
- this._ctx.addChild(this.displayObject);
+ constructor(protected _id: string) {
+ this._displayObject = new PIXI.Graphics();
}
get id(): string {
return this._id;
}
- get context(): TimeGraphContainer {
- return this._ctx;
+ get displayObject(): PIXI.Graphics {
+ return this._displayObject;
}
- get controller(): TimeGraphController {
- return this._controller;
+ clear() {
+ this._displayObject.clear();
}
abstract render(): void;
- clear(){
- this.displayObject.clear();
- }
-
- rect(opts: TimeGraphRect) {
- const { x, y, w, h, color } = opts;
- const c = this.controller;
- const calcX = (x * c.zoomFactor) + c.positionOffset.x ;
- const calcW = w * c.zoomFactor;
+ protected rect(opts: TimeGraphStyledRect) {
+ const { position, width, height, color } = opts;
this.displayObject.beginFill((color || 0x000000));
- this.displayObject.drawRect(calcX, y, calcW, h);
+ this.displayObject.drawRect(position.x, position.y, width, height);
this.displayObject.endFill();
}
- line(opts: TimeGraphLine) {
- const { width, color } = opts;
- this.displayObject.lineStyle(width || 1, color || 0x000000);
- this.displayObject.moveTo(opts.start.x, opts.start.y);
- this.displayObject.lineTo((opts.end.x * this.controller.zoomFactor), opts.end.y);
+ protected hline(opts: TimeGraphHorizontalLine) {
+ const { position, width, thickness, color } = opts;
+ this.displayObject.lineStyle(thickness || 1, color || 0x000000);
+ this.displayObject.moveTo(position.x, position.y);
+ this.displayObject.lineTo(position.x + width, position.y);
}
- protected addEvent(event: TimeGraphInteractionType, handler: TimeGraphInteractionHandler) {
- this.displayObject.interactive = true;
- this.displayObject.on(event, (e: PIXI.interaction.InteractionEvent) => {
- if (handler) {
- handler(e);
- }
- });
+ protected vline(opts: TimeGraphVerticalLine) {
+ const { position, height, thickness, color } = opts;
+ this.displayObject.lineStyle(thickness || 1, color || 0x000000);
+ this.displayObject.moveTo(position.x, position.y);
+ this.displayObject.lineTo(position.x, position.y + height);
}
}
\ No newline at end of file
diff --git a/src/time-graph-container.ts b/src/time-graph-container.ts
new file mode 100644
index 0000000..e2f4021
--- /dev/null
+++ b/src/time-graph-container.ts
@@ -0,0 +1,53 @@
+import { TimeGraphComponent } from "./time-graph-component";
+import * as PIXI from "pixi.js";
+import { TimeGraphStateController } from "./time-graph-state-controller";
+
+export interface TimeGraphContainerOptions {
+ id: string
+ width: number
+ height: number
+ backgroundColor?: number
+}
+
+export abstract class TimeGraphContainer {
+
+ protected _stage: PIXI.Container;
+ protected _canvas: HTMLCanvasElement;
+
+ protected _controller: TimeGraphStateController;
+
+ constructor(config: TimeGraphContainerOptions, controller: TimeGraphStateController) {
+ const canvas: HTMLCanvasElement = document.createElement('canvas');
+ canvas.width = config.width;
+ canvas.height = config.height;
+ canvas.id = config.id;
+ canvas.className = 'time-graph-canvas';
+ const application = new PIXI.Application({
+ width: config.width,
+ height: config.height,
+ view: canvas,
+ backgroundColor: config.backgroundColor || 0x000000
+ });
+ application.stage.height = config.height;
+
+ this._stage = application.stage;
+ this._canvas = application.view;
+
+ this._controller = controller;
+ }
+
+ get canvas(): HTMLCanvasElement {
+ return this._canvas;
+ }
+
+ get stage(): PIXI.Container {
+ return this._stage;
+ }
+
+ protected addChild(child: TimeGraphComponent) {
+ child.render();
+ this._stage.addChild(child.displayObject);
+ }
+
+ abstract update(): void;
+}
\ No newline at end of file
diff --git a/src/time-axis-scale.ts b/src/time-graph-interaction.ts
similarity index 66%
rename from src/time-axis-scale.ts
rename to src/time-graph-interaction.ts
index 11652e5..71a5d08 100644
--- a/src/time-axis-scale.ts
+++ b/src/time-graph-interaction.ts
@@ -1,23 +1,35 @@
-import { TimeGraphComponent, TimeGraphRect } from "./time-graph-component";
-import { TimeGraphApplication } from "./time-graph";
-import { TimeGraphController } from "./time-graph-controller";
+import { TimeGraphStateController } from "./time-graph-state-controller";
-export class TimeAxisScale extends TimeGraphComponent {
+export type TimeGraphInteractionType = 'mouseover' | 'mouseout' | 'mousemove' | 'mousedown' | 'mouseup' | 'mouseupoutside' | 'click';
+export type TimeGraphInteractionHandler = (event: PIXI.interaction.InteractionEvent) => void;
+export class TimeGraphInteraction {
protected mouseStartY: number;
protected mouseStartX: number;
protected graphWidthStart: number;
protected mouseIsDown: boolean = false;
- constructor(id: string, ctx: TimeGraphApplication, timeGraphController: TimeGraphController) {
- super(id, ctx, timeGraphController);
+ constructor(protected controller: TimeGraphStateController) {}
+
+ addMousewheelZoomAndPan(canvas: HTMLCanvasElement) {
+ canvas.addEventListener('mousewheel', (ev: WheelEvent) => {
+ this.mouseStartX = ev.x;
+ this.graphWidthStart = this.controller.graphWidth;
+ this.zoom((ev.deltaY / 100) * (-1));
+ this.setXOffset(ev.deltaX * (-1));
+ this.setZoomAndPosition();
+ return false;
+ });
+ }
+
+ addDnDZoomAndPan(displayObject: PIXI.DisplayObject) {
this.addEvent('mousedown', event => {
this.mouseStartY = event.data.global.y;
this.mouseStartX = event.data.global.x;
this.graphWidthStart = this.controller.graphWidth;
this.mouseIsDown = true;
- });
+ }, displayObject);
this.addEvent('mousemove', event => {
if (this.mouseIsDown) {
@@ -29,29 +41,21 @@ export class TimeAxisScale extends TimeGraphComponent {
const deltaMouseX = event.data.global.x - this.mouseStartX;
this.setXOffset(deltaMouseX);
}
- });
+ }, displayObject);
const mouseUp = (event: PIXI.interaction.InteractionEvent) => {
this.mouseIsDown = false;
this.setZoomAndPosition();
}
- this.addEvent('mouseup', mouseUp);
- this.addEvent('mouseupoutside', mouseUp);
- this.app.view.addEventListener('mousewheel', (ev: WheelEvent) => {
- this.mouseStartX = ev.x;
- this.graphWidthStart = this.controller.graphWidth;
- this.zoom((ev.deltaY / 100) * (-1));
- this.setXOffset(ev.deltaX * (-1));
- this.setZoomAndPosition();
- return false;
- });
+ this.addEvent('mouseup', mouseUp, displayObject);
+ this.addEvent('mouseupoutside', mouseUp, displayObject);
}
- setZoomAndPosition() {
+ protected setZoomAndPosition() {
this.controller.oldZoomFactor = this.controller.zoomFactor;
this.controller.oldPositionOffset = this.controller.positionOffset;
}
- setXOffset(deltaMouseX: number = 0) {
+ protected setXOffset(deltaMouseX: number = 0) {
const c = this.controller;
const normZoomFactor = c.graphWidth / this.graphWidthStart;
const graphMouseStartX = (c.oldPositionOffset.x * (-1)) + this.mouseStartX;
@@ -78,15 +82,12 @@ export class TimeAxisScale extends TimeGraphComponent {
}
}
- render() {
- this.options = {
- color: 0xFF0000,
- h: 30,
- w: 6000,
- x: 0,
- y: 0
- };
- this.rect(this.options as TimeGraphRect);
+ protected addEvent(event: TimeGraphInteractionType, handler: TimeGraphInteractionHandler, displayObject: PIXI.DisplayObject) {
+ displayObject.interactive = true;
+ displayObject.on(event, (e: PIXI.interaction.InteractionEvent) => {
+ if (handler) {
+ handler(e);
+ }
+ });
}
-
}
\ No newline at end of file
diff --git a/src/time-graph-model.ts b/src/time-graph-model.ts
new file mode 100644
index 0000000..affab9a
--- /dev/null
+++ b/src/time-graph-model.ts
@@ -0,0 +1,21 @@
+export interface TimeGraphRange {
+ start: number
+ end: number
+}
+
+export interface TimeGraphModel {
+ id: string
+ name: string
+ range: TimeGraphRange
+ rows: TimeGraphRowModel[]
+}
+
+export interface TimeGraphRowModel {
+ range?: TimeGraphRange
+ states: TimeGraphRowElementModel[]
+}
+
+export interface TimeGraphRowElementModel {
+ range: TimeGraphRange
+ label: string
+}
\ No newline at end of file
diff --git a/src/time-graph-row-element.ts b/src/time-graph-row-element.ts
new file mode 100644
index 0000000..5923fd0
--- /dev/null
+++ b/src/time-graph-row-element.ts
@@ -0,0 +1,26 @@
+import { TimeGraphComponent } from "./time-graph-component";
+import { TimeGraphRow } from "./time-graph-row";
+import { TimeGraphRowElementModel } from "./time-graph-model";
+
+export class TimeGraphRowElement extends TimeGraphComponent {
+
+ constructor(id: string, protected options: TimeGraphRowElementModel, protected row: TimeGraphRow) {
+ super(id);
+ }
+
+ render() {
+ const height = 20;
+ const position = {
+ x: this.options.range.start,
+ y: this.row.position.y - (height / 2)
+ };
+ const width = this.options.range.end - this.options.range.start;
+
+ this.rect({
+ color: 0xC80000,
+ height,
+ position,
+ width
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/time-graph-row-view.ts b/src/time-graph-row-view.ts
deleted file mode 100644
index 856b0b1..0000000
--- a/src/time-graph-row-view.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { TimeGraphState, TimeGraphStateView } from "./time-graph-state-view";
-import { TimeGraphComponent } from "./time-graph-component";
-import { TimeGraphRange, TimeGraphApplication } from "./time-graph";
-import { TimeGraphController } from "./time-graph-controller";
-
-export interface TimeGraphRow {
- start?: number
- end?: number
- states: TimeGraphState[]
-}
-
-export class TimeGraphRowView extends TimeGraphComponent {
-
- protected height: number;
- protected ypos: number;
- protected width: number;
-
- constructor(
- protected cid: string,
- app: TimeGraphApplication,
- protected rowIdx: number,
- protected row: TimeGraphRow,
- protected range: TimeGraphRange,
- timeGraphController: TimeGraphController
- ) {
- super(cid, app, timeGraphController);
- this.height = 20;
- this.ypos = (this.height * this.rowIdx) + this.height / 2;
- this.width = this.range.end - this.range.start;
- }
-
- render() {
- this.line({
- start: { x: 0, y: this.ypos },
- end: { x: this.width, y: this.ypos },
- color: 0x000000,
- opacity: 0.2,
- width: 1
- });
-
- this.row.states.forEach(state => {
- const timeGraphState = new TimeGraphStateView(this.id + state.label + state.range.start, this.app, state, this.ypos, this.range, this.controller);
- timeGraphState.render();
- });
- }
-
-}
\ No newline at end of file
diff --git a/src/time-graph-row.ts b/src/time-graph-row.ts
new file mode 100644
index 0000000..243c558
--- /dev/null
+++ b/src/time-graph-row.ts
@@ -0,0 +1,21 @@
+import { TimeGraphComponent, TimeGraphHorizontalElement, TimeGraphElementPosition } from "./time-graph-component";
+
+export class TimeGraphRow extends TimeGraphComponent {
+
+ constructor(id: string, protected options: TimeGraphHorizontalElement) {
+ super(id);
+ }
+
+ render() {
+ this.hline({
+ color: 0x000000,
+ opacity: 0.2,
+ width: this.options.width,
+ position: this.options.position
+ });
+ }
+
+ get position(): TimeGraphElementPosition {
+ return this.options.position;
+ }
+}
\ No newline at end of file
diff --git a/src/time-graph-controller.ts b/src/time-graph-state-controller.ts
similarity index 79%
rename from src/time-graph-controller.ts
rename to src/time-graph-state-controller.ts
index ca610c4..9537321 100644
--- a/src/time-graph-controller.ts
+++ b/src/time-graph-state-controller.ts
@@ -1,7 +1,6 @@
-import { TimeGraphComponent } from "./time-graph-component";
-import { TimeGraphContainer } from "./time-graph";
+import { TimeGraphInteraction } from "./time-graph-interaction";
-export class TimeGraphController {
+export class TimeGraphStateController {
protected _originalGraphWidth: number;
protected _zoomFactor: number;
protected _initialZoomFactor: number;
@@ -14,15 +13,13 @@ export class TimeGraphController {
x: number;
y: number;
};
- protected _components: TimeGraphComponent[];
- protected _contexts: Map;
protected zoomChangedHandler: (() => void)[];
protected positionChangedHandler: (() => void)[];
+ protected _zoomAndPanController: TimeGraphInteraction;
+
constructor(protected _canvasWidth: number, protected _graphWidth: number) {
- this._components = [];
- this._contexts = new Map();
this._originalGraphWidth = _graphWidth;
this._initialZoomFactor = _canvasWidth / _graphWidth;
this._graphWidth = this._originalGraphWidth * this._initialZoomFactor;
@@ -32,6 +29,11 @@ export class TimeGraphController {
this._oldPositionOffset = { x: 0, y: 0 };
this.zoomChangedHandler = [];
this.positionChangedHandler = [];
+ this._zoomAndPanController = new TimeGraphInteraction(this);
+ }
+
+ get zoomAndPanController(): TimeGraphInteraction {
+ return this._zoomAndPanController;
}
protected handleZoomChange() {
@@ -108,19 +110,4 @@ export class TimeGraphController {
}) {
this._oldPositionOffset = value;
}
-
- get components(): TimeGraphComponent[] {
- return this._components;
- }
- addComponent(component: TimeGraphComponent) {
- this.addContext(component.id, component.context);
- this._components.push(component);
- }
-
- addContext(id: string, ctx: TimeGraphContainer) {
- if (!this._contexts.get(id)) {
- this._contexts.set(id, ctx);
-
- }
- }
}
\ No newline at end of file
diff --git a/src/time-graph-state-view.ts b/src/time-graph-state-view.ts
deleted file mode 100644
index 6920aeb..0000000
--- a/src/time-graph-state-view.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { TimeGraphRange, TimeGraphApplication } from "./time-graph";
-import { TimeGraphComponent, TimeGraphRect } from "./time-graph-component";
-import { TimeGraphController } from "./time-graph-controller";
-
-export interface TimeGraphState {
- range: TimeGraphRange
- label: string
-}
-
-export class TimeGraphStateView extends TimeGraphComponent {
-
- protected start: number;
- protected end: number;
- protected y: number;
- protected height: number;
-
- constructor(protected cid: string, app: TimeGraphApplication, protected state: TimeGraphState, yPosition: number, protected range: TimeGraphRange, controller: TimeGraphController) {
- super(cid, app, controller);
-
- // TODO this calculation of the initial offset must be calculated differently later
- this.start = state.range.start - range.start;
- this.end = state.range.end - range.start;
-
- // TODO magic number 10 is the half of the row height...must come from a central style-config-provider later.
- this.y = yPosition - 10;
- // TODO magic number 20 must come from a central style-config-provider later.
- this.height = 20;
- }
-
- render() {
- this.options = {
- color: 0xC80000,
- x: this.start,
- y: this.y,
- w: this.end - this.start,
- h: this.height
- };
- this.addEvent('mouseover', this.handleMouseOver);
- this.addEvent('mouseout', this.handleMouseOut);
- this.addEvent('mousedown', this.handleMouseDown);
- this.addEvent('mouseup', this.handleMouseOut);
- this.rect(this.options as TimeGraphRect);
- }
-
- protected changeColor(color: number) {
- this.displayObject.clear();
- this.options.color = color;
- this.rect(this.options as TimeGraphRect);
- }
-
- protected handleMouseOver = ((event: PIXI.interaction.InteractionEvent) => {
- this.changeColor(0x00C800);
- }).bind(this);
-
- protected handleMouseOut = ((event: PIXI.interaction.InteractionEvent) => {
- this.changeColor(0xC80000);
- }).bind(this);
-
- protected handleMouseDown = ((event: PIXI.interaction.InteractionEvent) => {
- this.changeColor(0x0000C8);
- }).bind(this);
-}
\ No newline at end of file
diff --git a/src/time-graph.ts b/src/time-graph.ts
index b20b12a..fc77ca3 100644
--- a/src/time-graph.ts
+++ b/src/time-graph.ts
@@ -1,123 +1,59 @@
-import { TimeGraphRow, TimeGraphRowView } from "./time-graph-row-view";
-import { TimeAxisScale } from "./time-axis-scale";
-import { TimeGraphController } from "./time-graph-controller";
-import * as PIXI from "pixi.js";
-
-export interface TimeGraphRange {
- start: number
- end: number
-}
-
-export interface TimeGraphModel {
- id: string
- name: string
- range: TimeGraphRange
- rows: TimeGraphRow[]
-}
-
-export interface TimeGraphContextOptions {
- id: string
- width: number
- height: number
- backgroundColor?: number
-}
-
-export type TimeGraphContainer = PIXI.Container
-export type TimeGraphApplication = PIXI.Application;
+import { TimeGraphAxis } from "./time-graph-axis";
+import { TimeGraphChart } from "./time-graph-chart";
+import { TimeGraphStateController } from "./time-graph-state-controller";
+import { TimeGraphModel } from "./time-graph-model";
+import { TimeGraphContainer } from "./time-graph-container";
export class TimeGraph {
protected container?: HTMLElement;
- protected timeGraphWidth: number;
- protected containerWidth: number;
- protected timeGraphController: TimeGraphController;
- protected timeAxisApplication?: TimeGraphApplication;
- protected timeGraphRowsApplication?: TimeGraphApplication;
- protected timeAxis: TimeAxisScale;
+ protected axisContainer: HTMLElement;
+ protected chartContainer: HTMLElement;
- constructor(id: string, protected model: TimeGraphModel) {
- this.container = document.getElementById(id) || undefined;
+ protected tgContainers: TimeGraphContainer[];
+
+ protected _controller: TimeGraphStateController
+
+ constructor(containerId: string, timeGraphModel: TimeGraphModel) {
+ this.container = document.getElementById(containerId) || undefined;
if (!this.container) {
- throw (`No container with id ${id} available.`);
+ throw (`No container with id ${containerId} available.`);
}
+ this.container.innerHTML = '';
- this.timeGraphWidth = this.model.range.end;
- this.containerWidth = this.container.clientWidth;
- this.timeGraphController = new TimeGraphController(this.containerWidth, this.timeGraphWidth);
+ this.axisContainer = document.createElement('div');
+ this.axisContainer.id = containerId + '_axis';
+ this.container.appendChild(this.axisContainer);
- this.timeAxisApplication = this.getNewApplication({
- id: 'timeAxis_' + this.model.id,
- height: 30,
- width: this.timeGraphWidth,
- backgroundColor: 0xAA30f0
- });
- if (this.timeAxisApplication) {
- this.timeAxis = new TimeAxisScale('timeAxis_' + this.model.id, this.timeAxisApplication, this.timeGraphController);
- }
+ this.chartContainer = document.createElement('div');
+ this.chartContainer.id = containerId + '_chart';
+ this.container.appendChild(this.chartContainer);
- this.timeGraphRowsApplication = this.getNewApplication({
- id: 'timeGraphRows_' + this.model.id,
- width: this.timeGraphWidth,
- height: 200,
- backgroundColor: 0xFFFFFF
- });
+ this.tgContainers = [];
- // let fw = true;
- // setInterval(() => {
- // if (this.timeGraphController.zoomFactor < 2 && fw) {
- // this.timeGraphController.zoomFactor += 0.01;
- // } else {
- // fw = false;
- // if (this.timeGraphController.zoomFactor > 0.02) {
- // this.timeGraphController.zoomFactor -= 0.01;
- // } else {
- // fw = true;
- // }
- // }
- // this.render();
- // }, 10);
+ this._controller = new TimeGraphStateController(this.container.clientWidth, timeGraphModel.range.end);
- this.timeGraphController.onZoomChanged(() => {
- this.render();
+ this._controller.onZoomChanged(() => {
+ this.tgContainers.map(c => c.update());
});
- this.timeGraphController.onPositionChanged(() => {
- this.render();
+ this._controller.onPositionChanged(() => {
+ this.tgContainers.map(c => c.update());
});
}
- protected getNewApplication(config: TimeGraphContextOptions): TimeGraphApplication | undefined {
- if (this.container) {
- const canvas: HTMLCanvasElement = document.createElement('canvas');
- canvas.width = config.width;
- canvas.height = config.height;
- canvas.id = config.id;
- canvas.className = 'time-graph-canvas';
- const application = new PIXI.Application({
- width: config.width,
- height: config.height,
- view: canvas,
- backgroundColor: config.backgroundColor || 0x000000
- });
- this.container.appendChild(canvas);
- application.stage.height = config.height;
- return application;
- }
+ get controller(): TimeGraphStateController {
+ return this._controller;
}
- render() {
- this.timeAxis.clear();
- this.timeGraphController.addComponent(this.timeAxis);
- this.timeAxis.render();
+ set timeGraphAxis(tga: TimeGraphAxis) {
+ this.axisContainer.innerHTML = '';
+ this.tgContainers.push(tga);
+ this.axisContainer.appendChild(tga.canvas);
+ }
- if(this.timeGraphRowsApplication){
- this.timeGraphRowsApplication.stage.removeChildren();
- }
- this.model.rows.forEach((row: TimeGraphRow, idx: number) => {
- if (this.timeGraphRowsApplication) {
- const timeGraphRow = new TimeGraphRowView(this.model.id + 'row' + idx, this.timeGraphRowsApplication, idx, row, this.model.range, this.timeGraphController);
- this.timeGraphController.addComponent(timeGraphRow);
- timeGraphRow.render();
- }
- });
+ set timeGraphChart(tgc: TimeGraphChart) {
+ this.chartContainer.innerHTML = '';
+ this.tgContainers.push(tgc);
+ this.chartContainer.appendChild(tgc.canvas);
}
}
\ No newline at end of file