UNPKG

@progress/kendo-charts

Version:

Kendo UI platform-independent Charts library

420 lines (333 loc) 11.9 kB
import { geometry as g, drawing as d } from '@progress/kendo-drawing'; import { Class, defined, last, setDefaultOptions } from '../../common'; import { proxy } from '../utils'; import { Layer } from './layer'; import { Movable } from '../scroller/draggable'; import { Location } from '../location'; var Group = d.Group; export var ShapeLayer = (function (Layer) { function ShapeLayer(map, options) { Layer.call(this, map, options); this._pan = proxy(this._pan, this); this.surface = d.Surface.create(this.element, { width: map.scrollElement.clientWidth, height: map.scrollElement.clientHeight }); this._initRoot(); this.movable = new Movable(this.surface.element); this._markers = []; this._click = this._handler('shapeClick'); this.surface.bind('click', this._click); this._mouseleave = this._handler('shapeMouseLeave'); this.surface.bind('mouseleave', this._mouseleave); this.surface.bind('mouseenter', this._mouseenter.bind(this)); } if ( Layer ) ShapeLayer.__proto__ = Layer; ShapeLayer.prototype = Object.create( Layer && Layer.prototype ); ShapeLayer.prototype.constructor = ShapeLayer; ShapeLayer.prototype.destroy = function destroy () { Layer.prototype.destroy.call(this); this.surface.destroy(); }; ShapeLayer.prototype._reset = function _reset () { Layer.prototype._reset.call(this); this._translateSurface(); this._data = this._readData(); if (this._hasData()) { this._load(this._data); } }; ShapeLayer.prototype._initRoot = function _initRoot () { this._root = new Group(); this.surface.draw(this._root); }; ShapeLayer.prototype._beforeReset = function _beforeReset () { this.surface.clear(); this._initRoot(); }; ShapeLayer.prototype._resize = function _resize () { this.surface.size(this.map.size()); }; ShapeLayer.prototype._readData = function _readData () { var data = Layer.prototype._readData.call(this); if (data.type === "FeatureCollection") { return data.features; } if (data.type === "GeometryCollection") { return data.geometries; } return data; }; ShapeLayer.prototype._load = function _load (data) { var this$1 = this; this._data = data; this._clearMarkers(); if (!this._loader) { this._loader = new GeoJsonLoader(this.map, this.options.style, this); } var container = new Group(); for (var i = 0; i < data.length; i++) { var shape = this$1._loader.parse(data[i]); if (shape) { container.append(shape); } } this._root.clear(); this._root.append(container); }; ShapeLayer.prototype.shapeCreated = function shapeCreated (shape) { var cancelled = false; // the GeoJSON loader builds "Point" type as a circle // use the circle shape type as and indicator for rendering a marker // keep the behavior under a setting as this is supported by kendo jQuery Map // but we opted out of this in blazor if (shape instanceof d.Circle && this.map.options.renderPointsAsMarkers) { cancelled = defined(this._createMarker(shape)); } if (!cancelled) { var args = { layer: this, shape: shape }; cancelled = this.map.trigger('shapeCreated', args); } return cancelled; }; ShapeLayer.prototype.featureCreated = function featureCreated (e) { e.layer = this; this.map.trigger('shapeFeatureCreated', e); }; ShapeLayer.prototype._createMarker = function _createMarker (shape) { var marker = this.map.markers.bind({ location: shape.location }, shape.dataItem); if (marker) { this._markers.push(marker); } return marker; }; ShapeLayer.prototype._clearMarkers = function _clearMarkers () { var this$1 = this; for (var i = 0; i < this._markers.length; i++) { this$1.map.markers.remove(this$1._markers[i]); } this._markers = []; }; ShapeLayer.prototype._pan = function _pan () { if (!this._panning) { this._panning = true; this.surface.suspendTracking(); } }; ShapeLayer.prototype._panEnd = function _panEnd (e) { Layer.prototype._panEnd.call(this, e); this._translateSurface(); this.surface.resumeTracking(); this._panning = false; }; ShapeLayer.prototype._translateSurface = function _translateSurface () { var map = this.map; var nw = map.locationToView(map.extent().nw); if (this.surface.translate) { this.surface.translate(nw); this.movable.moveTo({ x: nw.x, y: nw.y }); } }; ShapeLayer.prototype._eventArgs = function _eventArgs (e) { return { layer: this, layerIndex: this._layerIndex(), shape: e.element, shapeIndex: (this._data || []).indexOf(e.element.dataItem), originalEvent: e.originalEvent }; }; ShapeLayer.prototype._handler = function _handler (eventName) { var this$1 = this; return function (e) { if (e.element) { this$1.map.trigger(eventName, this$1._eventArgs(e)); } }; }; ShapeLayer.prototype._mouseenter = function _mouseenter (e) { if (!e.element) { return; } this.map.trigger('shapeMouseEnter', this._eventArgs(e)); var shape = e.element; var anchor = this._tooltipAnchor(e); this.map._tooltip.show(anchor, this._tooltipContext(shape)); }; ShapeLayer.prototype._tooltipContext = function _tooltipContext (shape) { return { type: 'shape', layerIndex: this._layerIndex(), className: 'k-map-shape-tooltip', dataItem: shape.dataItem, location: shape.location }; }; ShapeLayer.prototype._tooltipAnchor = function _tooltipAnchor (e) { var cursor = this.map.eventOffset(e.originalEvent); return { top: cursor.y, left: cursor.x }; }; ShapeLayer.prototype._activate = function _activate () { Layer.prototype._activate.call(this); this._panHandler = proxy(this._pan, this); this.map.bind('pan', this.panHandler); }; ShapeLayer.prototype._deactivate = function _deactivate () { Layer.prototype._deactivate.call(this); this.map.unbind('pan', this._panHandler); }; return ShapeLayer; }(Layer)); setDefaultOptions(ShapeLayer, { autoBind: true, zIndex: 100 }); var GeoJsonLoader = (function (Class) { function GeoJsonLoader(locator, defaultStyle, observer) { Class.call(this); this.observer = observer; this.locator = locator; this.style = defaultStyle; } if ( Class ) GeoJsonLoader.__proto__ = Class; GeoJsonLoader.prototype = Object.create( Class && Class.prototype ); GeoJsonLoader.prototype.constructor = GeoJsonLoader; GeoJsonLoader.prototype.parse = function parse (item) { var root = new Group(); var unwrap = true; if (item.type === 'Feature') { unwrap = false; this._loadGeometryTo(root, item.geometry, item); this._featureCreated(root, item); } else { this._loadGeometryTo(root, item, item); } if (unwrap && root.children.length < 2) { root = root.children[0]; } return root; }; GeoJsonLoader.prototype._shapeCreated = function _shapeCreated (shape) { var cancelled = false; if (this.observer && this.observer.shapeCreated) { cancelled = this.observer.shapeCreated(shape); } return cancelled; }; GeoJsonLoader.prototype._featureCreated = function _featureCreated (group, dataItem) { if (this.observer && this.observer.featureCreated) { this.observer.featureCreated({ group: group, dataItem: dataItem, properties: dataItem.properties }); } }; GeoJsonLoader.prototype._loadGeometryTo = function _loadGeometryTo (container, geometry, dataItem) { var this$1 = this; var coords = geometry.coordinates; var i; var path; switch (geometry.type) { case 'LineString': path = this._loadPolygon(container, [coords], dataItem); this._setLineFill(path); break; case 'MultiLineString': for (i = 0; i < coords.length; i++) { path = this$1._loadPolygon(container, [coords[i]], dataItem); this$1._setLineFill(path); } break; case 'Polygon': this._loadPolygon(container, coords, dataItem); break; case 'MultiPolygon': for (i = 0; i < coords.length; i++) { this$1._loadPolygon(container, coords[i], dataItem); } break; case 'Point': this._loadPoint(container, coords, dataItem); break; case 'MultiPoint': for (i = 0; i < coords.length; i++) { this$1._loadPoint(container, coords[i], dataItem); } break; default: break; } }; GeoJsonLoader.prototype._setLineFill = function _setLineFill (path) { var segments = path.segments; if (segments.length < 4 || !segments[0].anchor().equals(last(segments).anchor())) { path.options.fill = null; } }; GeoJsonLoader.prototype._loadShape = function _loadShape (container, shape) { if (!this._shapeCreated(shape)) { container.append(shape); } return shape; }; GeoJsonLoader.prototype._loadPolygon = function _loadPolygon (container, rings, dataItem) { var shape = this._buildPolygon(rings); shape.dataItem = dataItem; shape.location = this.locator.viewToLocation(shape.bbox().center()); return this._loadShape(container, shape); }; GeoJsonLoader.prototype._buildPolygon = function _buildPolygon (rings) { var this$1 = this; var type = rings.length > 1 ? d.MultiPath : d.Path; var path = new type(this.style); for (var i = 0; i < rings.length; i++) { for (var j = 0; j < rings[i].length; j++) { var point = this$1.locator.locationToView(Location.fromLngLat(rings[i][j])); if (j === 0) { path.moveTo(point.x, point.y); } else { path.lineTo(point.x, point.y); } } } return path; }; GeoJsonLoader.prototype._loadPoint = function _loadPoint (container, coords, dataItem) { var location = Location.fromLngLat(coords); var point = this.locator.locationToView(location); var circle = new g.Circle(point, 10); var shape = new d.Circle(circle, this.style); shape.dataItem = dataItem; shape.location = location; return this._loadShape(container, shape); }; return GeoJsonLoader; }(Class));