Commit a87f7244 authored by Chris Tester's avatar Chris Tester
Browse files

Merge branch 'develop' of code.ornl.gov:idt/gist-charts into develop

parents 0ed2eb33 0ea41203
......@@ -6,6 +6,7 @@ import { LimiterType } from "../types/limiterType.type";
import { IMap } from '../types/iMap.interface';
/* cSpell: words TBLR debounced */
/**
* Base class for behaviors. This defines how they will manage being throttled or debounced;
*
......@@ -13,12 +14,15 @@ import { IMap } from '../types/iMap.interface';
* @class GetDataAtMouseEvent
*/
export abstract class GistBehavior {
/**
* The id of this behavior
*
* @memberof GistBehavior
*/
public readonly id = uID();
/**
* This will be set by the gistchart that this behavior is added to.
*
......@@ -26,6 +30,8 @@ export abstract class GistBehavior {
* @memberof GistBehavior
*/
public gistChart!: GistChart;
/**
* Whether or not the behavior should prevent the default handler for the event(s)
*
......@@ -33,6 +39,8 @@ export abstract class GistBehavior {
* @memberof GistBehavior
*/
public preventDefault: boolean = false;
/**
* The list of event names that this behavior will fire on. While we accept any string, behavior implementations will specify what strings are actually valid.
*
......@@ -40,6 +48,7 @@ export abstract class GistBehavior {
* @memberof GistBehavior
*/
public readonly eventNames: string[];
/**
* If and how this behavior fire rate should be limitted. If undefined, will be fired on every call.
*
......@@ -47,6 +56,7 @@ export abstract class GistBehavior {
* @memberof GistBehavior
*/
public readonly limiter: LimiterType;
/**
* how many milliseconds to for the limiter to wait
*
......@@ -55,6 +65,7 @@ export abstract class GistBehavior {
*/
public readonly waitTime: number;
/**
* List of what configs, and how they should handle the behavior when it activates
*
......@@ -63,6 +74,21 @@ export abstract class GistBehavior {
*/
public readonly eventHandlers: EventHandler[];
/**
* GistCharts Only. We store all callbacks for each event that we need to call. We do not manage it ourselves, but its up to the gistchart to call, add or remove events as other it may have other behaviors.
*/
public listenerCallbacks: IMap<Array<EventListenerOrEventListenerObject>> = {};
public cancelWaitForFire( shouldFireImmediate: boolean = false ): void {
const me = this;
console.log( 'cancelWaitForFire' );
me.reset();
if ( shouldFireImmediate ) {
me.callActivate();
}
}
/**
* setTimeout promise
*
......@@ -71,6 +97,7 @@ export abstract class GistBehavior {
* @memberof GistBehavior
*/
protected timer: number | undefined;
/**
* extra flag used in throttling
*
......@@ -80,6 +107,7 @@ export abstract class GistBehavior {
*/
protected isBusy: boolean = false;
/**
* the current X position of the mouse. updates on every event, even between limitted calls.
*
......@@ -88,6 +116,7 @@ export abstract class GistBehavior {
* @memberof GistBehavior
*/
protected currentX!: number;
/**
* the current Y position of the mouse. updates on every event, even between limitted calls.
*
......@@ -96,6 +125,7 @@ export abstract class GistBehavior {
* @memberof GistBehavior
*/
protected currentY!: number;
/**
* the current mouse event. updates on every event, even between limitted calls.
*
......@@ -116,6 +146,7 @@ export abstract class GistBehavior {
this.limiter = limiter;
}
/**
* Defines how what this behavior does on the limited calls.
*
......@@ -124,6 +155,7 @@ export abstract class GistBehavior {
*/
protected abstract _activate(): void;
/**
* Allows the implemented behaviors to do any clean up that they need
*
......@@ -132,9 +164,8 @@ export abstract class GistBehavior {
*/
protected onDestroy: () => void = () => {};
/**
* What actually gets called when the handled events happen. This should only be called by GistCharts.
* GistCharts Only! What actually gets called when the handled events happen.
*
* @param {number} x
* @param {number} y
......@@ -152,14 +183,12 @@ export abstract class GistBehavior {
}
/**
* This will be called when the behavior is removed. This should only be called by GistCharts.
* GistCharts Only! This will be called when the behavior is removed.
*
* @memberof GistBehavior
*/
public _destroy() {
if ( this.timer ) {
window.clearTimeout( this.timer );
}
this.cancelWaitForFire(false);
if ( this.onDestroy ) {
this.onDestroy();
}
......@@ -172,8 +201,7 @@ export abstract class GistBehavior {
me.currentX = x;
me.currentY = y;
me.currentEvent = event;
me.preventDefault = false;
me._activate();
me.callActivate();
}
if ( !me.isBusy ) {
me.isBusy = true;
......@@ -184,27 +212,40 @@ export abstract class GistBehavior {
me.timer = window.setTimeout(() => {
if ( me.isBusy ) {
callIt();
} else {
me.reset();
}
me.isBusy = false;
me.timer = undefined;
}, me.waitTime );
}
}
private debounce( x: number, y: number, event: MouseEvent ) {
const me = this;
if ( me.timer ) {
window.clearTimeout( me.timer );
}
this.cancelWaitForFire(false);
me.currentX = x;
me.currentY = y;
me.currentEvent = event;
me.timer = window.setTimeout(() => {
me.preventDefault = false;
me._activate();
me.timer = undefined;
me.callActivate();
}, me.waitTime );
}
public listernerCallbacks: IMap<Array<EventListenerOrEventListenerObject>> = {};
private callActivate(): void {
this._activate();
this.reset();
}
private reset(): void {
console.log( this.timer );
if ( this.timer ) {
console.log( 'clear the timeout' );
window.clearTimeout( this.timer );
}
this.timer = undefined;
this.isBusy = false;
}
}
......@@ -26,6 +26,13 @@ export class DataPoint<T = any> {
return this.chartConfigIdToExtentMap[ config.id ];
}
/**
* Returns a MinMax for the x, y that are the pixels realtive to the top left corner of the canvas element
*
* @param {BaseChartConfig} config
* @returns {Extent}
* @memberof DataPoint
*/
public getExtent( config: BaseChartConfig ): Extent {
let localExtent = this.chartConfigToLocalExtent( config );
let ret = new Extent();
......
......@@ -34,7 +34,7 @@ export class GistChart {
*
* @memberof GistChart
*/
public readonly debugLoger = new DebugLogger();
public readonly debugLogger = new DebugLogger();
/**
* This is the element that the chart will display in. When this is told to render, it will draw to size of this element.
......@@ -88,6 +88,7 @@ export class GistChart {
this.id = uID();
me.contextEle = container;
me.contextEle.appendChild( me.canvas.canvasEle );
me.contextEle.addEventListener( 'mouseleave', me.cancelBehaviorActivation.bind(me), { passive: true } );
}
public zoom( zoomLevel: number ) {
......@@ -112,6 +113,12 @@ export class GistChart {
}
}
/**
* Add behaviors to this chart.
*
* @param {(GistBehavior | GistBehavior[])} newb
* @memberof GistChart
*/
public addBehavior( newb: GistBehavior | GistBehavior[] ): void {
const me = this;
let list = makeList( newb ) as GistBehavior[];
......@@ -152,8 +159,8 @@ export class GistChart {
if ( !me.capturedEvents[ eName ] ) {
me.capturedEvents[ eName ] = {};
gb.listernerCallbacks[ eName ] = gb.listernerCallbacks[ eName ] || [];
gb.listernerCallbacks[ eName ].push( callback );
gb.listenerCallbacks[ eName ] = gb.listenerCallbacks[ eName ] || [];
gb.listenerCallbacks[ eName ].push( callback );
me.contextEle.addEventListener( eName, callback, { passive: false } as any );
}
me.capturedEvents[ eName ][ gb.id ] = gb;
......@@ -161,13 +168,20 @@ export class GistChart {
} );
}
public removeBehavior( newb: GistBehavior | GistBehavior[] ): void {
/**
* Remove the given behaviors from this chart, this will cancel any throttled events
*
* @param {(GistBehavior | GistBehavior[])} behaviors
* @memberof GistChart
*/
public removeBehavior( behaviors: GistBehavior | GistBehavior[] ): void {
const me = this;
let list = makeList( newb ) as GistBehavior[];
let list = makeList( behaviors ) as GistBehavior[];
list.forEach( gb => {
gb.cancelWaitForFire();
gb.eventNames.forEach( eName => {
while ( gb.listernerCallbacks[ eName ] && gb.listernerCallbacks[ eName ].length ) {
me.contextEle.removeEventListener( eName, gb.listernerCallbacks[ eName ].pop() as any );
while ( gb.listenerCallbacks[ eName ] && gb.listenerCallbacks[ eName ].length ) {
me.contextEle.removeEventListener( eName, gb.listenerCallbacks[ eName ].pop() as any );
}
delete me.capturedEvents[ eName ][ gb.id ];
......@@ -178,6 +192,20 @@ export class GistChart {
} );
}
/**
* Call this method to cancel all behaviors that are waiting to fire. This will be called automatically on mouse leave.
*
* @memberof GistChart
*/
public cancelBehaviorActivation(): void {
this.debugLogger.log( 'cancelBehaviorActivation' );
for ( let key in this.currentBehaviors ) {
if ( this.currentBehaviors[ key ] ) {
this.currentBehaviors[ key ].cancelWaitForFire();
}
}
}
/**
* Add one or many charts to be rendered
*
......@@ -279,7 +307,7 @@ export class GistChart {
let rs = me.renderedSizes;
me.canvas.setSize( rs.totalWidth, rs.totalHeight );
me.canvas.clearCanvas( me.background );
this.debugLoger.log( 'Master canvas has been cleared' );
this.debugLogger.log( 'Master canvas has been cleared' );
me.renderAxis();
me.renderCharts();
}
......@@ -323,7 +351,7 @@ export class GistChart {
axisConfig.implementation.gridLineCanvas.renderTo( me.canvas.canvasEle, rs.chartBounds.left, rs.chartBounds.top );
}
} );
this.debugLoger.log( 'axis line been rendered' );
this.debugLogger.log( 'axis line been rendered' );
}
/**
......@@ -358,7 +386,7 @@ export class GistChart {
ele.style.display = 'block';
chart.startDrawing();
} );
this.debugLoger.log( 'starting chartconfig polling' );
this.debugLogger.log( 'starting chartconfig polling' );
me.pollCharts();
}
......@@ -402,7 +430,7 @@ export class GistChart {
private showCharts() {
const me = this;
this.debugLoger.log( 'making config charts visible' );
this.debugLogger.log( 'making config charts visible' );
me.chartList.forEach( config => {
// me.canvas.context.globalAlpha = config.alpha;
let imp = config.implementation;
......@@ -423,7 +451,7 @@ export class GistChart {
}
private copyCharts() {
this.debugLoger.log( 'copying charts over' );
this.debugLogger.log( 'copying charts over' );
const me = this;
const rs = me.renderedSizes;
let cb = rs.chartBounds;
......@@ -449,7 +477,7 @@ export class GistChart {
private stopRender() {
const me = this;
this.debugLoger.log( 'stopping charts from rendering' );
this.debugLogger.log( 'stopping charts from rendering' );
if ( me.animationFrame ) {
window.cancelAnimationFrame( me.animationFrame );
}
......@@ -525,7 +553,7 @@ export class GistChart {
rs.totalHeight = vertical + rs.chartBounds.top + rs.chartBounds.bottom;
rs.totalWidth = horizontal + rs.chartBounds.left + rs.chartBounds.right;
this.debugLoger.log( 'chart layout set', rs );
this.debugLogger.log( 'chart layout set', rs );
return axisSizes;
}
......@@ -559,7 +587,7 @@ export class GistChart {
chartConfigs.forEach( ( chart, i ) => {
chart.zIndex = i;
} );
this.debugLoger.log( 'charts have been reordered', chartConfigs );
this.debugLogger.log( 'charts have been reordered', chartConfigs );
}
public getDataUrl( type?: string ): string {
......
......@@ -34,7 +34,7 @@ export abstract class BaseAxisConfig {
*
* @memberof BaseChartConfig
*/
public readonly debugLoger = new DebugLogger();
public readonly debugLogger = new DebugLogger();
/**
* How this axis is oriented in respect to the drawn charts
......
{
"name": "gist-charts",
"version": "0.0.76",
"version": "0.0.77",
"description": "6harts written in canvas ",
"main": "./package/index.js",
"types": "./package/index.d.ts",
......
......@@ -57,6 +57,11 @@ export declare abstract class GistBehavior {
* @memberof GistBehavior
*/
readonly eventHandlers: EventHandler[];
/**
* GistCharts Only. We store all callbacks for each event that we need to call. We do not manage it ourselves, but its up to the gistchart to call, add or remove events as other it may have other behaviors.
*/
listenerCallbacks: IMap<Array<EventListenerOrEventListenerObject>>;
cancelWaitForFire(shouldFireImmediate?: boolean): void;
/**
* setTimeout promise
*
......@@ -113,7 +118,7 @@ export declare abstract class GistBehavior {
*/
protected onDestroy: () => void;
/**
* What actually gets called when the handled events happen. This should only be called by GistCharts.
* GistCharts Only! What actually gets called when the handled events happen.
*
* @param {number} x
* @param {number} y
......@@ -122,12 +127,13 @@ export declare abstract class GistBehavior {
*/
_fire(x: number, y: number, event: MouseEvent): boolean;
/**
* This will be called when the behavior is removed. This should only be called by GistCharts.
* GistCharts Only! This will be called when the behavior is removed.
*
* @memberof GistBehavior
*/
_destroy(): void;
private throttle(x, y, event);
private debounce(x, y, event);
listernerCallbacks: IMap<Array<EventListenerOrEventListenerObject>>;
private callActivate();
private reset();
}
......@@ -18,6 +18,13 @@ export declare class DataPoint<T = any> {
* @memberof DataPoint
*/
chartConfigToLocalExtent(config: BaseChartConfig): Extent;
/**
* Returns a MinMax for the x, y that are the pixels realtive to the top left corner of the canvas element
*
* @param {BaseChartConfig} config
* @returns {Extent}
* @memberof DataPoint
*/
getExtent(config: BaseChartConfig): Extent;
constructor(d?: T);
}
......@@ -23,7 +23,7 @@ export declare class GistChart {
*
* @memberof GistChart
*/
readonly debugLoger: DebugLogger;
readonly debugLogger: DebugLogger;
/**
* This is the element that the chart will display in. When this is told to render, it will draw to size of this element.
*
......@@ -61,8 +61,26 @@ export declare class GistChart {
x: number;
y: number;
}): void;
/**
* Add behaviors to this chart.
*
* @param {(GistBehavior | GistBehavior[])} newb
* @memberof GistChart
*/
addBehavior(newb: GistBehavior | GistBehavior[]): void;
removeBehavior(newb: GistBehavior | GistBehavior[]): void;
/**
* Remove the given behaviors from this chart, this will cancel any throttled events
*
* @param {(GistBehavior | GistBehavior[])} behaviors
* @memberof GistChart
*/
removeBehavior(behaviors: GistBehavior | GistBehavior[]): void;
/**
* Call this method to cancel all behaviors that are waiting to fire. This will be called automatically on mouse leave.
*
* @memberof GistChart
*/
cancelBehaviorActivation(): void;
/**
* Add one or many charts to be rendered
*
......
......@@ -30,7 +30,7 @@ export declare abstract class BaseAxisConfig {
*
* @memberof BaseChartConfig
*/
readonly debugLoger: DebugLogger;
readonly debugLogger: DebugLogger;
/**
* How this axis is oriented in respect to the drawn charts
*
......
......@@ -89,6 +89,6 @@ export declare class CategoricalAxisConfig<T extends string | number = string> e
* @param a
* @param b
*/
sortValues(a: T, b: T): 1 | 0 | -1;
sortValues(a: T, b: T): 0 | 1 | -1;
constructor(orientation: Orientation);
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment