UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

1,641 lines (1,630 loc) 74.6 kB
//#region ../src/util/main.js (function() { var kendo = window.kendo, deepExtend = kendo.deepExtend; function sqr(value) { return value * value; } var now = Date.now; if (!now) { now = function() { return new Date().getTime(); }; } function renderSize(size) { if (typeof size !== "string") { size += "px"; } return size; } function renderPosNew(pos) { if (pos) { const map = { "topLeft": "k-top-start", "topRight": "k-top-end", "bottomLeft": "k-bottom-start", "bottomRight": "k-bottom-end" }; return map[pos]; } } function renderPos(pos) { var result = []; if (pos) { var parts = kendo.toHyphens(pos).split("-"); for (var i = 0; i < parts.length; i++) { result.push("k-pos-" + parts[i]); } } return result.join(" "); } function arabicToRoman(n) { var literals = { 1: "i", 10: "x", 100: "c", 2: "ii", 20: "xx", 200: "cc", 3: "iii", 30: "xxx", 300: "ccc", 4: "iv", 40: "xl", 400: "cd", 5: "v", 50: "l", 500: "d", 6: "vi", 60: "lx", 600: "dc", 7: "vii", 70: "lxx", 700: "dcc", 8: "viii", 80: "lxxx", 800: "dccc", 9: "ix", 90: "xc", 900: "cm", 1e3: "m" }; var values = [ 1e3, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; var roman = ""; while (n > 0) { if (n < values[0]) { values.shift(); } else { roman += literals[values[0]]; n -= values[0]; } } return roman; } function romanToArabic(r) { r = r.toLowerCase(); var digits = { i: 1, v: 5, x: 10, l: 50, c: 100, d: 500, m: 1e3 }; var value = 0, prev = 0; for (var i = 0; i < r.length; ++i) { var v = digits[r.charAt(i)]; if (!v) { return null; } value += v; if (v > prev) { value -= 2 * prev; } prev = v; } return value; } function memoize(f) { var cache = Object.create(null); return function() { var id = ""; for (var i = arguments.length; --i >= 0;) { id += ":" + arguments[i]; } return id in cache ? cache[id] : cache[id] = f.apply(this, arguments); }; } function isUnicodeLetter(ch) { return RX_UNICODE_LETTER.test(ch); } function withExit(f, obj) { try { return f.call(obj, function(value) { throw new Return(value); }); } catch (ex) { if (ex instanceof Return) { return ex.value; } throw ex; } function Return(value) { this.value = value; } } deepExtend(kendo, { util: { now, renderPos, renderPosNew, renderSize, sqr, romanToArabic, arabicToRoman, memoize, isUnicodeLetter, withExit } }); var RX_UNICODE_LETTER = new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"); })(); //#endregion //#region ../src/dataviz/map/location.js (function($, undefined) { var math = Math, abs = math.abs, atan = math.atan, atan2 = math.atan2, cos = math.cos, max = math.max, min = math.min, sin = math.sin, tan = math.tan, kendo = window.kendo, Class = kendo.Class, dataviz = kendo.dataviz, deepExtend = kendo.deepExtend, util = kendo.drawing.util, defined = util.defined, deg = util.deg, rad = util.rad, round = util.round, valueOrDefault = util.valueOrDefault, sqr = kendo.util.sqr; var Location = Class.extend({ init: function(lat, lng) { if (arguments.length === 1) { this.lat = lat[0]; this.lng = lat[1]; } else { this.lat = lat; this.lng = lng; } }, DISTANCE_ITERATIONS: 100, DISTANCE_CONVERGENCE: 1e-12, DISTANCE_PRECISION: 2, FORMAT: "{0:N6},{1:N6}", toArray: function() { return [this.lat, this.lng]; }, equals: function(loc) { return loc && loc.lat === this.lat && loc.lng === this.lng; }, clone: function() { return new Location(this.lat, this.lng); }, round: function(precision) { this.lng = round(this.lng, precision); this.lat = round(this.lat, precision); return this; }, wrap: function() { this.lng = this.lng % 180; this.lat = this.lat % 90; return this; }, distanceTo: function(dest, datum) { return this.greatCircleTo(dest, datum).distance; }, destination: function(distance, bearing, datum) { bearing = rad(bearing); datum = datum || dataviz.map.datums.WGS84; var fromLat = rad(this.lat); var fromLng = rad(this.lng); var dToR = distance / kendo.dataviz.map.datums.WGS84.a; var lat = math.asin(sin(fromLat) * cos(dToR) + cos(fromLat) * sin(dToR) * cos(bearing)); var lng = fromLng + atan2(sin(bearing) * sin(dToR) * cos(fromLat), cos(dToR) - sin(fromLat) * sin(lat)); return new Location(deg(lat), deg(lng)); }, greatCircleTo: function(dest, datum) { dest = Location.create(dest); datum = datum || dataviz.map.datums.WGS84; if (!dest || this.clone().round(8).equals(dest.clone().round(8))) { return { distance: 0, azimuthFrom: 0, azimuthTo: 0 }; } var a = datum.a; var b = datum.b; var f = datum.f; var L = rad(dest.lng - this.lng); var U1 = atan((1 - f) * tan(rad(this.lat))); var sinU1 = sin(U1); var cosU1 = cos(U1); var U2 = atan((1 - f) * tan(rad(dest.lat))); var sinU2 = sin(U2); var cosU2 = cos(U2); var lambda = L; var prevLambda; var i = this.DISTANCE_ITERATIONS; var converged = false; var sinLambda; var cosLambda; var sino; var cosA2; var coso; var cos2om; var sigma; while (!converged && i-- > 0) { sinLambda = sin(lambda); cosLambda = cos(lambda); sino = math.sqrt(sqr(cosU2 * sinLambda) + sqr(cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); coso = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; sigma = atan2(sino, coso); var sinA = cosU1 * cosU2 * sinLambda / sino; cosA2 = 1 - sqr(sinA); cos2om = 0; if (cosA2 !== 0) { cos2om = coso - 2 * sinU1 * sinU2 / cosA2; } prevLambda = lambda; var C = f / 16 * cosA2 * (4 + f * (4 - 3 * cosA2)); lambda = L + (1 - C) * f * sinA * (sigma + C * sino * (cos2om + C * coso * (-1 + 2 * sqr(cos2om)))); converged = abs(lambda - prevLambda) <= this.DISTANCE_CONVERGENCE; } var u2 = cosA2 * (sqr(a) - sqr(b)) / sqr(b); var A = 1 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2))); var B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 47 * u2))); var deltao = B * sino * (cos2om + B / 4 * (coso * (-1 + 2 * sqr(cos2om)) - B / 6 * cos2om * (-3 + 4 * sqr(sino)) * (-3 + 4 * sqr(cos2om)))); var azimuthFrom = atan2(cosU2 * sinLambda, cosU1 * sinU2 - sinU1 * cosU2 * cosLambda); var azimuthTo = atan2(cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda); return { distance: round(b * A * (sigma - deltao), this.DISTANCE_PRECISION), azimuthFrom: deg(azimuthFrom), azimuthTo: deg(azimuthTo) }; } }); Location.fn.toString = function() { return kendo.format(this.FORMAT, this.lat, this.lng); }; Location.fromLngLat = function(ll) { return new Location(ll[1], ll[0]); }; Location.fromLatLng = function(ll) { return new Location(ll[0], ll[1]); }; Location.create = function(a, b) { if (defined(a)) { if (a instanceof Location) { return a.clone(); } else if (arguments.length === 1 && a.length === 2) { return Location.fromLatLng(a); } else { return new Location(a, b); } } }; var Extent = Class.extend({ init: function(nw, se) { nw = Location.create(nw); se = Location.create(se); if (nw.lng + 180 > se.lng + 180 && nw.lat + 90 < se.lat + 90) { this.se = nw; this.nw = se; } else { this.se = se; this.nw = nw; } }, contains: function(loc) { var nw = this.nw, se = this.se, lng = valueOrDefault(loc.lng, loc[1]), lat = valueOrDefault(loc.lat, loc[0]); return loc && lng + 180 >= nw.lng + 180 && lng + 180 <= se.lng + 180 && lat + 90 >= se.lat + 90 && lat + 90 <= nw.lat + 90; }, center: function() { var nw = this.nw; var se = this.se; var lng = nw.lng + (se.lng - nw.lng) / 2; var lat = nw.lat + (se.lat - nw.lat) / 2; return new Location(lat, lng); }, containsAny: function(locs) { var result = false; for (var i = 0; i < locs.length; i++) { result = result || this.contains(locs[i]); } return result; }, include: function(loc) { var nw = this.nw, se = this.se, lng = valueOrDefault(loc.lng, loc[1]), lat = valueOrDefault(loc.lat, loc[0]); nw.lng = min(nw.lng, lng); nw.lat = max(nw.lat, lat); se.lng = max(se.lng, lng); se.lat = min(se.lat, lat); }, includeAll: function(locs) { for (var i = 0; i < locs.length; i++) { this.include(locs[i]); } }, edges: function() { var nw = this.nw, se = this.se; return { nw: this.nw, ne: new Location(nw.lat, se.lng), se: this.se, sw: new Location(se.lat, nw.lng) }; }, toArray: function() { var nw = this.nw, se = this.se; return [ nw, new Location(nw.lat, se.lng), se, new Location(se.lat, nw.lng) ]; }, overlaps: function(extent) { return this.containsAny(extent.toArray()) || extent.containsAny(this.toArray()); } }); Extent.World = new Extent([90, -180], [-90, 180]); Extent.create = function(a, b) { if (a instanceof Extent) { return a; } else if (a && b) { return new Extent(a, b); } else if (a && a.length === 4 && !b) { return new Extent([a[0], a[1]], [a[2], a[3]]); } }; deepExtend(dataviz, { map: { Extent, Location } }); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/attribution.js (function($, undefined) { var kendo = window.kendo, Widget = kendo.ui.Widget, template = kendo.template, util = kendo.drawing.util, valueOrDefault = util.valueOrDefault, defined = util.defined; var Attribution = Widget.extend({ init: function(element, options) { Widget.fn.init.call(this, element, options); this._initOptions(options); this.items = []; this.element.addClass("k-attribution"); }, options: { name: "Attribution", separator: "&nbsp;|&nbsp;", itemTemplate: ({ text }) => text }, filter: function(extent, zoom) { this._extent = extent; this._zoom = zoom; this._render(); }, add: function(item) { if (defined(item)) { if (typeof item === "string") { item = { text: item }; } this.items.push(item); this._render(); } }, remove: function(text) { var result = []; for (var i = 0; i < this.items.length; i++) { var item = this.items[i]; if (item.text !== text) { result.push(item); } } this.items = result; this._render(); }, clear: function() { this.items = []; this.element.empty(); }, _render: function() { var result = []; var itemTemplate = template(this.options.itemTemplate); for (var i = 0; i < this.items.length; i++) { var item = this.items[i]; var text = this._itemText(item); if (text !== "") { result.push(itemTemplate({ text })); } } if (result.length > 0) { this.element.empty().append(result.join(this.options.separator)).show(); } else { this.element.hide(); } }, _itemText: function(item) { var text = ""; var inZoomLevel = this._inZoomLevel(item.minZoom, item.maxZoom); var inArea = this._inArea(item.extent); if (inZoomLevel && inArea) { text += item.text; } return text; }, _inZoomLevel: function(min, max) { var result = true; min = valueOrDefault(min, -Number.MAX_VALUE); max = valueOrDefault(max, Number.MAX_VALUE); result = this._zoom > min && this._zoom < max; return result; }, _inArea: function(area) { var result = true; if (area) { result = area.contains(this._extent); } return result; } }); kendo.dataviz.ui.plugin(Attribution); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/navigator.js (function($) { var kendo = window.kendo; var Widget = kendo.ui.Widget; var keys = kendo.keys; var NS = ".kendoNavigator"; function button(dir) { const mapIcon = { n: "up", s: "down", e: "right", w: "left" }; return kendo.html.renderButton(`<button class="k-navigator-${dir}" aria-label="move ${mapIcon[dir]}"></button>`, { icon: `caret-alt-${mapIcon[dir]}`, fillMode: "flat", rounded: "full" }); } var BUTTONS = button("n") + button("e") + button("s") + button("w"); var Navigator = Widget.extend({ init: function(element, options) { Widget.fn.init.call(this, element, options); this._initOptions(options); this.element.addClass("k-navigator").append(BUTTONS).on("click" + NS, ".k-button", this._click.bind(this)); var parentElement = this.element.parent().closest("[" + kendo.attr("role") + "]"); this._keyroot = parentElement.length > 0 ? parentElement : this.element; this._tabindex(this._keyroot); this._keydown = this._keydown.bind(this); this._keyroot.on("keydown", this._keydown); }, options: { name: "Navigator", panStep: 1 }, events: ["pan"], dispose: function() { this._keyroot.off("keydown", this._keydown); }, _pan: function(x, y) { var panStep = this.options.panStep; this.trigger("pan", { x: x * panStep, y: y * panStep }); }, _click: function(e) { var x = 0; var y = 0; var button = $(e.currentTarget); if (button.is(".k-navigator-n")) { y = 1; } else if (button.is(".k-navigator-s")) { y = -1; } else if (button.is(".k-navigator-e")) { x = 1; } else if (button.is(".k-navigator-w")) { x = -1; } this._pan(x, y); e.preventDefault(); }, _keydown: function(e) { switch (e.which) { case keys.UP: this._pan(0, 1); e.preventDefault(); break; case keys.DOWN: this._pan(0, -1); e.preventDefault(); break; case keys.RIGHT: this._pan(1, 0); e.preventDefault(); break; case keys.LEFT: this._pan(-1, 0); e.preventDefault(); break; } } }); kendo.dataviz.ui.plugin(Navigator); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/zoom.js (function($) { var kendo = window.kendo; var Widget = kendo.ui.Widget; var keys = kendo.keys; function button(dir, icon) { return `<button class="k-button k-icon-button k-zoom-${dir}" title="zoom-${dir}" aria-label="zoom-${dir}">${kendo.ui.icon({ icon, iconClass: "k-button-icon" })}</button>`; } var NS = ".kendoZoomControl"; var BUTTONS = button("in", "plus") + button("out", "minus"); var PLUS = 187; var MINUS = 189; var FF_PLUS = 61; var FF_MINUS = 173; var ZoomControl = Widget.extend({ init: function(element, options) { Widget.fn.init.call(this, element, options); this._initOptions(options); this.element.addClass("k-zoom-control k-button-group k-group-horizontal").append(BUTTONS).on("click" + NS, ".k-button", this._click.bind(this)); var parentElement = this.element.parent().closest("[" + kendo.attr("role") + "]"); this._keyroot = parentElement.length > 0 ? parentElement : this.element; this._tabindex(this._keyroot); this._keydown = this._keydown.bind(this); this._keyroot.on("keydown", this._keydown); }, options: { name: "ZoomControl", zoomStep: 1 }, events: ["change"], _change: function(dir) { var zoomStep = this.options.zoomStep; this.trigger("change", { delta: dir * zoomStep }); }, _click: function(e) { var button = $(e.currentTarget); var dir = 1; if (button.is(".k-zoom-out")) { dir = -1; } this._change(dir); e.preventDefault(); }, _keydown: function(e) { switch (e.which) { case keys.NUMPAD_PLUS: case PLUS: case FF_PLUS: this._change(1); break; case keys.NUMPAD_MINUS: case MINUS: case FF_MINUS: this._change(-1); break; } } }); kendo.dataviz.ui.plugin(ZoomControl); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/crs.js (function($, undefined) { var math = Math, atan = math.atan, exp = math.exp, pow = math.pow, sin = math.sin, log = math.log, tan = math.tan, kendo = window.kendo, Class = kendo.Class, dataviz = kendo.dataviz, deepExtend = kendo.deepExtend, g = kendo.geometry, Point = g.Point, map = dataviz.map, Location = map.Location, util = kendo.drawing.util, rad = util.rad, deg = util.deg, limit = util.limitValue; var PI = math.PI, PI_DIV_2 = PI / 2, PI_DIV_4 = PI / 4, DEG_TO_RAD = PI / 180; var WGS84 = { a: 6378137, b: 6356752.314245179, f: .0033528106647474805, e: .08181919084262149 }; var Mercator = Class.extend({ init: function(options) { this._initOptions(options); }, MAX_LNG: 180, MAX_LAT: 85.0840590501, INVERSE_ITERATIONS: 15, INVERSE_CONVERGENCE: 1e-12, options: { centralMeridian: 0, datum: WGS84 }, forward: function(loc, clamp) { var proj = this, options = proj.options, datum = options.datum, r = datum.a, lng0 = options.centralMeridian, lat = limit(loc.lat, -proj.MAX_LAT, proj.MAX_LAT), lng = clamp ? limit(loc.lng, -proj.MAX_LNG, proj.MAX_LNG) : loc.lng, x = rad(lng - lng0) * r, y = proj._projectLat(lat); return new Point(x, y); }, _projectLat: function(lat) { var datum = this.options.datum, ecc = datum.e, r = datum.a, y = rad(lat), ts = tan(PI_DIV_4 + y / 2), con = ecc * sin(y), p = pow((1 - con) / (1 + con), ecc / 2); return r * log(ts * p); }, inverse: function(point, clamp) { var proj = this, options = proj.options, datum = options.datum, r = datum.a, lng0 = options.centralMeridian, lng = point.x / (DEG_TO_RAD * r) + lng0, lat = limit(proj._inverseY(point.y), -proj.MAX_LAT, proj.MAX_LAT); if (clamp) { lng = limit(lng, -proj.MAX_LNG, proj.MAX_LNG); } return new Location(lat, lng); }, _inverseY: function(y) { var proj = this, datum = proj.options.datum, r = datum.a, ecc = datum.e, ecch = ecc / 2, ts = exp(-y / r), phi = PI_DIV_2 - 2 * atan(ts), i; for (i = 0; i <= proj.INVERSE_ITERATIONS; i++) { var con = ecc * sin(phi), p = pow((1 - con) / (1 + con), ecch), dphi = PI_DIV_2 - 2 * atan(ts * p) - phi; phi += dphi; if (math.abs(dphi) <= proj.INVERSE_CONVERGENCE) { break; } } return deg(phi); } }); var SphericalMercator = Mercator.extend({ MAX_LAT: 85.0511287798, _projectLat: function(lat) { var r = this.options.datum.a, y = rad(lat), ts = tan(PI_DIV_4 + y / 2); return r * log(ts); }, _inverseY: function(y) { var r = this.options.datum.a, ts = exp(-y / r); return deg(PI_DIV_2 - 2 * atan(ts)); } }); var Equirectangular = Class.extend({ forward: function(loc) { return new Point(loc.lng, loc.lat); }, inverse: function(point) { return new Location(point.y, point.x); } }); var EPSG3857 = Class.extend({ init: function() { var crs = this, proj = crs._proj = new SphericalMercator(); var c = this.c = 2 * PI * proj.options.datum.a; this._tm = g.transform().translate(.5, .5).scale(1 / c, -1 / c); this._itm = g.transform().scale(c, -c).translate(-.5, -.5); }, toPoint: function(loc, scale, clamp) { var point = this._proj.forward(loc, clamp); return point.transform(this._tm).scale(scale || 1); }, toLocation: function(point, scale, clamp) { point = point.clone().scale(1 / (scale || 1)).transform(this._itm); return this._proj.inverse(point, clamp); } }); var EPSG3395 = Class.extend({ init: function() { this._proj = new Mercator(); }, toPoint: function(loc) { return this._proj.forward(loc); }, toLocation: function(point) { return this._proj.inverse(point); } }); var EPSG4326 = Class.extend({ init: function() { this._proj = new Equirectangular(); }, toPoint: function(loc) { return this._proj.forward(loc); }, toLocation: function(point) { return this._proj.inverse(point); } }); deepExtend(dataviz, { map: { crs: { EPSG3395, EPSG3857, EPSG4326 }, datums: { WGS84 }, projections: { Equirectangular, Mercator, SphericalMercator } } }); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/layers/base.js (function($, undefined) { var kendo = window.kendo, Class = kendo.Class, dataviz = kendo.dataviz, deepExtend = kendo.deepExtend, Extent = dataviz.map.Extent, util = kendo.drawing.util, defined = util.defined; var Layer = Class.extend({ init: function(map, options) { this._initOptions(options); this.map = map; this.element = $("<div class='k-layer'></div>").css({ "zIndex": this.options.zIndex, "opacity": this.options.opacity }).appendTo(map.scrollElement); this._beforeReset = this._beforeReset.bind(this); this._reset = this._reset.bind(this); this._resize = this._resize.bind(this); this._panEnd = this._panEnd.bind(this); this._activate(); this._updateAttribution(); }, destroy: function() { this._deactivate(); }, show: function() { this.reset(); this._activate(); this._applyExtent(true); }, hide: function() { this._deactivate(); this._setVisibility(false); }, reset: function() { this._beforeReset(); this._reset(); }, _reset: function() { this._applyExtent(); }, _beforeReset: $.noop, _resize: $.noop, _panEnd: function() { this._applyExtent(); }, _applyExtent: function() { var options = this.options; var zoom = this.map.zoom(); var matchMinZoom = !defined(options.minZoom) || zoom >= options.minZoom; var matchMaxZoom = !defined(options.maxZoom) || zoom <= options.maxZoom; var extent = Extent.create(options.extent); var inside = !extent || extent.overlaps(this.map.extent()); this._setVisibility(matchMinZoom && matchMaxZoom && inside); }, _setVisibility: function(visible) { this.element.css("display", visible ? "" : "none"); }, _activate: function() { var map = this.map; this._deactivate(); map.bind("beforeReset", this._beforeReset); map.bind("reset", this._reset); map.bind("resize", this._resize); map.bind("panEnd", this._panEnd); }, _deactivate: function() { var map = this.map; map.unbind("beforeReset", this._beforeReset); map.unbind("reset", this._reset); map.unbind("resize", this._resize); map.unbind("panEnd", this._panEnd); }, _updateAttribution: function() { var attr = this.map.attribution; if (attr) { attr.add(this.options.attribution); } } }); deepExtend(dataviz, { map: { layers: { Layer } } }); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/layers/shape.js (function($, undefined) { var kendo = window.kendo, Class = kendo.Class, DataSource = kendo.data.DataSource, dataviz = kendo.dataviz, deepExtend = kendo.deepExtend, g = kendo.geometry, d = kendo.drawing, Group = d.Group, last = d.util.last, defined = d.util.defined, map = dataviz.map, Location = map.Location, Layer = map.layers.Layer; var ShapeLayer = Layer.extend({ init: function(map, options) { this._pan = this._pan.bind(this); Layer.fn.init.call(this, map, options); this.surface = d.Surface.create(this.element, { width: map.scrollElement.width(), height: map.scrollElement.height() }); this._initRoot(); this.movable = new kendo.ui.Movable(this.surface.element); this._markers = []; this._click = this._handler("shapeClick"); this.surface.bind("click", this._click); this._mouseenter = this._handler("shapeMouseEnter"); this.surface.bind("mouseenter", this._mouseenter); this._mouseleave = this._handler("shapeMouseLeave"); this.surface.bind("mouseleave", this._mouseleave); this._initDataSource(); }, options: { autoBind: true }, destroy: function() { Layer.fn.destroy.call(this); this.surface.destroy(); this.dataSource.unbind("change", this._dataChange); }, setDataSource: function(dataSource) { if (this.dataSource) { this.dataSource.unbind("change", this._dataChange); } this.dataSource = kendo.data.DataSource.create(dataSource); this.dataSource.bind("change", this._dataChange); if (this.options.autoBind) { this.dataSource.fetch(); } }, _reset: function() { Layer.fn._reset.call(this); this._translateSurface(); if (this._data) { this._load(this._data); } }, _initRoot: function() { this._root = new Group(); this.surface.draw(this._root); }, _beforeReset: function() { this.surface.clear(); this._initRoot(); }, _resize: function() { this.surface.size(this.map.size()); }, _initDataSource: function() { var dsOptions = this.options.dataSource; this._dataChange = this._dataChange.bind(this); this.dataSource = DataSource.create(dsOptions).bind("change", this._dataChange); if (dsOptions && this.options.autoBind) { this.dataSource.fetch(); } }, _dataChange: function(e) { this._data = e.sender.view(); this._load(this._data); }, _load: function(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._loader.parse(data[i]); if (shape) { container.append(shape); } } this._root.clear(); this._root.append(container); }, shapeCreated: function(shape) { var cancelled = false; if (shape instanceof d.Circle) { cancelled = defined(this._createMarker(shape)); } if (!cancelled) { var args = { layer: this, shape }; cancelled = this.map.trigger("shapeCreated", args); } return cancelled; }, featureCreated: function(e) { e.layer = this; this.map.trigger("shapeFeatureCreated", e); }, _createMarker: function(shape) { var marker = this.map.markers.bind({ location: shape.location }, shape.dataItem); if (marker) { this._markers.push(marker); } return marker; }, _clearMarkers: function() { for (var i = 0; i < this._markers.length; i++) { this.map.markers.remove(this._markers[i]); } this._markers = []; }, _pan: function() { if (!this._panning) { this._panning = true; this.surface.suspendTracking(); } }, _panEnd: function(e) { Layer.fn._panEnd.call(this, e); this._translateSurface(); this.surface.resumeTracking(); this._panning = false; }, _translateSurface: function() { var map = this.map; var nw = map.locationToView(map.extent().nw); if (this.surface.translate && this.surface.element.width() > 0 && this.surface.element.height() > 0) { this.surface.translate(nw); this.movable.moveTo({ x: nw.x, y: nw.y }); } }, _handler: function(event) { var layer = this; return function(e) { if (e.element) { var args = { layer, shape: e.element, originalEvent: e.originalEvent }; layer.map.trigger(event, args); } }; }, _activate: function() { Layer.fn._activate.call(this); this.map.bind("pan", this._pan); }, _deactivate: function() { Layer.fn._deactivate.call(this); this.map.unbind("pan", this._pan); } }); var GeoJSONLoader = Class.extend({ init: function(locator, defaultStyle, observer) { this.observer = observer; this.locator = locator; this.style = defaultStyle; }, parse: function(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; }, _shapeCreated: function(shape) { var cancelled = false; if (this.observer && this.observer.shapeCreated) { cancelled = this.observer.shapeCreated(shape); } return cancelled; }, _featureCreated: function(group, dataItem) { if (this.observer && this.observer.featureCreated) { this.observer.featureCreated({ group, dataItem, properties: dataItem.properties }); } }, _loadGeometryTo: function(container, geometry, dataItem) { 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._loadPolygon(container, [coords[i]], dataItem); this._setLineFill(path); } break; case "Polygon": this._loadPolygon(container, coords, dataItem); break; case "MultiPolygon": for (i = 0; i < coords.length; i++) { this._loadPolygon(container, coords[i], dataItem); } break; case "Point": this._loadPoint(container, coords, dataItem); break; case "MultiPoint": for (i = 0; i < coords.length; i++) { this._loadPoint(container, coords[i], dataItem); } break; } }, _setLineFill: function(path) { var segments = path.segments; if (segments.length < 4 || !segments[0].anchor().equals(last(segments).anchor())) { path.options.fill = null; } }, _loadShape: function(container, shape) { if (!this._shapeCreated(shape)) { container.append(shape); } return shape; }, _loadPolygon: function(container, rings, dataItem) { var shape = this._buildPolygon(rings); shape.dataItem = dataItem; return this._loadShape(container, shape); }, _buildPolygon: function(rings) { 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.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; }, _loadPoint: function(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); } }); deepExtend(kendo.data, { schemas: { geojson: { type: "json", data: function(data) { if (data.type === "FeatureCollection") { return data.features; } if (data.type === "GeometryCollection") { return data.geometries; } return data; } } }, transports: { geojson: { read: { dataType: "json" } } } }); deepExtend(dataviz, { map: { layers: { shape: ShapeLayer, ShapeLayer }, GeoJSONLoader } }); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/layers/bubble.js (function($, undefined) { var kendo = window.kendo, getter = kendo.getter, dataviz = kendo.dataviz, deepExtend = kendo.deepExtend, g = kendo.geometry, d = kendo.drawing, util = d.util, defined = util.defined, map = dataviz.map, Location = map.Location, ShapeLayer = map.layers.ShapeLayer; var BubbleLayer = ShapeLayer.extend({ options: { autoBind: true, locationField: "location", valueField: "value", minSize: 0, maxSize: 100, scale: "sqrt", symbol: "circle" }, _load: function(data) { this.surface.clear(); if (data.length === 0) { return; } var opt = this.options; var getValue = getter(opt.valueField); data = data.slice(0); data.sort(function(a, b) { return getValue(b) - getValue(a); }); var scaleType = this._scaleType(); var scale; for (var i = 0; i < data.length; i++) { var dataItem = data[i]; var location = getter(opt.locationField)(dataItem); var value = getter(opt.valueField)(dataItem); if (defined(location) && defined(value)) { if (!scale) { scale = new scaleType([0, value], [opt.minSize, opt.maxSize]); } location = Location.create(location); var center = this.map.locationToView(location); var size = scale.map(value); var symbol = this._createSymbol({ center, size, style: opt.style, dataItem, location }); symbol.dataItem = dataItem; symbol.location = location; symbol.value = value; this._drawSymbol(symbol); } } }, _scaleType: function() { var scale = this.options.scale; if (kendo.isFunction(scale)) { return scale; } return dataviz.map.scales[scale]; }, _createSymbol: function(args) { var symbol = this.options.symbol; if (!kendo.isFunction(symbol)) { symbol = dataviz.map.symbols[symbol]; } return symbol(args); }, _drawSymbol: function(shape) { var args = { layer: this, shape }; var cancelled = this.map.trigger("shapeCreated", args); if (!cancelled) { this.surface.draw(shape); } } }); var SqrtScale = kendo.Class.extend({ init: function(domain, range) { this._domain = domain; this._range = range; var domainRange = Math.sqrt(domain[1]) - Math.sqrt(domain[0]); var outputRange = range[1] - range[0]; this._ratio = outputRange / domainRange; }, map: function(value) { var rel = (Math.sqrt(value) - Math.sqrt(this._domain[0])) * this._ratio; return this._range[0] + rel; } }); var Symbols = { circle: function(args) { var geo = new g.Circle(args.center, args.size / 2); return new d.Circle(geo, args.style); }, square: function(args) { var path = new d.Path(args.style); var halfSize = args.size / 2; var center = args.center; path.moveTo(center.x - halfSize, center.y - halfSize).lineTo(center.x + halfSize, center.y - halfSize).lineTo(center.x + halfSize, center.y + halfSize).lineTo(center.x - halfSize, center.y + halfSize).close(); return path; } }; deepExtend(dataviz, { map: { layers: { bubble: BubbleLayer, BubbleLayer }, scales: { sqrt: SqrtScale }, symbols: Symbols } }); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/layers/tile.js (function($, undefined) { var math = Math, kendo = window.kendo, Class = kendo.Class, template = kendo.template, dataviz = kendo.dataviz, deepExtend = kendo.deepExtend, g = kendo.geometry, Point = g.Point, Layer = dataviz.map.layers.Layer, util = kendo.util, renderSize = util.renderSize, drawingUtil = kendo.drawing.util, round = drawingUtil.round, limit = drawingUtil.limitValue; var TileLayer = Layer.extend({ init: function(map, options) { Layer.fn.init.call(this, map, options); if (typeof this.options.subdomains === "string") { this.options.subdomains = this.options.subdomains.split(""); } var viewType = this._viewType(); this._view = new viewType(this.element, this.options); }, destroy: function() { Layer.fn.destroy.call(this); this._view.destroy(); this._view = null; }, _beforeReset: function() { var map = this.map; var origin = map.locationToLayer(map.extent().nw).round(); this._view.viewOrigin(origin); }, _reset: function(e) { var tileTitle; if (e) { tileTitle = e.tileTitle; } else { tileTitle = ""; } Layer.fn._reset.call(this); this._updateView(); this._view.reset(tileTitle); }, _viewType: function() { return TileView; }, _activate: function() { Layer.fn._activate.call(this); if (!kendo.support.mobileOS) { if (!this._pan) { this._pan = kendo.throttle(this._render.bind(this), 100); } this.map.bind("pan", this._pan); } }, _deactivate: function() { Layer.fn._deactivate.call(this); if (this._pan) { this.map.unbind("pan", this._pan); } }, _updateView: function() { var view = this._view, map = this.map, extent = map.extent(), extentToPoint = { nw: map.locationToLayer(extent.nw).round(), se: map.locationToLayer(extent.se).round() }; view.center(map.locationToLayer(map.center())); view.extent(extentToPoint); view.zoom(map.zoom()); }, _resize: function() { this._render(); }, _panEnd: function(e) { Layer.fn._panEnd.call(this, e); this._render(); }, _render: function() { this._updateView(); this._view.render(); } }); var TileView = Class.extend({ init: function(element, options) { this.element = element; this._initOptions(options); this.pool = new TilePool(); }, options: { tileSize: 256, subdomains: [ "a", "b", "c" ], urlTemplate: () => "" }, center: function(center) { this._center = center; }, extent: function(extent) { this._extent = extent; }, viewOrigin: function(origin) { this._viewOrigin = origin; }, zoom: function(zoom) { this._zoom = zoom; }, pointToTileIndex: function(point) { return new Point(math.floor(point.x / this.options.tileSize), math.floor(point.y / this.options.tileSize)); }, tileCount: function() { var size = this.size(), firstTileIndex = this.pointToTileIndex(this._extent.nw), nw = this._extent.nw, point = this.indexToPoint(firstTileIndex).translate(-nw.x, -nw.y); return { x: math.ceil((math.abs(point.x) + size.width) / this.options.tileSize), y: math.ceil((math.abs(point.y) + size.height) / this.options.tileSize) }; }, size: function() { var nw = this._extent.nw, se = this._extent.se, diff = se.clone().translate(-nw.x, -nw.y); return { width: diff.x, height: diff.y }; }, indexToPoint: function(index) { var x = index.x, y = index.y; return new Point(x * this.options.tileSize, y * this.options.tileSize); }, subdomainText: function() { var subdomains = this.options.subdomains; return subdomains[this.subdomainIndex++ % subdomains.length]; }, destroy: function() { this.element.empty(); this.pool.empty(); }, reset: function(tileTitle) { this._tileTitle = tileTitle; this.pool.reset(); this.subdomainIndex = 0; this.render(); }, render: function() { var size = this.tileCount(), firstTileIndex = this.pointToTileIndex(this._extent.nw), tile, x, y; for (x = 0; x < size.x; x++) { for (y = 0; y < size.y; y++) { tile = this.createTile({ x: firstTileIndex.x + x, y: firstTileIndex.y + y }); if (!tile.visible) { tile.show(); } } } }, createTile: function(currentIndex) { var options = this.tileOptions(currentIndex); var tile = this.pool.get(this._center, options); if (tile.element.parent().length === 0) { this.element.append(tile.element); } return tile; }, tileOptions: function(currentIndex) { var index = this.wrapIndex(currentIndex), point = this.indexToPoint(currentIndex), origin = this._viewOrigin, offset = point.clone().translate(-origin.x, -origin.y); return { index, currentIndex, point, offset: roundPoint(offset), zoom: this._zoom, size: this.options.tileSize, subdomain: this.subdomainText(), urlTemplate: this.options.urlTemplate, errorUrlTemplate: this.options.errorUrlTemplate, tileTitle: this._tileTitle }; }, wrapIndex: function(index) { var boundary = math.pow(2, this._zoom); return { x: this.wrapValue(index.x, boundary), y: limit(index.y, 0, boundary - 1) }; }, wrapValue: function(value, boundary) { var remainder = math.abs(value) % boundary; if (value >= 0) { value = remainder; } else { value = boundary - (remainder === 0 ? boundary : remainder); } return value; } }); var ImageTile = Class.extend({ init: function(id, options) { this.id = id; this.visible = true; this._initOptions(options); this.createElement(); this.show(); }, options: { urlTemplate: () => "", errorUrlTemplate: () => "" }, createElement: function() { this.element = $("<img alt='" + this.options.tileTitle + "' />").css({ position: "absolute", display: "block", width: this.options.size, height: this.options.size }).on("error", (function(e) { if (this.errorUrl()) { e.target.setAttribute("src", this.errorUrl()); } else { e.target.removeAttribute("src"); } }).bind(this)); }, show: function() { var element = this.element[0]; element.style.top = renderSize(this.options.offset.y); element.style.left = renderSize(this.options.offset.x); var url = this.url(); if (url) { element.setAttribute("src", url); } element.style.visibility = "visible"; this.visible = true; }, hide: function() { this.element[0].style.visibility = "hidden"; this.visible = false; }, url: function() { var urlResult = template(this.options.urlTemplate); return urlResult(this.urlOptions()); }, errorUrl: function() { var urlResult = template(this.options.errorUrlTemplate); return urlResult(this.urlOptions()); }, urlOptions: function() { var options = this.options; return { zoom: options.zoom, subdomain: options.subdomain, z: options.zoom, x: options.index.x, y: options.index.y, s: options.subdomain, quadkey: options.quadkey, q: options.quadkey, culture: options.culture, c: options.culture }; }, destroy: function() { if (this.element) { this.element.remove(); this.element = null; } } }); var TilePool = Class.extend({ init: function() { this._items = []; }, options: { maxSize: 100 }, get: function(center, options) { if (this._items.length >= this.options.maxSize) { this._remove(center); } return this._create(options); }, empty: function() { var items = this._items; for (var i = 0; i < items.length; i++) { items[i].destroy(); } this._items = []; }, reset: function() { var items = this._items; for (var i = 0; i < items.length; i++) { items[i].hide(); } }, _create: function(options) { var items = this._items; var tile; var id = util.hashKey(options.point.toString() + options.offset.toString() + options.zoom + options.urlTemplate); for (var i = 0; i < items.length; i++) { if (items[i].id === id) { tile = items[i]; break; } } if (tile) { tile.show(); } else { tile = new ImageTile(id, options); this._items.push(tile); } return tile; }, _remove: function(center) { var items = this._items; var maxDist = -1; var index = -1; for (var i = 0; i < items.length; i++) { var dist = items[i].options.point.distanceTo(center); if (dist > maxDist && !items[i].visible) { index = i; maxDist = dist; } } if (index !== -1) { items[index].destroy(); items.splice(index, 1); } } }); function roundPoint(point) { return new Point(round(point.x), round(point.y)); } deepExtend(dataviz, { map: { layers: { tile: TileLayer, TileLayer, ImageTile, TilePool, TileView } } }); })(window.kendo.jQuery); //#endregion //#region ../src/dataviz/map/layers/bing.js (function($, undefined) { var kendo = window.kendo, dataviz = kendo.dataviz, deepExtend = kendo.deepExtend, defined = kendo.drawing.util.defined, Extent = dataviz.map.Extent, Location = dataviz.map.Location, TileLayer = dataviz.map.layers.TileLayer, TileView = dataviz.map.layers.TileView; var BingLayer = TileLayer.extend({ init: function(map, options) { this.options.baseUrl = this._scheme() + "://dev.virtualearth.net/REST/v1/Imagery/Metadata/"; TileLayer.fn.init.call(this, map, options); this._onMetadata = this._onMetadata.bind(this); this._fetchMetadata(); }, options: { imagerySet: "road" }, _fetchMetadata: function() { var options = this.options; if (!options.key) { throw new Error("Bing tile layer: API key is required"); } $.ajax({ url: options.baseUrl + options.imagerySet, data: { output: "json", include: "ImageryProviders", key: options.key, uriScheme: this._scheme() }, type: "get", dataType: "jsonp", jsonp: "jsonp", success: this._onMetadata }); }, _scheme: function(proto) { proto = proto || window.location.protocol; return proto.replace(":", "") === "https" ? "https" : "http"; }, _onMetadata: function(data) { var that = this; if (data && data.resourceSets.length) { var resource = that.resource = data.resourceSets[0].resources[0]; deepExtend(that._view.options, { urlTemplate: ({ subdomain, quadkey, culture }) => that.resource.imageUrl.replace("{subdomain}", subdomain).replace("{quadkey}", quadkey).replace("{culture}", culture), subdomains: resource.imageUrlSubdomains }); var options = that.options; if (!defined(options.minZoom)) { options.minZoom = resource.zoomMin; } if (!defined(options.maxZoom)) { options.maxZoom = resource.zoomMax; } that._addAttribution(); if (that.element.css("display") !== "none") { that._reset(); } } }, _viewType: function() { return BingView; }, _addAttribution: function() { var attr = this.map.attribution; if (attr) { var items = this.resource.imageryProviders; if (items) { for (var i = 0; i < items.length; i++) { var item = items[i]; for (var y = 0; y < item.coverageAreas.length; y++) { var area =