TargetProcess/tauCharts

View on GitHub
src/elements/element.ts

Summary

Maintainability
A
1 hr
Test Coverage
import {Emitter} from '../event';
import * as utils from '../utils/utils';
import * as d3Selection from 'd3-selection';
const d3 = {...d3Selection};
import {
    global_Element,
    GrammarElement,
    GrammarModel,
    ScaleFunction,
    ScreenModel,
    Unit
} from '../definitions';

import {DataFrame} from '../data-frame';

export abstract class Element extends Emitter implements GrammarElement {

    abstract init(config: Unit);

    config: Unit;
    screenModel: GrammarModel;
    _elementNameSpace: string;
    _elementScalesHub: {[scale: string]: ScaleFunction};

    // add base behaviour here
    constructor(config: Unit) {
        super();
        this.screenModel = null;
        this._elementNameSpace = (config.namespace || 'default');
        this._elementScalesHub = {};
    }

    regScale(paramId: string, scaleObj: ScaleFunction) {
        this._elementScalesHub[paramId] = scaleObj;
        return this;
    }

    getScale(paramId: string) {
        return this._elementScalesHub[paramId] || null;
    }

    fireNameSpaceEvent(eventName: string, eventData: any) {
        var namespace = this._elementNameSpace;
        this.fire(`${eventName}.${namespace}`, eventData);
    }

    subscribe(sel: GrammarElement, dataInterceptor = ((x: any) => x), eventInterceptor = ((x: Event) => x)) {
        var self = this;
        var last = {};
        ([
            {
                event: 'mouseover',
                limit: 0
            },
            {
                event: 'mouseout',
                limit: 0
            },
            {
                event: 'click',
                limit: 0
            },
            {
                event: 'mousemove',
                limit: 'requestAnimationFrame'
            }
        ] as {event: string; limit: 'requestAnimationFrame' | number}[]).forEach((item) => {
            var eventName = item.event;
            var limit = item.limit;

            var callback = function (d) {
                var eventData = {
                    data: dataInterceptor.call(this, d),
                    event: eventInterceptor.call(this, d3Selection.event, d)
                };
                self.fire(eventName, eventData);
                self.fireNameSpaceEvent(eventName, eventData);
            };

            sel.on(eventName, utils.throttleLastEvent(last, eventName, callback, limit));
        });
    }

    allocateRect() {
        return {
            left: 0,
            top: 0,
            width: 0,
            height: 0
        };
    }

    /* eslint-disable */
    defineGrammarModel(fnCreateScale) {
        return {};
    }

    getGrammarRules() {
        return [];
    }

    getAdjustScalesRules() {
        return [];
    }

    createScreenModel(grammarModel) {
        return null;
    }

    getClosestElement(x, y) {
        return null;
    }
    /* eslint-enable */

    addInteraction() {
        // do nothing
    }

    abstract drawFrames(frames: DataFrame[]);

    draw() {
        // TODO: expose to explicit call everywhere
        this.config.options.container = this.config.options.slot(this.config.uid);
        this.drawFrames(this.config.frames);
    }

    data() {
        return this
            .config
            .frames
            .reduce(((data, frame) => data.concat(frame.part())), []);
    }

    node() {
        return this;
    }
}