Skip to content

Commit

Permalink
Add support for range events
Browse files Browse the repository at this point in the history
Signed-off-by: Ankush Tyagi <ankush.tyagi@ericsson.com>
  • Loading branch information
ankusht-work authored and bhufmann committed Jun 7, 2021
1 parent dab8c9e commit bd7f984
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 53 deletions.
91 changes: 51 additions & 40 deletions example/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TestDataProvider } from "./test-data-provider";
import { TimeGraphChartGrid } from "timeline-chart/lib/layer/time-graph-chart-grid";
import { TimeGraphVerticalScrollbar } from "timeline-chart/lib/layer/time-graph-vertical-scrollbar";
import { TimeGraphChartArrows } from "timeline-chart/lib/layer/time-graph-chart-arrows";
import { TimeGraphRangeEventsLayer } from "timeline-chart/lib/layer/time-graph-range-events-layer";

const styleConfig = {
mainWidth: 1000,
Expand Down Expand Up @@ -42,45 +43,7 @@ unitController.numberTranslator = (theNumber: number) => {
return milli + ':' + micro + ':' + nano;
};

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);

const axisCanvas = document.createElement('canvas');
const timeGraphAxisContainer = new TimeGraphContainer({
height: 30,
width: styleConfig.mainWidth,
id: timeGraph.id + '_axis',
backgroundColor: 0xffffff
}, unitController, axisCanvas);
axisHTMLContainer.appendChild(timeGraphAxisContainer.canvas);

const timeAxisLayer = new TimeGraphAxis('timeGraphAxis', { color: styleConfig.naviBackgroundColor });
timeGraphAxisContainer.addLayer(timeAxisLayer);

const chartHTMLContainer = document.createElement('div');
chartHTMLContainer.id = 'main_chart';
container.appendChild(chartHTMLContainer);

const chartCanvas = document.createElement('canvas');
chartCanvas.tabIndex = 1;

const timeGraphChartContainer = new TimeGraphContainer({
id: timeGraph.id + '_chart',
height: styleConfig.mainHeight,
width: styleConfig.mainWidth,
backgroundColor: styleConfig.chartBackgroundColor
}, unitController, chartCanvas);
chartHTMLContainer.appendChild(timeGraphChartContainer.canvas);

const timeGraphChartGridLayer = new TimeGraphChartGrid('timeGraphGrid', rowHeight);
timeGraphChartContainer.addLayer(timeGraphChartGridLayer);

const timeGraphChart = new TimeGraphChart('timeGraphChart', {
const providers = {
dataProvider: (range: TimelineChart.TimeGraphRange, resolution: number) => {
const length = range.end - range.start;
const overlap = ((length * 20) - length) / 2;
Expand Down Expand Up @@ -131,8 +94,53 @@ const timeGraphChart = new TimeGraphChart('timeGraphChart', {
lineColor: row.data && row.data.hasStates ? 0xdddddd : 0xaa4444,
lineThickness: row.data && row.data.hasStates ? 1 : 3
}
},
rowAnnotationStyleProvider: (annotation: TimelineChart.TimeGraphAnnotation) => {
return {
color: 0xFF0000, size: 7, symbol: 'none', verticalAlign: 'middle', opacity: 0.2
}
}
}, rowController);
}

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);

const axisCanvas = document.createElement('canvas');
const timeGraphAxisContainer = new TimeGraphContainer({
height: 30,
width: styleConfig.mainWidth,
id: timeGraph.id + '_axis',
backgroundColor: 0xffffff
}, unitController, axisCanvas);
axisHTMLContainer.appendChild(timeGraphAxisContainer.canvas);

const timeAxisLayer = new TimeGraphAxis('timeGraphAxis', { color: styleConfig.naviBackgroundColor });
timeGraphAxisContainer.addLayer(timeAxisLayer);

const chartHTMLContainer = document.createElement('div');
chartHTMLContainer.id = 'main_chart';
container.appendChild(chartHTMLContainer);

const chartCanvas = document.createElement('canvas');
chartCanvas.tabIndex = 1;

const timeGraphChartContainer = new TimeGraphContainer({
id: timeGraph.id + '_chart',
height: styleConfig.mainHeight,
width: styleConfig.mainWidth,
backgroundColor: styleConfig.chartBackgroundColor
}, unitController, chartCanvas);
chartHTMLContainer.appendChild(timeGraphChartContainer.canvas);

const timeGraphChartGridLayer = new TimeGraphChartGrid('timeGraphGrid', rowHeight);
timeGraphChartContainer.addLayer(timeGraphChartGridLayer);

const timeGraphChart = new TimeGraphChart('timeGraphChart', providers, rowController);
timeGraphChartContainer.addLayer(timeGraphChart);

