UNPKG

@carto/airship-bridge

Version:

Airship bridge to other libs (CARTO VL, CARTO.js)

242 lines (213 loc) 5.61 kB
import mitt from 'mitt'; import { LegendData, LegendEntry } from '../../types'; /** * Base class for all possible CARTO VL Filters to be combined with Airship * * @export * @abstract * @class BaseFilter */ export abstract class BaseFilter { // Internal counter to prevent colission between filters for the same // column and the same type private static _counter: number = 0; protected _emitter: mitt.Emitter; protected _column: string; protected _layer: any; protected _source: any; protected _legendData: LegendEntry[]; protected _mapColors: boolean; protected _widget: any; protected _weight: number | string; private _readOnly: boolean; private _name: string; /** * Creates an instance of BaseFilter. * @param {string} type A type describing what widget this filter represents * @param {string} column The column this filter is related to * @param {*} layer A CARTO VL layer * @param {*} source A CARTO VL source * @param {boolean} [readOnly=true] Whether this filter should be read only or not * @memberof BaseFilter */ constructor( type: string, carto: any, column: string, layer: any, source: any, readOnly: boolean = true, weight: number | string = 1 ) { const s = carto.expressions; this._emitter = mitt(); this._name = `asbind_${type}_${column}_${BaseFilter._counter}`; this._column = column; this._layer = layer; this._source = source; this._readOnly = readOnly; BaseFilter._counter++; this._weight = typeof weight === 'number' ? weight : s.prop(weight); // TODO: loadLegendData from used variable here instead this._loadLegendData = this._loadLegendData.bind(this, this._name); } /** * Provide a CARTO VL layer to be used as the source of data for the filter. * * @abstract * @param {*} layer a CARTO VL layer * @memberof BaseFilter */ public abstract setDataLayer(layer: any); /** * This function should be implemented by each filter to provide a valid filter for CARTO VL Viz objects. * * @readonly * @abstract * @type {string} * @memberof BaseFilter */ public abstract get filter(): string; /** * This function should be implemented by each filter to create the appropriate data source expression. For instance * a histogram. * * @readonly * @abstract * @type {*} * @memberof BaseFilter */ public abstract get expression(): any; /** * If the filter returns this, this expression will be assigned to a variable called this.name_global * * @readonly * @abstract * @type {*} * @memberof BaseFilter */ public get globalExpression() { return null; } /** * Returns the name of the filter. The name is a compound of the type, the column and an internal counter to prevent * collisions. It will be used as the name for the VL variable containing BaseFilter.expression. * * @readonly * @type {string} * @memberof BaseFilter */ public get name(): string { return this._name; } /** * Get the column of the filter. * * @readonly * @type {string} * @memberof BaseFilter */ public get column(): string { return this._column; } public get columnPropName(): string { return `${this._name}_col`; } /** * Get whether the filter is read only or not. * * @readonly * @type {boolean} * @memberof BaseFilter */ public get readOnly(): boolean { return this._readOnly; } /** * Get the currently set CARTO VL Visualization layer. * * @readonly * @type {*} * @memberof BaseFilter */ public get layer(): any { return this._layer; } /** * Get the current CARTO VL source. * * @readonly * @type {*} * @memberof BaseFilter */ public get source(): any { return this._source; } /** * Bind to an event of the filter. Currently only `filterChanged` is supported. * * @param {string} type * @param {mitt.Handler} handler * @memberof BaseFilter */ public on(type: string, handler: mitt.Handler) { this._emitter.on(type, handler); } /** * Set LegendData, which can be used by certain filter implementations to display colors * for certain values. * * @param {LegendData} legendData * @memberof BaseFilter */ public setLegendData(legendData: LegendData) { this._legendData = legendData.data; } /** * Automatically extract LegendData from the CARTO VL Viz object. This requires the `color` property * in the Viz object to be a ramp. * * @memberof BaseFilter */ public enableColorMapping() { this._mapColors = true; if (this._layer.viz) { this._loadLegendData(); } else { this._layer.on('loaded', this._loadLegendData); } } /** * Trigger a filterChanged event * * @protected * @memberof BaseFilter */ protected _filterChanged() { this._emitter.emit('filterChanged', this._name); } /** * Load the legend data from the Viz object. Used from `enableColorMapping` * * @protected * @returns * @memberof BaseFilter */ protected _loadLegendData(property= 'color') { const prop = this._layer.viz[property]; if (!prop.getLegendData) { return; } this.setLegendData(prop.getLegendData(this._getLegendConfig())); } /** * Override this method on a specific filter to configure CARTO VL ramps getLegendData arguments * * @protected * @returns * @memberof BaseFilter */ protected _getLegendConfig() { return undefined; } }