UNPKG

@tabler/core

Version:

Premium and Open Source dashboard template with responsive and high quality UI.

344 lines (276 loc) 8.15 kB
import { merge, getLineUid, getElement, createElement, removeElement, } from './util' import core from './core' import Defaults from './defaults/options' import SVGCanvasElement from './svg/canvasElement' import Events from './defaults/events' import EventHandler from './eventHandler' import Tooltip from './components/tooltip' import DataVisualization from './dataVisualization' /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ class Map { static maps = {} static defaults = Defaults constructor(options = {}) { // Merge the given options with the default options this.params = merge(Map.defaults, options, true) // Throw an error if the given map name doesn't match // the map that was set in map file if (!Map.maps[this.params.map]) { throw new Error(`Attempt to use map which was not loaded: ${options.map}`) } this.regions = {} this.scale = 1 this.transX = 0 this.transY = 0 this._mapData = Map.maps[this.params.map] this._markers = {} this._lines = {} this._defaultWidth = this._mapData.width this._defaultHeight = this._mapData.height this._height = 0 this._width = 0 this._baseScale = 1 this._baseTransX = 0 this._baseTransY = 0 // `document` is already ready, just initialise now if (document.readyState !== 'loading') { this._init() } else { // Wait until `document` is ready window.addEventListener('DOMContentLoaded', () => this._init()) } } _init() { const options = this.params this.container = getElement(options.selector) this.container.classList.add('jvm-container') // The map canvas element this.canvas = new SVGCanvasElement(this.container) // Set the map's background color this.setBackgroundColor(options.backgroundColor) // Create regions this._createRegions() // Update size this.updateSize() // Create lines this._createLines(options.lines || {}, options.markers || {}) // Create markers this._createMarkers(options.markers) // Position labels this._repositionLabels() // Setup the container events this._setupContainerEvents() // Setup regions/markers events this._setupElementEvents() // Create zoom buttons if `zoomButtons` is presented if (options.zoomButtons) { this._setupZoomButtons() } // Create toolip if (options.showTooltip) { this._tooltip = new Tooltip(this) } // Set selected regions if any if (options.selectedRegions) { this._setSelected('regions', options.selectedRegions) } // Set selected regions if any if (options.selectedMarkers) { this._setSelected('_markers', options.selectedMarkers) } // Set focus on a spcific region if (options.focusOn) { this.setFocus(options.focusOn) } // Data visualization if (options.visualizeData) { this.dataVisualization = new DataVisualization(options.visualizeData, this) } // Bind touch events if true if (options.bindTouchEvents) { if ( ('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch) ) { this._setupContainerTouchEvents() } } // Create series if any if (options.series) { this.container.appendChild(this.legendHorizontal = createElement( 'div', 'jvm-series-container jvm-series-h' )) this.container.appendChild(this.legendVertical = createElement( 'div', 'jvm-series-container jvm-series-v' )) this._createSeries() } // Fire loaded event this._emit(Events.onLoaded, [this]) } // Public setBackgroundColor(color) { this.container.style.backgroundColor = color } // Region methods getSelectedRegions() { return this._getSelected('regions') } clearSelectedRegions(regions = undefined) { regions = this._normalizeRegions(regions) || this._getSelected('regions') regions.forEach((key) => { this.regions[key].element.select(false) }) } setSelectedRegions(regions) { this.clearSelectedRegions() this._setSelected('regions', this._normalizeRegions(regions)) } // Markers methods getSelectedMarkers() { return this._getSelected('_markers') } clearSelectedMarkers() { this._clearSelected('_markers') } addMarkers(config) { config = Array.isArray(config) ? config : [config] this._createMarkers(config, true) } removeMarkers(markers) { if (!markers) { markers = Object.keys(this._markers) } markers.forEach(index => { // Remove the element from the DOM this._markers[index].element.remove() // Remove the element from markers object delete this._markers[index] }) } addLine(from, to, style = {}) { console.warn('`addLine` method is deprecated, please use `addLines` instead.') this._createLines([{ from, to, style }], this._markers, true) } addLines(config) { const uids = this._getLinesAsUids() if (!Array.isArray(config)) { config = [config] } this._createLines(config.filter(line => { return !(uids.indexOf(getLineUid(line.from, line.to)) > -1) }), this._markers, true) } removeLines(lines) { if (Array.isArray(lines)) { lines = lines.map(line => getLineUid(line.from, line.to)) } else { lines = this._getLinesAsUids() } lines.forEach(uid => { this._lines[uid].dispose() delete this._lines[uid] }) } removeLine(from, to) { console.warn('`removeLine` method is deprecated, please use `removeLines` instead.') const uid = getLineUid(from, to) if (this._lines.hasOwnProperty(uid)) { this._lines[uid].element.remove() delete this._lines[uid] } } // Reset map reset() { for (let key in this.series) { for (let i = 0; i < this.series[key].length; i++) { this.series[key][i].clear() } } if (this.legendHorizontal) { removeElement(this.legendHorizontal) this.legendHorizontal = null } if (this.legendVertical) { removeElement(this.legendVertical) this.legendVertical = null } this.scale = this._baseScale this.transX = this._baseTransX this.transY = this._baseTransY this._applyTransform() this.clearSelectedMarkers() this.clearSelectedRegions() this.removeMarkers() } // Destroy the map destroy(destroyInstance = true) { // Remove event registry EventHandler.flush() // Remove tooltip from DOM and memory this._tooltip.dispose() // Fire destroyed event this._emit(Events.onDestroyed) // Remove references if (destroyInstance) { Object.keys(this).forEach(key => { try { delete this[key] } catch (e) {} }) } } extend(name, callback) { if (typeof this[name] === 'function') { throw new Error(`The method [${name}] does already exist, please use another name.`) } Map.prototype[name] = callback } // Private _emit(eventName, args) { for (const event in Events) { if (Events[event] === eventName && typeof this.params[event] === 'function') { this.params[event].apply(this, args) } } } // Get selected markers/regions _getSelected(type) { const selected = [] for (const key in this[type]) { if (this[type][key].element.isSelected) { selected.push(key) } } return selected } _setSelected(type, keys) { keys.forEach(key => { if (this[type][key]) { this[type][key].element.select(true) } }) } _clearSelected(type) { this._getSelected(type).forEach(key => { this[type][key].element.select(false) }) } _getLinesAsUids() { return Object.keys(this._lines) } _normalizeRegions(regions) { return typeof regions === 'string' ? [regions] : regions } } Object.assign(Map.prototype, core) export default Map