timeGraphChart.registerStateMouseInteractions({
Expand All @@ -154,6 +162,9 @@ const timeGraphSelectionRange = new TimeGraphChartSelectionRange('chart-selectio
timeGraphChartContainer.addLayer(timeGraphSelectionRange);
const timeGraphChartCursors = new TimeGraphChartCursors('chart-cursors', timeGraphChart, rowController, { color: styleConfig.cursorColor });
timeGraphChartContainer.addLayer(timeGraphChartCursors);
const timeGraphChartRangeEvents = new TimeGraphRangeEventsLayer('timeGraphChartRangeEvents', providers);
timeGraphChartContainer.addLayer(timeGraphChartRangeEvents);
timeGraphChartRangeEvents.addRangeEvents(timeGraph.rangeEvents);

const cursorReset = document.getElementById('cursor-reset');
if (cursorReset) {
Expand Down
19 changes: 19 additions & 0 deletions example/src/test-data-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,24 @@ export class TestDataProvider {
const rows: TimelineChart.TimeGraphRowModel[] = [];
const range = opts.range || { start: 0, end: this.totalLength };
const resolution = opts.resolution || this.totalLength / this.canvasDisplayWidth;
const commonRow = timeGraphStates.model.rows.find(row => row.entryId === -1);
const _rangeEvents = commonRow?.annotations;
const rangeEvents: TimelineChart.TimeGraphAnnotation[] = [];
const startTime = 1332170682440133097;
_rangeEvents?.forEach((annotation: any, annotationIndex: number) => {
const start = annotation.range.start - startTime;
if (range.start < start && range.end > start) {
rangeEvents.push({
id: 'mark_' + -1 + '_' + annotationIndex,
range: {
start: annotation.range.start - this.absoluteStart,
end: annotation.range.end - this.absoluteStart
},
label: '',
});
}
});

timeGraphEntries.model.entries.forEach((entry: any, rowIndex: number): void => {
const states: TimelineChart.TimeGraphState[] = [];
const annotations: TimelineChart.TimeGraphAnnotation[] = [];
Expand Down Expand Up @@ -266,6 +284,7 @@ export class TestDataProvider {
id: "",
arrows,
rows,
rangeEvents,
totalLength: this.totalLength
};
}
Expand Down
12 changes: 12 additions & 0 deletions example/src/test-states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8868,6 +8868,18 @@ export const timeGraphStates = {
"value": -2147483648
}
]
},
{
"entryId": -1,
"annotations": [
{
"range": {
"start": 1332170682486039800,
"end": 1332170682488039800
},
}
],
"states": []
}
]
},
Expand Down
1 change: 1 addition & 0 deletions timeline-chart/src/components/time-graph-annotation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface TimeGraphAnnotationStyle extends TimeGraphComponentOptions {
size?: number
color?: number
verticalAlign?: string
opacity?:number
}

/*
Expand Down
16 changes: 12 additions & 4 deletions timeline-chart/src/components/time-graph-rectangle.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { TimeGraphComponent, TimeGraphStyledRect } from "./time-graph-component";

export class TimeGraphRectangle extends TimeGraphComponent {
constructor(protected opts: TimeGraphStyledRect){
protected _options: TimeGraphStyledRect;

constructor(protected opts: TimeGraphStyledRect) {
super('rect');
this._options = opts;
}

get rectOptions(): TimeGraphStyledRect {
return this._options as TimeGraphStyledRect;
update(opts?: TimeGraphStyledRect): void {

if (opts) {
this._options.width = opts.width;
this._options.height = opts.height;
this._options.position = opts.position;
}
super.update();
}

render(): void {
this.rect(this._options as TimeGraphStyledRect);
this.rect(this._options);
}
}
15 changes: 10 additions & 5 deletions timeline-chart/src/layer/time-graph-chart-selection-range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ export class TimeGraphChartSelectionRange extends TimeGraphLayer {

protected updateScaleAndPosition() {
if (this.unitController.selectionRange && this.selectionRange) {
this.selectionRange.rectOptions.position.x = this.getPixels(this.unitController.selectionRange.start - this.unitController.viewRange.start);
this.selectionRange.rectOptions.width = this.getPixels(this.unitController.selectionRange.end - this.unitController.selectionRange.start)
this.selectionRange.update();
const firstCursorPosition = this.getPixels(this.unitController.selectionRange.start - this.unitController.viewRange.start);
const width = this.getPixels(this.unitController.selectionRange.end - this.unitController.selectionRange.start)
this.selectionRange.update({
position: {
x: firstCursorPosition,
y: 0
},
height: this.stateController.canvasDisplayHeight,
width
});
}
}

Expand Down Expand Up @@ -58,8 +65,6 @@ export class TimeGraphChartSelectionRange extends TimeGraphLayer {
this.addChild(this.selectionRange);
} else {
this.selectionRange.update({
color: this.color,
opacity: 0.2,
position: {
x: firstCursorPosition,
y: 0
Expand Down
2 changes: 1 addition & 1 deletion timeline-chart/src/layer/time-graph-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export abstract class TimeGraphLayer {
if (!this.canvas) {
throw ("Layers must be added to a container before components can be added.");
}
child.render();
child.update();
if (parent) {
parent.addChild(child);
} else {
Expand Down
87 changes: 87 additions & 0 deletions timeline-chart/src/layer/time-graph-range-events-layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { TimeGraphRectangle } from "../components/time-graph-rectangle";
import { TimelineChart } from "../time-graph-model";
import { TimeGraphChartProviders } from "./time-graph-chart";
import { TimeGraphLayer } from "./time-graph-layer";

export class TimeGraphRangeEventsLayer extends TimeGraphLayer {
protected rangeEvents: Map<TimelineChart.TimeGraphAnnotation, TimeGraphRectangle>;
protected providers: TimeGraphChartProviders;

private _viewRangeUpdateHandler: { (): void; (viewRange: TimelineChart.TimeGraphRange): void; (viewRange: TimelineChart.TimeGraphRange): void; };
private _updateHandler: { (): void; (selectionRange: TimelineChart.TimeGraphRange): void; (selectionRange: TimelineChart.TimeGraphRange): void; };

constructor(id: string, providers: TimeGraphChartProviders) {
super(id);
this.providers = providers;
}

protected afterAddToContainer() {
this._updateHandler = (): void => this.update();
this.unitController.onViewRangeChanged(this._updateHandler);
}

protected addRangeEvent(rangeEvent: TimelineChart.TimeGraphAnnotation) {
const start = this.getPixels(rangeEvent.range.start - this.unitController.viewRange.start);
const end = this.getPixels(rangeEvent.range.end - this.unitController.viewRange.start);
const width = end - start;
const elementStyle = this.providers.rowAnnotationStyleProvider ? this.providers.rowAnnotationStyleProvider(rangeEvent) : undefined;
const rangeEventComponent = new TimeGraphRectangle({
color: (elementStyle && elementStyle.color) || 0xFF0000,
opacity: (elementStyle && elementStyle.opacity) || 0.2,
position: {
x: start,
y: 0
},
height: this.stateController.canvasDisplayHeight,
width
});
this.rangeEvents.set(rangeEvent, rangeEventComponent);
this.addChild(rangeEventComponent);
}

addRangeEvents(rangeEvents: TimelineChart.TimeGraphAnnotation[]): void {
if (!this.stateController) {
throw ('Add the TimeGraphRangeEventsLayer to a container before adding range events.');
}
if (this.rangeEvents) {
this.removeChildren();
}
this.rangeEvents = new Map();
rangeEvents.forEach(range => {
this.addRangeEvent(range);
})
}

update(): void {
if (this.rangeEvents) {
for (const range of this.rangeEvents.keys()) {
this.updateRangeEvent(range);
}
}
}

protected updateRangeEvent(rangeEvent: TimelineChart.TimeGraphAnnotation) {
const rangeEventComponent = this.rangeEvents.get(rangeEvent);
const start = this.getPixels(rangeEvent.range.start - this.unitController.viewRange.start);
const end = this.getPixels(rangeEvent.range.end - this.unitController.viewRange.start);
const width = end - start;
if (rangeEventComponent) {
rangeEventComponent.update({
position: {
x: start,
y: 0
},
height: this.stateController.canvasDisplayHeight,
width
});
}
}

destroy(): void {
if (this.unitController) {
this.unitController.removeViewRangeChangedHandler(this._viewRangeUpdateHandler);
this.unitController.removeSelectionRangeChangedHandler(this._updateHandler);
}
super.destroy();
}
}
10 changes: 7 additions & 3 deletions timeline-chart/src/time-graph-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,13 @@ export class TimeGraphContainer {
this.application.renderer.resize(newWidth, newHeight);
this.stateController.updateDisplayWidth();
this.stateController.updateDisplayHeight();
this.background.displayObject.width = newWidth;
this.background.displayObject.height = newHeight;
this.background.update();
this.background.update({
position: {
x: 0, y: 0
},
height: newHeight,
width: newWidth
});
this.layers.forEach(l => l.update());
}

Expand Down
1 change: 1 addition & 0 deletions timeline-chart/src/time-graph-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export namespace TimelineChart {
id: string
totalLength: number
rows: TimeGraphRowModel[]
rangeEvents: TimeGraphAnnotation[]
arrows: TimeGraphArrow[]
readonly data?: { [key: string]: any }
}
Expand Down

0 comments on commit bd7f984

Please sign in to comment.