Created
January 19, 2016 16:12
-
-
Save epixa/419b8e0b93001732c10b to your computer and use it in GitHub Desktop.
This file has been truncated, but you can view the full file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
webpackJsonp([0],[ | |
/* 0 */ | |
/***/ function(module, exports, __webpack_require__) { | |
/** | |
* Test entry file | |
* | |
* This is programatically created and updated, do not modify | |
* | |
* context: {"env":"production","urlBasePath":"","sourceMaps":false,"kbnVersion":"4.3.1","buildNum":9518} | |
* includes code from: | |
* - [email protected] | |
* - [email protected] | |
* - [email protected] | |
* - [email protected] | |
* - [email protected] | |
* - [email protected] | |
* - [email protected] | |
* - [email protected] | |
* | |
*/ | |
'use strict'; | |
__webpack_require__(1); | |
__webpack_require__(333); | |
__webpack_require__(779); | |
__webpack_require__(844); | |
__webpack_require__(311); | |
__webpack_require__(832); | |
__webpack_require__(445); | |
__webpack_require__(446); | |
__webpack_require__(831); | |
__webpack_require__(503); | |
__webpack_require__(472); | |
__webpack_require__(845); | |
__webpack_require__(502); | |
__webpack_require__(313); | |
__webpack_require__(622); | |
__webpack_require__(847); | |
__webpack_require__(848); | |
__webpack_require__(849); | |
__webpack_require__(850); | |
__webpack_require__(852); | |
__webpack_require__(853); | |
__webpack_require__(738); | |
__webpack_require__(855); | |
__webpack_require__(471); | |
__webpack_require__(660); | |
__webpack_require__(654); | |
__webpack_require__(778); | |
__webpack_require__(658); | |
__webpack_require__(508); | |
__webpack_require__(856); | |
__webpack_require__(627); | |
__webpack_require__(583); | |
__webpack_require__(720); | |
__webpack_require__(509); | |
__webpack_require__(799); | |
__webpack_require__(447); | |
__webpack_require__(837); | |
__webpack_require__(487); | |
__webpack_require__(448); | |
__webpack_require__(798); | |
__webpack_require__(857); | |
__webpack_require__(858); | |
__webpack_require__(859); | |
__webpack_require__(860); | |
__webpack_require__(861); | |
__webpack_require__(862); | |
__webpack_require__(863); | |
__webpack_require__(864); | |
__webpack_require__(865); | |
__webpack_require__(866); | |
__webpack_require__(867); | |
__webpack_require__(868); | |
__webpack_require__(869); | |
__webpack_require__(870); | |
__webpack_require__(871); | |
__webpack_require__(872); | |
__webpack_require__(857); | |
__webpack_require__(873); | |
__webpack_require__(874); | |
__webpack_require__(212); | |
__webpack_require__(1); | |
__webpack_require__(875); | |
__webpack_require__(878); | |
__webpack_require__(879); | |
__webpack_require__(745); | |
__webpack_require__(510); | |
__webpack_require__(880); | |
__webpack_require__(682); | |
__webpack_require__(822); | |
__webpack_require__(511); | |
__webpack_require__(242); | |
__webpack_require__(881); | |
__webpack_require__(883); | |
__webpack_require__(703); | |
__webpack_require__(514); | |
__webpack_require__(890); | |
__webpack_require__(315); | |
__webpack_require__(891); | |
__webpack_require__(894); | |
__webpack_require__(264); | |
__webpack_require__(265); | |
__webpack_require__(513); | |
__webpack_require__(565); | |
__webpack_require__(258); | |
__webpack_require__(895); | |
__webpack_require__(896); | |
__webpack_require__(933); | |
__webpack_require__(217); | |
__webpack_require__(500); | |
__webpack_require__(935); | |
__webpack_require__(748); | |
__webpack_require__(797); | |
__webpack_require__(629); | |
__webpack_require__(312); | |
__webpack_require__(334); | |
__webpack_require__(709); | |
__webpack_require__(744); | |
__webpack_require__(774); | |
__webpack_require__(775); | |
__webpack_require__(840); | |
__webpack_require__(356); | |
__webpack_require__(939); | |
__webpack_require__(578); | |
__webpack_require__(415); | |
__webpack_require__(972); | |
__webpack_require__(996); | |
__webpack_require__(1004); | |
__webpack_require__(1009); | |
__webpack_require__(1021); | |
__webpack_require__(1023); | |
__webpack_require__(1).bootstrap(); | |
/* xoxo */ | |
/***/ }, | |
/* 1 */, | |
/* 2 */, | |
/* 3 */, | |
/* 4 */, | |
/* 5 */, | |
/* 6 */, | |
/* 7 */, | |
/* 8 */, | |
/* 9 */, | |
/* 10 */, | |
/* 11 */, | |
/* 12 */, | |
/* 13 */, | |
/* 14 */, | |
/* 15 */, | |
/* 16 */, | |
/* 17 */, | |
/* 18 */, | |
/* 19 */, | |
/* 20 */, | |
/* 21 */, | |
/* 22 */, | |
/* 23 */, | |
/* 24 */, | |
/* 25 */, | |
/* 26 */, | |
/* 27 */, | |
/* 28 */, | |
/* 29 */, | |
/* 30 */, | |
/* 31 */, | |
/* 32 */, | |
/* 33 */, | |
/* 34 */, | |
/* 35 */, | |
/* 36 */, | |
/* 37 */, | |
/* 38 */, | |
/* 39 */, | |
/* 40 */, | |
/* 41 */, | |
/* 42 */, | |
/* 43 */, | |
/* 44 */, | |
/* 45 */, | |
/* 46 */, | |
/* 47 */, | |
/* 48 */, | |
/* 49 */, | |
/* 50 */, | |
/* 51 */, | |
/* 52 */, | |
/* 53 */, | |
/* 54 */, | |
/* 55 */, | |
/* 56 */, | |
/* 57 */, | |
/* 58 */, | |
/* 59 */, | |
/* 60 */, | |
/* 61 */, | |
/* 62 */, | |
/* 63 */, | |
/* 64 */, | |
/* 65 */, | |
/* 66 */, | |
/* 67 */, | |
/* 68 */, | |
/* 69 */, | |
/* 70 */, | |
/* 71 */, | |
/* 72 */, | |
/* 73 */, | |
/* 74 */, | |
/* 75 */, | |
/* 76 */, | |
/* 77 */, | |
/* 78 */, | |
/* 79 */, | |
/* 80 */, | |
/* 81 */, | |
/* 82 */, | |
/* 83 */, | |
/* 84 */, | |
/* 85 */, | |
/* 86 */, | |
/* 87 */, | |
/* 88 */, | |
/* 89 */, | |
/* 90 */, | |
/* 91 */, | |
/* 92 */, | |
/* 93 */, | |
/* 94 */, | |
/* 95 */, | |
/* 96 */, | |
/* 97 */, | |
/* 98 */, | |
/* 99 */, | |
/* 100 */, | |
/* 101 */, | |
/* 102 */, | |
/* 103 */, | |
/* 104 */, | |
/* 105 */, | |
/* 106 */, | |
/* 107 */, | |
/* 108 */, | |
/* 109 */, | |
/* 110 */, | |
/* 111 */, | |
/* 112 */, | |
/* 113 */, | |
/* 114 */, | |
/* 115 */, | |
/* 116 */, | |
/* 117 */, | |
/* 118 */, | |
/* 119 */, | |
/* 120 */, | |
/* 121 */, | |
/* 122 */, | |
/* 123 */, | |
/* 124 */, | |
/* 125 */, | |
/* 126 */, | |
/* 127 */, | |
/* 128 */, | |
/* 129 */, | |
/* 130 */, | |
/* 131 */, | |
/* 132 */, | |
/* 133 */, | |
/* 134 */, | |
/* 135 */, | |
/* 136 */, | |
/* 137 */, | |
/* 138 */, | |
/* 139 */, | |
/* 140 */, | |
/* 141 */, | |
/* 142 */, | |
/* 143 */, | |
/* 144 */, | |
/* 145 */, | |
/* 146 */, | |
/* 147 */, | |
/* 148 */, | |
/* 149 */, | |
/* 150 */, | |
/* 151 */, | |
/* 152 */, | |
/* 153 */, | |
/* 154 */, | |
/* 155 */, | |
/* 156 */, | |
/* 157 */, | |
/* 158 */, | |
/* 159 */, | |
/* 160 */, | |
/* 161 */, | |
/* 162 */, | |
/* 163 */, | |
/* 164 */, | |
/* 165 */, | |
/* 166 */, | |
/* 167 */, | |
/* 168 */, | |
/* 169 */, | |
/* 170 */, | |
/* 171 */, | |
/* 172 */, | |
/* 173 */, | |
/* 174 */, | |
/* 175 */, | |
/* 176 */, | |
/* 177 */, | |
/* 178 */, | |
/* 179 */, | |
/* 180 */, | |
/* 181 */, | |
/* 182 */, | |
/* 183 */, | |
/* 184 */, | |
/* 185 */, | |
/* 186 */, | |
/* 187 */, | |
/* 188 */, | |
/* 189 */, | |
/* 190 */, | |
/* 191 */, | |
/* 192 */, | |
/* 193 */, | |
/* 194 */, | |
/* 195 */, | |
/* 196 */, | |
/* 197 */, | |
/* 198 */, | |
/* 199 */, | |
/* 200 */, | |
/* 201 */, | |
/* 202 */, | |
/* 203 */, | |
/* 204 */, | |
/* 205 */, | |
/* 206 */, | |
/* 207 */, | |
/* 208 */, | |
/* 209 */, | |
/* 210 */, | |
/* 211 */, | |
/* 212 */, | |
/* 213 */, | |
/* 214 */, | |
/* 215 */, | |
/* 216 */, | |
/* 217 */, | |
/* 218 */, | |
/* 219 */, | |
/* 220 */, | |
/* 221 */, | |
/* 222 */, | |
/* 223 */, | |
/* 224 */, | |
/* 225 */, | |
/* 226 */, | |
/* 227 */, | |
/* 228 */, | |
/* 229 */, | |
/* 230 */, | |
/* 231 */, | |
/* 232 */, | |
/* 233 */, | |
/* 234 */, | |
/* 235 */, | |
/* 236 */, | |
/* 237 */, | |
/* 238 */, | |
/* 239 */, | |
/* 240 */, | |
/* 241 */, | |
/* 242 */, | |
/* 243 */, | |
/* 244 */, | |
/* 245 */, | |
/* 246 */, | |
/* 247 */, | |
/* 248 */, | |
/* 249 */, | |
/* 250 */, | |
/* 251 */, | |
/* 252 */, | |
/* 253 */, | |
/* 254 */, | |
/* 255 */, | |
/* 256 */, | |
/* 257 */, | |
/* 258 */, | |
/* 259 */, | |
/* 260 */, | |
/* 261 */, | |
/* 262 */, | |
/* 263 */, | |
/* 264 */, | |
/* 265 */, | |
/* 266 */, | |
/* 267 */, | |
/* 268 */, | |
/* 269 */, | |
/* 270 */, | |
/* 271 */, | |
/* 272 */, | |
/* 273 */, | |
/* 274 */, | |
/* 275 */, | |
/* 276 */, | |
/* 277 */, | |
/* 278 */, | |
/* 279 */, | |
/* 280 */, | |
/* 281 */, | |
/* 282 */, | |
/* 283 */, | |
/* 284 */, | |
/* 285 */, | |
/* 286 */, | |
/* 287 */, | |
/* 288 */, | |
/* 289 */, | |
/* 290 */, | |
/* 291 */, | |
/* 292 */, | |
/* 293 */, | |
/* 294 */, | |
/* 295 */, | |
/* 296 */, | |
/* 297 */, | |
/* 298 */, | |
/* 299 */, | |
/* 300 */, | |
/* 301 */, | |
/* 302 */, | |
/* 303 */, | |
/* 304 */, | |
/* 305 */, | |
/* 306 */, | |
/* 307 */, | |
/* 308 */, | |
/* 309 */, | |
/* 310 */, | |
/* 311 */, | |
/* 312 */, | |
/* 313 */, | |
/* 314 */, | |
/* 315 */, | |
/* 316 */, | |
/* 317 */, | |
/* 318 */, | |
/* 319 */, | |
/* 320 */, | |
/* 321 */, | |
/* 322 */, | |
/* 323 */, | |
/* 324 */, | |
/* 325 */, | |
/* 326 */, | |
/* 327 */, | |
/* 328 */, | |
/* 329 */, | |
/* 330 */, | |
/* 331 */, | |
/* 332 */, | |
/* 333 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
__webpack_require__(334); | |
__webpack_require__(709); | |
__webpack_require__(744); | |
__webpack_require__(774); | |
__webpack_require__(840); | |
var moment = __webpack_require__(624); | |
var chrome = __webpack_require__(1); | |
var routes = __webpack_require__(218); | |
var modules = __webpack_require__(216); | |
var kibanaLogoUrl = __webpack_require__(843); | |
routes.otherwise({ | |
redirectTo: '/' + chrome.getInjected('kbnDefaultAppId', 'discover') | |
}); | |
chrome.setBrand({ | |
'logo': 'url(' + kibanaLogoUrl + ') left no-repeat', | |
'smallLogo': 'url(' + kibanaLogoUrl + ') left no-repeat' | |
}).setNavBackground('#222222').setTabDefaults({ | |
resetWhenActive: true, | |
lastUrlStore: window.sessionStore, | |
activeIndicatorColor: '#656a76' | |
}).setTabs([{ | |
id: 'discover', | |
title: 'Discover' | |
}, { | |
id: 'visualize', | |
title: 'Visualize', | |
activeIndicatorColor: function activeIndicatorColor() { | |
return String(this.lastUrl).indexOf('/visualize/step/') === 0 ? 'white' : '#656a76'; | |
} | |
}, { | |
id: 'dashboard', | |
title: 'Dashboard' | |
}, { | |
id: 'settings', | |
title: 'Settings' | |
}]).setRootController('kibana', function ($scope, $rootScope, courier, config) { | |
function setDefaultTimezone() { | |
moment.tz.setDefault(config.get('dateFormat:tz')); | |
} | |
// wait for the application to finish loading | |
$scope.$on('application.load', function () { | |
courier.start(); | |
}); | |
$scope.$on('init:config', setDefaultTimezone); | |
$scope.$on('change:config.dateFormat:tz', setDefaultTimezone); | |
}); | |
/***/ }, | |
/* 334 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(335); | |
__webpack_require__(355); | |
__webpack_require__(442); | |
__webpack_require__(444); | |
__webpack_require__(466); | |
__webpack_require__(706); | |
__webpack_require__(475); | |
__webpack_require__(707); | |
__webpack_require__(708); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, module, exports) { | |
__webpack_require__(335); | |
__webpack_require__(355); | |
__webpack_require__(442); | |
__webpack_require__(444); | |
__webpack_require__(466); | |
__webpack_require__(706); | |
// preload | |
__webpack_require__(475); | |
__webpack_require__(707).register(__webpack_require__(708)); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 335 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(336); | |
__webpack_require__(353); | |
__webpack_require__(315); | |
__webpack_require__(216); | |
__webpack_require__(354); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var Scanner = __webpack_require__(336); | |
__webpack_require__(353); | |
__webpack_require__(315); | |
var module = __webpack_require__(216).get('discover/saved_searches', ['kibana/notify']); | |
// Register this service with the saved object registry so it can be | |
// edited by the object editor. | |
__webpack_require__(354).register({ | |
service: 'savedSearches', | |
title: 'searches' | |
}); | |
module.service('savedSearches', function (Promise, config, kbnIndex, es, createNotifier, SavedSearch, kbnUrl) { | |
var scanner = new Scanner(es, { | |
index: kbnIndex, | |
type: 'search' | |
}); | |
var notify = createNotifier({ | |
location: 'Saved Searches' | |
}); | |
this.type = SavedSearch.type; | |
this.Class = SavedSearch; | |
this.loaderProperties = { | |
name: 'searches', | |
noun: 'Saved Search', | |
nouns: 'saved searches' | |
}; | |
this.scanAll = function (queryString) { | |
var _this = this; | |
var pageSize = arguments.length <= 1 || arguments[1] === undefined ? 1000 : arguments[1]; | |
return scanner.scanAndMap(queryString, { | |
pageSize: pageSize, | |
docCount: Infinity | |
}, function (hit) { | |
return _this.mapHits(hit); | |
}); | |
}; | |
this.get = function (id) { | |
return new SavedSearch(id).init(); | |
}; | |
this.urlFor = function (id) { | |
return kbnUrl.eval('#/discover/{{id}}', { id: id }); | |
}; | |
this['delete'] = function (ids) { | |
ids = !_.isArray(ids) ? [ids] : ids; | |
return Promise.map(ids, function (id) { | |
return new SavedSearch(id)['delete'](); | |
}); | |
}; | |
this.mapHits = function (hit) { | |
var source = hit._source; | |
source.id = hit._id; | |
source.url = this.urlFor(hit._id); | |
return source; | |
}; | |
this.find = function (searchString) { | |
var _this2 = this; | |
var size = arguments.length <= 1 || arguments[1] === undefined ? 100 : arguments[1]; | |
var body; | |
if (searchString) { | |
body = { | |
query: { | |
simple_query_string: { | |
query: searchString + '*', | |
fields: ['title^3', 'description'], | |
default_operator: 'AND' | |
} | |
} | |
}; | |
} else { | |
body = { query: { match_all: {} } }; | |
} | |
return es.search({ | |
index: kbnIndex, | |
type: 'search', | |
body: body, | |
size: size | |
}).then(function (resp) { | |
return { | |
total: resp.hits.total, | |
hits: resp.hits.hits.map(function (hit) { | |
return _this2.mapHits(hit); | |
}) | |
}; | |
}); | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 336 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var _Promise = __webpack_require__(337)['default']; | |
Object.defineProperty(exports, '__esModule', { | |
value: true | |
}); | |
var _ = __webpack_require__(194); | |
var Scanner = function Scanner(client) { | |
var _ref = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | |
var index = _ref.index; | |
var type = _ref.type; | |
if (!index) throw new Error('Expected index'); | |
if (!type) throw new Error('Expected type'); | |
if (!client) throw new Error('Expected client'); | |
this.client = client; | |
this.index = index; | |
this.type = type; | |
}; | |
Scanner.prototype.scanAndMap = function (searchString, options, mapFn) { | |
var _this = this; | |
var scrollId = undefined; | |
var body = undefined; | |
var allResults = { | |
hits: [], | |
total: 0 | |
}; | |
var opts = _.defaults(options || {}, { | |
pageSize: 100, | |
docCount: 1000 | |
}); | |
if (searchString) { | |
body = { | |
query: { | |
simple_query_string: { | |
query: searchString + '*', | |
fields: ['title^3', 'description'], | |
default_operator: 'AND' | |
} | |
} | |
}; | |
} else { | |
body = { query: { match_all: {} } }; | |
} | |
return new _Promise(function (resolve, reject) { | |
var getMoreUntilDone = function getMoreUntilDone(error, response) { | |
var scanAllResults = opts.docCount === Infinity; | |
allResults.total = scanAllResults ? response.hits.total : Math.min(response.hits.total, opts.docCount); | |
scrollId = response._scroll_id || scrollId; | |
var hits = response.hits.hits.slice(0, allResults.total - allResults.hits.length); | |
if (mapFn) hits = hits.map(mapFn); | |
allResults.hits = allResults.hits.concat(hits); | |
var collectedAllResults = allResults.total === allResults.hits.length; | |
if (collectedAllResults) { | |
resolve(allResults); | |
} else { | |
_this.client.scroll({ | |
scrollId: scrollId | |
}, getMoreUntilDone); | |
} | |
}; | |
_this.client.search({ | |
index: _this.index, | |
type: _this.type, | |
size: opts.pageSize, | |
body: body, | |
searchType: 'scan', | |
scroll: '1m' | |
}, getMoreUntilDone); | |
}); | |
}; | |
exports['default'] = Scanner; | |
module.exports = exports['default']; | |
/***/ }, | |
/* 337 */ | |
/***/ function(module, exports, __webpack_require__) { | |
module.exports = { "default": __webpack_require__(338), __esModule: true }; | |
/***/ }, | |
/* 338 */ | |
/***/ function(module, exports, __webpack_require__) { | |
__webpack_require__(339); | |
__webpack_require__(298); | |
__webpack_require__(278); | |
__webpack_require__(340); | |
module.exports = __webpack_require__(238).Promise; | |
/***/ }, | |
/* 339 */ | |
/***/ function(module, exports) { | |
/***/ }, | |
/* 340 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var $ = __webpack_require__(205) | |
, LIBRARY = __webpack_require__(287) | |
, global = __webpack_require__(237) | |
, ctx = __webpack_require__(239) | |
, classof = __webpack_require__(304) | |
, $export = __webpack_require__(236) | |
, isObject = __webpack_require__(234) | |
, anObject = __webpack_require__(302) | |
, aFunction = __webpack_require__(240) | |
, strictNew = __webpack_require__(341) | |
, forOf = __webpack_require__(342) | |
, setProto = __webpack_require__(343).set | |
, same = __webpack_require__(344) | |
, SPECIES = __webpack_require__(295)('species') | |
, speciesConstructor = __webpack_require__(345) | |
, asap = __webpack_require__(346) | |
, PROMISE = 'Promise' | |
, process = global.process | |
, isNode = classof(process) == 'process' | |
, P = global[PROMISE] | |
, Wrapper; | |
var testResolve = function(sub){ | |
var test = new P(function(){}); | |
if(sub)test.constructor = Object; | |
return P.resolve(test) === test; | |
}; | |
var USE_NATIVE = function(){ | |
var works = false; | |
function P2(x){ | |
var self = new P(x); | |
setProto(self, P2.prototype); | |
return self; | |
} | |
try { | |
works = P && P.resolve && testResolve(); | |
setProto(P2, P); | |
P2.prototype = $.create(P.prototype, {constructor: {value: P2}}); | |
// actual Firefox has broken subclass support, test that | |
if(!(P2.resolve(5).then(function(){}) instanceof P2)){ | |
works = false; | |
} | |
// actual V8 bug, https://code.google.com/p/v8/issues/detail?id=4162 | |
if(works && __webpack_require__(291)){ | |
var thenableThenGotten = false; | |
P.resolve($.setDesc({}, 'then', { | |
get: function(){ thenableThenGotten = true; } | |
})); | |
works = thenableThenGotten; | |
} | |
} catch(e){ works = false; } | |
return works; | |
}(); | |
// helpers | |
var sameConstructor = function(a, b){ | |
// library wrapper special case | |
if(LIBRARY && a === P && b === Wrapper)return true; | |
return same(a, b); | |
}; | |
var getConstructor = function(C){ | |
var S = anObject(C)[SPECIES]; | |
return S != undefined ? S : C; | |
}; | |
var isThenable = function(it){ | |
var then; | |
return isObject(it) && typeof (then = it.then) == 'function' ? then : false; | |
}; | |
var PromiseCapability = function(C){ | |
var resolve, reject; | |
this.promise = new C(function($$resolve, $$reject){ | |
if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor'); | |
resolve = $$resolve; | |
reject = $$reject; | |
}); | |
this.resolve = aFunction(resolve), | |
this.reject = aFunction(reject) | |
}; | |
var perform = function(exec){ | |
try { | |
exec(); | |
} catch(e){ | |
return {error: e}; | |
} | |
}; | |
var notify = function(record, isReject){ | |
if(record.n)return; | |
record.n = true; | |
var chain = record.c; | |
asap(function(){ | |
var value = record.v | |
, ok = record.s == 1 | |
, i = 0; | |
var run = function(reaction){ | |
var handler = ok ? reaction.ok : reaction.fail | |
, resolve = reaction.resolve | |
, reject = reaction.reject | |
, result, then; | |
try { | |
if(handler){ | |
if(!ok)record.h = true; | |
result = handler === true ? value : handler(value); | |
if(result === reaction.promise){ | |
reject(TypeError('Promise-chain cycle')); | |
} else if(then = isThenable(result)){ | |
then.call(result, resolve, reject); | |
} else resolve(result); | |
} else reject(value); | |
} catch(e){ | |
reject(e); | |
} | |
}; | |
while(chain.length > i)run(chain[i++]); // variable length - can't use forEach | |
chain.length = 0; | |
record.n = false; | |
if(isReject)setTimeout(function(){ | |
var promise = record.p | |
, handler, console; | |
if(isUnhandled(promise)){ | |
if(isNode){ | |
process.emit('unhandledRejection', value, promise); | |
} else if(handler = global.onunhandledrejection){ | |
handler({promise: promise, reason: value}); | |
} else if((console = global.console) && console.error){ | |
console.error('Unhandled promise rejection', value); | |
} | |
} record.a = undefined; | |
}, 1); | |
}); | |
}; | |
var isUnhandled = function(promise){ | |
var record = promise._d | |
, chain = record.a || record.c | |
, i = 0 | |
, reaction; | |
if(record.h)return false; | |
while(chain.length > i){ | |
reaction = chain[i++]; | |
if(reaction.fail || !isUnhandled(reaction.promise))return false; | |
} return true; | |
}; | |
var $reject = function(value){ | |
var record = this; | |
if(record.d)return; | |
record.d = true; | |
record = record.r || record; // unwrap | |
record.v = value; | |
record.s = 2; | |
record.a = record.c.slice(); | |
notify(record, true); | |
}; | |
var $resolve = function(value){ | |
var record = this | |
, then; | |
if(record.d)return; | |
record.d = true; | |
record = record.r || record; // unwrap | |
try { | |
if(record.p === value)throw TypeError("Promise can't be resolved itself"); | |
if(then = isThenable(value)){ | |
asap(function(){ | |
var wrapper = {r: record, d: false}; // wrap | |
try { | |
then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); | |
} catch(e){ | |
$reject.call(wrapper, e); | |
} | |
}); | |
} else { | |
record.v = value; | |
record.s = 1; | |
notify(record, false); | |
} | |
} catch(e){ | |
$reject.call({r: record, d: false}, e); // wrap | |
} | |
}; | |
// constructor polyfill | |
if(!USE_NATIVE){ | |
// 25.4.3.1 Promise(executor) | |
P = function Promise(executor){ | |
aFunction(executor); | |
var record = this._d = { | |
p: strictNew(this, P, PROMISE), // <- promise | |
c: [], // <- awaiting reactions | |
a: undefined, // <- checked in isUnhandled reactions | |
s: 0, // <- state | |
d: false, // <- done | |
v: undefined, // <- value | |
h: false, // <- handled rejection | |
n: false // <- notify | |
}; | |
try { | |
executor(ctx($resolve, record, 1), ctx($reject, record, 1)); | |
} catch(err){ | |
$reject.call(record, err); | |
} | |
}; | |
__webpack_require__(351)(P.prototype, { | |
// 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) | |
then: function then(onFulfilled, onRejected){ | |
var reaction = new PromiseCapability(speciesConstructor(this, P)) | |
, promise = reaction.promise | |
, record = this._d; | |
reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; | |
reaction.fail = typeof onRejected == 'function' && onRejected; | |
record.c.push(reaction); | |
if(record.a)record.a.push(reaction); | |
if(record.s)notify(record, false); | |
return promise; | |
}, | |
// 25.4.5.1 Promise.prototype.catch(onRejected) | |
'catch': function(onRejected){ | |
return this.then(undefined, onRejected); | |
} | |
}); | |
} | |
$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: P}); | |
__webpack_require__(294)(P, PROMISE); | |
__webpack_require__(352)(PROMISE); | |
Wrapper = __webpack_require__(238)[PROMISE]; | |
// statics | |
$export($export.S + $export.F * !USE_NATIVE, PROMISE, { | |
// 25.4.4.5 Promise.reject(r) | |
reject: function reject(r){ | |
var capability = new PromiseCapability(this) | |
, $$reject = capability.reject; | |
$$reject(r); | |
return capability.promise; | |
} | |
}); | |
$export($export.S + $export.F * (!USE_NATIVE || testResolve(true)), PROMISE, { | |
// 25.4.4.6 Promise.resolve(x) | |
resolve: function resolve(x){ | |
// instanceof instead of internal slot check because we should fix it without replacement native Promise core | |
if(x instanceof P && sameConstructor(x.constructor, this))return x; | |
var capability = new PromiseCapability(this) | |
, $$resolve = capability.resolve; | |
$$resolve(x); | |
return capability.promise; | |
} | |
}); | |
$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(332)(function(iter){ | |
P.all(iter)['catch'](function(){}); | |
})), PROMISE, { | |
// 25.4.4.1 Promise.all(iterable) | |
all: function all(iterable){ | |
var C = getConstructor(this) | |
, capability = new PromiseCapability(C) | |
, resolve = capability.resolve | |
, reject = capability.reject | |
, values = []; | |
var abrupt = perform(function(){ | |
forOf(iterable, false, values.push, values); | |
var remaining = values.length | |
, results = Array(remaining); | |
if(remaining)$.each.call(values, function(promise, index){ | |
var alreadyCalled = false; | |
C.resolve(promise).then(function(value){ | |
if(alreadyCalled)return; | |
alreadyCalled = true; | |
results[index] = value; | |
--remaining || resolve(results); | |
}, reject); | |
}); | |
else resolve(results); | |
}); | |
if(abrupt)reject(abrupt.error); | |
return capability.promise; | |
}, | |
// 25.4.4.4 Promise.race(iterable) | |
race: function race(iterable){ | |
var C = getConstructor(this) | |
, capability = new PromiseCapability(C) | |
, reject = capability.reject; | |
var abrupt = perform(function(){ | |
forOf(iterable, false, function(promise){ | |
C.resolve(promise).then(capability.resolve, reject); | |
}); | |
}); | |
if(abrupt)reject(abrupt.error); | |
return capability.promise; | |
} | |
}); | |
/***/ }, | |
/* 341 */ | |
/***/ function(module, exports) { | |
module.exports = function(it, Constructor, name){ | |
if(!(it instanceof Constructor))throw TypeError(name + ": use the 'new' operator!"); | |
return it; | |
}; | |
/***/ }, | |
/* 342 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var ctx = __webpack_require__(239) | |
, call = __webpack_require__(329) | |
, isArrayIter = __webpack_require__(330) | |
, anObject = __webpack_require__(302) | |
, toLength = __webpack_require__(331) | |
, getIterFn = __webpack_require__(303); | |
module.exports = function(iterable, entries, fn, that){ | |
var iterFn = getIterFn(iterable) | |
, f = ctx(fn, that, entries ? 2 : 1) | |
, index = 0 | |
, length, step, iterator; | |
if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!'); | |
// fast case for arrays with default iterator | |
if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){ | |
entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); | |
} else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){ | |
call(iterator, f, step.value, entries); | |
} | |
}; | |
/***/ }, | |
/* 343 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// Works with __proto__ only. Old v8 can't work with null proto objects. | |
/* eslint-disable no-proto */ | |
var getDesc = __webpack_require__(205).getDesc | |
, isObject = __webpack_require__(234) | |
, anObject = __webpack_require__(302); | |
var check = function(O, proto){ | |
anObject(O); | |
if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!"); | |
}; | |
module.exports = { | |
set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line | |
function(test, buggy, set){ | |
try { | |
set = __webpack_require__(239)(Function.call, getDesc(Object.prototype, '__proto__').set, 2); | |
set(test, []); | |
buggy = !(test instanceof Array); | |
} catch(e){ buggy = true; } | |
return function setPrototypeOf(O, proto){ | |
check(O, proto); | |
if(buggy)O.__proto__ = proto; | |
else set(O, proto); | |
return O; | |
}; | |
}({}, false) : undefined), | |
check: check | |
}; | |
/***/ }, | |
/* 344 */ | |
/***/ function(module, exports) { | |
// 7.2.9 SameValue(x, y) | |
module.exports = Object.is || function is(x, y){ | |
return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y; | |
}; | |
/***/ }, | |
/* 345 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// 7.3.20 SpeciesConstructor(O, defaultConstructor) | |
var anObject = __webpack_require__(302) | |
, aFunction = __webpack_require__(240) | |
, SPECIES = __webpack_require__(295)('species'); | |
module.exports = function(O, D){ | |
var C = anObject(O).constructor, S; | |
return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); | |
}; | |
/***/ }, | |
/* 346 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var global = __webpack_require__(237) | |
, macrotask = __webpack_require__(347).set | |
, Observer = global.MutationObserver || global.WebKitMutationObserver | |
, process = global.process | |
, Promise = global.Promise | |
, isNode = __webpack_require__(285)(process) == 'process' | |
, head, last, notify; | |
var flush = function(){ | |
var parent, domain, fn; | |
if(isNode && (parent = process.domain)){ | |
process.domain = null; | |
parent.exit(); | |
} | |
while(head){ | |
domain = head.domain; | |
fn = head.fn; | |
if(domain)domain.enter(); | |
fn(); // <- currently we use it only for Promise - try / catch not required | |
if(domain)domain.exit(); | |
head = head.next; | |
} last = undefined; | |
if(parent)parent.enter(); | |
}; | |
// Node.js | |
if(isNode){ | |
notify = function(){ | |
process.nextTick(flush); | |
}; | |
// browsers with MutationObserver | |
} else if(Observer){ | |
var toggle = 1 | |
, node = document.createTextNode(''); | |
new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new | |
notify = function(){ | |
node.data = toggle = -toggle; | |
}; | |
// environments with maybe non-completely correct, but existent Promise | |
} else if(Promise && Promise.resolve){ | |
notify = function(){ | |
Promise.resolve().then(flush); | |
}; | |
// for other environments - macrotask based on: | |
// - setImmediate | |
// - MessageChannel | |
// - window.postMessag | |
// - onreadystatechange | |
// - setTimeout | |
} else { | |
notify = function(){ | |
// strange IE + webpack dev server bug - use .call(global) | |
macrotask.call(global, flush); | |
}; | |
} | |
module.exports = function asap(fn){ | |
var task = {fn: fn, next: undefined, domain: isNode && process.domain}; | |
if(last)last.next = task; | |
if(!head){ | |
head = task; | |
notify(); | |
} last = task; | |
}; | |
/***/ }, | |
/* 347 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var ctx = __webpack_require__(239) | |
, invoke = __webpack_require__(348) | |
, html = __webpack_require__(349) | |
, cel = __webpack_require__(350) | |
, global = __webpack_require__(237) | |
, process = global.process | |
, setTask = global.setImmediate | |
, clearTask = global.clearImmediate | |
, MessageChannel = global.MessageChannel | |
, counter = 0 | |
, queue = {} | |
, ONREADYSTATECHANGE = 'onreadystatechange' | |
, defer, channel, port; | |
var run = function(){ | |
var id = +this; | |
if(queue.hasOwnProperty(id)){ | |
var fn = queue[id]; | |
delete queue[id]; | |
fn(); | |
} | |
}; | |
var listner = function(event){ | |
run.call(event.data); | |
}; | |
// Node.js 0.9+ & IE10+ has setImmediate, otherwise: | |
if(!setTask || !clearTask){ | |
setTask = function setImmediate(fn){ | |
var args = [], i = 1; | |
while(arguments.length > i)args.push(arguments[i++]); | |
queue[++counter] = function(){ | |
invoke(typeof fn == 'function' ? fn : Function(fn), args); | |
}; | |
defer(counter); | |
return counter; | |
}; | |
clearTask = function clearImmediate(id){ | |
delete queue[id]; | |
}; | |
// Node.js 0.8- | |
if(__webpack_require__(285)(process) == 'process'){ | |
defer = function(id){ | |
process.nextTick(ctx(run, id, 1)); | |
}; | |
// Browsers with MessageChannel, includes WebWorkers | |
} else if(MessageChannel){ | |
channel = new MessageChannel; | |
port = channel.port2; | |
channel.port1.onmessage = listner; | |
defer = ctx(port.postMessage, port, 1); | |
// Browsers with postMessage, skip WebWorkers | |
// IE8 has postMessage, but it's sync & typeof its postMessage is 'object' | |
} else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ | |
defer = function(id){ | |
global.postMessage(id + '', '*'); | |
}; | |
global.addEventListener('message', listner, false); | |
// IE8- | |
} else if(ONREADYSTATECHANGE in cel('script')){ | |
defer = function(id){ | |
html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ | |
html.removeChild(this); | |
run.call(id); | |
}; | |
}; | |
// Rest old browsers | |
} else { | |
defer = function(id){ | |
setTimeout(ctx(run, id, 1), 0); | |
}; | |
} | |
} | |
module.exports = { | |
set: setTask, | |
clear: clearTask | |
}; | |
/***/ }, | |
/* 348 */ | |
/***/ function(module, exports) { | |
// fast apply, http://jsperf.lnkit.com/fast-apply/5 | |
module.exports = function(fn, args, that){ | |
var un = that === undefined; | |
switch(args.length){ | |
case 0: return un ? fn() | |
: fn.call(that); | |
case 1: return un ? fn(args[0]) | |
: fn.call(that, args[0]); | |
case 2: return un ? fn(args[0], args[1]) | |
: fn.call(that, args[0], args[1]); | |
case 3: return un ? fn(args[0], args[1], args[2]) | |
: fn.call(that, args[0], args[1], args[2]); | |
case 4: return un ? fn(args[0], args[1], args[2], args[3]) | |
: fn.call(that, args[0], args[1], args[2], args[3]); | |
} return fn.apply(that, args); | |
}; | |
/***/ }, | |
/* 349 */ | |
/***/ function(module, exports, __webpack_require__) { | |
module.exports = __webpack_require__(237).document && document.documentElement; | |
/***/ }, | |
/* 350 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var isObject = __webpack_require__(234) | |
, document = __webpack_require__(237).document | |
// in old IE typeof document.createElement is 'object' | |
, is = isObject(document) && isObject(document.createElement); | |
module.exports = function(it){ | |
return is ? document.createElement(it) : {}; | |
}; | |
/***/ }, | |
/* 351 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var redefine = __webpack_require__(288); | |
module.exports = function(target, src){ | |
for(var key in src)redefine(target, key, src[key]); | |
return target; | |
}; | |
/***/ }, | |
/* 352 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var core = __webpack_require__(238) | |
, $ = __webpack_require__(205) | |
, DESCRIPTORS = __webpack_require__(291) | |
, SPECIES = __webpack_require__(295)('species'); | |
module.exports = function(KEY){ | |
var C = core[KEY]; | |
if(DESCRIPTORS && C && !C[SPECIES])$.setDesc(C, SPECIES, { | |
configurable: true, | |
get: function(){ return this; } | |
}); | |
}; | |
/***/ }, | |
/* 353 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(315); | |
__webpack_require__(216); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
__webpack_require__(315); | |
var module = __webpack_require__(216).get('discover/saved_searches', ['kibana/notify', 'kibana/courier']); | |
module.factory('SavedSearch', function (courier) { | |
_['class'](SavedSearch).inherits(courier.SavedObject); | |
function SavedSearch(id) { | |
courier.SavedObject.call(this, { | |
type: SavedSearch.type, | |
mapping: SavedSearch.mapping, | |
searchSource: SavedSearch.searchSource, | |
id: id, | |
defaults: { | |
title: 'New Saved Search', | |
description: '', | |
columns: [], | |
hits: 0, | |
sort: [], | |
version: 1 | |
} | |
}); | |
} | |
SavedSearch.type = 'search'; | |
SavedSearch.mapping = { | |
title: 'string', | |
description: 'string', | |
hits: 'long', | |
columns: 'string', | |
sort: 'string', | |
version: 'long' | |
}; | |
SavedSearch.searchSource = true; | |
return SavedSearch; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 354 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var registry = []; | |
return { | |
register: function register(service) { | |
registry.push(service); | |
}, | |
all: function all() { | |
return registry; | |
}, | |
get: function get(id) { | |
return _.find(registry, { service: id }); | |
} | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 355 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
__webpack_require__(216).get('apps/discover').directive('discoverTimechart', function (Private, $compile) { | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var vislib = Private(__webpack_require__(356)); | |
return { | |
restrict: 'E', | |
scope: { | |
data: '=' | |
}, | |
link: function link($scope, elem) { | |
var init = function init() { | |
// This elem should already have a height/width | |
var myChart = new vislib.Chart(elem[0], {}); | |
$scope.$watch('data', function (data) { | |
if (data != null) { | |
myChart.render(data); | |
} | |
}); | |
}; | |
// Start the directive | |
init(); | |
} | |
}; | |
}); | |
/***/ }, | |
/* 356 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// prefetched for faster optimization runs | |
'use strict'; | |
__webpack_require__(357); | |
__webpack_require__(407); | |
__webpack_require__(412); | |
__webpack_require__(413); | |
__webpack_require__(388); | |
__webpack_require__(361); | |
__webpack_require__(414); | |
__webpack_require__(427); | |
// end prefetching | |
/** | |
* Provides the Kibana4 Visualization Library | |
* | |
* @module vislib | |
* @main vislib | |
* @return {Object} Contains the version number and the Vis Class for creating visualizations | |
*/ | |
module.exports = function VislibProvider(Private) { | |
__webpack_require__(437); | |
return { | |
version: '0.0.0', | |
Vis: Private(__webpack_require__(438)) | |
}; | |
}; | |
/***/ }, | |
/* 357 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(358); | |
__webpack_require__(361); | |
__webpack_require__(399); | |
__webpack_require__(405); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function PieHandler(Private) { | |
var Handler = Private(__webpack_require__(358)); | |
var Data = Private(__webpack_require__(361)); | |
var Legend = Private(__webpack_require__(399)); | |
var ChartTitle = Private(__webpack_require__(405)); | |
/* | |
* Handler for Pie visualizations. | |
*/ | |
return function (vis) { | |
return new Handler(vis, { | |
legend: new Legend(vis), | |
chartTitle: new ChartTitle(vis.el) | |
}); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 358 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(222); | |
__webpack_require__(360); | |
__webpack_require__(361); | |
__webpack_require__(387); | |
__webpack_require__(399); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function HandlerBaseClass(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var errors = __webpack_require__(222); | |
var Binder = __webpack_require__(360); | |
var Data = Private(__webpack_require__(361)); | |
var Layout = Private(__webpack_require__(387)); | |
var Legend = Private(__webpack_require__(399)); | |
/** | |
* Handles building all the components of the visualization | |
* | |
* @class Handler | |
* @constructor | |
* @param vis {Object} Reference to the Vis Class Constructor | |
* @param opts {Object} Reference to Visualization constructors needed to | |
* create the visualization | |
*/ | |
function Handler(vis, opts) { | |
if (!(this instanceof Handler)) { | |
return new Handler(vis, opts); | |
} | |
this.data = opts.data || new Data(vis.data, vis._attr); | |
this.vis = vis; | |
this.el = vis.el; | |
this.ChartClass = vis.ChartClass; | |
this.charts = []; | |
this._attr = _.defaults(vis._attr || {}, { | |
'margin': { top: 10, right: 3, bottom: 5, left: 3 } | |
}); | |
this.xAxis = opts.xAxis; | |
this.yAxis = opts.yAxis; | |
this.chartTitle = opts.chartTitle; | |
this.axisTitle = opts.axisTitle; | |
this.alerts = opts.alerts; | |
if (this._attr.addLegend) { | |
this.legend = opts.legend; | |
} | |
this.layout = new Layout(vis.el, vis.data, vis._attr.type, opts); | |
this.binder = new Binder(); | |
this.renderArray = _.filter([this.layout, this.legend, this.axisTitle, this.chartTitle, this.alerts, this.xAxis, this.yAxis], Boolean); | |
// memoize so that the same function is returned every time, | |
// allowing us to remove/re-add the same function | |
this.getProxyHandler = _.memoize(function (event) { | |
var self = this; | |
return function (e) { | |
self.vis.emit(event, e); | |
}; | |
}); | |
} | |
/** | |
* Validates whether data is actually present in the data object | |
* used to render the Vis. Throws a no results error if data is not | |
* present. | |
* | |
* @private | |
*/ | |
Handler.prototype._validateData = function () { | |
var dataType = this.data.type; | |
if (!dataType) { | |
throw new errors.NoResults(); | |
} | |
}; | |
/** | |
* Renders the constructors that create the visualization, | |
* including the chart constructor | |
* | |
* @method render | |
* @returns {HTMLElement} With the visualization child element | |
*/ | |
Handler.prototype.render = function () { | |
var self = this; | |
var charts = this.charts = []; | |
var selection = d3.select(this.el); | |
selection.selectAll('*').remove(); | |
this._validateData(); | |
this.renderArray.forEach(function (property) { | |
if (property instanceof Legend) { | |
self.vis.activeEvents().forEach(function (event) { | |
self.enable(event, property); | |
}); | |
} | |
if (typeof property.render === 'function') { | |
property.render(); | |
} | |
}); | |
// render the chart(s) | |
selection.selectAll('.chart').each(function (chartData) { | |
var chart = new self.ChartClass(self, this, chartData); | |
self.vis.activeEvents().forEach(function (event) { | |
self.enable(event, chart); | |
}); | |
charts.push(chart); | |
chart.render(); | |
}); | |
}; | |
/** | |
* Enables events, i.e. binds specific events to the chart | |
* object(s) `on` method. For example, `click` or `mousedown` events. | |
* | |
* @method enable | |
* @param event {String} Event type | |
* @param chart {Object} Chart | |
* @returns {*} | |
*/ | |
Handler.prototype.enable = chartEventProxyToggle('on'); | |
/** | |
* Disables events for all charts | |
* | |
* @method disable | |
* @param event {String} Event type | |
* @param chart {Object} Chart | |
* @returns {*} | |
*/ | |
Handler.prototype.disable = chartEventProxyToggle('off'); | |
function chartEventProxyToggle(method) { | |
return function (event, chart) { | |
var proxyHandler = this.getProxyHandler(event); | |
_.each(chart ? [chart] : this.charts, function (chart) { | |
chart.events[method](event, proxyHandler); | |
}); | |
}; | |
} | |
/** | |
* Removes all DOM elements from the HTML element provided | |
* | |
* @method removeAll | |
* @param el {HTMLElement} Reference to the HTML Element that | |
* contains the chart | |
* @returns {D3.Selection|D3.Transition.Transition} With the chart | |
* child element removed | |
*/ | |
Handler.prototype.removeAll = function (el) { | |
return d3.select(el).selectAll('*').remove(); | |
}; | |
/** | |
* Displays an error message in the DOM | |
* | |
* @method error | |
* @param message {String} Error message to display | |
* @returns {HTMLElement} Displays the input message | |
*/ | |
Handler.prototype.error = function (message) { | |
this.removeAll(this.el); | |
var div = d3.select(this.el).append('div') | |
// class name needs `chart` in it for the polling checkSize function | |
// to continuously call render on resize | |
.attr('class', 'visualize-error chart error'); | |
if (message === 'No results found') { | |
div.append('div').attr('class', 'text-center visualize-error visualize-chart ng-scope').append('div').attr('class', 'item top').append('div').attr('class', 'item').append('h2').html('<i class="fa fa-meh-o"></i>').append('h4').text(message); | |
div.append('div').attr('class', 'item bottom'); | |
return div; | |
} | |
return div.append('h4').text(message); | |
}; | |
/** | |
* Destroys all the charts in the visualization | |
* | |
* @method destroy | |
*/ | |
Handler.prototype.destroy = function () { | |
this.binder.destroy(); | |
this.renderArray.forEach(function (renderable) { | |
if (_.isFunction(renderable.destroy)) { | |
renderable.destroy(); | |
} | |
}); | |
this.charts.splice(0).forEach(function (chart) { | |
if (_.isFunction(chart.destroy)) { | |
chart.destroy(); | |
} | |
}); | |
}; | |
return Handler; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 359 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;!function() { | |
var d3 = { | |
version: "3.5.6" | |
}; | |
var d3_arraySlice = [].slice, d3_array = function(list) { | |
return d3_arraySlice.call(list); | |
}; | |
var d3_document = this.document; | |
function d3_documentElement(node) { | |
return node && (node.ownerDocument || node.document || node).documentElement; | |
} | |
function d3_window(node) { | |
return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView); | |
} | |
if (d3_document) { | |
try { | |
d3_array(d3_document.documentElement.childNodes)[0].nodeType; | |
} catch (e) { | |
d3_array = function(list) { | |
var i = list.length, array = new Array(i); | |
while (i--) array[i] = list[i]; | |
return array; | |
}; | |
} | |
} | |
if (!Date.now) Date.now = function() { | |
return +new Date(); | |
}; | |
if (d3_document) { | |
try { | |
d3_document.createElement("DIV").style.setProperty("opacity", 0, ""); | |
} catch (error) { | |
var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; | |
d3_element_prototype.setAttribute = function(name, value) { | |
d3_element_setAttribute.call(this, name, value + ""); | |
}; | |
d3_element_prototype.setAttributeNS = function(space, local, value) { | |
d3_element_setAttributeNS.call(this, space, local, value + ""); | |
}; | |
d3_style_prototype.setProperty = function(name, value, priority) { | |
d3_style_setProperty.call(this, name, value + "", priority); | |
}; | |
} | |
} | |
d3.ascending = d3_ascending; | |
function d3_ascending(a, b) { | |
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; | |
} | |
d3.descending = function(a, b) { | |
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; | |
}; | |
d3.min = function(array, f) { | |
var i = -1, n = array.length, a, b; | |
if (arguments.length === 1) { | |
while (++i < n) if ((b = array[i]) != null && b >= b) { | |
a = b; | |
break; | |
} | |
while (++i < n) if ((b = array[i]) != null && a > b) a = b; | |
} else { | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { | |
a = b; | |
break; | |
} | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; | |
} | |
return a; | |
}; | |
d3.max = function(array, f) { | |
var i = -1, n = array.length, a, b; | |
if (arguments.length === 1) { | |
while (++i < n) if ((b = array[i]) != null && b >= b) { | |
a = b; | |
break; | |
} | |
while (++i < n) if ((b = array[i]) != null && b > a) a = b; | |
} else { | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { | |
a = b; | |
break; | |
} | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; | |
} | |
return a; | |
}; | |
d3.extent = function(array, f) { | |
var i = -1, n = array.length, a, b, c; | |
if (arguments.length === 1) { | |
while (++i < n) if ((b = array[i]) != null && b >= b) { | |
a = c = b; | |
break; | |
} | |
while (++i < n) if ((b = array[i]) != null) { | |
if (a > b) a = b; | |
if (c < b) c = b; | |
} | |
} else { | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { | |
a = c = b; | |
break; | |
} | |
while (++i < n) if ((b = f.call(array, array[i], i)) != null) { | |
if (a > b) a = b; | |
if (c < b) c = b; | |
} | |
} | |
return [ a, c ]; | |
}; | |
function d3_number(x) { | |
return x === null ? NaN : +x; | |
} | |
function d3_numeric(x) { | |
return !isNaN(x); | |
} | |
d3.sum = function(array, f) { | |
var s = 0, n = array.length, a, i = -1; | |
if (arguments.length === 1) { | |
while (++i < n) if (d3_numeric(a = +array[i])) s += a; | |
} else { | |
while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a; | |
} | |
return s; | |
}; | |
d3.mean = function(array, f) { | |
var s = 0, n = array.length, a, i = -1, j = n; | |
if (arguments.length === 1) { | |
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j; | |
} else { | |
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j; | |
} | |
if (j) return s / j; | |
}; | |
d3.quantile = function(values, p) { | |
var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; | |
return e ? v + e * (values[h] - v) : v; | |
}; | |
d3.median = function(array, f) { | |
var numbers = [], n = array.length, a, i = -1; | |
if (arguments.length === 1) { | |
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a); | |
} else { | |
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a); | |
} | |
if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5); | |
}; | |
d3.variance = function(array, f) { | |
var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0; | |
if (arguments.length === 1) { | |
while (++i < n) { | |
if (d3_numeric(a = d3_number(array[i]))) { | |
d = a - m; | |
m += d / ++j; | |
s += d * (a - m); | |
} | |
} | |
} else { | |
while (++i < n) { | |
if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) { | |
d = a - m; | |
m += d / ++j; | |
s += d * (a - m); | |
} | |
} | |
} | |
if (j > 1) return s / (j - 1); | |
}; | |
d3.deviation = function() { | |
var v = d3.variance.apply(this, arguments); | |
return v ? Math.sqrt(v) : v; | |
}; | |
function d3_bisector(compare) { | |
return { | |
left: function(a, x, lo, hi) { | |
if (arguments.length < 3) lo = 0; | |
if (arguments.length < 4) hi = a.length; | |
while (lo < hi) { | |
var mid = lo + hi >>> 1; | |
if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; | |
} | |
return lo; | |
}, | |
right: function(a, x, lo, hi) { | |
if (arguments.length < 3) lo = 0; | |
if (arguments.length < 4) hi = a.length; | |
while (lo < hi) { | |
var mid = lo + hi >>> 1; | |
if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; | |
} | |
return lo; | |
} | |
}; | |
} | |
var d3_bisect = d3_bisector(d3_ascending); | |
d3.bisectLeft = d3_bisect.left; | |
d3.bisect = d3.bisectRight = d3_bisect.right; | |
d3.bisector = function(f) { | |
return d3_bisector(f.length === 1 ? function(d, x) { | |
return d3_ascending(f(d), x); | |
} : f); | |
}; | |
d3.shuffle = function(array, i0, i1) { | |
if ((m = arguments.length) < 3) { | |
i1 = array.length; | |
if (m < 2) i0 = 0; | |
} | |
var m = i1 - i0, t, i; | |
while (m) { | |
i = Math.random() * m-- | 0; | |
t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t; | |
} | |
return array; | |
}; | |
d3.permute = function(array, indexes) { | |
var i = indexes.length, permutes = new Array(i); | |
while (i--) permutes[i] = array[indexes[i]]; | |
return permutes; | |
}; | |
d3.pairs = function(array) { | |
var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); | |
while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; | |
return pairs; | |
}; | |
d3.zip = function() { | |
if (!(n = arguments.length)) return []; | |
for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { | |
for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { | |
zip[j] = arguments[j][i]; | |
} | |
} | |
return zips; | |
}; | |
function d3_zipLength(d) { | |
return d.length; | |
} | |
d3.transpose = function(matrix) { | |
return d3.zip.apply(d3, matrix); | |
}; | |
d3.keys = function(map) { | |
var keys = []; | |
for (var key in map) keys.push(key); | |
return keys; | |
}; | |
d3.values = function(map) { | |
var values = []; | |
for (var key in map) values.push(map[key]); | |
return values; | |
}; | |
d3.entries = function(map) { | |
var entries = []; | |
for (var key in map) entries.push({ | |
key: key, | |
value: map[key] | |
}); | |
return entries; | |
}; | |
d3.merge = function(arrays) { | |
var n = arrays.length, m, i = -1, j = 0, merged, array; | |
while (++i < n) j += arrays[i].length; | |
merged = new Array(j); | |
while (--n >= 0) { | |
array = arrays[n]; | |
m = array.length; | |
while (--m >= 0) { | |
merged[--j] = array[m]; | |
} | |
} | |
return merged; | |
}; | |
var abs = Math.abs; | |
d3.range = function(start, stop, step) { | |
if (arguments.length < 3) { | |
step = 1; | |
if (arguments.length < 2) { | |
stop = start; | |
start = 0; | |
} | |
} | |
if ((stop - start) / step === Infinity) throw new Error("infinite range"); | |
var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; | |
start *= k, stop *= k, step *= k; | |
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); | |
return range; | |
}; | |
function d3_range_integerScale(x) { | |
var k = 1; | |
while (x * k % 1) k *= 10; | |
return k; | |
} | |
function d3_class(ctor, properties) { | |
for (var key in properties) { | |
Object.defineProperty(ctor.prototype, key, { | |
value: properties[key], | |
enumerable: false | |
}); | |
} | |
} | |
d3.map = function(object, f) { | |
var map = new d3_Map(); | |
if (object instanceof d3_Map) { | |
object.forEach(function(key, value) { | |
map.set(key, value); | |
}); | |
} else if (Array.isArray(object)) { | |
var i = -1, n = object.length, o; | |
if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o); | |
} else { | |
for (var key in object) map.set(key, object[key]); | |
} | |
return map; | |
}; | |
function d3_Map() { | |
this._ = Object.create(null); | |
} | |
var d3_map_proto = "__proto__", d3_map_zero = "\x00"; | |
d3_class(d3_Map, { | |
has: d3_map_has, | |
get: function(key) { | |
return this._[d3_map_escape(key)]; | |
}, | |
set: function(key, value) { | |
return this._[d3_map_escape(key)] = value; | |
}, | |
remove: d3_map_remove, | |
keys: d3_map_keys, | |
values: function() { | |
var values = []; | |
for (var key in this._) values.push(this._[key]); | |
return values; | |
}, | |
entries: function() { | |
var entries = []; | |
for (var key in this._) entries.push({ | |
key: d3_map_unescape(key), | |
value: this._[key] | |
}); | |
return entries; | |
}, | |
size: d3_map_size, | |
empty: d3_map_empty, | |
forEach: function(f) { | |
for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]); | |
} | |
}); | |
function d3_map_escape(key) { | |
return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key; | |
} | |
function d3_map_unescape(key) { | |
return (key += "")[0] === d3_map_zero ? key.slice(1) : key; | |
} | |
function d3_map_has(key) { | |
return d3_map_escape(key) in this._; | |
} | |
function d3_map_remove(key) { | |
return (key = d3_map_escape(key)) in this._ && delete this._[key]; | |
} | |
function d3_map_keys() { | |
var keys = []; | |
for (var key in this._) keys.push(d3_map_unescape(key)); | |
return keys; | |
} | |
function d3_map_size() { | |
var size = 0; | |
for (var key in this._) ++size; | |
return size; | |
} | |
function d3_map_empty() { | |
for (var key in this._) return false; | |
return true; | |
} | |
d3.nest = function() { | |
var nest = {}, keys = [], sortKeys = [], sortValues, rollup; | |
function map(mapType, array, depth) { | |
if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; | |
var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; | |
while (++i < n) { | |
if (values = valuesByKey.get(keyValue = key(object = array[i]))) { | |
values.push(object); | |
} else { | |
valuesByKey.set(keyValue, [ object ]); | |
} | |
} | |
if (mapType) { | |
object = mapType(); | |
setter = function(keyValue, values) { | |
object.set(keyValue, map(mapType, values, depth)); | |
}; | |
} else { | |
object = {}; | |
setter = function(keyValue, values) { | |
object[keyValue] = map(mapType, values, depth); | |
}; | |
} | |
valuesByKey.forEach(setter); | |
return object; | |
} | |
function entries(map, depth) { | |
if (depth >= keys.length) return map; | |
var array = [], sortKey = sortKeys[depth++]; | |
map.forEach(function(key, keyMap) { | |
array.push({ | |
key: key, | |
values: entries(keyMap, depth) | |
}); | |
}); | |
return sortKey ? array.sort(function(a, b) { | |
return sortKey(a.key, b.key); | |
}) : array; | |
} | |
nest.map = function(array, mapType) { | |
return map(mapType, array, 0); | |
}; | |
nest.entries = function(array) { | |
return entries(map(d3.map, array, 0), 0); | |
}; | |
nest.key = function(d) { | |
keys.push(d); | |
return nest; | |
}; | |
nest.sortKeys = function(order) { | |
sortKeys[keys.length - 1] = order; | |
return nest; | |
}; | |
nest.sortValues = function(order) { | |
sortValues = order; | |
return nest; | |
}; | |
nest.rollup = function(f) { | |
rollup = f; | |
return nest; | |
}; | |
return nest; | |
}; | |
d3.set = function(array) { | |
var set = new d3_Set(); | |
if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); | |
return set; | |
}; | |
function d3_Set() { | |
this._ = Object.create(null); | |
} | |
d3_class(d3_Set, { | |
has: d3_map_has, | |
add: function(key) { | |
this._[d3_map_escape(key += "")] = true; | |
return key; | |
}, | |
remove: d3_map_remove, | |
values: d3_map_keys, | |
size: d3_map_size, | |
empty: d3_map_empty, | |
forEach: function(f) { | |
for (var key in this._) f.call(this, d3_map_unescape(key)); | |
} | |
}); | |
d3.behavior = {}; | |
function d3_identity(d) { | |
return d; | |
} | |
d3.rebind = function(target, source) { | |
var i = 1, n = arguments.length, method; | |
while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); | |
return target; | |
}; | |
function d3_rebind(target, source, method) { | |
return function() { | |
var value = method.apply(source, arguments); | |
return value === source ? target : value; | |
}; | |
} | |
function d3_vendorSymbol(object, name) { | |
if (name in object) return name; | |
name = name.charAt(0).toUpperCase() + name.slice(1); | |
for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { | |
var prefixName = d3_vendorPrefixes[i] + name; | |
if (prefixName in object) return prefixName; | |
} | |
} | |
var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; | |
function d3_noop() {} | |
d3.dispatch = function() { | |
var dispatch = new d3_dispatch(), i = -1, n = arguments.length; | |
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); | |
return dispatch; | |
}; | |
function d3_dispatch() {} | |
d3_dispatch.prototype.on = function(type, listener) { | |
var i = type.indexOf("."), name = ""; | |
if (i >= 0) { | |
name = type.slice(i + 1); | |
type = type.slice(0, i); | |
} | |
if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); | |
if (arguments.length === 2) { | |
if (listener == null) for (type in this) { | |
if (this.hasOwnProperty(type)) this[type].on(name, null); | |
} | |
return this; | |
} | |
}; | |
function d3_dispatch_event(dispatch) { | |
var listeners = [], listenerByName = new d3_Map(); | |
function event() { | |
var z = listeners, i = -1, n = z.length, l; | |
while (++i < n) if (l = z[i].on) l.apply(this, arguments); | |
return dispatch; | |
} | |
event.on = function(name, listener) { | |
var l = listenerByName.get(name), i; | |
if (arguments.length < 2) return l && l.on; | |
if (l) { | |
l.on = null; | |
listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); | |
listenerByName.remove(name); | |
} | |
if (listener) listeners.push(listenerByName.set(name, { | |
on: listener | |
})); | |
return dispatch; | |
}; | |
return event; | |
} | |
d3.event = null; | |
function d3_eventPreventDefault() { | |
d3.event.preventDefault(); | |
} | |
function d3_eventSource() { | |
var e = d3.event, s; | |
while (s = e.sourceEvent) e = s; | |
return e; | |
} | |
function d3_eventDispatch(target) { | |
var dispatch = new d3_dispatch(), i = 0, n = arguments.length; | |
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); | |
dispatch.of = function(thiz, argumentz) { | |
return function(e1) { | |
try { | |
var e0 = e1.sourceEvent = d3.event; | |
e1.target = target; | |
d3.event = e1; | |
dispatch[e1.type].apply(thiz, argumentz); | |
} finally { | |
d3.event = e0; | |
} | |
}; | |
}; | |
return dispatch; | |
} | |
d3.requote = function(s) { | |
return s.replace(d3_requote_re, "\\$&"); | |
}; | |
var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; | |
var d3_subclass = {}.__proto__ ? function(object, prototype) { | |
object.__proto__ = prototype; | |
} : function(object, prototype) { | |
for (var property in prototype) object[property] = prototype[property]; | |
}; | |
function d3_selection(groups) { | |
d3_subclass(groups, d3_selectionPrototype); | |
return groups; | |
} | |
var d3_select = function(s, n) { | |
return n.querySelector(s); | |
}, d3_selectAll = function(s, n) { | |
return n.querySelectorAll(s); | |
}, d3_selectMatches = function(n, s) { | |
var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, "matchesSelector")]; | |
d3_selectMatches = function(n, s) { | |
return d3_selectMatcher.call(n, s); | |
}; | |
return d3_selectMatches(n, s); | |
}; | |
if (typeof Sizzle === "function") { | |
d3_select = function(s, n) { | |
return Sizzle(s, n)[0] || null; | |
}; | |
d3_selectAll = Sizzle; | |
d3_selectMatches = Sizzle.matchesSelector; | |
} | |
d3.selection = function() { | |
return d3.select(d3_document.documentElement); | |
}; | |
var d3_selectionPrototype = d3.selection.prototype = []; | |
d3_selectionPrototype.select = function(selector) { | |
var subgroups = [], subgroup, subnode, group, node; | |
selector = d3_selection_selector(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
subgroups.push(subgroup = []); | |
subgroup.parentNode = (group = this[j]).parentNode; | |
for (var i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
subgroup.push(subnode = selector.call(node, node.__data__, i, j)); | |
if (subnode && "__data__" in node) subnode.__data__ = node.__data__; | |
} else { | |
subgroup.push(null); | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
function d3_selection_selector(selector) { | |
return typeof selector === "function" ? selector : function() { | |
return d3_select(selector, this); | |
}; | |
} | |
d3_selectionPrototype.selectAll = function(selector) { | |
var subgroups = [], subgroup, node; | |
selector = d3_selection_selectorAll(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); | |
subgroup.parentNode = node; | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
function d3_selection_selectorAll(selector) { | |
return typeof selector === "function" ? selector : function() { | |
return d3_selectAll(selector, this); | |
}; | |
} | |
var d3_nsPrefix = { | |
svg: "http://www.w3.org/2000/svg", | |
xhtml: "http://www.w3.org/1999/xhtml", | |
xlink: "http://www.w3.org/1999/xlink", | |
xml: "http://www.w3.org/XML/1998/namespace", | |
xmlns: "http://www.w3.org/2000/xmlns/" | |
}; | |
d3.ns = { | |
prefix: d3_nsPrefix, | |
qualify: function(name) { | |
var i = name.indexOf(":"), prefix = name; | |
if (i >= 0) { | |
prefix = name.slice(0, i); | |
name = name.slice(i + 1); | |
} | |
return d3_nsPrefix.hasOwnProperty(prefix) ? { | |
space: d3_nsPrefix[prefix], | |
local: name | |
} : name; | |
} | |
}; | |
d3_selectionPrototype.attr = function(name, value) { | |
if (arguments.length < 2) { | |
if (typeof name === "string") { | |
var node = this.node(); | |
name = d3.ns.qualify(name); | |
return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); | |
} | |
for (value in name) this.each(d3_selection_attr(value, name[value])); | |
return this; | |
} | |
return this.each(d3_selection_attr(name, value)); | |
}; | |
function d3_selection_attr(name, value) { | |
name = d3.ns.qualify(name); | |
function attrNull() { | |
this.removeAttribute(name); | |
} | |
function attrNullNS() { | |
this.removeAttributeNS(name.space, name.local); | |
} | |
function attrConstant() { | |
this.setAttribute(name, value); | |
} | |
function attrConstantNS() { | |
this.setAttributeNS(name.space, name.local, value); | |
} | |
function attrFunction() { | |
var x = value.apply(this, arguments); | |
if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); | |
} | |
function attrFunctionNS() { | |
var x = value.apply(this, arguments); | |
if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); | |
} | |
return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; | |
} | |
function d3_collapse(s) { | |
return s.trim().replace(/\s+/g, " "); | |
} | |
d3_selectionPrototype.classed = function(name, value) { | |
if (arguments.length < 2) { | |
if (typeof name === "string") { | |
var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; | |
if (value = node.classList) { | |
while (++i < n) if (!value.contains(name[i])) return false; | |
} else { | |
value = node.getAttribute("class"); | |
while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; | |
} | |
return true; | |
} | |
for (value in name) this.each(d3_selection_classed(value, name[value])); | |
return this; | |
} | |
return this.each(d3_selection_classed(name, value)); | |
}; | |
function d3_selection_classedRe(name) { | |
return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); | |
} | |
function d3_selection_classes(name) { | |
return (name + "").trim().split(/^|\s+/); | |
} | |
function d3_selection_classed(name, value) { | |
name = d3_selection_classes(name).map(d3_selection_classedName); | |
var n = name.length; | |
function classedConstant() { | |
var i = -1; | |
while (++i < n) name[i](this, value); | |
} | |
function classedFunction() { | |
var i = -1, x = value.apply(this, arguments); | |
while (++i < n) name[i](this, x); | |
} | |
return typeof value === "function" ? classedFunction : classedConstant; | |
} | |
function d3_selection_classedName(name) { | |
var re = d3_selection_classedRe(name); | |
return function(node, value) { | |
if (c = node.classList) return value ? c.add(name) : c.remove(name); | |
var c = node.getAttribute("class") || ""; | |
if (value) { | |
re.lastIndex = 0; | |
if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); | |
} else { | |
node.setAttribute("class", d3_collapse(c.replace(re, " "))); | |
} | |
}; | |
} | |
d3_selectionPrototype.style = function(name, value, priority) { | |
var n = arguments.length; | |
if (n < 3) { | |
if (typeof name !== "string") { | |
if (n < 2) value = ""; | |
for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); | |
return this; | |
} | |
if (n < 2) { | |
var node = this.node(); | |
return d3_window(node).getComputedStyle(node, null).getPropertyValue(name); | |
} | |
priority = ""; | |
} | |
return this.each(d3_selection_style(name, value, priority)); | |
}; | |
function d3_selection_style(name, value, priority) { | |
function styleNull() { | |
this.style.removeProperty(name); | |
} | |
function styleConstant() { | |
this.style.setProperty(name, value, priority); | |
} | |
function styleFunction() { | |
var x = value.apply(this, arguments); | |
if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); | |
} | |
return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; | |
} | |
d3_selectionPrototype.property = function(name, value) { | |
if (arguments.length < 2) { | |
if (typeof name === "string") return this.node()[name]; | |
for (value in name) this.each(d3_selection_property(value, name[value])); | |
return this; | |
} | |
return this.each(d3_selection_property(name, value)); | |
}; | |
function d3_selection_property(name, value) { | |
function propertyNull() { | |
delete this[name]; | |
} | |
function propertyConstant() { | |
this[name] = value; | |
} | |
function propertyFunction() { | |
var x = value.apply(this, arguments); | |
if (x == null) delete this[name]; else this[name] = x; | |
} | |
return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; | |
} | |
d3_selectionPrototype.text = function(value) { | |
return arguments.length ? this.each(typeof value === "function" ? function() { | |
var v = value.apply(this, arguments); | |
this.textContent = v == null ? "" : v; | |
} : value == null ? function() { | |
this.textContent = ""; | |
} : function() { | |
this.textContent = value; | |
}) : this.node().textContent; | |
}; | |
d3_selectionPrototype.html = function(value) { | |
return arguments.length ? this.each(typeof value === "function" ? function() { | |
var v = value.apply(this, arguments); | |
this.innerHTML = v == null ? "" : v; | |
} : value == null ? function() { | |
this.innerHTML = ""; | |
} : function() { | |
this.innerHTML = value; | |
}) : this.node().innerHTML; | |
}; | |
d3_selectionPrototype.append = function(name) { | |
name = d3_selection_creator(name); | |
return this.select(function() { | |
return this.appendChild(name.apply(this, arguments)); | |
}); | |
}; | |
function d3_selection_creator(name) { | |
function create() { | |
var document = this.ownerDocument, namespace = this.namespaceURI; | |
return namespace ? document.createElementNS(namespace, name) : document.createElement(name); | |
} | |
function createNS() { | |
return this.ownerDocument.createElementNS(name.space, name.local); | |
} | |
return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? createNS : create; | |
} | |
d3_selectionPrototype.insert = function(name, before) { | |
name = d3_selection_creator(name); | |
before = d3_selection_selector(before); | |
return this.select(function() { | |
return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); | |
}); | |
}; | |
d3_selectionPrototype.remove = function() { | |
return this.each(d3_selectionRemove); | |
}; | |
function d3_selectionRemove() { | |
var parent = this.parentNode; | |
if (parent) parent.removeChild(this); | |
} | |
d3_selectionPrototype.data = function(value, key) { | |
var i = -1, n = this.length, group, node; | |
if (!arguments.length) { | |
value = new Array(n = (group = this[0]).length); | |
while (++i < n) { | |
if (node = group[i]) { | |
value[i] = node.__data__; | |
} | |
} | |
return value; | |
} | |
function bind(group, groupData) { | |
var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; | |
if (key) { | |
var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue; | |
for (i = -1; ++i < n; ) { | |
if (nodeByKeyValue.has(keyValue = key.call(node = group[i], node.__data__, i))) { | |
exitNodes[i] = node; | |
} else { | |
nodeByKeyValue.set(keyValue, node); | |
} | |
keyValues[i] = keyValue; | |
} | |
for (i = -1; ++i < m; ) { | |
if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) { | |
enterNodes[i] = d3_selection_dataNode(nodeData); | |
} else if (node !== true) { | |
updateNodes[i] = node; | |
node.__data__ = nodeData; | |
} | |
nodeByKeyValue.set(keyValue, true); | |
} | |
for (i = -1; ++i < n; ) { | |
if (nodeByKeyValue.get(keyValues[i]) !== true) { | |
exitNodes[i] = group[i]; | |
} | |
} | |
} else { | |
for (i = -1; ++i < n0; ) { | |
node = group[i]; | |
nodeData = groupData[i]; | |
if (node) { | |
node.__data__ = nodeData; | |
updateNodes[i] = node; | |
} else { | |
enterNodes[i] = d3_selection_dataNode(nodeData); | |
} | |
} | |
for (;i < m; ++i) { | |
enterNodes[i] = d3_selection_dataNode(groupData[i]); | |
} | |
for (;i < n; ++i) { | |
exitNodes[i] = group[i]; | |
} | |
} | |
enterNodes.update = updateNodes; | |
enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; | |
enter.push(enterNodes); | |
update.push(updateNodes); | |
exit.push(exitNodes); | |
} | |
var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); | |
if (typeof value === "function") { | |
while (++i < n) { | |
bind(group = this[i], value.call(group, group.parentNode.__data__, i)); | |
} | |
} else { | |
while (++i < n) { | |
bind(group = this[i], value); | |
} | |
} | |
update.enter = function() { | |
return enter; | |
}; | |
update.exit = function() { | |
return exit; | |
}; | |
return update; | |
}; | |
function d3_selection_dataNode(data) { | |
return { | |
__data__: data | |
}; | |
} | |
d3_selectionPrototype.datum = function(value) { | |
return arguments.length ? this.property("__data__", value) : this.property("__data__"); | |
}; | |
d3_selectionPrototype.filter = function(filter) { | |
var subgroups = [], subgroup, group, node; | |
if (typeof filter !== "function") filter = d3_selection_filter(filter); | |
for (var j = 0, m = this.length; j < m; j++) { | |
subgroups.push(subgroup = []); | |
subgroup.parentNode = (group = this[j]).parentNode; | |
for (var i = 0, n = group.length; i < n; i++) { | |
if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { | |
subgroup.push(node); | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
function d3_selection_filter(selector) { | |
return function() { | |
return d3_selectMatches(this, selector); | |
}; | |
} | |
d3_selectionPrototype.order = function() { | |
for (var j = -1, m = this.length; ++j < m; ) { | |
for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { | |
if (node = group[i]) { | |
if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); | |
next = node; | |
} | |
} | |
} | |
return this; | |
}; | |
d3_selectionPrototype.sort = function(comparator) { | |
comparator = d3_selection_sortComparator.apply(this, arguments); | |
for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); | |
return this.order(); | |
}; | |
function d3_selection_sortComparator(comparator) { | |
if (!arguments.length) comparator = d3_ascending; | |
return function(a, b) { | |
return a && b ? comparator(a.__data__, b.__data__) : !a - !b; | |
}; | |
} | |
d3_selectionPrototype.each = function(callback) { | |
return d3_selection_each(this, function(node, i, j) { | |
callback.call(node, node.__data__, i, j); | |
}); | |
}; | |
function d3_selection_each(groups, callback) { | |
for (var j = 0, m = groups.length; j < m; j++) { | |
for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { | |
if (node = group[i]) callback(node, i, j); | |
} | |
} | |
return groups; | |
} | |
d3_selectionPrototype.call = function(callback) { | |
var args = d3_array(arguments); | |
callback.apply(args[0] = this, args); | |
return this; | |
}; | |
d3_selectionPrototype.empty = function() { | |
return !this.node(); | |
}; | |
d3_selectionPrototype.node = function() { | |
for (var j = 0, m = this.length; j < m; j++) { | |
for (var group = this[j], i = 0, n = group.length; i < n; i++) { | |
var node = group[i]; | |
if (node) return node; | |
} | |
} | |
return null; | |
}; | |
d3_selectionPrototype.size = function() { | |
var n = 0; | |
d3_selection_each(this, function() { | |
++n; | |
}); | |
return n; | |
}; | |
function d3_selection_enter(selection) { | |
d3_subclass(selection, d3_selection_enterPrototype); | |
return selection; | |
} | |
var d3_selection_enterPrototype = []; | |
d3.selection.enter = d3_selection_enter; | |
d3.selection.enter.prototype = d3_selection_enterPrototype; | |
d3_selection_enterPrototype.append = d3_selectionPrototype.append; | |
d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; | |
d3_selection_enterPrototype.node = d3_selectionPrototype.node; | |
d3_selection_enterPrototype.call = d3_selectionPrototype.call; | |
d3_selection_enterPrototype.size = d3_selectionPrototype.size; | |
d3_selection_enterPrototype.select = function(selector) { | |
var subgroups = [], subgroup, subnode, upgroup, group, node; | |
for (var j = -1, m = this.length; ++j < m; ) { | |
upgroup = (group = this[j]).update; | |
subgroups.push(subgroup = []); | |
subgroup.parentNode = group.parentNode; | |
for (var i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); | |
subnode.__data__ = node.__data__; | |
} else { | |
subgroup.push(null); | |
} | |
} | |
} | |
return d3_selection(subgroups); | |
}; | |
d3_selection_enterPrototype.insert = function(name, before) { | |
if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); | |
return d3_selectionPrototype.insert.call(this, name, before); | |
}; | |
function d3_selection_enterInsertBefore(enter) { | |
var i0, j0; | |
return function(d, i, j) { | |
var group = enter[j].update, n = group.length, node; | |
if (j != j0) j0 = j, i0 = 0; | |
if (i >= i0) i0 = i + 1; | |
while (!(node = group[i0]) && ++i0 < n) ; | |
return node; | |
}; | |
} | |
d3.select = function(node) { | |
var group; | |
if (typeof node === "string") { | |
group = [ d3_select(node, d3_document) ]; | |
group.parentNode = d3_document.documentElement; | |
} else { | |
group = [ node ]; | |
group.parentNode = d3_documentElement(node); | |
} | |
return d3_selection([ group ]); | |
}; | |
d3.selectAll = function(nodes) { | |
var group; | |
if (typeof nodes === "string") { | |
group = d3_array(d3_selectAll(nodes, d3_document)); | |
group.parentNode = d3_document.documentElement; | |
} else { | |
group = nodes; | |
group.parentNode = null; | |
} | |
return d3_selection([ group ]); | |
}; | |
d3_selectionPrototype.on = function(type, listener, capture) { | |
var n = arguments.length; | |
if (n < 3) { | |
if (typeof type !== "string") { | |
if (n < 2) listener = false; | |
for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); | |
return this; | |
} | |
if (n < 2) return (n = this.node()["__on" + type]) && n._; | |
capture = false; | |
} | |
return this.each(d3_selection_on(type, listener, capture)); | |
}; | |
function d3_selection_on(type, listener, capture) { | |
var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; | |
if (i > 0) type = type.slice(0, i); | |
var filter = d3_selection_onFilters.get(type); | |
if (filter) type = filter, wrap = d3_selection_onFilter; | |
function onRemove() { | |
var l = this[name]; | |
if (l) { | |
this.removeEventListener(type, l, l.$); | |
delete this[name]; | |
} | |
} | |
function onAdd() { | |
var l = wrap(listener, d3_array(arguments)); | |
onRemove.call(this); | |
this.addEventListener(type, this[name] = l, l.$ = capture); | |
l._ = listener; | |
} | |
function removeAll() { | |
var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; | |
for (var name in this) { | |
if (match = name.match(re)) { | |
var l = this[name]; | |
this.removeEventListener(match[1], l, l.$); | |
delete this[name]; | |
} | |
} | |
} | |
return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; | |
} | |
var d3_selection_onFilters = d3.map({ | |
mouseenter: "mouseover", | |
mouseleave: "mouseout" | |
}); | |
if (d3_document) { | |
d3_selection_onFilters.forEach(function(k) { | |
if ("on" + k in d3_document) d3_selection_onFilters.remove(k); | |
}); | |
} | |
function d3_selection_onListener(listener, argumentz) { | |
return function(e) { | |
var o = d3.event; | |
d3.event = e; | |
argumentz[0] = this.__data__; | |
try { | |
listener.apply(this, argumentz); | |
} finally { | |
d3.event = o; | |
} | |
}; | |
} | |
function d3_selection_onFilter(listener, argumentz) { | |
var l = d3_selection_onListener(listener, argumentz); | |
return function(e) { | |
var target = this, related = e.relatedTarget; | |
if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { | |
l.call(target, e); | |
} | |
}; | |
} | |
var d3_event_dragSelect, d3_event_dragId = 0; | |
function d3_event_dragSuppress(node) { | |
var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window(node)).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); | |
if (d3_event_dragSelect == null) { | |
d3_event_dragSelect = "onselectstart" in node ? false : d3_vendorSymbol(node.style, "userSelect"); | |
} | |
if (d3_event_dragSelect) { | |
var style = d3_documentElement(node).style, select = style[d3_event_dragSelect]; | |
style[d3_event_dragSelect] = "none"; | |
} | |
return function(suppressClick) { | |
w.on(name, null); | |
if (d3_event_dragSelect) style[d3_event_dragSelect] = select; | |
if (suppressClick) { | |
var off = function() { | |
w.on(click, null); | |
}; | |
w.on(click, function() { | |
d3_eventPreventDefault(); | |
off(); | |
}, true); | |
setTimeout(off, 0); | |
} | |
}; | |
} | |
d3.mouse = function(container) { | |
return d3_mousePoint(container, d3_eventSource()); | |
}; | |
var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0; | |
function d3_mousePoint(container, e) { | |
if (e.changedTouches) e = e.changedTouches[0]; | |
var svg = container.ownerSVGElement || container; | |
if (svg.createSVGPoint) { | |
var point = svg.createSVGPoint(); | |
if (d3_mouse_bug44083 < 0) { | |
var window = d3_window(container); | |
if (window.scrollX || window.scrollY) { | |
svg = d3.select("body").append("svg").style({ | |
position: "absolute", | |
top: 0, | |
left: 0, | |
margin: 0, | |
padding: 0, | |
border: "none" | |
}, "important"); | |
var ctm = svg[0][0].getScreenCTM(); | |
d3_mouse_bug44083 = !(ctm.f || ctm.e); | |
svg.remove(); | |
} | |
} | |
if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, | |
point.y = e.clientY; | |
point = point.matrixTransform(container.getScreenCTM().inverse()); | |
return [ point.x, point.y ]; | |
} | |
var rect = container.getBoundingClientRect(); | |
return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; | |
} | |
d3.touch = function(container, touches, identifier) { | |
if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches; | |
if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) { | |
if ((touch = touches[i]).identifier === identifier) { | |
return d3_mousePoint(container, touch); | |
} | |
} | |
}; | |
d3.behavior.drag = function() { | |
var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, "touchmove", "touchend"); | |
function drag() { | |
this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); | |
} | |
function dragstart(id, position, subject, move, end) { | |
return function() { | |
var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId); | |
if (origin) { | |
dragOffset = origin.apply(that, arguments); | |
dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ]; | |
} else { | |
dragOffset = [ 0, 0 ]; | |
} | |
dispatch({ | |
type: "dragstart" | |
}); | |
function moved() { | |
var position1 = position(parent, dragId), dx, dy; | |
if (!position1) return; | |
dx = position1[0] - position0[0]; | |
dy = position1[1] - position0[1]; | |
dragged |= dx | dy; | |
position0 = position1; | |
dispatch({ | |
type: "drag", | |
x: position1[0] + dragOffset[0], | |
y: position1[1] + dragOffset[1], | |
dx: dx, | |
dy: dy | |
}); | |
} | |
function ended() { | |
if (!position(parent, dragId)) return; | |
dragSubject.on(move + dragName, null).on(end + dragName, null); | |
dragRestore(dragged && d3.event.target === target); | |
dispatch({ | |
type: "dragend" | |
}); | |
} | |
}; | |
} | |
drag.origin = function(x) { | |
if (!arguments.length) return origin; | |
origin = x; | |
return drag; | |
}; | |
return d3.rebind(drag, event, "on"); | |
}; | |
function d3_behavior_dragTouchId() { | |
return d3.event.changedTouches[0].identifier; | |
} | |
d3.touches = function(container, touches) { | |
if (arguments.length < 2) touches = d3_eventSource().touches; | |
return touches ? d3_array(touches).map(function(touch) { | |
var point = d3_mousePoint(container, touch); | |
point.identifier = touch.identifier; | |
return point; | |
}) : []; | |
}; | |
var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π; | |
function d3_sgn(x) { | |
return x > 0 ? 1 : x < 0 ? -1 : 0; | |
} | |
function d3_cross2d(a, b, c) { | |
return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); | |
} | |
function d3_acos(x) { | |
return x > 1 ? 0 : x < -1 ? π : Math.acos(x); | |
} | |
function d3_asin(x) { | |
return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x); | |
} | |
function d3_sinh(x) { | |
return ((x = Math.exp(x)) - 1 / x) / 2; | |
} | |
function d3_cosh(x) { | |
return ((x = Math.exp(x)) + 1 / x) / 2; | |
} | |
function d3_tanh(x) { | |
return ((x = Math.exp(2 * x)) - 1) / (x + 1); | |
} | |
function d3_haversin(x) { | |
return (x = Math.sin(x / 2)) * x; | |
} | |
var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; | |
d3.interpolateZoom = function(p0, p1) { | |
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; | |
var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ; | |
function interpolate(t) { | |
var s = t * S; | |
if (dr) { | |
var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); | |
return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; | |
} | |
return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ]; | |
} | |
interpolate.duration = S * 1e3; | |
return interpolate; | |
}; | |
d3.behavior.zoom = function() { | |
var view = { | |
x: 0, | |
y: 0, | |
k: 1 | |
}, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; | |
if (!d3_behavior_zoomWheel) { | |
d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { | |
return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); | |
}, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { | |
return d3.event.wheelDelta; | |
}, "mousewheel") : (d3_behavior_zoomDelta = function() { | |
return -d3.event.detail; | |
}, "MozMousePixelScroll"); | |
} | |
function zoom(g) { | |
g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); | |
} | |
zoom.event = function(g) { | |
g.each(function() { | |
var dispatch = event.of(this, arguments), view1 = view; | |
if (d3_transitionInheritId) { | |
d3.select(this).transition().each("start.zoom", function() { | |
view = this.__chart__ || { | |
x: 0, | |
y: 0, | |
k: 1 | |
}; | |
zoomstarted(dispatch); | |
}).tween("zoom:zoom", function() { | |
var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); | |
return function(t) { | |
var l = i(t), k = dx / l[2]; | |
this.__chart__ = view = { | |
x: cx - l[0] * k, | |
y: cy - l[1] * k, | |
k: k | |
}; | |
zoomed(dispatch); | |
}; | |
}).each("interrupt.zoom", function() { | |
zoomended(dispatch); | |
}).each("end.zoom", function() { | |
zoomended(dispatch); | |
}); | |
} else { | |
this.__chart__ = view; | |
zoomstarted(dispatch); | |
zoomed(dispatch); | |
zoomended(dispatch); | |
} | |
}); | |
}; | |
zoom.translate = function(_) { | |
if (!arguments.length) return [ view.x, view.y ]; | |
view = { | |
x: +_[0], | |
y: +_[1], | |
k: view.k | |
}; | |
rescale(); | |
return zoom; | |
}; | |
zoom.scale = function(_) { | |
if (!arguments.length) return view.k; | |
view = { | |
x: view.x, | |
y: view.y, | |
k: +_ | |
}; | |
rescale(); | |
return zoom; | |
}; | |
zoom.scaleExtent = function(_) { | |
if (!arguments.length) return scaleExtent; | |
scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; | |
return zoom; | |
}; | |
zoom.center = function(_) { | |
if (!arguments.length) return center; | |
center = _ && [ +_[0], +_[1] ]; | |
return zoom; | |
}; | |
zoom.size = function(_) { | |
if (!arguments.length) return size; | |
size = _ && [ +_[0], +_[1] ]; | |
return zoom; | |
}; | |
zoom.duration = function(_) { | |
if (!arguments.length) return duration; | |
duration = +_; | |
return zoom; | |
}; | |
zoom.x = function(z) { | |
if (!arguments.length) return x1; | |
x1 = z; | |
x0 = z.copy(); | |
view = { | |
x: 0, | |
y: 0, | |
k: 1 | |
}; | |
return zoom; | |
}; | |
zoom.y = function(z) { | |
if (!arguments.length) return y1; | |
y1 = z; | |
y0 = z.copy(); | |
view = { | |
x: 0, | |
y: 0, | |
k: 1 | |
}; | |
return zoom; | |
}; | |
function location(p) { | |
return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; | |
} | |
function point(l) { | |
return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; | |
} | |
function scaleTo(s) { | |
view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); | |
} | |
function translateTo(p, l) { | |
l = point(l); | |
view.x += p[0] - l[0]; | |
view.y += p[1] - l[1]; | |
} | |
function zoomTo(that, p, l, k) { | |
that.__chart__ = { | |
x: view.x, | |
y: view.y, | |
k: view.k | |
}; | |
scaleTo(Math.pow(2, k)); | |
translateTo(center0 = p, l); | |
that = d3.select(that); | |
if (duration > 0) that = that.transition().duration(duration); | |
that.call(zoom.event); | |
} | |
function rescale() { | |
if (x1) x1.domain(x0.range().map(function(x) { | |
return (x - view.x) / view.k; | |
}).map(x0.invert)); | |
if (y1) y1.domain(y0.range().map(function(y) { | |
return (y - view.y) / view.k; | |
}).map(y0.invert)); | |
} | |
function zoomstarted(dispatch) { | |
if (!zooming++) dispatch({ | |
type: "zoomstart" | |
}); | |
} | |
function zoomed(dispatch) { | |
rescale(); | |
dispatch({ | |
type: "zoom", | |
scale: view.k, | |
translate: [ view.x, view.y ] | |
}); | |
} | |
function zoomended(dispatch) { | |
if (!--zooming) dispatch({ | |
type: "zoomend" | |
}), center0 = null; | |
} | |
function mousedowned() { | |
var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that); | |
d3_selection_interrupt.call(that); | |
zoomstarted(dispatch); | |
function moved() { | |
dragged = 1; | |
translateTo(d3.mouse(that), location0); | |
zoomed(dispatch); | |
} | |
function ended() { | |
subject.on(mousemove, null).on(mouseup, null); | |
dragRestore(dragged && d3.event.target === target); | |
zoomended(dispatch); | |
} | |
} | |
function touchstarted() { | |
var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that); | |
started(); | |
zoomstarted(dispatch); | |
subject.on(mousedown, null).on(touchstart, started); | |
function relocate() { | |
var touches = d3.touches(that); | |
scale0 = view.k; | |
touches.forEach(function(t) { | |
if (t.identifier in locations0) locations0[t.identifier] = location(t); | |
}); | |
return touches; | |
} | |
function started() { | |
var target = d3.event.target; | |
d3.select(target).on(touchmove, moved).on(touchend, ended); | |
targets.push(target); | |
var changed = d3.event.changedTouches; | |
for (var i = 0, n = changed.length; i < n; ++i) { | |
locations0[changed[i].identifier] = null; | |
} | |
var touches = relocate(), now = Date.now(); | |
if (touches.length === 1) { | |
if (now - touchtime < 500) { | |
var p = touches[0]; | |
zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1); | |
d3_eventPreventDefault(); | |
} | |
touchtime = now; | |
} else if (touches.length > 1) { | |
var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; | |
distance0 = dx * dx + dy * dy; | |
} | |
} | |
function moved() { | |
var touches = d3.touches(that), p0, l0, p1, l1; | |
d3_selection_interrupt.call(that); | |
for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { | |
p1 = touches[i]; | |
if (l1 = locations0[p1.identifier]) { | |
if (l0) break; | |
p0 = p1, l0 = l1; | |
} | |
} | |
if (l1) { | |
var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); | |
p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; | |
l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; | |
scaleTo(scale1 * scale0); | |
} | |
touchtime = null; | |
translateTo(p0, l0); | |
zoomed(dispatch); | |
} | |
function ended() { | |
if (d3.event.touches.length) { | |
var changed = d3.event.changedTouches; | |
for (var i = 0, n = changed.length; i < n; ++i) { | |
delete locations0[changed[i].identifier]; | |
} | |
for (var identifier in locations0) { | |
return void relocate(); | |
} | |
} | |
d3.selectAll(targets).on(zoomName, null); | |
subject.on(mousedown, mousedowned).on(touchstart, touchstarted); | |
dragRestore(); | |
zoomended(dispatch); | |
} | |
} | |
function mousewheeled() { | |
var dispatch = event.of(this, arguments); | |
if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), | |
translate0 = location(center0 = center || d3.mouse(this)), zoomstarted(dispatch); | |
mousewheelTimer = setTimeout(function() { | |
mousewheelTimer = null; | |
zoomended(dispatch); | |
}, 50); | |
d3_eventPreventDefault(); | |
scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); | |
translateTo(center0, translate0); | |
zoomed(dispatch); | |
} | |
function dblclicked() { | |
var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2; | |
zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1); | |
} | |
return d3.rebind(zoom, event, "on"); | |
}; | |
var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel; | |
d3.color = d3_color; | |
function d3_color() {} | |
d3_color.prototype.toString = function() { | |
return this.rgb() + ""; | |
}; | |
d3.hsl = d3_hsl; | |
function d3_hsl(h, s, l) { | |
return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l); | |
} | |
var d3_hslPrototype = d3_hsl.prototype = new d3_color(); | |
d3_hslPrototype.brighter = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
return new d3_hsl(this.h, this.s, this.l / k); | |
}; | |
d3_hslPrototype.darker = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
return new d3_hsl(this.h, this.s, k * this.l); | |
}; | |
d3_hslPrototype.rgb = function() { | |
return d3_hsl_rgb(this.h, this.s, this.l); | |
}; | |
function d3_hsl_rgb(h, s, l) { | |
var m1, m2; | |
h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; | |
s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; | |
l = l < 0 ? 0 : l > 1 ? 1 : l; | |
m2 = l <= .5 ? l * (1 + s) : l + s - l * s; | |
m1 = 2 * l - m2; | |
function v(h) { | |
if (h > 360) h -= 360; else if (h < 0) h += 360; | |
if (h < 60) return m1 + (m2 - m1) * h / 60; | |
if (h < 180) return m2; | |
if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; | |
return m1; | |
} | |
function vv(h) { | |
return Math.round(v(h) * 255); | |
} | |
return new d3_rgb(vv(h + 120), vv(h), vv(h - 120)); | |
} | |
d3.hcl = d3_hcl; | |
function d3_hcl(h, c, l) { | |
return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l); | |
} | |
var d3_hclPrototype = d3_hcl.prototype = new d3_color(); | |
d3_hclPrototype.brighter = function(k) { | |
return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); | |
}; | |
d3_hclPrototype.darker = function(k) { | |
return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); | |
}; | |
d3_hclPrototype.rgb = function() { | |
return d3_hcl_lab(this.h, this.c, this.l).rgb(); | |
}; | |
function d3_hcl_lab(h, c, l) { | |
if (isNaN(h)) h = 0; | |
if (isNaN(c)) c = 0; | |
return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); | |
} | |
d3.lab = d3_lab; | |
function d3_lab(l, a, b) { | |
return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b); | |
} | |
var d3_lab_K = 18; | |
var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; | |
var d3_labPrototype = d3_lab.prototype = new d3_color(); | |
d3_labPrototype.brighter = function(k) { | |
return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); | |
}; | |
d3_labPrototype.darker = function(k) { | |
return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); | |
}; | |
d3_labPrototype.rgb = function() { | |
return d3_lab_rgb(this.l, this.a, this.b); | |
}; | |
function d3_lab_rgb(l, a, b) { | |
var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; | |
x = d3_lab_xyz(x) * d3_lab_X; | |
y = d3_lab_xyz(y) * d3_lab_Y; | |
z = d3_lab_xyz(z) * d3_lab_Z; | |
return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); | |
} | |
function d3_lab_hcl(l, a, b) { | |
return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l); | |
} | |
function d3_lab_xyz(x) { | |
return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; | |
} | |
function d3_xyz_lab(x) { | |
return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; | |
} | |
function d3_xyz_rgb(r) { | |
return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); | |
} | |
d3.rgb = d3_rgb; | |
function d3_rgb(r, g, b) { | |
return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b); | |
} | |
function d3_rgbNumber(value) { | |
return new d3_rgb(value >> 16, value >> 8 & 255, value & 255); | |
} | |
function d3_rgbString(value) { | |
return d3_rgbNumber(value) + ""; | |
} | |
var d3_rgbPrototype = d3_rgb.prototype = new d3_color(); | |
d3_rgbPrototype.brighter = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
var r = this.r, g = this.g, b = this.b, i = 30; | |
if (!r && !g && !b) return new d3_rgb(i, i, i); | |
if (r && r < i) r = i; | |
if (g && g < i) g = i; | |
if (b && b < i) b = i; | |
return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k)); | |
}; | |
d3_rgbPrototype.darker = function(k) { | |
k = Math.pow(.7, arguments.length ? k : 1); | |
return new d3_rgb(k * this.r, k * this.g, k * this.b); | |
}; | |
d3_rgbPrototype.hsl = function() { | |
return d3_rgb_hsl(this.r, this.g, this.b); | |
}; | |
d3_rgbPrototype.toString = function() { | |
return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); | |
}; | |
function d3_rgb_hex(v) { | |
return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); | |
} | |
function d3_rgb_parse(format, rgb, hsl) { | |
format = format.toLowerCase(); | |
var r = 0, g = 0, b = 0, m1, m2, color; | |
m1 = /([a-z]+)\((.*)\)/.exec(format); | |
if (m1) { | |
m2 = m1[2].split(","); | |
switch (m1[1]) { | |
case "hsl": | |
{ | |
return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); | |
} | |
case "rgb": | |
{ | |
return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); | |
} | |
} | |
} | |
if (color = d3_rgb_names.get(format)) { | |
return rgb(color.r, color.g, color.b); | |
} | |
if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.slice(1), 16))) { | |
if (format.length === 4) { | |
r = (color & 3840) >> 4; | |
r = r >> 4 | r; | |
g = color & 240; | |
g = g >> 4 | g; | |
b = color & 15; | |
b = b << 4 | b; | |
} else if (format.length === 7) { | |
r = (color & 16711680) >> 16; | |
g = (color & 65280) >> 8; | |
b = color & 255; | |
} | |
} | |
return rgb(r, g, b); | |
} | |
function d3_rgb_hsl(r, g, b) { | |
var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; | |
if (d) { | |
s = l < .5 ? d / (max + min) : d / (2 - max - min); | |
if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; | |
h *= 60; | |
} else { | |
h = NaN; | |
s = l > 0 && l < 1 ? 0 : h; | |
} | |
return new d3_hsl(h, s, l); | |
} | |
function d3_rgb_lab(r, g, b) { | |
r = d3_rgb_xyz(r); | |
g = d3_rgb_xyz(g); | |
b = d3_rgb_xyz(b); | |
var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); | |
return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); | |
} | |
function d3_rgb_xyz(r) { | |
return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); | |
} | |
function d3_rgb_parseNumber(c) { | |
var f = parseFloat(c); | |
return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; | |
} | |
var d3_rgb_names = d3.map({ | |
aliceblue: 15792383, | |
antiquewhite: 16444375, | |
aqua: 65535, | |
aquamarine: 8388564, | |
azure: 15794175, | |
beige: 16119260, | |
bisque: 16770244, | |
black: 0, | |
blanchedalmond: 16772045, | |
blue: 255, | |
blueviolet: 9055202, | |
brown: 10824234, | |
burlywood: 14596231, | |
cadetblue: 6266528, | |
chartreuse: 8388352, | |
chocolate: 13789470, | |
coral: 16744272, | |
cornflowerblue: 6591981, | |
cornsilk: 16775388, | |
crimson: 14423100, | |
cyan: 65535, | |
darkblue: 139, | |
darkcyan: 35723, | |
darkgoldenrod: 12092939, | |
darkgray: 11119017, | |
darkgreen: 25600, | |
darkgrey: 11119017, | |
darkkhaki: 12433259, | |
darkmagenta: 9109643, | |
darkolivegreen: 5597999, | |
darkorange: 16747520, | |
darkorchid: 10040012, | |
darkred: 9109504, | |
darksalmon: 15308410, | |
darkseagreen: 9419919, | |
darkslateblue: 4734347, | |
darkslategray: 3100495, | |
darkslategrey: 3100495, | |
darkturquoise: 52945, | |
darkviolet: 9699539, | |
deeppink: 16716947, | |
deepskyblue: 49151, | |
dimgray: 6908265, | |
dimgrey: 6908265, | |
dodgerblue: 2003199, | |
firebrick: 11674146, | |
floralwhite: 16775920, | |
forestgreen: 2263842, | |
fuchsia: 16711935, | |
gainsboro: 14474460, | |
ghostwhite: 16316671, | |
gold: 16766720, | |
goldenrod: 14329120, | |
gray: 8421504, | |
green: 32768, | |
greenyellow: 11403055, | |
grey: 8421504, | |
honeydew: 15794160, | |
hotpink: 16738740, | |
indianred: 13458524, | |
indigo: 4915330, | |
ivory: 16777200, | |
khaki: 15787660, | |
lavender: 15132410, | |
lavenderblush: 16773365, | |
lawngreen: 8190976, | |
lemonchiffon: 16775885, | |
lightblue: 11393254, | |
lightcoral: 15761536, | |
lightcyan: 14745599, | |
lightgoldenrodyellow: 16448210, | |
lightgray: 13882323, | |
lightgreen: 9498256, | |
lightgrey: 13882323, | |
lightpink: 16758465, | |
lightsalmon: 16752762, | |
lightseagreen: 2142890, | |
lightskyblue: 8900346, | |
lightslategray: 7833753, | |
lightslategrey: 7833753, | |
lightsteelblue: 11584734, | |
lightyellow: 16777184, | |
lime: 65280, | |
limegreen: 3329330, | |
linen: 16445670, | |
magenta: 16711935, | |
maroon: 8388608, | |
mediumaquamarine: 6737322, | |
mediumblue: 205, | |
mediumorchid: 12211667, | |
mediumpurple: 9662683, | |
mediumseagreen: 3978097, | |
mediumslateblue: 8087790, | |
mediumspringgreen: 64154, | |
mediumturquoise: 4772300, | |
mediumvioletred: 13047173, | |
midnightblue: 1644912, | |
mintcream: 16121850, | |
mistyrose: 16770273, | |
moccasin: 16770229, | |
navajowhite: 16768685, | |
navy: 128, | |
oldlace: 16643558, | |
olive: 8421376, | |
olivedrab: 7048739, | |
orange: 16753920, | |
orangered: 16729344, | |
orchid: 14315734, | |
palegoldenrod: 15657130, | |
palegreen: 10025880, | |
paleturquoise: 11529966, | |
palevioletred: 14381203, | |
papayawhip: 16773077, | |
peachpuff: 16767673, | |
peru: 13468991, | |
pink: 16761035, | |
plum: 14524637, | |
powderblue: 11591910, | |
purple: 8388736, | |
rebeccapurple: 6697881, | |
red: 16711680, | |
rosybrown: 12357519, | |
royalblue: 4286945, | |
saddlebrown: 9127187, | |
salmon: 16416882, | |
sandybrown: 16032864, | |
seagreen: 3050327, | |
seashell: 16774638, | |
sienna: 10506797, | |
silver: 12632256, | |
skyblue: 8900331, | |
slateblue: 6970061, | |
slategray: 7372944, | |
slategrey: 7372944, | |
snow: 16775930, | |
springgreen: 65407, | |
steelblue: 4620980, | |
tan: 13808780, | |
teal: 32896, | |
thistle: 14204888, | |
tomato: 16737095, | |
turquoise: 4251856, | |
violet: 15631086, | |
wheat: 16113331, | |
white: 16777215, | |
whitesmoke: 16119285, | |
yellow: 16776960, | |
yellowgreen: 10145074 | |
}); | |
d3_rgb_names.forEach(function(key, value) { | |
d3_rgb_names.set(key, d3_rgbNumber(value)); | |
}); | |
function d3_functor(v) { | |
return typeof v === "function" ? v : function() { | |
return v; | |
}; | |
} | |
d3.functor = d3_functor; | |
d3.xhr = d3_xhrType(d3_identity); | |
function d3_xhrType(response) { | |
return function(url, mimeType, callback) { | |
if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, | |
mimeType = null; | |
return d3_xhr(url, mimeType, response, callback); | |
}; | |
} | |
function d3_xhr(url, mimeType, response, callback) { | |
var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; | |
if (this.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); | |
"onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { | |
request.readyState > 3 && respond(); | |
}; | |
function respond() { | |
var status = request.status, result; | |
if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { | |
try { | |
result = response.call(xhr, request); | |
} catch (e) { | |
dispatch.error.call(xhr, e); | |
return; | |
} | |
dispatch.load.call(xhr, result); | |
} else { | |
dispatch.error.call(xhr, request); | |
} | |
} | |
request.onprogress = function(event) { | |
var o = d3.event; | |
d3.event = event; | |
try { | |
dispatch.progress.call(xhr, request); | |
} finally { | |
d3.event = o; | |
} | |
}; | |
xhr.header = function(name, value) { | |
name = (name + "").toLowerCase(); | |
if (arguments.length < 2) return headers[name]; | |
if (value == null) delete headers[name]; else headers[name] = value + ""; | |
return xhr; | |
}; | |
xhr.mimeType = function(value) { | |
if (!arguments.length) return mimeType; | |
mimeType = value == null ? null : value + ""; | |
return xhr; | |
}; | |
xhr.responseType = function(value) { | |
if (!arguments.length) return responseType; | |
responseType = value; | |
return xhr; | |
}; | |
xhr.response = function(value) { | |
response = value; | |
return xhr; | |
}; | |
[ "get", "post" ].forEach(function(method) { | |
xhr[method] = function() { | |
return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); | |
}; | |
}); | |
xhr.send = function(method, data, callback) { | |
if (arguments.length === 2 && typeof data === "function") callback = data, data = null; | |
request.open(method, url, true); | |
if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; | |
if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); | |
if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); | |
if (responseType != null) request.responseType = responseType; | |
if (callback != null) xhr.on("error", callback).on("load", function(request) { | |
callback(null, request); | |
}); | |
dispatch.beforesend.call(xhr, request); | |
request.send(data == null ? null : data); | |
return xhr; | |
}; | |
xhr.abort = function() { | |
request.abort(); | |
return xhr; | |
}; | |
d3.rebind(xhr, dispatch, "on"); | |
return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); | |
} | |
function d3_xhr_fixCallback(callback) { | |
return callback.length === 1 ? function(error, request) { | |
callback(error == null ? request : null); | |
} : callback; | |
} | |
function d3_xhrHasResponse(request) { | |
var type = request.responseType; | |
return type && type !== "text" ? request.response : request.responseText; | |
} | |
d3.dsv = function(delimiter, mimeType) { | |
var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); | |
function dsv(url, row, callback) { | |
if (arguments.length < 3) callback = row, row = null; | |
var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); | |
xhr.row = function(_) { | |
return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; | |
}; | |
return xhr; | |
} | |
function response(request) { | |
return dsv.parse(request.responseText); | |
} | |
function typedResponse(f) { | |
return function(request) { | |
return dsv.parse(request.responseText, f); | |
}; | |
} | |
dsv.parse = function(text, f) { | |
var o; | |
return dsv.parseRows(text, function(row, i) { | |
if (o) return o(row, i - 1); | |
var a = new Function("d", "return {" + row.map(function(name, i) { | |
return JSON.stringify(name) + ": d[" + i + "]"; | |
}).join(",") + "}"); | |
o = f ? function(row, i) { | |
return f(a(row), i); | |
} : a; | |
}); | |
}; | |
dsv.parseRows = function(text, f) { | |
var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; | |
function token() { | |
if (I >= N) return EOF; | |
if (eol) return eol = false, EOL; | |
var j = I; | |
if (text.charCodeAt(j) === 34) { | |
var i = j; | |
while (i++ < N) { | |
if (text.charCodeAt(i) === 34) { | |
if (text.charCodeAt(i + 1) !== 34) break; | |
++i; | |
} | |
} | |
I = i + 2; | |
var c = text.charCodeAt(i + 1); | |
if (c === 13) { | |
eol = true; | |
if (text.charCodeAt(i + 2) === 10) ++I; | |
} else if (c === 10) { | |
eol = true; | |
} | |
return text.slice(j + 1, i).replace(/""/g, '"'); | |
} | |
while (I < N) { | |
var c = text.charCodeAt(I++), k = 1; | |
if (c === 10) eol = true; else if (c === 13) { | |
eol = true; | |
if (text.charCodeAt(I) === 10) ++I, ++k; | |
} else if (c !== delimiterCode) continue; | |
return text.slice(j, I - k); | |
} | |
return text.slice(j); | |
} | |
while ((t = token()) !== EOF) { | |
var a = []; | |
while (t !== EOL && t !== EOF) { | |
a.push(t); | |
t = token(); | |
} | |
if (f && (a = f(a, n++)) == null) continue; | |
rows.push(a); | |
} | |
return rows; | |
}; | |
dsv.format = function(rows) { | |
if (Array.isArray(rows[0])) return dsv.formatRows(rows); | |
var fieldSet = new d3_Set(), fields = []; | |
rows.forEach(function(row) { | |
for (var field in row) { | |
if (!fieldSet.has(field)) { | |
fields.push(fieldSet.add(field)); | |
} | |
} | |
}); | |
return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { | |
return fields.map(function(field) { | |
return formatValue(row[field]); | |
}).join(delimiter); | |
})).join("\n"); | |
}; | |
dsv.formatRows = function(rows) { | |
return rows.map(formatRow).join("\n"); | |
}; | |
function formatRow(row) { | |
return row.map(formatValue).join(delimiter); | |
} | |
function formatValue(text) { | |
return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; | |
} | |
return dsv; | |
}; | |
d3.csv = d3.dsv(",", "text/csv"); | |
d3.tsv = d3.dsv(" ", "text/tab-separated-values"); | |
var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) { | |
setTimeout(callback, 17); | |
}; | |
d3.timer = function(callback, delay, then) { | |
var n = arguments.length; | |
if (n < 2) delay = 0; | |
if (n < 3) then = Date.now(); | |
var time = then + delay, timer = { | |
c: callback, | |
t: time, | |
f: false, | |
n: null | |
}; | |
if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; | |
d3_timer_queueTail = timer; | |
if (!d3_timer_interval) { | |
d3_timer_timeout = clearTimeout(d3_timer_timeout); | |
d3_timer_interval = 1; | |
d3_timer_frame(d3_timer_step); | |
} | |
}; | |
function d3_timer_step() { | |
var now = d3_timer_mark(), delay = d3_timer_sweep() - now; | |
if (delay > 24) { | |
if (isFinite(delay)) { | |
clearTimeout(d3_timer_timeout); | |
d3_timer_timeout = setTimeout(d3_timer_step, delay); | |
} | |
d3_timer_interval = 0; | |
} else { | |
d3_timer_interval = 1; | |
d3_timer_frame(d3_timer_step); | |
} | |
} | |
d3.timer.flush = function() { | |
d3_timer_mark(); | |
d3_timer_sweep(); | |
}; | |
function d3_timer_mark() { | |
var now = Date.now(); | |
d3_timer_active = d3_timer_queueHead; | |
while (d3_timer_active) { | |
if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t); | |
d3_timer_active = d3_timer_active.n; | |
} | |
return now; | |
} | |
function d3_timer_sweep() { | |
var t0, t1 = d3_timer_queueHead, time = Infinity; | |
while (t1) { | |
if (t1.f) { | |
t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; | |
} else { | |
if (t1.t < time) time = t1.t; | |
t1 = (t0 = t1).n; | |
} | |
} | |
d3_timer_queueTail = t0; | |
return time; | |
} | |
function d3_format_precision(x, p) { | |
return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); | |
} | |
d3.round = function(x, n) { | |
return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); | |
}; | |
var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); | |
d3.formatPrefix = function(value, precision) { | |
var i = 0; | |
if (value) { | |
if (value < 0) value *= -1; | |
if (precision) value = d3.round(value, d3_format_precision(value, precision)); | |
i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); | |
i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3)); | |
} | |
return d3_formatPrefixes[8 + i / 3]; | |
}; | |
function d3_formatPrefix(d, i) { | |
var k = Math.pow(10, abs(8 - i) * 3); | |
return { | |
scale: i > 8 ? function(d) { | |
return d / k; | |
} : function(d) { | |
return d * k; | |
}, | |
symbol: d | |
}; | |
} | |
function d3_locale_numberFormat(locale) { | |
var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) { | |
var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0; | |
while (i > 0 && g > 0) { | |
if (length + g + 1 > width) g = Math.max(1, width - length); | |
t.push(value.substring(i -= g, i + g)); | |
if ((length += g + 1) > width) break; | |
g = locale_grouping[j = (j + 1) % locale_grouping.length]; | |
} | |
return t.reverse().join(locale_thousands); | |
} : d3_identity; | |
return function(specifier) { | |
var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false, exponent = true; | |
if (precision) precision = +precision.substring(1); | |
if (zfill || fill === "0" && align === "=") { | |
zfill = fill = "0"; | |
align = "="; | |
} | |
switch (type) { | |
case "n": | |
comma = true; | |
type = "g"; | |
break; | |
case "%": | |
scale = 100; | |
suffix = "%"; | |
type = "f"; | |
break; | |
case "p": | |
scale = 100; | |
suffix = "%"; | |
type = "r"; | |
break; | |
case "b": | |
case "o": | |
case "x": | |
case "X": | |
if (symbol === "#") prefix = "0" + type.toLowerCase(); | |
case "c": | |
exponent = false; | |
case "d": | |
integer = true; | |
precision = 0; | |
break; | |
case "s": | |
scale = -1; | |
type = "r"; | |
break; | |
} | |
if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; | |
if (type == "r" && !precision) type = "g"; | |
if (precision != null) { | |
if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); | |
} | |
type = d3_format_types.get(type) || d3_format_typeDefault; | |
var zcomma = zfill && comma; | |
return function(value) { | |
var fullSuffix = suffix; | |
if (integer && value % 1) return ""; | |
var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign; | |
if (scale < 0) { | |
var unit = d3.formatPrefix(value, precision); | |
value = unit.scale(value); | |
fullSuffix = unit.symbol + suffix; | |
} else { | |
value *= scale; | |
} | |
value = type(value, precision); | |
var i = value.lastIndexOf("."), before, after; | |
if (i < 0) { | |
var j = exponent ? value.lastIndexOf("e") : -1; | |
if (j < 0) before = value, after = ""; else before = value.substring(0, j), after = value.substring(j); | |
} else { | |
before = value.substring(0, i); | |
after = locale_decimal + value.substring(i + 1); | |
} | |
if (!zfill && comma) before = formatGroup(before, Infinity); | |
var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; | |
if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity); | |
negative += prefix; | |
value = before + after; | |
return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix; | |
}; | |
}; | |
} | |
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; | |
var d3_format_types = d3.map({ | |
b: function(x) { | |
return x.toString(2); | |
}, | |
c: function(x) { | |
return String.fromCharCode(x); | |
}, | |
o: function(x) { | |
return x.toString(8); | |
}, | |
x: function(x) { | |
return x.toString(16); | |
}, | |
X: function(x) { | |
return x.toString(16).toUpperCase(); | |
}, | |
g: function(x, p) { | |
return x.toPrecision(p); | |
}, | |
e: function(x, p) { | |
return x.toExponential(p); | |
}, | |
f: function(x, p) { | |
return x.toFixed(p); | |
}, | |
r: function(x, p) { | |
return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); | |
} | |
}); | |
function d3_format_typeDefault(x) { | |
return x + ""; | |
} | |
var d3_time = d3.time = {}, d3_date = Date; | |
function d3_date_utc() { | |
this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); | |
} | |
d3_date_utc.prototype = { | |
getDate: function() { | |
return this._.getUTCDate(); | |
}, | |
getDay: function() { | |
return this._.getUTCDay(); | |
}, | |
getFullYear: function() { | |
return this._.getUTCFullYear(); | |
}, | |
getHours: function() { | |
return this._.getUTCHours(); | |
}, | |
getMilliseconds: function() { | |
return this._.getUTCMilliseconds(); | |
}, | |
getMinutes: function() { | |
return this._.getUTCMinutes(); | |
}, | |
getMonth: function() { | |
return this._.getUTCMonth(); | |
}, | |
getSeconds: function() { | |
return this._.getUTCSeconds(); | |
}, | |
getTime: function() { | |
return this._.getTime(); | |
}, | |
getTimezoneOffset: function() { | |
return 0; | |
}, | |
valueOf: function() { | |
return this._.valueOf(); | |
}, | |
setDate: function() { | |
d3_time_prototype.setUTCDate.apply(this._, arguments); | |
}, | |
setDay: function() { | |
d3_time_prototype.setUTCDay.apply(this._, arguments); | |
}, | |
setFullYear: function() { | |
d3_time_prototype.setUTCFullYear.apply(this._, arguments); | |
}, | |
setHours: function() { | |
d3_time_prototype.setUTCHours.apply(this._, arguments); | |
}, | |
setMilliseconds: function() { | |
d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); | |
}, | |
setMinutes: function() { | |
d3_time_prototype.setUTCMinutes.apply(this._, arguments); | |
}, | |
setMonth: function() { | |
d3_time_prototype.setUTCMonth.apply(this._, arguments); | |
}, | |
setSeconds: function() { | |
d3_time_prototype.setUTCSeconds.apply(this._, arguments); | |
}, | |
setTime: function() { | |
d3_time_prototype.setTime.apply(this._, arguments); | |
} | |
}; | |
var d3_time_prototype = Date.prototype; | |
function d3_time_interval(local, step, number) { | |
function round(date) { | |
var d0 = local(date), d1 = offset(d0, 1); | |
return date - d0 < d1 - date ? d0 : d1; | |
} | |
function ceil(date) { | |
step(date = local(new d3_date(date - 1)), 1); | |
return date; | |
} | |
function offset(date, k) { | |
step(date = new d3_date(+date), k); | |
return date; | |
} | |
function range(t0, t1, dt) { | |
var time = ceil(t0), times = []; | |
if (dt > 1) { | |
while (time < t1) { | |
if (!(number(time) % dt)) times.push(new Date(+time)); | |
step(time, 1); | |
} | |
} else { | |
while (time < t1) times.push(new Date(+time)), step(time, 1); | |
} | |
return times; | |
} | |
function range_utc(t0, t1, dt) { | |
try { | |
d3_date = d3_date_utc; | |
var utc = new d3_date_utc(); | |
utc._ = t0; | |
return range(utc, t1, dt); | |
} finally { | |
d3_date = Date; | |
} | |
} | |
local.floor = local; | |
local.round = round; | |
local.ceil = ceil; | |
local.offset = offset; | |
local.range = range; | |
var utc = local.utc = d3_time_interval_utc(local); | |
utc.floor = utc; | |
utc.round = d3_time_interval_utc(round); | |
utc.ceil = d3_time_interval_utc(ceil); | |
utc.offset = d3_time_interval_utc(offset); | |
utc.range = range_utc; | |
return local; | |
} | |
function d3_time_interval_utc(method) { | |
return function(date, k) { | |
try { | |
d3_date = d3_date_utc; | |
var utc = new d3_date_utc(); | |
utc._ = date; | |
return method(utc, k)._; | |
} finally { | |
d3_date = Date; | |
} | |
}; | |
} | |
d3_time.year = d3_time_interval(function(date) { | |
date = d3_time.day(date); | |
date.setMonth(0, 1); | |
return date; | |
}, function(date, offset) { | |
date.setFullYear(date.getFullYear() + offset); | |
}, function(date) { | |
return date.getFullYear(); | |
}); | |
d3_time.years = d3_time.year.range; | |
d3_time.years.utc = d3_time.year.utc.range; | |
d3_time.day = d3_time_interval(function(date) { | |
var day = new d3_date(2e3, 0); | |
day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); | |
return day; | |
}, function(date, offset) { | |
date.setDate(date.getDate() + offset); | |
}, function(date) { | |
return date.getDate() - 1; | |
}); | |
d3_time.days = d3_time.day.range; | |
d3_time.days.utc = d3_time.day.utc.range; | |
d3_time.dayOfYear = function(date) { | |
var year = d3_time.year(date); | |
return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); | |
}; | |
[ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { | |
i = 7 - i; | |
var interval = d3_time[day] = d3_time_interval(function(date) { | |
(date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); | |
return date; | |
}, function(date, offset) { | |
date.setDate(date.getDate() + Math.floor(offset) * 7); | |
}, function(date) { | |
var day = d3_time.year(date).getDay(); | |
return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); | |
}); | |
d3_time[day + "s"] = interval.range; | |
d3_time[day + "s"].utc = interval.utc.range; | |
d3_time[day + "OfYear"] = function(date) { | |
var day = d3_time.year(date).getDay(); | |
return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); | |
}; | |
}); | |
d3_time.week = d3_time.sunday; | |
d3_time.weeks = d3_time.sunday.range; | |
d3_time.weeks.utc = d3_time.sunday.utc.range; | |
d3_time.weekOfYear = d3_time.sundayOfYear; | |
function d3_locale_timeFormat(locale) { | |
var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; | |
function d3_time_format(template) { | |
var n = template.length; | |
function format(date) { | |
var string = [], i = -1, j = 0, c, p, f; | |
while (++i < n) { | |
if (template.charCodeAt(i) === 37) { | |
string.push(template.slice(j, i)); | |
if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); | |
if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); | |
string.push(c); | |
j = i + 1; | |
} | |
} | |
string.push(template.slice(j, i)); | |
return string.join(""); | |
} | |
format.parse = function(string) { | |
var d = { | |
y: 1900, | |
m: 0, | |
d: 1, | |
H: 0, | |
M: 0, | |
S: 0, | |
L: 0, | |
Z: null | |
}, i = d3_time_parse(d, template, string, 0); | |
if (i != string.length) return null; | |
if ("p" in d) d.H = d.H % 12 + d.p * 12; | |
var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); | |
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { | |
date.setFullYear(d.y, 0, 1); | |
date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); | |
} else date.setFullYear(d.y, d.m, d.d); | |
date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L); | |
return localZ ? date._ : date; | |
}; | |
format.toString = function() { | |
return template; | |
}; | |
return format; | |
} | |
function d3_time_parse(date, template, string, j) { | |
var c, p, t, i = 0, n = template.length, m = string.length; | |
while (i < n) { | |
if (j >= m) return -1; | |
c = template.charCodeAt(i++); | |
if (c === 37) { | |
t = template.charAt(i++); | |
p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; | |
if (!p || (j = p(date, string, j)) < 0) return -1; | |
} else if (c != string.charCodeAt(j++)) { | |
return -1; | |
} | |
} | |
return j; | |
} | |
d3_time_format.utc = function(template) { | |
var local = d3_time_format(template); | |
function format(date) { | |
try { | |
d3_date = d3_date_utc; | |
var utc = new d3_date(); | |
utc._ = date; | |
return local(utc); | |
} finally { | |
d3_date = Date; | |
} | |
} | |
format.parse = function(string) { | |
try { | |
d3_date = d3_date_utc; | |
var date = local.parse(string); | |
return date && date._; | |
} finally { | |
d3_date = Date; | |
} | |
}; | |
format.toString = local.toString; | |
return format; | |
}; | |
d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; | |
var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); | |
locale_periods.forEach(function(p, i) { | |
d3_time_periodLookup.set(p.toLowerCase(), i); | |
}); | |
var d3_time_formats = { | |
a: function(d) { | |
return locale_shortDays[d.getDay()]; | |
}, | |
A: function(d) { | |
return locale_days[d.getDay()]; | |
}, | |
b: function(d) { | |
return locale_shortMonths[d.getMonth()]; | |
}, | |
B: function(d) { | |
return locale_months[d.getMonth()]; | |
}, | |
c: d3_time_format(locale_dateTime), | |
d: function(d, p) { | |
return d3_time_formatPad(d.getDate(), p, 2); | |
}, | |
e: function(d, p) { | |
return d3_time_formatPad(d.getDate(), p, 2); | |
}, | |
H: function(d, p) { | |
return d3_time_formatPad(d.getHours(), p, 2); | |
}, | |
I: function(d, p) { | |
return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); | |
}, | |
j: function(d, p) { | |
return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); | |
}, | |
L: function(d, p) { | |
return d3_time_formatPad(d.getMilliseconds(), p, 3); | |
}, | |
m: function(d, p) { | |
return d3_time_formatPad(d.getMonth() + 1, p, 2); | |
}, | |
M: function(d, p) { | |
return d3_time_formatPad(d.getMinutes(), p, 2); | |
}, | |
p: function(d) { | |
return locale_periods[+(d.getHours() >= 12)]; | |
}, | |
S: function(d, p) { | |
return d3_time_formatPad(d.getSeconds(), p, 2); | |
}, | |
U: function(d, p) { | |
return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); | |
}, | |
w: function(d) { | |
return d.getDay(); | |
}, | |
W: function(d, p) { | |
return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); | |
}, | |
x: d3_time_format(locale_date), | |
X: d3_time_format(locale_time), | |
y: function(d, p) { | |
return d3_time_formatPad(d.getFullYear() % 100, p, 2); | |
}, | |
Y: function(d, p) { | |
return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); | |
}, | |
Z: d3_time_zone, | |
"%": function() { | |
return "%"; | |
} | |
}; | |
var d3_time_parsers = { | |
a: d3_time_parseWeekdayAbbrev, | |
A: d3_time_parseWeekday, | |
b: d3_time_parseMonthAbbrev, | |
B: d3_time_parseMonth, | |
c: d3_time_parseLocaleFull, | |
d: d3_time_parseDay, | |
e: d3_time_parseDay, | |
H: d3_time_parseHour24, | |
I: d3_time_parseHour24, | |
j: d3_time_parseDayOfYear, | |
L: d3_time_parseMilliseconds, | |
m: d3_time_parseMonthNumber, | |
M: d3_time_parseMinutes, | |
p: d3_time_parseAmPm, | |
S: d3_time_parseSeconds, | |
U: d3_time_parseWeekNumberSunday, | |
w: d3_time_parseWeekdayNumber, | |
W: d3_time_parseWeekNumberMonday, | |
x: d3_time_parseLocaleDate, | |
X: d3_time_parseLocaleTime, | |
y: d3_time_parseYear, | |
Y: d3_time_parseFullYear, | |
Z: d3_time_parseZone, | |
"%": d3_time_parseLiteralPercent | |
}; | |
function d3_time_parseWeekdayAbbrev(date, string, i) { | |
d3_time_dayAbbrevRe.lastIndex = 0; | |
var n = d3_time_dayAbbrevRe.exec(string.slice(i)); | |
return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseWeekday(date, string, i) { | |
d3_time_dayRe.lastIndex = 0; | |
var n = d3_time_dayRe.exec(string.slice(i)); | |
return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseMonthAbbrev(date, string, i) { | |
d3_time_monthAbbrevRe.lastIndex = 0; | |
var n = d3_time_monthAbbrevRe.exec(string.slice(i)); | |
return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseMonth(date, string, i) { | |
d3_time_monthRe.lastIndex = 0; | |
var n = d3_time_monthRe.exec(string.slice(i)); | |
return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; | |
} | |
function d3_time_parseLocaleFull(date, string, i) { | |
return d3_time_parse(date, d3_time_formats.c.toString(), string, i); | |
} | |
function d3_time_parseLocaleDate(date, string, i) { | |
return d3_time_parse(date, d3_time_formats.x.toString(), string, i); | |
} | |
function d3_time_parseLocaleTime(date, string, i) { | |
return d3_time_parse(date, d3_time_formats.X.toString(), string, i); | |
} | |
function d3_time_parseAmPm(date, string, i) { | |
var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase()); | |
return n == null ? -1 : (date.p = n, i); | |
} | |
return d3_time_format; | |
} | |
var d3_time_formatPads = { | |
"-": "", | |
_: " ", | |
"0": "0" | |
}, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; | |
function d3_time_formatPad(value, fill, width) { | |
var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; | |
return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); | |
} | |
function d3_time_formatRe(names) { | |
return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); | |
} | |
function d3_time_formatLookup(names) { | |
var map = new d3_Map(), i = -1, n = names.length; | |
while (++i < n) map.set(names[i].toLowerCase(), i); | |
return map; | |
} | |
function d3_time_parseWeekdayNumber(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 1)); | |
return n ? (date.w = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseWeekNumberSunday(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i)); | |
return n ? (date.U = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseWeekNumberMonday(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i)); | |
return n ? (date.W = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseFullYear(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 4)); | |
return n ? (date.y = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseYear(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 2)); | |
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; | |
} | |
function d3_time_parseZone(date, string, i) { | |
return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, | |
i + 5) : -1; | |
} | |
function d3_time_expandYear(d) { | |
return d + (d > 68 ? 1900 : 2e3); | |
} | |
function d3_time_parseMonthNumber(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 2)); | |
return n ? (date.m = n[0] - 1, i + n[0].length) : -1; | |
} | |
function d3_time_parseDay(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 2)); | |
return n ? (date.d = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseDayOfYear(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 3)); | |
return n ? (date.j = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseHour24(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 2)); | |
return n ? (date.H = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseMinutes(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 2)); | |
return n ? (date.M = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseSeconds(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 2)); | |
return n ? (date.S = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_parseMilliseconds(date, string, i) { | |
d3_time_numberRe.lastIndex = 0; | |
var n = d3_time_numberRe.exec(string.slice(i, i + 3)); | |
return n ? (date.L = +n[0], i + n[0].length) : -1; | |
} | |
function d3_time_zone(d) { | |
var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = abs(z) / 60 | 0, zm = abs(z) % 60; | |
return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); | |
} | |
function d3_time_parseLiteralPercent(date, string, i) { | |
d3_time_percentRe.lastIndex = 0; | |
var n = d3_time_percentRe.exec(string.slice(i, i + 1)); | |
return n ? i + n[0].length : -1; | |
} | |
function d3_time_formatMulti(formats) { | |
var n = formats.length, i = -1; | |
while (++i < n) formats[i][0] = this(formats[i][0]); | |
return function(date) { | |
var i = 0, f = formats[i]; | |
while (!f[1](date)) f = formats[++i]; | |
return f[0](date); | |
}; | |
} | |
d3.locale = function(locale) { | |
return { | |
numberFormat: d3_locale_numberFormat(locale), | |
timeFormat: d3_locale_timeFormat(locale) | |
}; | |
}; | |
var d3_locale_enUS = d3.locale({ | |
decimal: ".", | |
thousands: ",", | |
grouping: [ 3 ], | |
currency: [ "$", "" ], | |
dateTime: "%a %b %e %X %Y", | |
date: "%m/%d/%Y", | |
time: "%H:%M:%S", | |
periods: [ "AM", "PM" ], | |
days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], | |
shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], | |
months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], | |
shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] | |
}); | |
d3.format = d3_locale_enUS.numberFormat; | |
d3.geo = {}; | |
function d3_adder() {} | |
d3_adder.prototype = { | |
s: 0, | |
t: 0, | |
add: function(y) { | |
d3_adderSum(y, this.t, d3_adderTemp); | |
d3_adderSum(d3_adderTemp.s, this.s, this); | |
if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; | |
}, | |
reset: function() { | |
this.s = this.t = 0; | |
}, | |
valueOf: function() { | |
return this.s; | |
} | |
}; | |
var d3_adderTemp = new d3_adder(); | |
function d3_adderSum(a, b, o) { | |
var x = o.s = a + b, bv = x - a, av = x - bv; | |
o.t = a - av + (b - bv); | |
} | |
d3.geo.stream = function(object, listener) { | |
if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { | |
d3_geo_streamObjectType[object.type](object, listener); | |
} else { | |
d3_geo_streamGeometry(object, listener); | |
} | |
}; | |
function d3_geo_streamGeometry(geometry, listener) { | |
if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { | |
d3_geo_streamGeometryType[geometry.type](geometry, listener); | |
} | |
} | |
var d3_geo_streamObjectType = { | |
Feature: function(feature, listener) { | |
d3_geo_streamGeometry(feature.geometry, listener); | |
}, | |
FeatureCollection: function(object, listener) { | |
var features = object.features, i = -1, n = features.length; | |
while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); | |
} | |
}; | |
var d3_geo_streamGeometryType = { | |
Sphere: function(object, listener) { | |
listener.sphere(); | |
}, | |
Point: function(object, listener) { | |
object = object.coordinates; | |
listener.point(object[0], object[1], object[2]); | |
}, | |
MultiPoint: function(object, listener) { | |
var coordinates = object.coordinates, i = -1, n = coordinates.length; | |
while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); | |
}, | |
LineString: function(object, listener) { | |
d3_geo_streamLine(object.coordinates, listener, 0); | |
}, | |
MultiLineString: function(object, listener) { | |
var coordinates = object.coordinates, i = -1, n = coordinates.length; | |
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); | |
}, | |
Polygon: function(object, listener) { | |
d3_geo_streamPolygon(object.coordinates, listener); | |
}, | |
MultiPolygon: function(object, listener) { | |
var coordinates = object.coordinates, i = -1, n = coordinates.length; | |
while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); | |
}, | |
GeometryCollection: function(object, listener) { | |
var geometries = object.geometries, i = -1, n = geometries.length; | |
while (++i < n) d3_geo_streamGeometry(geometries[i], listener); | |
} | |
}; | |
function d3_geo_streamLine(coordinates, listener, closed) { | |
var i = -1, n = coordinates.length - closed, coordinate; | |
listener.lineStart(); | |
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); | |
listener.lineEnd(); | |
} | |
function d3_geo_streamPolygon(coordinates, listener) { | |
var i = -1, n = coordinates.length; | |
listener.polygonStart(); | |
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); | |
listener.polygonEnd(); | |
} | |
d3.geo.area = function(object) { | |
d3_geo_areaSum = 0; | |
d3.geo.stream(object, d3_geo_area); | |
return d3_geo_areaSum; | |
}; | |
var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); | |
var d3_geo_area = { | |
sphere: function() { | |
d3_geo_areaSum += 4 * π; | |
}, | |
point: d3_noop, | |
lineStart: d3_noop, | |
lineEnd: d3_noop, | |
polygonStart: function() { | |
d3_geo_areaRingSum.reset(); | |
d3_geo_area.lineStart = d3_geo_areaRingStart; | |
}, | |
polygonEnd: function() { | |
var area = 2 * d3_geo_areaRingSum; | |
d3_geo_areaSum += area < 0 ? 4 * π + area : area; | |
d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; | |
} | |
}; | |
function d3_geo_areaRingStart() { | |
var λ00, φ00, λ0, cosφ0, sinφ0; | |
d3_geo_area.point = function(λ, φ) { | |
d3_geo_area.point = nextPoint; | |
λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), | |
sinφ0 = Math.sin(φ); | |
}; | |
function nextPoint(λ, φ) { | |
λ *= d3_radians; | |
φ = φ * d3_radians / 2 + π / 4; | |
var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ); | |
d3_geo_areaRingSum.add(Math.atan2(v, u)); | |
λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; | |
} | |
d3_geo_area.lineEnd = function() { | |
nextPoint(λ00, φ00); | |
}; | |
} | |
function d3_geo_cartesian(spherical) { | |
var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); | |
return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; | |
} | |
function d3_geo_cartesianDot(a, b) { | |
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; | |
} | |
function d3_geo_cartesianCross(a, b) { | |
return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; | |
} | |
function d3_geo_cartesianAdd(a, b) { | |
a[0] += b[0]; | |
a[1] += b[1]; | |
a[2] += b[2]; | |
} | |
function d3_geo_cartesianScale(vector, k) { | |
return [ vector[0] * k, vector[1] * k, vector[2] * k ]; | |
} | |
function d3_geo_cartesianNormalize(d) { | |
var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); | |
d[0] /= l; | |
d[1] /= l; | |
d[2] /= l; | |
} | |
function d3_geo_spherical(cartesian) { | |
return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; | |
} | |
function d3_geo_sphericalEqual(a, b) { | |
return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; | |
} | |
d3.geo.bounds = function() { | |
var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; | |
var bound = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
bound.point = ringPoint; | |
bound.lineStart = ringStart; | |
bound.lineEnd = ringEnd; | |
dλSum = 0; | |
d3_geo_area.polygonStart(); | |
}, | |
polygonEnd: function() { | |
d3_geo_area.polygonEnd(); | |
bound.point = point; | |
bound.lineStart = lineStart; | |
bound.lineEnd = lineEnd; | |
if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; | |
range[0] = λ0, range[1] = λ1; | |
} | |
}; | |
function point(λ, φ) { | |
ranges.push(range = [ λ0 = λ, λ1 = λ ]); | |
if (φ < φ0) φ0 = φ; | |
if (φ > φ1) φ1 = φ; | |
} | |
function linePoint(λ, φ) { | |
var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); | |
if (p0) { | |
var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); | |
d3_geo_cartesianNormalize(inflection); | |
inflection = d3_geo_spherical(inflection); | |
var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; | |
if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { | |
var φi = inflection[1] * d3_degrees; | |
if (φi > φ1) φ1 = φi; | |
} else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { | |
var φi = -inflection[1] * d3_degrees; | |
if (φi < φ0) φ0 = φi; | |
} else { | |
if (φ < φ0) φ0 = φ; | |
if (φ > φ1) φ1 = φ; | |
} | |
if (antimeridian) { | |
if (λ < λ_) { | |
if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; | |
} else { | |
if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; | |
} | |
} else { | |
if (λ1 >= λ0) { | |
if (λ < λ0) λ0 = λ; | |
if (λ > λ1) λ1 = λ; | |
} else { | |
if (λ > λ_) { | |
if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; | |
} else { | |
if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; | |
} | |
} | |
} | |
} else { | |
point(λ, φ); | |
} | |
p0 = p, λ_ = λ; | |
} | |
function lineStart() { | |
bound.point = linePoint; | |
} | |
function lineEnd() { | |
range[0] = λ0, range[1] = λ1; | |
bound.point = point; | |
p0 = null; | |
} | |
function ringPoint(λ, φ) { | |
if (p0) { | |
var dλ = λ - λ_; | |
dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; | |
} else λ__ = λ, φ__ = φ; | |
d3_geo_area.point(λ, φ); | |
linePoint(λ, φ); | |
} | |
function ringStart() { | |
d3_geo_area.lineStart(); | |
} | |
function ringEnd() { | |
ringPoint(λ__, φ__); | |
d3_geo_area.lineEnd(); | |
if (abs(dλSum) > ε) λ0 = -(λ1 = 180); | |
range[0] = λ0, range[1] = λ1; | |
p0 = null; | |
} | |
function angle(λ0, λ1) { | |
return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; | |
} | |
function compareRanges(a, b) { | |
return a[0] - b[0]; | |
} | |
function withinRange(x, range) { | |
return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; | |
} | |
return function(feature) { | |
φ1 = λ1 = -(λ0 = φ0 = Infinity); | |
ranges = []; | |
d3.geo.stream(feature, bound); | |
var n = ranges.length; | |
if (n) { | |
ranges.sort(compareRanges); | |
for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { | |
b = ranges[i]; | |
if (withinRange(b[0], a) || withinRange(b[1], a)) { | |
if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; | |
if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; | |
} else { | |
merged.push(a = b); | |
} | |
} | |
var best = -Infinity, dλ; | |
for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { | |
b = merged[i]; | |
if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; | |
} | |
} | |
ranges = range = null; | |
return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; | |
}; | |
}(); | |
d3.geo.centroid = function(object) { | |
d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; | |
d3.geo.stream(object, d3_geo_centroid); | |
var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; | |
if (m < ε2) { | |
x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; | |
if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; | |
m = x * x + y * y + z * z; | |
if (m < ε2) return [ NaN, NaN ]; | |
} | |
return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; | |
}; | |
var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; | |
var d3_geo_centroid = { | |
sphere: d3_noop, | |
point: d3_geo_centroidPoint, | |
lineStart: d3_geo_centroidLineStart, | |
lineEnd: d3_geo_centroidLineEnd, | |
polygonStart: function() { | |
d3_geo_centroid.lineStart = d3_geo_centroidRingStart; | |
}, | |
polygonEnd: function() { | |
d3_geo_centroid.lineStart = d3_geo_centroidLineStart; | |
} | |
}; | |
function d3_geo_centroidPoint(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians); | |
d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); | |
} | |
function d3_geo_centroidPointXYZ(x, y, z) { | |
++d3_geo_centroidW0; | |
d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; | |
d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; | |
d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; | |
} | |
function d3_geo_centroidLineStart() { | |
var x0, y0, z0; | |
d3_geo_centroid.point = function(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians); | |
x0 = cosφ * Math.cos(λ); | |
y0 = cosφ * Math.sin(λ); | |
z0 = Math.sin(φ); | |
d3_geo_centroid.point = nextPoint; | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
}; | |
function nextPoint(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); | |
d3_geo_centroidW1 += w; | |
d3_geo_centroidX1 += w * (x0 + (x0 = x)); | |
d3_geo_centroidY1 += w * (y0 + (y0 = y)); | |
d3_geo_centroidZ1 += w * (z0 + (z0 = z)); | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
} | |
} | |
function d3_geo_centroidLineEnd() { | |
d3_geo_centroid.point = d3_geo_centroidPoint; | |
} | |
function d3_geo_centroidRingStart() { | |
var λ00, φ00, x0, y0, z0; | |
d3_geo_centroid.point = function(λ, φ) { | |
λ00 = λ, φ00 = φ; | |
d3_geo_centroid.point = nextPoint; | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians); | |
x0 = cosφ * Math.cos(λ); | |
y0 = cosφ * Math.sin(λ); | |
z0 = Math.sin(φ); | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
}; | |
d3_geo_centroid.lineEnd = function() { | |
nextPoint(λ00, φ00); | |
d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; | |
d3_geo_centroid.point = d3_geo_centroidPoint; | |
}; | |
function nextPoint(λ, φ) { | |
λ *= d3_radians; | |
var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); | |
d3_geo_centroidX2 += v * cx; | |
d3_geo_centroidY2 += v * cy; | |
d3_geo_centroidZ2 += v * cz; | |
d3_geo_centroidW1 += w; | |
d3_geo_centroidX1 += w * (x0 + (x0 = x)); | |
d3_geo_centroidY1 += w * (y0 + (y0 = y)); | |
d3_geo_centroidZ1 += w * (z0 + (z0 = z)); | |
d3_geo_centroidPointXYZ(x0, y0, z0); | |
} | |
} | |
function d3_geo_compose(a, b) { | |
function compose(x, y) { | |
return x = a(x, y), b(x[0], x[1]); | |
} | |
if (a.invert && b.invert) compose.invert = function(x, y) { | |
return x = b.invert(x, y), x && a.invert(x[0], x[1]); | |
}; | |
return compose; | |
} | |
function d3_true() { | |
return true; | |
} | |
function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { | |
var subject = [], clip = []; | |
segments.forEach(function(segment) { | |
if ((n = segment.length - 1) <= 0) return; | |
var n, p0 = segment[0], p1 = segment[n]; | |
if (d3_geo_sphericalEqual(p0, p1)) { | |
listener.lineStart(); | |
for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); | |
listener.lineEnd(); | |
return; | |
} | |
var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); | |
a.o = b; | |
subject.push(a); | |
clip.push(b); | |
a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); | |
b = new d3_geo_clipPolygonIntersection(p1, null, a, true); | |
a.o = b; | |
subject.push(a); | |
clip.push(b); | |
}); | |
clip.sort(compare); | |
d3_geo_clipPolygonLinkCircular(subject); | |
d3_geo_clipPolygonLinkCircular(clip); | |
if (!subject.length) return; | |
for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { | |
clip[i].e = entry = !entry; | |
} | |
var start = subject[0], points, point; | |
while (1) { | |
var current = start, isSubject = true; | |
while (current.v) if ((current = current.n) === start) return; | |
points = current.z; | |
listener.lineStart(); | |
do { | |
current.v = current.o.v = true; | |
if (current.e) { | |
if (isSubject) { | |
for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); | |
} else { | |
interpolate(current.x, current.n.x, 1, listener); | |
} | |
current = current.n; | |
} else { | |
if (isSubject) { | |
points = current.p.z; | |
for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); | |
} else { | |
interpolate(current.x, current.p.x, -1, listener); | |
} | |
current = current.p; | |
} | |
current = current.o; | |
points = current.z; | |
isSubject = !isSubject; | |
} while (!current.v); | |
listener.lineEnd(); | |
} | |
} | |
function d3_geo_clipPolygonLinkCircular(array) { | |
if (!(n = array.length)) return; | |
var n, i = 0, a = array[0], b; | |
while (++i < n) { | |
a.n = b = array[i]; | |
b.p = a; | |
a = b; | |
} | |
a.n = b = array[0]; | |
b.p = a; | |
} | |
function d3_geo_clipPolygonIntersection(point, points, other, entry) { | |
this.x = point; | |
this.z = points; | |
this.o = other; | |
this.e = entry; | |
this.v = false; | |
this.n = this.p = null; | |
} | |
function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { | |
return function(rotate, listener) { | |
var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); | |
var clip = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
clip.point = pointRing; | |
clip.lineStart = ringStart; | |
clip.lineEnd = ringEnd; | |
segments = []; | |
polygon = []; | |
}, | |
polygonEnd: function() { | |
clip.point = point; | |
clip.lineStart = lineStart; | |
clip.lineEnd = lineEnd; | |
segments = d3.merge(segments); | |
var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); | |
if (segments.length) { | |
if (!polygonStarted) listener.polygonStart(), polygonStarted = true; | |
d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); | |
} else if (clipStartInside) { | |
if (!polygonStarted) listener.polygonStart(), polygonStarted = true; | |
listener.lineStart(); | |
interpolate(null, null, 1, listener); | |
listener.lineEnd(); | |
} | |
if (polygonStarted) listener.polygonEnd(), polygonStarted = false; | |
segments = polygon = null; | |
}, | |
sphere: function() { | |
listener.polygonStart(); | |
listener.lineStart(); | |
interpolate(null, null, 1, listener); | |
listener.lineEnd(); | |
listener.polygonEnd(); | |
} | |
}; | |
function point(λ, φ) { | |
var point = rotate(λ, φ); | |
if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); | |
} | |
function pointLine(λ, φ) { | |
var point = rotate(λ, φ); | |
line.point(point[0], point[1]); | |
} | |
function lineStart() { | |
clip.point = pointLine; | |
line.lineStart(); | |
} | |
function lineEnd() { | |
clip.point = point; | |
line.lineEnd(); | |
} | |
var segments; | |
var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring; | |
function pointRing(λ, φ) { | |
ring.push([ λ, φ ]); | |
var point = rotate(λ, φ); | |
ringListener.point(point[0], point[1]); | |
} | |
function ringStart() { | |
ringListener.lineStart(); | |
ring = []; | |
} | |
function ringEnd() { | |
pointRing(ring[0][0], ring[0][1]); | |
ringListener.lineEnd(); | |
var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; | |
ring.pop(); | |
polygon.push(ring); | |
ring = null; | |
if (!n) return; | |
if (clean & 1) { | |
segment = ringSegments[0]; | |
var n = segment.length - 1, i = -1, point; | |
if (n > 0) { | |
if (!polygonStarted) listener.polygonStart(), polygonStarted = true; | |
listener.lineStart(); | |
while (++i < n) listener.point((point = segment[i])[0], point[1]); | |
listener.lineEnd(); | |
} | |
return; | |
} | |
if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); | |
segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); | |
} | |
return clip; | |
}; | |
} | |
function d3_geo_clipSegmentLength1(segment) { | |
return segment.length > 1; | |
} | |
function d3_geo_clipBufferListener() { | |
var lines = [], line; | |
return { | |
lineStart: function() { | |
lines.push(line = []); | |
}, | |
point: function(λ, φ) { | |
line.push([ λ, φ ]); | |
}, | |
lineEnd: d3_noop, | |
buffer: function() { | |
var buffer = lines; | |
lines = []; | |
line = null; | |
return buffer; | |
}, | |
rejoin: function() { | |
if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); | |
} | |
}; | |
} | |
function d3_geo_clipSort(a, b) { | |
return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]); | |
} | |
var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]); | |
function d3_geo_clipAntimeridianLine(listener) { | |
var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; | |
return { | |
lineStart: function() { | |
listener.lineStart(); | |
clean = 1; | |
}, | |
point: function(λ1, φ1) { | |
var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0); | |
if (abs(dλ - π) < ε) { | |
listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ); | |
listener.point(sλ0, φ0); | |
listener.lineEnd(); | |
listener.lineStart(); | |
listener.point(sλ1, φ0); | |
listener.point(λ1, φ0); | |
clean = 0; | |
} else if (sλ0 !== sλ1 && dλ >= π) { | |
if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; | |
if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; | |
φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); | |
listener.point(sλ0, φ0); | |
listener.lineEnd(); | |
listener.lineStart(); | |
listener.point(sλ1, φ0); | |
clean = 0; | |
} | |
listener.point(λ0 = λ1, φ0 = φ1); | |
sλ0 = sλ1; | |
}, | |
lineEnd: function() { | |
listener.lineEnd(); | |
λ0 = φ0 = NaN; | |
}, | |
clean: function() { | |
return 2 - clean; | |
} | |
}; | |
} | |
function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { | |
var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); | |
return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; | |
} | |
function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { | |
var φ; | |
if (from == null) { | |
φ = direction * halfπ; | |
listener.point(-π, φ); | |
listener.point(0, φ); | |
listener.point(π, φ); | |
listener.point(π, 0); | |
listener.point(π, -φ); | |
listener.point(0, -φ); | |
listener.point(-π, -φ); | |
listener.point(-π, 0); | |
listener.point(-π, φ); | |
} else if (abs(from[0] - to[0]) > ε) { | |
var s = from[0] < to[0] ? π : -π; | |
φ = direction * s / 2; | |
listener.point(-s, φ); | |
listener.point(0, φ); | |
listener.point(s, φ); | |
} else { | |
listener.point(to[0], to[1]); | |
} | |
} | |
function d3_geo_pointInPolygon(point, polygon) { | |
var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; | |
d3_geo_areaRingSum.reset(); | |
for (var i = 0, n = polygon.length; i < n; ++i) { | |
var ring = polygon[i], m = ring.length; | |
if (!m) continue; | |
var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; | |
while (true) { | |
if (j === m) j = 0; | |
point = ring[j]; | |
var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ; | |
d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ))); | |
polarAngle += antimeridian ? dλ + sdλ * τ : dλ; | |
if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { | |
var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); | |
d3_geo_cartesianNormalize(arc); | |
var intersection = d3_geo_cartesianCross(meridianNormal, arc); | |
d3_geo_cartesianNormalize(intersection); | |
var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); | |
if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { | |
winding += antimeridian ^ dλ >= 0 ? 1 : -1; | |
} | |
} | |
if (!j++) break; | |
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; | |
} | |
} | |
return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; | |
} | |
function d3_geo_clipCircle(radius) { | |
var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); | |
return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]); | |
function visible(λ, φ) { | |
return Math.cos(λ) * Math.cos(φ) > cr; | |
} | |
function clipLine(listener) { | |
var point0, c0, v0, v00, clean; | |
return { | |
lineStart: function() { | |
v00 = v0 = false; | |
clean = 1; | |
}, | |
point: function(λ, φ) { | |
var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; | |
if (!point0 && (v00 = v0 = v)) listener.lineStart(); | |
if (v !== v0) { | |
point2 = intersect(point0, point1); | |
if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { | |
point1[0] += ε; | |
point1[1] += ε; | |
v = visible(point1[0], point1[1]); | |
} | |
} | |
if (v !== v0) { | |
clean = 0; | |
if (v) { | |
listener.lineStart(); | |
point2 = intersect(point1, point0); | |
listener.point(point2[0], point2[1]); | |
} else { | |
point2 = intersect(point0, point1); | |
listener.point(point2[0], point2[1]); | |
listener.lineEnd(); | |
} | |
point0 = point2; | |
} else if (notHemisphere && point0 && smallRadius ^ v) { | |
var t; | |
if (!(c & c0) && (t = intersect(point1, point0, true))) { | |
clean = 0; | |
if (smallRadius) { | |
listener.lineStart(); | |
listener.point(t[0][0], t[0][1]); | |
listener.point(t[1][0], t[1][1]); | |
listener.lineEnd(); | |
} else { | |
listener.point(t[1][0], t[1][1]); | |
listener.lineEnd(); | |
listener.lineStart(); | |
listener.point(t[0][0], t[0][1]); | |
} | |
} | |
} | |
if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { | |
listener.point(point1[0], point1[1]); | |
} | |
point0 = point1, v0 = v, c0 = c; | |
}, | |
lineEnd: function() { | |
if (v0) listener.lineEnd(); | |
point0 = null; | |
}, | |
clean: function() { | |
return clean | (v00 && v0) << 1; | |
} | |
}; | |
} | |
function intersect(a, b, two) { | |
var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); | |
var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; | |
if (!determinant) return !two && a; | |
var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); | |
d3_geo_cartesianAdd(A, B); | |
var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); | |
if (t2 < 0) return; | |
var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); | |
d3_geo_cartesianAdd(q, A); | |
q = d3_geo_spherical(q); | |
if (!two) return q; | |
var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; | |
if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; | |
var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε; | |
if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; | |
if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { | |
var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); | |
d3_geo_cartesianAdd(q1, A); | |
return [ q, d3_geo_spherical(q1) ]; | |
} | |
} | |
function code(λ, φ) { | |
var r = smallRadius ? radius : π - radius, code = 0; | |
if (λ < -r) code |= 1; else if (λ > r) code |= 2; | |
if (φ < -r) code |= 4; else if (φ > r) code |= 8; | |
return code; | |
} | |
} | |
function d3_geom_clipLine(x0, y0, x1, y1) { | |
return function(line) { | |
var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; | |
r = x0 - ax; | |
if (!dx && r > 0) return; | |
r /= dx; | |
if (dx < 0) { | |
if (r < t0) return; | |
if (r < t1) t1 = r; | |
} else if (dx > 0) { | |
if (r > t1) return; | |
if (r > t0) t0 = r; | |
} | |
r = x1 - ax; | |
if (!dx && r < 0) return; | |
r /= dx; | |
if (dx < 0) { | |
if (r > t1) return; | |
if (r > t0) t0 = r; | |
} else if (dx > 0) { | |
if (r < t0) return; | |
if (r < t1) t1 = r; | |
} | |
r = y0 - ay; | |
if (!dy && r > 0) return; | |
r /= dy; | |
if (dy < 0) { | |
if (r < t0) return; | |
if (r < t1) t1 = r; | |
} else if (dy > 0) { | |
if (r > t1) return; | |
if (r > t0) t0 = r; | |
} | |
r = y1 - ay; | |
if (!dy && r < 0) return; | |
r /= dy; | |
if (dy < 0) { | |
if (r > t1) return; | |
if (r > t0) t0 = r; | |
} else if (dy > 0) { | |
if (r < t0) return; | |
if (r < t1) t1 = r; | |
} | |
if (t0 > 0) line.a = { | |
x: ax + t0 * dx, | |
y: ay + t0 * dy | |
}; | |
if (t1 < 1) line.b = { | |
x: ax + t1 * dx, | |
y: ay + t1 * dy | |
}; | |
return line; | |
}; | |
} | |
var d3_geo_clipExtentMAX = 1e9; | |
d3.geo.clipExtent = function() { | |
var x0, y0, x1, y1, stream, clip, clipExtent = { | |
stream: function(output) { | |
if (stream) stream.valid = false; | |
stream = clip(output); | |
stream.valid = true; | |
return stream; | |
}, | |
extent: function(_) { | |
if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; | |
clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); | |
if (stream) stream.valid = false, stream = null; | |
return clipExtent; | |
} | |
}; | |
return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); | |
}; | |
function d3_geo_clipExtent(x0, y0, x1, y1) { | |
return function(listener) { | |
var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; | |
var clip = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
listener = bufferListener; | |
segments = []; | |
polygon = []; | |
clean = true; | |
}, | |
polygonEnd: function() { | |
listener = listener_; | |
segments = d3.merge(segments); | |
var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; | |
if (inside || visible) { | |
listener.polygonStart(); | |
if (inside) { | |
listener.lineStart(); | |
interpolate(null, null, 1, listener); | |
listener.lineEnd(); | |
} | |
if (visible) { | |
d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); | |
} | |
listener.polygonEnd(); | |
} | |
segments = polygon = ring = null; | |
} | |
}; | |
function insidePolygon(p) { | |
var wn = 0, n = polygon.length, y = p[1]; | |
for (var i = 0; i < n; ++i) { | |
for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { | |
b = v[j]; | |
if (a[1] <= y) { | |
if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; | |
} else { | |
if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; | |
} | |
a = b; | |
} | |
} | |
return wn !== 0; | |
} | |
function interpolate(from, to, direction, listener) { | |
var a = 0, a1 = 0; | |
if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { | |
do { | |
listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); | |
} while ((a = (a + direction + 4) % 4) !== a1); | |
} else { | |
listener.point(to[0], to[1]); | |
} | |
} | |
function pointVisible(x, y) { | |
return x0 <= x && x <= x1 && y0 <= y && y <= y1; | |
} | |
function point(x, y) { | |
if (pointVisible(x, y)) listener.point(x, y); | |
} | |
var x__, y__, v__, x_, y_, v_, first, clean; | |
function lineStart() { | |
clip.point = linePoint; | |
if (polygon) polygon.push(ring = []); | |
first = true; | |
v_ = false; | |
x_ = y_ = NaN; | |
} | |
function lineEnd() { | |
if (segments) { | |
linePoint(x__, y__); | |
if (v__ && v_) bufferListener.rejoin(); | |
segments.push(bufferListener.buffer()); | |
} | |
clip.point = point; | |
if (v_) listener.lineEnd(); | |
} | |
function linePoint(x, y) { | |
x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); | |
y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); | |
var v = pointVisible(x, y); | |
if (polygon) ring.push([ x, y ]); | |
if (first) { | |
x__ = x, y__ = y, v__ = v; | |
first = false; | |
if (v) { | |
listener.lineStart(); | |
listener.point(x, y); | |
} | |
} else { | |
if (v && v_) listener.point(x, y); else { | |
var l = { | |
a: { | |
x: x_, | |
y: y_ | |
}, | |
b: { | |
x: x, | |
y: y | |
} | |
}; | |
if (clipLine(l)) { | |
if (!v_) { | |
listener.lineStart(); | |
listener.point(l.a.x, l.a.y); | |
} | |
listener.point(l.b.x, l.b.y); | |
if (!v) listener.lineEnd(); | |
clean = false; | |
} else if (v) { | |
listener.lineStart(); | |
listener.point(x, y); | |
clean = false; | |
} | |
} | |
} | |
x_ = x, y_ = y, v_ = v; | |
} | |
return clip; | |
}; | |
function corner(p, direction) { | |
return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; | |
} | |
function compare(a, b) { | |
return comparePoints(a.x, b.x); | |
} | |
function comparePoints(a, b) { | |
var ca = corner(a, 1), cb = corner(b, 1); | |
return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; | |
} | |
} | |
function d3_geo_conic(projectAt) { | |
var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); | |
p.parallels = function(_) { | |
if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; | |
return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); | |
}; | |
return p; | |
} | |
function d3_geo_conicEqualArea(φ0, φ1) { | |
var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; | |
function forward(λ, φ) { | |
var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; | |
return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; | |
} | |
forward.invert = function(x, y) { | |
var ρ0_y = ρ0 - y; | |
return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; | |
}; | |
return forward; | |
} | |
(d3.geo.conicEqualArea = function() { | |
return d3_geo_conic(d3_geo_conicEqualArea); | |
}).raw = d3_geo_conicEqualArea; | |
d3.geo.albers = function() { | |
return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); | |
}; | |
d3.geo.albersUsa = function() { | |
var lower48 = d3.geo.albers(); | |
var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); | |
var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); | |
var point, pointStream = { | |
point: function(x, y) { | |
point = [ x, y ]; | |
} | |
}, lower48Point, alaskaPoint, hawaiiPoint; | |
function albersUsa(coordinates) { | |
var x = coordinates[0], y = coordinates[1]; | |
point = null; | |
(lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); | |
return point; | |
} | |
albersUsa.invert = function(coordinates) { | |
var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; | |
return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); | |
}; | |
albersUsa.stream = function(stream) { | |
var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); | |
return { | |
point: function(x, y) { | |
lower48Stream.point(x, y); | |
alaskaStream.point(x, y); | |
hawaiiStream.point(x, y); | |
}, | |
sphere: function() { | |
lower48Stream.sphere(); | |
alaskaStream.sphere(); | |
hawaiiStream.sphere(); | |
}, | |
lineStart: function() { | |
lower48Stream.lineStart(); | |
alaskaStream.lineStart(); | |
hawaiiStream.lineStart(); | |
}, | |
lineEnd: function() { | |
lower48Stream.lineEnd(); | |
alaskaStream.lineEnd(); | |
hawaiiStream.lineEnd(); | |
}, | |
polygonStart: function() { | |
lower48Stream.polygonStart(); | |
alaskaStream.polygonStart(); | |
hawaiiStream.polygonStart(); | |
}, | |
polygonEnd: function() { | |
lower48Stream.polygonEnd(); | |
alaskaStream.polygonEnd(); | |
hawaiiStream.polygonEnd(); | |
} | |
}; | |
}; | |
albersUsa.precision = function(_) { | |
if (!arguments.length) return lower48.precision(); | |
lower48.precision(_); | |
alaska.precision(_); | |
hawaii.precision(_); | |
return albersUsa; | |
}; | |
albersUsa.scale = function(_) { | |
if (!arguments.length) return lower48.scale(); | |
lower48.scale(_); | |
alaska.scale(_ * .35); | |
hawaii.scale(_); | |
return albersUsa.translate(lower48.translate()); | |
}; | |
albersUsa.translate = function(_) { | |
if (!arguments.length) return lower48.translate(); | |
var k = lower48.scale(), x = +_[0], y = +_[1]; | |
lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; | |
alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; | |
hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; | |
return albersUsa; | |
}; | |
return albersUsa.scale(1070); | |
}; | |
var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { | |
point: d3_noop, | |
lineStart: d3_noop, | |
lineEnd: d3_noop, | |
polygonStart: function() { | |
d3_geo_pathAreaPolygon = 0; | |
d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; | |
}, | |
polygonEnd: function() { | |
d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; | |
d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); | |
} | |
}; | |
function d3_geo_pathAreaRingStart() { | |
var x00, y00, x0, y0; | |
d3_geo_pathArea.point = function(x, y) { | |
d3_geo_pathArea.point = nextPoint; | |
x00 = x0 = x, y00 = y0 = y; | |
}; | |
function nextPoint(x, y) { | |
d3_geo_pathAreaPolygon += y0 * x - x0 * y; | |
x0 = x, y0 = y; | |
} | |
d3_geo_pathArea.lineEnd = function() { | |
nextPoint(x00, y00); | |
}; | |
} | |
var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; | |
var d3_geo_pathBounds = { | |
point: d3_geo_pathBoundsPoint, | |
lineStart: d3_noop, | |
lineEnd: d3_noop, | |
polygonStart: d3_noop, | |
polygonEnd: d3_noop | |
}; | |
function d3_geo_pathBoundsPoint(x, y) { | |
if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; | |
if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; | |
if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; | |
if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; | |
} | |
function d3_geo_pathBuffer() { | |
var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; | |
var stream = { | |
point: point, | |
lineStart: function() { | |
stream.point = pointLineStart; | |
}, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
stream.lineEnd = lineEndPolygon; | |
}, | |
polygonEnd: function() { | |
stream.lineEnd = lineEnd; | |
stream.point = point; | |
}, | |
pointRadius: function(_) { | |
pointCircle = d3_geo_pathBufferCircle(_); | |
return stream; | |
}, | |
result: function() { | |
if (buffer.length) { | |
var result = buffer.join(""); | |
buffer = []; | |
return result; | |
} | |
} | |
}; | |
function point(x, y) { | |
buffer.push("M", x, ",", y, pointCircle); | |
} | |
function pointLineStart(x, y) { | |
buffer.push("M", x, ",", y); | |
stream.point = pointLine; | |
} | |
function pointLine(x, y) { | |
buffer.push("L", x, ",", y); | |
} | |
function lineEnd() { | |
stream.point = point; | |
} | |
function lineEndPolygon() { | |
buffer.push("Z"); | |
} | |
return stream; | |
} | |
function d3_geo_pathBufferCircle(radius) { | |
return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; | |
} | |
var d3_geo_pathCentroid = { | |
point: d3_geo_pathCentroidPoint, | |
lineStart: d3_geo_pathCentroidLineStart, | |
lineEnd: d3_geo_pathCentroidLineEnd, | |
polygonStart: function() { | |
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; | |
}, | |
polygonEnd: function() { | |
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; | |
d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; | |
d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; | |
} | |
}; | |
function d3_geo_pathCentroidPoint(x, y) { | |
d3_geo_centroidX0 += x; | |
d3_geo_centroidY0 += y; | |
++d3_geo_centroidZ0; | |
} | |
function d3_geo_pathCentroidLineStart() { | |
var x0, y0; | |
d3_geo_pathCentroid.point = function(x, y) { | |
d3_geo_pathCentroid.point = nextPoint; | |
d3_geo_pathCentroidPoint(x0 = x, y0 = y); | |
}; | |
function nextPoint(x, y) { | |
var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); | |
d3_geo_centroidX1 += z * (x0 + x) / 2; | |
d3_geo_centroidY1 += z * (y0 + y) / 2; | |
d3_geo_centroidZ1 += z; | |
d3_geo_pathCentroidPoint(x0 = x, y0 = y); | |
} | |
} | |
function d3_geo_pathCentroidLineEnd() { | |
d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; | |
} | |
function d3_geo_pathCentroidRingStart() { | |
var x00, y00, x0, y0; | |
d3_geo_pathCentroid.point = function(x, y) { | |
d3_geo_pathCentroid.point = nextPoint; | |
d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); | |
}; | |
function nextPoint(x, y) { | |
var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); | |
d3_geo_centroidX1 += z * (x0 + x) / 2; | |
d3_geo_centroidY1 += z * (y0 + y) / 2; | |
d3_geo_centroidZ1 += z; | |
z = y0 * x - x0 * y; | |
d3_geo_centroidX2 += z * (x0 + x); | |
d3_geo_centroidY2 += z * (y0 + y); | |
d3_geo_centroidZ2 += z * 3; | |
d3_geo_pathCentroidPoint(x0 = x, y0 = y); | |
} | |
d3_geo_pathCentroid.lineEnd = function() { | |
nextPoint(x00, y00); | |
}; | |
} | |
function d3_geo_pathContext(context) { | |
var pointRadius = 4.5; | |
var stream = { | |
point: point, | |
lineStart: function() { | |
stream.point = pointLineStart; | |
}, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
stream.lineEnd = lineEndPolygon; | |
}, | |
polygonEnd: function() { | |
stream.lineEnd = lineEnd; | |
stream.point = point; | |
}, | |
pointRadius: function(_) { | |
pointRadius = _; | |
return stream; | |
}, | |
result: d3_noop | |
}; | |
function point(x, y) { | |
context.moveTo(x + pointRadius, y); | |
context.arc(x, y, pointRadius, 0, τ); | |
} | |
function pointLineStart(x, y) { | |
context.moveTo(x, y); | |
stream.point = pointLine; | |
} | |
function pointLine(x, y) { | |
context.lineTo(x, y); | |
} | |
function lineEnd() { | |
stream.point = point; | |
} | |
function lineEndPolygon() { | |
context.closePath(); | |
} | |
return stream; | |
} | |
function d3_geo_resample(project) { | |
var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; | |
function resample(stream) { | |
return (maxDepth ? resampleRecursive : resampleNone)(stream); | |
} | |
function resampleNone(stream) { | |
return d3_geo_transformPoint(stream, function(x, y) { | |
x = project(x, y); | |
stream.point(x[0], x[1]); | |
}); | |
} | |
function resampleRecursive(stream) { | |
var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; | |
var resample = { | |
point: point, | |
lineStart: lineStart, | |
lineEnd: lineEnd, | |
polygonStart: function() { | |
stream.polygonStart(); | |
resample.lineStart = ringStart; | |
}, | |
polygonEnd: function() { | |
stream.polygonEnd(); | |
resample.lineStart = lineStart; | |
} | |
}; | |
function point(x, y) { | |
x = project(x, y); | |
stream.point(x[0], x[1]); | |
} | |
function lineStart() { | |
x0 = NaN; | |
resample.point = linePoint; | |
stream.lineStart(); | |
} | |
function linePoint(λ, φ) { | |
var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); | |
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); | |
stream.point(x0, y0); | |
} | |
function lineEnd() { | |
resample.point = point; | |
stream.lineEnd(); | |
} | |
function ringStart() { | |
lineStart(); | |
resample.point = ringPoint; | |
resample.lineEnd = ringEnd; | |
} | |
function ringPoint(λ, φ) { | |
linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; | |
resample.point = linePoint; | |
} | |
function ringEnd() { | |
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); | |
resample.lineEnd = lineEnd; | |
lineEnd(); | |
} | |
return resample; | |
} | |
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { | |
var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; | |
if (d2 > 4 * δ2 && depth--) { | |
var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; | |
if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { | |
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); | |
stream.point(x2, y2); | |
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); | |
} | |
} | |
} | |
resample.precision = function(_) { | |
if (!arguments.length) return Math.sqrt(δ2); | |
maxDepth = (δ2 = _ * _) > 0 && 16; | |
return resample; | |
}; | |
return resample; | |
} | |
d3.geo.path = function() { | |
var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; | |
function path(object) { | |
if (object) { | |
if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); | |
if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); | |
d3.geo.stream(object, cacheStream); | |
} | |
return contextStream.result(); | |
} | |
path.area = function(object) { | |
d3_geo_pathAreaSum = 0; | |
d3.geo.stream(object, projectStream(d3_geo_pathArea)); | |
return d3_geo_pathAreaSum; | |
}; | |
path.centroid = function(object) { | |
d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; | |
d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); | |
return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; | |
}; | |
path.bounds = function(object) { | |
d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); | |
d3.geo.stream(object, projectStream(d3_geo_pathBounds)); | |
return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; | |
}; | |
path.projection = function(_) { | |
if (!arguments.length) return projection; | |
projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; | |
return reset(); | |
}; | |
path.context = function(_) { | |
if (!arguments.length) return context; | |
contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); | |
if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); | |
return reset(); | |
}; | |
path.pointRadius = function(_) { | |
if (!arguments.length) return pointRadius; | |
pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); | |
return path; | |
}; | |
function reset() { | |
cacheStream = null; | |
return path; | |
} | |
return path.projection(d3.geo.albersUsa()).context(null); | |
}; | |
function d3_geo_pathProjectStream(project) { | |
var resample = d3_geo_resample(function(x, y) { | |
return project([ x * d3_degrees, y * d3_degrees ]); | |
}); | |
return function(stream) { | |
return d3_geo_projectionRadians(resample(stream)); | |
}; | |
} | |
d3.geo.transform = function(methods) { | |
return { | |
stream: function(stream) { | |
var transform = new d3_geo_transform(stream); | |
for (var k in methods) transform[k] = methods[k]; | |
return transform; | |
} | |
}; | |
}; | |
function d3_geo_transform(stream) { | |
this.stream = stream; | |
} | |
d3_geo_transform.prototype = { | |
point: function(x, y) { | |
this.stream.point(x, y); | |
}, | |
sphere: function() { | |
this.stream.sphere(); | |
}, | |
lineStart: function() { | |
this.stream.lineStart(); | |
}, | |
lineEnd: function() { | |
this.stream.lineEnd(); | |
}, | |
polygonStart: function() { | |
this.stream.polygonStart(); | |
}, | |
polygonEnd: function() { | |
this.stream.polygonEnd(); | |
} | |
}; | |
function d3_geo_transformPoint(stream, point) { | |
return { | |
point: point, | |
sphere: function() { | |
stream.sphere(); | |
}, | |
lineStart: function() { | |
stream.lineStart(); | |
}, | |
lineEnd: function() { | |
stream.lineEnd(); | |
}, | |
polygonStart: function() { | |
stream.polygonStart(); | |
}, | |
polygonEnd: function() { | |
stream.polygonEnd(); | |
} | |
}; | |
} | |
d3.geo.projection = d3_geo_projection; | |
d3.geo.projectionMutator = d3_geo_projectionMutator; | |
function d3_geo_projection(project) { | |
return d3_geo_projectionMutator(function() { | |
return project; | |
})(); | |
} | |
function d3_geo_projectionMutator(projectAt) { | |
var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { | |
x = project(x, y); | |
return [ x[0] * k + δx, δy - x[1] * k ]; | |
}), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; | |
function projection(point) { | |
point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); | |
return [ point[0] * k + δx, δy - point[1] * k ]; | |
} | |
function invert(point) { | |
point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); | |
return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; | |
} | |
projection.stream = function(output) { | |
if (stream) stream.valid = false; | |
stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); | |
stream.valid = true; | |
return stream; | |
}; | |
projection.clipAngle = function(_) { | |
if (!arguments.length) return clipAngle; | |
preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); | |
return invalidate(); | |
}; | |
projection.clipExtent = function(_) { | |
if (!arguments.length) return clipExtent; | |
clipExtent = _; | |
postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; | |
return invalidate(); | |
}; | |
projection.scale = function(_) { | |
if (!arguments.length) return k; | |
k = +_; | |
return reset(); | |
}; | |
projection.translate = function(_) { | |
if (!arguments.length) return [ x, y ]; | |
x = +_[0]; | |
y = +_[1]; | |
return reset(); | |
}; | |
projection.center = function(_) { | |
if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; | |
λ = _[0] % 360 * d3_radians; | |
φ = _[1] % 360 * d3_radians; | |
return reset(); | |
}; | |
projection.rotate = function(_) { | |
if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; | |
δλ = _[0] % 360 * d3_radians; | |
δφ = _[1] % 360 * d3_radians; | |
δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; | |
return reset(); | |
}; | |
d3.rebind(projection, projectResample, "precision"); | |
function reset() { | |
projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); | |
var center = project(λ, φ); | |
δx = x - center[0] * k; | |
δy = y + center[1] * k; | |
return invalidate(); | |
} | |
function invalidate() { | |
if (stream) stream.valid = false, stream = null; | |
return projection; | |
} | |
return function() { | |
project = projectAt.apply(this, arguments); | |
projection.invert = project.invert && invert; | |
return reset(); | |
}; | |
} | |
function d3_geo_projectionRadians(stream) { | |
return d3_geo_transformPoint(stream, function(x, y) { | |
stream.point(x * d3_radians, y * d3_radians); | |
}); | |
} | |
function d3_geo_equirectangular(λ, φ) { | |
return [ λ, φ ]; | |
} | |
(d3.geo.equirectangular = function() { | |
return d3_geo_projection(d3_geo_equirectangular); | |
}).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; | |
d3.geo.rotation = function(rotate) { | |
rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); | |
function forward(coordinates) { | |
coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); | |
return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; | |
} | |
forward.invert = function(coordinates) { | |
coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); | |
return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; | |
}; | |
return forward; | |
}; | |
function d3_geo_identityRotation(λ, φ) { | |
return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; | |
} | |
d3_geo_identityRotation.invert = d3_geo_equirectangular; | |
function d3_geo_rotation(δλ, δφ, δγ) { | |
return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; | |
} | |
function d3_geo_forwardRotationλ(δλ) { | |
return function(λ, φ) { | |
return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; | |
}; | |
} | |
function d3_geo_rotationλ(δλ) { | |
var rotation = d3_geo_forwardRotationλ(δλ); | |
rotation.invert = d3_geo_forwardRotationλ(-δλ); | |
return rotation; | |
} | |
function d3_geo_rotationφγ(δφ, δγ) { | |
var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); | |
function rotation(λ, φ) { | |
var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; | |
return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; | |
} | |
rotation.invert = function(λ, φ) { | |
var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; | |
return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; | |
}; | |
return rotation; | |
} | |
d3.geo.circle = function() { | |
var origin = [ 0, 0 ], angle, precision = 6, interpolate; | |
function circle() { | |
var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; | |
interpolate(null, null, 1, { | |
point: function(x, y) { | |
ring.push(x = rotate(x, y)); | |
x[0] *= d3_degrees, x[1] *= d3_degrees; | |
} | |
}); | |
return { | |
type: "Polygon", | |
coordinates: [ ring ] | |
}; | |
} | |
circle.origin = function(x) { | |
if (!arguments.length) return origin; | |
origin = x; | |
return circle; | |
}; | |
circle.angle = function(x) { | |
if (!arguments.length) return angle; | |
interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); | |
return circle; | |
}; | |
circle.precision = function(_) { | |
if (!arguments.length) return precision; | |
interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); | |
return circle; | |
}; | |
return circle.angle(90); | |
}; | |
function d3_geo_circleInterpolate(radius, precision) { | |
var cr = Math.cos(radius), sr = Math.sin(radius); | |
return function(from, to, direction, listener) { | |
var step = direction * precision; | |
if (from != null) { | |
from = d3_geo_circleAngle(cr, from); | |
to = d3_geo_circleAngle(cr, to); | |
if (direction > 0 ? from < to : from > to) from += direction * τ; | |
} else { | |
from = radius + direction * τ; | |
to = radius - .5 * step; | |
} | |
for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { | |
listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); | |
} | |
}; | |
} | |
function d3_geo_circleAngle(cr, point) { | |
var a = d3_geo_cartesian(point); | |
a[0] -= cr; | |
d3_geo_cartesianNormalize(a); | |
var angle = d3_acos(-a[1]); | |
return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); | |
} | |
d3.geo.distance = function(a, b) { | |
var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; | |
return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); | |
}; | |
d3.geo.graticule = function() { | |
var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; | |
function graticule() { | |
return { | |
type: "MultiLineString", | |
coordinates: lines() | |
}; | |
} | |
function lines() { | |
return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { | |
return abs(x % DX) > ε; | |
}).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { | |
return abs(y % DY) > ε; | |
}).map(y)); | |
} | |
graticule.lines = function() { | |
return lines().map(function(coordinates) { | |
return { | |
type: "LineString", | |
coordinates: coordinates | |
}; | |
}); | |
}; | |
graticule.outline = function() { | |
return { | |
type: "Polygon", | |
coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] | |
}; | |
}; | |
graticule.extent = function(_) { | |
if (!arguments.length) return graticule.minorExtent(); | |
return graticule.majorExtent(_).minorExtent(_); | |
}; | |
graticule.majorExtent = function(_) { | |
if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; | |
X0 = +_[0][0], X1 = +_[1][0]; | |
Y0 = +_[0][1], Y1 = +_[1][1]; | |
if (X0 > X1) _ = X0, X0 = X1, X1 = _; | |
if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; | |
return graticule.precision(precision); | |
}; | |
graticule.minorExtent = function(_) { | |
if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; | |
x0 = +_[0][0], x1 = +_[1][0]; | |
y0 = +_[0][1], y1 = +_[1][1]; | |
if (x0 > x1) _ = x0, x0 = x1, x1 = _; | |
if (y0 > y1) _ = y0, y0 = y1, y1 = _; | |
return graticule.precision(precision); | |
}; | |
graticule.step = function(_) { | |
if (!arguments.length) return graticule.minorStep(); | |
return graticule.majorStep(_).minorStep(_); | |
}; | |
graticule.majorStep = function(_) { | |
if (!arguments.length) return [ DX, DY ]; | |
DX = +_[0], DY = +_[1]; | |
return graticule; | |
}; | |
graticule.minorStep = function(_) { | |
if (!arguments.length) return [ dx, dy ]; | |
dx = +_[0], dy = +_[1]; | |
return graticule; | |
}; | |
graticule.precision = function(_) { | |
if (!arguments.length) return precision; | |
precision = +_; | |
x = d3_geo_graticuleX(y0, y1, 90); | |
y = d3_geo_graticuleY(x0, x1, precision); | |
X = d3_geo_graticuleX(Y0, Y1, 90); | |
Y = d3_geo_graticuleY(X0, X1, precision); | |
return graticule; | |
}; | |
return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); | |
}; | |
function d3_geo_graticuleX(y0, y1, dy) { | |
var y = d3.range(y0, y1 - ε, dy).concat(y1); | |
return function(x) { | |
return y.map(function(y) { | |
return [ x, y ]; | |
}); | |
}; | |
} | |
function d3_geo_graticuleY(x0, x1, dx) { | |
var x = d3.range(x0, x1 - ε, dx).concat(x1); | |
return function(y) { | |
return x.map(function(x) { | |
return [ x, y ]; | |
}); | |
}; | |
} | |
function d3_source(d) { | |
return d.source; | |
} | |
function d3_target(d) { | |
return d.target; | |
} | |
d3.geo.greatArc = function() { | |
var source = d3_source, source_, target = d3_target, target_; | |
function greatArc() { | |
return { | |
type: "LineString", | |
coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] | |
}; | |
} | |
greatArc.distance = function() { | |
return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); | |
}; | |
greatArc.source = function(_) { | |
if (!arguments.length) return source; | |
source = _, source_ = typeof _ === "function" ? null : _; | |
return greatArc; | |
}; | |
greatArc.target = function(_) { | |
if (!arguments.length) return target; | |
target = _, target_ = typeof _ === "function" ? null : _; | |
return greatArc; | |
}; | |
greatArc.precision = function() { | |
return arguments.length ? greatArc : 0; | |
}; | |
return greatArc; | |
}; | |
d3.geo.interpolate = function(source, target) { | |
return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); | |
}; | |
function d3_geo_interpolate(x0, y0, x1, y1) { | |
var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); | |
var interpolate = d ? function(t) { | |
var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; | |
return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; | |
} : function() { | |
return [ x0 * d3_degrees, y0 * d3_degrees ]; | |
}; | |
interpolate.distance = d; | |
return interpolate; | |
} | |
d3.geo.length = function(object) { | |
d3_geo_lengthSum = 0; | |
d3.geo.stream(object, d3_geo_length); | |
return d3_geo_lengthSum; | |
}; | |
var d3_geo_lengthSum; | |
var d3_geo_length = { | |
sphere: d3_noop, | |
point: d3_noop, | |
lineStart: d3_geo_lengthLineStart, | |
lineEnd: d3_noop, | |
polygonStart: d3_noop, | |
polygonEnd: d3_noop | |
}; | |
function d3_geo_lengthLineStart() { | |
var λ0, sinφ0, cosφ0; | |
d3_geo_length.point = function(λ, φ) { | |
λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); | |
d3_geo_length.point = nextPoint; | |
}; | |
d3_geo_length.lineEnd = function() { | |
d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; | |
}; | |
function nextPoint(λ, φ) { | |
var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); | |
d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); | |
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; | |
} | |
} | |
function d3_geo_azimuthal(scale, angle) { | |
function azimuthal(λ, φ) { | |
var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); | |
return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; | |
} | |
azimuthal.invert = function(x, y) { | |
var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); | |
return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; | |
}; | |
return azimuthal; | |
} | |
var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { | |
return Math.sqrt(2 / (1 + cosλcosφ)); | |
}, function(ρ) { | |
return 2 * Math.asin(ρ / 2); | |
}); | |
(d3.geo.azimuthalEqualArea = function() { | |
return d3_geo_projection(d3_geo_azimuthalEqualArea); | |
}).raw = d3_geo_azimuthalEqualArea; | |
var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { | |
var c = Math.acos(cosλcosφ); | |
return c && c / Math.sin(c); | |
}, d3_identity); | |
(d3.geo.azimuthalEquidistant = function() { | |
return d3_geo_projection(d3_geo_azimuthalEquidistant); | |
}).raw = d3_geo_azimuthalEquidistant; | |
function d3_geo_conicConformal(φ0, φ1) { | |
var cosφ0 = Math.cos(φ0), t = function(φ) { | |
return Math.tan(π / 4 + φ / 2); | |
}, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; | |
if (!n) return d3_geo_mercator; | |
function forward(λ, φ) { | |
if (F > 0) { | |
if (φ < -halfπ + ε) φ = -halfπ + ε; | |
} else { | |
if (φ > halfπ - ε) φ = halfπ - ε; | |
} | |
var ρ = F / Math.pow(t(φ), n); | |
return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; | |
} | |
forward.invert = function(x, y) { | |
var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); | |
return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ]; | |
}; | |
return forward; | |
} | |
(d3.geo.conicConformal = function() { | |
return d3_geo_conic(d3_geo_conicConformal); | |
}).raw = d3_geo_conicConformal; | |
function d3_geo_conicEquidistant(φ0, φ1) { | |
var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; | |
if (abs(n) < ε) return d3_geo_equirectangular; | |
function forward(λ, φ) { | |
var ρ = G - φ; | |
return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; | |
} | |
forward.invert = function(x, y) { | |
var ρ0_y = G - y; | |
return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; | |
}; | |
return forward; | |
} | |
(d3.geo.conicEquidistant = function() { | |
return d3_geo_conic(d3_geo_conicEquidistant); | |
}).raw = d3_geo_conicEquidistant; | |
var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { | |
return 1 / cosλcosφ; | |
}, Math.atan); | |
(d3.geo.gnomonic = function() { | |
return d3_geo_projection(d3_geo_gnomonic); | |
}).raw = d3_geo_gnomonic; | |
function d3_geo_mercator(λ, φ) { | |
return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; | |
} | |
d3_geo_mercator.invert = function(x, y) { | |
return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ]; | |
}; | |
function d3_geo_mercatorProjection(project) { | |
var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; | |
m.scale = function() { | |
var v = scale.apply(m, arguments); | |
return v === m ? clipAuto ? m.clipExtent(null) : m : v; | |
}; | |
m.translate = function() { | |
var v = translate.apply(m, arguments); | |
return v === m ? clipAuto ? m.clipExtent(null) : m : v; | |
}; | |
m.clipExtent = function(_) { | |
var v = clipExtent.apply(m, arguments); | |
if (v === m) { | |
if (clipAuto = _ == null) { | |
var k = π * scale(), t = translate(); | |
clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); | |
} | |
} else if (clipAuto) { | |
v = null; | |
} | |
return v; | |
}; | |
return m.clipExtent(null); | |
} | |
(d3.geo.mercator = function() { | |
return d3_geo_mercatorProjection(d3_geo_mercator); | |
}).raw = d3_geo_mercator; | |
var d3_geo_orthographic = d3_geo_azimuthal(function() { | |
return 1; | |
}, Math.asin); | |
(d3.geo.orthographic = function() { | |
return d3_geo_projection(d3_geo_orthographic); | |
}).raw = d3_geo_orthographic; | |
var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { | |
return 1 / (1 + cosλcosφ); | |
}, function(ρ) { | |
return 2 * Math.atan(ρ); | |
}); | |
(d3.geo.stereographic = function() { | |
return d3_geo_projection(d3_geo_stereographic); | |
}).raw = d3_geo_stereographic; | |
function d3_geo_transverseMercator(λ, φ) { | |
return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ]; | |
} | |
d3_geo_transverseMercator.invert = function(x, y) { | |
return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ]; | |
}; | |
(d3.geo.transverseMercator = function() { | |
var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; | |
projection.center = function(_) { | |
return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]); | |
}; | |
projection.rotate = function(_) { | |
return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), | |
[ _[0], _[1], _[2] - 90 ]); | |
}; | |
return rotate([ 0, 0, 90 ]); | |
}).raw = d3_geo_transverseMercator; | |
d3.geom = {}; | |
function d3_geom_pointX(d) { | |
return d[0]; | |
} | |
function d3_geom_pointY(d) { | |
return d[1]; | |
} | |
d3.geom.hull = function(vertices) { | |
var x = d3_geom_pointX, y = d3_geom_pointY; | |
if (arguments.length) return hull(vertices); | |
function hull(data) { | |
if (data.length < 3) return []; | |
var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; | |
for (i = 0; i < n; i++) { | |
points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); | |
} | |
points.sort(d3_geom_hullOrder); | |
for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); | |
var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); | |
var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; | |
for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); | |
for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); | |
return polygon; | |
} | |
hull.x = function(_) { | |
return arguments.length ? (x = _, hull) : x; | |
}; | |
hull.y = function(_) { | |
return arguments.length ? (y = _, hull) : y; | |
}; | |
return hull; | |
}; | |
function d3_geom_hullUpper(points) { | |
var n = points.length, hull = [ 0, 1 ], hs = 2; | |
for (var i = 2; i < n; i++) { | |
while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; | |
hull[hs++] = i; | |
} | |
return hull.slice(0, hs); | |
} | |
function d3_geom_hullOrder(a, b) { | |
return a[0] - b[0] || a[1] - b[1]; | |
} | |
d3.geom.polygon = function(coordinates) { | |
d3_subclass(coordinates, d3_geom_polygonPrototype); | |
return coordinates; | |
}; | |
var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; | |
d3_geom_polygonPrototype.area = function() { | |
var i = -1, n = this.length, a, b = this[n - 1], area = 0; | |
while (++i < n) { | |
a = b; | |
b = this[i]; | |
area += a[1] * b[0] - a[0] * b[1]; | |
} | |
return area * .5; | |
}; | |
d3_geom_polygonPrototype.centroid = function(k) { | |
var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; | |
if (!arguments.length) k = -1 / (6 * this.area()); | |
while (++i < n) { | |
a = b; | |
b = this[i]; | |
c = a[0] * b[1] - b[0] * a[1]; | |
x += (a[0] + b[0]) * c; | |
y += (a[1] + b[1]) * c; | |
} | |
return [ x * k, y * k ]; | |
}; | |
d3_geom_polygonPrototype.clip = function(subject) { | |
var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; | |
while (++i < n) { | |
input = subject.slice(); | |
subject.length = 0; | |
b = this[i]; | |
c = input[(m = input.length - closed) - 1]; | |
j = -1; | |
while (++j < m) { | |
d = input[j]; | |
if (d3_geom_polygonInside(d, a, b)) { | |
if (!d3_geom_polygonInside(c, a, b)) { | |
subject.push(d3_geom_polygonIntersect(c, d, a, b)); | |
} | |
subject.push(d); | |
} else if (d3_geom_polygonInside(c, a, b)) { | |
subject.push(d3_geom_polygonIntersect(c, d, a, b)); | |
} | |
c = d; | |
} | |
if (closed) subject.push(subject[0]); | |
a = b; | |
} | |
return subject; | |
}; | |
function d3_geom_polygonInside(p, a, b) { | |
return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); | |
} | |
function d3_geom_polygonIntersect(c, d, a, b) { | |
var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); | |
return [ x1 + ua * x21, y1 + ua * y21 ]; | |
} | |
function d3_geom_polygonClosed(coordinates) { | |
var a = coordinates[0], b = coordinates[coordinates.length - 1]; | |
return !(a[0] - b[0] || a[1] - b[1]); | |
} | |
var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; | |
function d3_geom_voronoiBeach() { | |
d3_geom_voronoiRedBlackNode(this); | |
this.edge = this.site = this.circle = null; | |
} | |
function d3_geom_voronoiCreateBeach(site) { | |
var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); | |
beach.site = site; | |
return beach; | |
} | |
function d3_geom_voronoiDetachBeach(beach) { | |
d3_geom_voronoiDetachCircle(beach); | |
d3_geom_voronoiBeaches.remove(beach); | |
d3_geom_voronoiBeachPool.push(beach); | |
d3_geom_voronoiRedBlackNode(beach); | |
} | |
function d3_geom_voronoiRemoveBeach(beach) { | |
var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { | |
x: x, | |
y: y | |
}, previous = beach.P, next = beach.N, disappearing = [ beach ]; | |
d3_geom_voronoiDetachBeach(beach); | |
var lArc = previous; | |
while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { | |
previous = lArc.P; | |
disappearing.unshift(lArc); | |
d3_geom_voronoiDetachBeach(lArc); | |
lArc = previous; | |
} | |
disappearing.unshift(lArc); | |
d3_geom_voronoiDetachCircle(lArc); | |
var rArc = next; | |
while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { | |
next = rArc.N; | |
disappearing.push(rArc); | |
d3_geom_voronoiDetachBeach(rArc); | |
rArc = next; | |
} | |
disappearing.push(rArc); | |
d3_geom_voronoiDetachCircle(rArc); | |
var nArcs = disappearing.length, iArc; | |
for (iArc = 1; iArc < nArcs; ++iArc) { | |
rArc = disappearing[iArc]; | |
lArc = disappearing[iArc - 1]; | |
d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); | |
} | |
lArc = disappearing[0]; | |
rArc = disappearing[nArcs - 1]; | |
rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); | |
d3_geom_voronoiAttachCircle(lArc); | |
d3_geom_voronoiAttachCircle(rArc); | |
} | |
function d3_geom_voronoiAddBeach(site) { | |
var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; | |
while (node) { | |
dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; | |
if (dxl > ε) node = node.L; else { | |
dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); | |
if (dxr > ε) { | |
if (!node.R) { | |
lArc = node; | |
break; | |
} | |
node = node.R; | |
} else { | |
if (dxl > -ε) { | |
lArc = node.P; | |
rArc = node; | |
} else if (dxr > -ε) { | |
lArc = node; | |
rArc = node.N; | |
} else { | |
lArc = rArc = node; | |
} | |
break; | |
} | |
} | |
} | |
var newArc = d3_geom_voronoiCreateBeach(site); | |
d3_geom_voronoiBeaches.insert(lArc, newArc); | |
if (!lArc && !rArc) return; | |
if (lArc === rArc) { | |
d3_geom_voronoiDetachCircle(lArc); | |
rArc = d3_geom_voronoiCreateBeach(lArc.site); | |
d3_geom_voronoiBeaches.insert(newArc, rArc); | |
newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); | |
d3_geom_voronoiAttachCircle(lArc); | |
d3_geom_voronoiAttachCircle(rArc); | |
return; | |
} | |
if (!rArc) { | |
newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); | |
return; | |
} | |
d3_geom_voronoiDetachCircle(lArc); | |
d3_geom_voronoiDetachCircle(rArc); | |
var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { | |
x: (cy * hb - by * hc) / d + ax, | |
y: (bx * hc - cx * hb) / d + ay | |
}; | |
d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); | |
newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); | |
rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); | |
d3_geom_voronoiAttachCircle(lArc); | |
d3_geom_voronoiAttachCircle(rArc); | |
} | |
function d3_geom_voronoiLeftBreakPoint(arc, directrix) { | |
var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; | |
if (!pby2) return rfocx; | |
var lArc = arc.P; | |
if (!lArc) return -Infinity; | |
site = lArc.site; | |
var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; | |
if (!plby2) return lfocx; | |
var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; | |
if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; | |
return (rfocx + lfocx) / 2; | |
} | |
function d3_geom_voronoiRightBreakPoint(arc, directrix) { | |
var rArc = arc.N; | |
if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); | |
var site = arc.site; | |
return site.y === directrix ? site.x : Infinity; | |
} | |
function d3_geom_voronoiCell(site) { | |
this.site = site; | |
this.edges = []; | |
} | |
d3_geom_voronoiCell.prototype.prepare = function() { | |
var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; | |
while (iHalfEdge--) { | |
edge = halfEdges[iHalfEdge].edge; | |
if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); | |
} | |
halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); | |
return halfEdges.length; | |
}; | |
function d3_geom_voronoiCloseCells(extent) { | |
var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; | |
while (iCell--) { | |
cell = cells[iCell]; | |
if (!cell || !cell.prepare()) continue; | |
halfEdges = cell.edges; | |
nHalfEdges = halfEdges.length; | |
iHalfEdge = 0; | |
while (iHalfEdge < nHalfEdges) { | |
end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; | |
start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; | |
if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { | |
halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { | |
x: x0, | |
y: abs(x2 - x0) < ε ? y2 : y1 | |
} : abs(y3 - y1) < ε && x1 - x3 > ε ? { | |
x: abs(y2 - y1) < ε ? x2 : x1, | |
y: y1 | |
} : abs(x3 - x1) < ε && y3 - y0 > ε ? { | |
x: x1, | |
y: abs(x2 - x1) < ε ? y2 : y0 | |
} : abs(y3 - y0) < ε && x3 - x0 > ε ? { | |
x: abs(y2 - y0) < ε ? x2 : x0, | |
y: y0 | |
} : null), cell.site, null)); | |
++nHalfEdges; | |
} | |
} | |
} | |
} | |
function d3_geom_voronoiHalfEdgeOrder(a, b) { | |
return b.angle - a.angle; | |
} | |
function d3_geom_voronoiCircle() { | |
d3_geom_voronoiRedBlackNode(this); | |
this.x = this.y = this.arc = this.site = this.cy = null; | |
} | |
function d3_geom_voronoiAttachCircle(arc) { | |
var lArc = arc.P, rArc = arc.N; | |
if (!lArc || !rArc) return; | |
var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; | |
if (lSite === rSite) return; | |
var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; | |
var d = 2 * (ax * cy - ay * cx); | |
if (d >= -ε2) return; | |
var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; | |
var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); | |
circle.arc = arc; | |
circle.site = cSite; | |
circle.x = x + bx; | |
circle.y = cy + Math.sqrt(x * x + y * y); | |
circle.cy = cy; | |
arc.circle = circle; | |
var before = null, node = d3_geom_voronoiCircles._; | |
while (node) { | |
if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { | |
if (node.L) node = node.L; else { | |
before = node.P; | |
break; | |
} | |
} else { | |
if (node.R) node = node.R; else { | |
before = node; | |
break; | |
} | |
} | |
} | |
d3_geom_voronoiCircles.insert(before, circle); | |
if (!before) d3_geom_voronoiFirstCircle = circle; | |
} | |
function d3_geom_voronoiDetachCircle(arc) { | |
var circle = arc.circle; | |
if (circle) { | |
if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; | |
d3_geom_voronoiCircles.remove(circle); | |
d3_geom_voronoiCirclePool.push(circle); | |
d3_geom_voronoiRedBlackNode(circle); | |
arc.circle = null; | |
} | |
} | |
function d3_geom_voronoiClipEdges(extent) { | |
var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; | |
while (i--) { | |
e = edges[i]; | |
if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { | |
e.a = e.b = null; | |
edges.splice(i, 1); | |
} | |
} | |
} | |
function d3_geom_voronoiConnectEdge(edge, extent) { | |
var vb = edge.b; | |
if (vb) return true; | |
var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; | |
if (ry === ly) { | |
if (fx < x0 || fx >= x1) return; | |
if (lx > rx) { | |
if (!va) va = { | |
x: fx, | |
y: y0 | |
}; else if (va.y >= y1) return; | |
vb = { | |
x: fx, | |
y: y1 | |
}; | |
} else { | |
if (!va) va = { | |
x: fx, | |
y: y1 | |
}; else if (va.y < y0) return; | |
vb = { | |
x: fx, | |
y: y0 | |
}; | |
} | |
} else { | |
fm = (lx - rx) / (ry - ly); | |
fb = fy - fm * fx; | |
if (fm < -1 || fm > 1) { | |
if (lx > rx) { | |
if (!va) va = { | |
x: (y0 - fb) / fm, | |
y: y0 | |
}; else if (va.y >= y1) return; | |
vb = { | |
x: (y1 - fb) / fm, | |
y: y1 | |
}; | |
} else { | |
if (!va) va = { | |
x: (y1 - fb) / fm, | |
y: y1 | |
}; else if (va.y < y0) return; | |
vb = { | |
x: (y0 - fb) / fm, | |
y: y0 | |
}; | |
} | |
} else { | |
if (ly < ry) { | |
if (!va) va = { | |
x: x0, | |
y: fm * x0 + fb | |
}; else if (va.x >= x1) return; | |
vb = { | |
x: x1, | |
y: fm * x1 + fb | |
}; | |
} else { | |
if (!va) va = { | |
x: x1, | |
y: fm * x1 + fb | |
}; else if (va.x < x0) return; | |
vb = { | |
x: x0, | |
y: fm * x0 + fb | |
}; | |
} | |
} | |
} | |
edge.a = va; | |
edge.b = vb; | |
return true; | |
} | |
function d3_geom_voronoiEdge(lSite, rSite) { | |
this.l = lSite; | |
this.r = rSite; | |
this.a = this.b = null; | |
} | |
function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { | |
var edge = new d3_geom_voronoiEdge(lSite, rSite); | |
d3_geom_voronoiEdges.push(edge); | |
if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); | |
if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); | |
d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); | |
d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); | |
return edge; | |
} | |
function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { | |
var edge = new d3_geom_voronoiEdge(lSite, null); | |
edge.a = va; | |
edge.b = vb; | |
d3_geom_voronoiEdges.push(edge); | |
return edge; | |
} | |
function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { | |
if (!edge.a && !edge.b) { | |
edge.a = vertex; | |
edge.l = lSite; | |
edge.r = rSite; | |
} else if (edge.l === rSite) { | |
edge.b = vertex; | |
} else { | |
edge.a = vertex; | |
} | |
} | |
function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { | |
var va = edge.a, vb = edge.b; | |
this.edge = edge; | |
this.site = lSite; | |
this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); | |
} | |
d3_geom_voronoiHalfEdge.prototype = { | |
start: function() { | |
return this.edge.l === this.site ? this.edge.a : this.edge.b; | |
}, | |
end: function() { | |
return this.edge.l === this.site ? this.edge.b : this.edge.a; | |
} | |
}; | |
function d3_geom_voronoiRedBlackTree() { | |
this._ = null; | |
} | |
function d3_geom_voronoiRedBlackNode(node) { | |
node.U = node.C = node.L = node.R = node.P = node.N = null; | |
} | |
d3_geom_voronoiRedBlackTree.prototype = { | |
insert: function(after, node) { | |
var parent, grandpa, uncle; | |
if (after) { | |
node.P = after; | |
node.N = after.N; | |
if (after.N) after.N.P = node; | |
after.N = node; | |
if (after.R) { | |
after = after.R; | |
while (after.L) after = after.L; | |
after.L = node; | |
} else { | |
after.R = node; | |
} | |
parent = after; | |
} else if (this._) { | |
after = d3_geom_voronoiRedBlackFirst(this._); | |
node.P = null; | |
node.N = after; | |
after.P = after.L = node; | |
parent = after; | |
} else { | |
node.P = node.N = null; | |
this._ = node; | |
parent = null; | |
} | |
node.L = node.R = null; | |
node.U = parent; | |
node.C = true; | |
after = node; | |
while (parent && parent.C) { | |
grandpa = parent.U; | |
if (parent === grandpa.L) { | |
uncle = grandpa.R; | |
if (uncle && uncle.C) { | |
parent.C = uncle.C = false; | |
grandpa.C = true; | |
after = grandpa; | |
} else { | |
if (after === parent.R) { | |
d3_geom_voronoiRedBlackRotateLeft(this, parent); | |
after = parent; | |
parent = after.U; | |
} | |
parent.C = false; | |
grandpa.C = true; | |
d3_geom_voronoiRedBlackRotateRight(this, grandpa); | |
} | |
} else { | |
uncle = grandpa.L; | |
if (uncle && uncle.C) { | |
parent.C = uncle.C = false; | |
grandpa.C = true; | |
after = grandpa; | |
} else { | |
if (after === parent.L) { | |
d3_geom_voronoiRedBlackRotateRight(this, parent); | |
after = parent; | |
parent = after.U; | |
} | |
parent.C = false; | |
grandpa.C = true; | |
d3_geom_voronoiRedBlackRotateLeft(this, grandpa); | |
} | |
} | |
parent = after.U; | |
} | |
this._.C = false; | |
}, | |
remove: function(node) { | |
if (node.N) node.N.P = node.P; | |
if (node.P) node.P.N = node.N; | |
node.N = node.P = null; | |
var parent = node.U, sibling, left = node.L, right = node.R, next, red; | |
if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); | |
if (parent) { | |
if (parent.L === node) parent.L = next; else parent.R = next; | |
} else { | |
this._ = next; | |
} | |
if (left && right) { | |
red = next.C; | |
next.C = node.C; | |
next.L = left; | |
left.U = next; | |
if (next !== right) { | |
parent = next.U; | |
next.U = node.U; | |
node = next.R; | |
parent.L = node; | |
next.R = right; | |
right.U = next; | |
} else { | |
next.U = parent; | |
parent = next; | |
node = next.R; | |
} | |
} else { | |
red = node.C; | |
node = next; | |
} | |
if (node) node.U = parent; | |
if (red) return; | |
if (node && node.C) { | |
node.C = false; | |
return; | |
} | |
do { | |
if (node === this._) break; | |
if (node === parent.L) { | |
sibling = parent.R; | |
if (sibling.C) { | |
sibling.C = false; | |
parent.C = true; | |
d3_geom_voronoiRedBlackRotateLeft(this, parent); | |
sibling = parent.R; | |
} | |
if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { | |
if (!sibling.R || !sibling.R.C) { | |
sibling.L.C = false; | |
sibling.C = true; | |
d3_geom_voronoiRedBlackRotateRight(this, sibling); | |
sibling = parent.R; | |
} | |
sibling.C = parent.C; | |
parent.C = sibling.R.C = false; | |
d3_geom_voronoiRedBlackRotateLeft(this, parent); | |
node = this._; | |
break; | |
} | |
} else { | |
sibling = parent.L; | |
if (sibling.C) { | |
sibling.C = false; | |
parent.C = true; | |
d3_geom_voronoiRedBlackRotateRight(this, parent); | |
sibling = parent.L; | |
} | |
if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { | |
if (!sibling.L || !sibling.L.C) { | |
sibling.R.C = false; | |
sibling.C = true; | |
d3_geom_voronoiRedBlackRotateLeft(this, sibling); | |
sibling = parent.L; | |
} | |
sibling.C = parent.C; | |
parent.C = sibling.L.C = false; | |
d3_geom_voronoiRedBlackRotateRight(this, parent); | |
node = this._; | |
break; | |
} | |
} | |
sibling.C = true; | |
node = parent; | |
parent = parent.U; | |
} while (!node.C); | |
if (node) node.C = false; | |
} | |
}; | |
function d3_geom_voronoiRedBlackRotateLeft(tree, node) { | |
var p = node, q = node.R, parent = p.U; | |
if (parent) { | |
if (parent.L === p) parent.L = q; else parent.R = q; | |
} else { | |
tree._ = q; | |
} | |
q.U = parent; | |
p.U = q; | |
p.R = q.L; | |
if (p.R) p.R.U = p; | |
q.L = p; | |
} | |
function d3_geom_voronoiRedBlackRotateRight(tree, node) { | |
var p = node, q = node.L, parent = p.U; | |
if (parent) { | |
if (parent.L === p) parent.L = q; else parent.R = q; | |
} else { | |
tree._ = q; | |
} | |
q.U = parent; | |
p.U = q; | |
p.L = q.R; | |
if (p.L) p.L.U = p; | |
q.R = p; | |
} | |
function d3_geom_voronoiRedBlackFirst(node) { | |
while (node.L) node = node.L; | |
return node; | |
} | |
function d3_geom_voronoi(sites, bbox) { | |
var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; | |
d3_geom_voronoiEdges = []; | |
d3_geom_voronoiCells = new Array(sites.length); | |
d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); | |
d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); | |
while (true) { | |
circle = d3_geom_voronoiFirstCircle; | |
if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { | |
if (site.x !== x0 || site.y !== y0) { | |
d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); | |
d3_geom_voronoiAddBeach(site); | |
x0 = site.x, y0 = site.y; | |
} | |
site = sites.pop(); | |
} else if (circle) { | |
d3_geom_voronoiRemoveBeach(circle.arc); | |
} else { | |
break; | |
} | |
} | |
if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); | |
var diagram = { | |
cells: d3_geom_voronoiCells, | |
edges: d3_geom_voronoiEdges | |
}; | |
d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; | |
return diagram; | |
} | |
function d3_geom_voronoiVertexOrder(a, b) { | |
return b.y - a.y || b.x - a.x; | |
} | |
d3.geom.voronoi = function(points) { | |
var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; | |
if (points) return voronoi(points); | |
function voronoi(data) { | |
var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; | |
d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { | |
var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { | |
var s = e.start(); | |
return [ s.x, s.y ]; | |
}) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; | |
polygon.point = data[i]; | |
}); | |
return polygons; | |
} | |
function sites(data) { | |
return data.map(function(d, i) { | |
return { | |
x: Math.round(fx(d, i) / ε) * ε, | |
y: Math.round(fy(d, i) / ε) * ε, | |
i: i | |
}; | |
}); | |
} | |
voronoi.links = function(data) { | |
return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { | |
return edge.l && edge.r; | |
}).map(function(edge) { | |
return { | |
source: data[edge.l.i], | |
target: data[edge.r.i] | |
}; | |
}); | |
}; | |
voronoi.triangles = function(data) { | |
var triangles = []; | |
d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { | |
var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; | |
while (++j < m) { | |
e0 = e1; | |
s0 = s1; | |
e1 = edges[j].edge; | |
s1 = e1.l === site ? e1.r : e1.l; | |
if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { | |
triangles.push([ data[i], data[s0.i], data[s1.i] ]); | |
} | |
} | |
}); | |
return triangles; | |
}; | |
voronoi.x = function(_) { | |
return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; | |
}; | |
voronoi.y = function(_) { | |
return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; | |
}; | |
voronoi.clipExtent = function(_) { | |
if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; | |
clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; | |
return voronoi; | |
}; | |
voronoi.size = function(_) { | |
if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; | |
return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); | |
}; | |
return voronoi; | |
}; | |
var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; | |
function d3_geom_voronoiTriangleArea(a, b, c) { | |
return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); | |
} | |
d3.geom.delaunay = function(vertices) { | |
return d3.geom.voronoi().triangles(vertices); | |
}; | |
d3.geom.quadtree = function(points, x1, y1, x2, y2) { | |
var x = d3_geom_pointX, y = d3_geom_pointY, compat; | |
if (compat = arguments.length) { | |
x = d3_geom_quadtreeCompatX; | |
y = d3_geom_quadtreeCompatY; | |
if (compat === 3) { | |
y2 = y1; | |
x2 = x1; | |
y1 = x1 = 0; | |
} | |
return quadtree(points); | |
} | |
function quadtree(data) { | |
var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; | |
if (x1 != null) { | |
x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; | |
} else { | |
x2_ = y2_ = -(x1_ = y1_ = Infinity); | |
xs = [], ys = []; | |
n = data.length; | |
if (compat) for (i = 0; i < n; ++i) { | |
d = data[i]; | |
if (d.x < x1_) x1_ = d.x; | |
if (d.y < y1_) y1_ = d.y; | |
if (d.x > x2_) x2_ = d.x; | |
if (d.y > y2_) y2_ = d.y; | |
xs.push(d.x); | |
ys.push(d.y); | |
} else for (i = 0; i < n; ++i) { | |
var x_ = +fx(d = data[i], i), y_ = +fy(d, i); | |
if (x_ < x1_) x1_ = x_; | |
if (y_ < y1_) y1_ = y_; | |
if (x_ > x2_) x2_ = x_; | |
if (y_ > y2_) y2_ = y_; | |
xs.push(x_); | |
ys.push(y_); | |
} | |
} | |
var dx = x2_ - x1_, dy = y2_ - y1_; | |
if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; | |
function insert(n, d, x, y, x1, y1, x2, y2) { | |
if (isNaN(x) || isNaN(y)) return; | |
if (n.leaf) { | |
var nx = n.x, ny = n.y; | |
if (nx != null) { | |
if (abs(nx - x) + abs(ny - y) < .01) { | |
insertChild(n, d, x, y, x1, y1, x2, y2); | |
} else { | |
var nPoint = n.point; | |
n.x = n.y = n.point = null; | |
insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); | |
insertChild(n, d, x, y, x1, y1, x2, y2); | |
} | |
} else { | |
n.x = x, n.y = y, n.point = d; | |
} | |
} else { | |
insertChild(n, d, x, y, x1, y1, x2, y2); | |
} | |
} | |
function insertChild(n, d, x, y, x1, y1, x2, y2) { | |
var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right; | |
n.leaf = false; | |
n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); | |
if (right) x1 = xm; else x2 = xm; | |
if (below) y1 = ym; else y2 = ym; | |
insert(n, d, x, y, x1, y1, x2, y2); | |
} | |
var root = d3_geom_quadtreeNode(); | |
root.add = function(d) { | |
insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); | |
}; | |
root.visit = function(f) { | |
d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); | |
}; | |
root.find = function(point) { | |
return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_); | |
}; | |
i = -1; | |
if (x1 == null) { | |
while (++i < n) { | |
insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); | |
} | |
--i; | |
} else data.forEach(root.add); | |
xs = ys = data = d = null; | |
return root; | |
} | |
quadtree.x = function(_) { | |
return arguments.length ? (x = _, quadtree) : x; | |
}; | |
quadtree.y = function(_) { | |
return arguments.length ? (y = _, quadtree) : y; | |
}; | |
quadtree.extent = function(_) { | |
if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; | |
if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], | |
y2 = +_[1][1]; | |
return quadtree; | |
}; | |
quadtree.size = function(_) { | |
if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; | |
if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; | |
return quadtree; | |
}; | |
return quadtree; | |
}; | |
function d3_geom_quadtreeCompatX(d) { | |
return d.x; | |
} | |
function d3_geom_quadtreeCompatY(d) { | |
return d.y; | |
} | |
function d3_geom_quadtreeNode() { | |
return { | |
leaf: true, | |
nodes: [], | |
point: null, | |
x: null, | |
y: null | |
}; | |
} | |
function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { | |
if (!f(node, x1, y1, x2, y2)) { | |
var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; | |
if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); | |
if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); | |
if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); | |
if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); | |
} | |
} | |
function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) { | |
var minDistance2 = Infinity, closestPoint; | |
(function find(node, x1, y1, x2, y2) { | |
if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return; | |
if (point = node.point) { | |
var point, dx = x - node.x, dy = y - node.y, distance2 = dx * dx + dy * dy; | |
if (distance2 < minDistance2) { | |
var distance = Math.sqrt(minDistance2 = distance2); | |
x0 = x - distance, y0 = y - distance; | |
x3 = x + distance, y3 = y + distance; | |
closestPoint = point; | |
} | |
} | |
var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym; | |
for (var i = below << 1 | right, j = i + 4; i < j; ++i) { | |
if (node = children[i & 3]) switch (i & 3) { | |
case 0: | |
find(node, x1, y1, xm, ym); | |
break; | |
case 1: | |
find(node, xm, y1, x2, ym); | |
break; | |
case 2: | |
find(node, x1, ym, xm, y2); | |
break; | |
case 3: | |
find(node, xm, ym, x2, y2); | |
break; | |
} | |
} | |
})(root, x0, y0, x3, y3); | |
return closestPoint; | |
} | |
d3.interpolateRgb = d3_interpolateRgb; | |
function d3_interpolateRgb(a, b) { | |
a = d3.rgb(a); | |
b = d3.rgb(b); | |
var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; | |
return function(t) { | |
return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); | |
}; | |
} | |
d3.interpolateObject = d3_interpolateObject; | |
function d3_interpolateObject(a, b) { | |
var i = {}, c = {}, k; | |
for (k in a) { | |
if (k in b) { | |
i[k] = d3_interpolate(a[k], b[k]); | |
} else { | |
c[k] = a[k]; | |
} | |
} | |
for (k in b) { | |
if (!(k in a)) { | |
c[k] = b[k]; | |
} | |
} | |
return function(t) { | |
for (k in i) c[k] = i[k](t); | |
return c; | |
}; | |
} | |
d3.interpolateNumber = d3_interpolateNumber; | |
function d3_interpolateNumber(a, b) { | |
a = +a, b = +b; | |
return function(t) { | |
return a * (1 - t) + b * t; | |
}; | |
} | |
d3.interpolateString = d3_interpolateString; | |
function d3_interpolateString(a, b) { | |
var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = []; | |
a = a + "", b = b + ""; | |
while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) { | |
if ((bs = bm.index) > bi) { | |
bs = b.slice(bi, bs); | |
if (s[i]) s[i] += bs; else s[++i] = bs; | |
} | |
if ((am = am[0]) === (bm = bm[0])) { | |
if (s[i]) s[i] += bm; else s[++i] = bm; | |
} else { | |
s[++i] = null; | |
q.push({ | |
i: i, | |
x: d3_interpolateNumber(am, bm) | |
}); | |
} | |
bi = d3_interpolate_numberB.lastIndex; | |
} | |
if (bi < b.length) { | |
bs = b.slice(bi); | |
if (s[i]) s[i] += bs; else s[++i] = bs; | |
} | |
return s.length < 2 ? q[0] ? (b = q[0].x, function(t) { | |
return b(t) + ""; | |
}) : function() { | |
return b; | |
} : (b = q.length, function(t) { | |
for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); | |
return s.join(""); | |
}); | |
} | |
var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g"); | |
d3.interpolate = d3_interpolate; | |
function d3_interpolate(a, b) { | |
var i = d3.interpolators.length, f; | |
while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; | |
return f; | |
} | |
d3.interpolators = [ function(a, b) { | |
var t = typeof b; | |
return (t === "string" ? d3_rgb_names.has(b.toLowerCase()) || /^(#|rgb\(|hsl\()/i.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b); | |
} ]; | |
d3.interpolateArray = d3_interpolateArray; | |
function d3_interpolateArray(a, b) { | |
var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; | |
for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); | |
for (;i < na; ++i) c[i] = a[i]; | |
for (;i < nb; ++i) c[i] = b[i]; | |
return function(t) { | |
for (i = 0; i < n0; ++i) c[i] = x[i](t); | |
return c; | |
}; | |
} | |
var d3_ease_default = function() { | |
return d3_identity; | |
}; | |
var d3_ease = d3.map({ | |
linear: d3_ease_default, | |
poly: d3_ease_poly, | |
quad: function() { | |
return d3_ease_quad; | |
}, | |
cubic: function() { | |
return d3_ease_cubic; | |
}, | |
sin: function() { | |
return d3_ease_sin; | |
}, | |
exp: function() { | |
return d3_ease_exp; | |
}, | |
circle: function() { | |
return d3_ease_circle; | |
}, | |
elastic: d3_ease_elastic, | |
back: d3_ease_back, | |
bounce: function() { | |
return d3_ease_bounce; | |
} | |
}); | |
var d3_ease_mode = d3.map({ | |
"in": d3_identity, | |
out: d3_ease_reverse, | |
"in-out": d3_ease_reflect, | |
"out-in": function(f) { | |
return d3_ease_reflect(d3_ease_reverse(f)); | |
} | |
}); | |
d3.ease = function(name) { | |
var i = name.indexOf("-"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : "in"; | |
t = d3_ease.get(t) || d3_ease_default; | |
m = d3_ease_mode.get(m) || d3_identity; | |
return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); | |
}; | |
function d3_ease_clamp(f) { | |
return function(t) { | |
return t <= 0 ? 0 : t >= 1 ? 1 : f(t); | |
}; | |
} | |
function d3_ease_reverse(f) { | |
return function(t) { | |
return 1 - f(1 - t); | |
}; | |
} | |
function d3_ease_reflect(f) { | |
return function(t) { | |
return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); | |
}; | |
} | |
function d3_ease_quad(t) { | |
return t * t; | |
} | |
function d3_ease_cubic(t) { | |
return t * t * t; | |
} | |
function d3_ease_cubicInOut(t) { | |
if (t <= 0) return 0; | |
if (t >= 1) return 1; | |
var t2 = t * t, t3 = t2 * t; | |
return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); | |
} | |
function d3_ease_poly(e) { | |
return function(t) { | |
return Math.pow(t, e); | |
}; | |
} | |
function d3_ease_sin(t) { | |
return 1 - Math.cos(t * halfπ); | |
} | |
function d3_ease_exp(t) { | |
return Math.pow(2, 10 * (t - 1)); | |
} | |
function d3_ease_circle(t) { | |
return 1 - Math.sqrt(1 - t * t); | |
} | |
function d3_ease_elastic(a, p) { | |
var s; | |
if (arguments.length < 2) p = .45; | |
if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4; | |
return function(t) { | |
return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p); | |
}; | |
} | |
function d3_ease_back(s) { | |
if (!s) s = 1.70158; | |
return function(t) { | |
return t * t * ((s + 1) * t - s); | |
}; | |
} | |
function d3_ease_bounce(t) { | |
return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; | |
} | |
d3.interpolateHcl = d3_interpolateHcl; | |
function d3_interpolateHcl(a, b) { | |
a = d3.hcl(a); | |
b = d3.hcl(b); | |
var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; | |
if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; | |
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; | |
return function(t) { | |
return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; | |
}; | |
} | |
d3.interpolateHsl = d3_interpolateHsl; | |
function d3_interpolateHsl(a, b) { | |
a = d3.hsl(a); | |
b = d3.hsl(b); | |
var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; | |
if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; | |
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; | |
return function(t) { | |
return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; | |
}; | |
} | |
d3.interpolateLab = d3_interpolateLab; | |
function d3_interpolateLab(a, b) { | |
a = d3.lab(a); | |
b = d3.lab(b); | |
var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; | |
return function(t) { | |
return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; | |
}; | |
} | |
d3.interpolateRound = d3_interpolateRound; | |
function d3_interpolateRound(a, b) { | |
b -= a; | |
return function(t) { | |
return Math.round(a + b * t); | |
}; | |
} | |
d3.transform = function(string) { | |
var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); | |
return (d3.transform = function(string) { | |
if (string != null) { | |
g.setAttribute("transform", string); | |
var t = g.transform.baseVal.consolidate(); | |
} | |
return new d3_transform(t ? t.matrix : d3_transformIdentity); | |
})(string); | |
}; | |
function d3_transform(m) { | |
var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; | |
if (r0[0] * r1[1] < r1[0] * r0[1]) { | |
r0[0] *= -1; | |
r0[1] *= -1; | |
kx *= -1; | |
kz *= -1; | |
} | |
this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; | |
this.translate = [ m.e, m.f ]; | |
this.scale = [ kx, ky ]; | |
this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; | |
} | |
d3_transform.prototype.toString = function() { | |
return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; | |
}; | |
function d3_transformDot(a, b) { | |
return a[0] * b[0] + a[1] * b[1]; | |
} | |
function d3_transformNormalize(a) { | |
var k = Math.sqrt(d3_transformDot(a, a)); | |
if (k) { | |
a[0] /= k; | |
a[1] /= k; | |
} | |
return k; | |
} | |
function d3_transformCombine(a, b, k) { | |
a[0] += k * b[0]; | |
a[1] += k * b[1]; | |
return a; | |
} | |
var d3_transformIdentity = { | |
a: 1, | |
b: 0, | |
c: 0, | |
d: 1, | |
e: 0, | |
f: 0 | |
}; | |
d3.interpolateTransform = d3_interpolateTransform; | |
function d3_interpolateTransform(a, b) { | |
var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; | |
if (ta[0] != tb[0] || ta[1] != tb[1]) { | |
s.push("translate(", null, ",", null, ")"); | |
q.push({ | |
i: 1, | |
x: d3_interpolateNumber(ta[0], tb[0]) | |
}, { | |
i: 3, | |
x: d3_interpolateNumber(ta[1], tb[1]) | |
}); | |
} else if (tb[0] || tb[1]) { | |
s.push("translate(" + tb + ")"); | |
} else { | |
s.push(""); | |
} | |
if (ra != rb) { | |
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; | |
q.push({ | |
i: s.push(s.pop() + "rotate(", null, ")") - 2, | |
x: d3_interpolateNumber(ra, rb) | |
}); | |
} else if (rb) { | |
s.push(s.pop() + "rotate(" + rb + ")"); | |
} | |
if (wa != wb) { | |
q.push({ | |
i: s.push(s.pop() + "skewX(", null, ")") - 2, | |
x: d3_interpolateNumber(wa, wb) | |
}); | |
} else if (wb) { | |
s.push(s.pop() + "skewX(" + wb + ")"); | |
} | |
if (ka[0] != kb[0] || ka[1] != kb[1]) { | |
n = s.push(s.pop() + "scale(", null, ",", null, ")"); | |
q.push({ | |
i: n - 4, | |
x: d3_interpolateNumber(ka[0], kb[0]) | |
}, { | |
i: n - 2, | |
x: d3_interpolateNumber(ka[1], kb[1]) | |
}); | |
} else if (kb[0] != 1 || kb[1] != 1) { | |
s.push(s.pop() + "scale(" + kb + ")"); | |
} | |
n = q.length; | |
return function(t) { | |
var i = -1, o; | |
while (++i < n) s[(o = q[i]).i] = o.x(t); | |
return s.join(""); | |
}; | |
} | |
function d3_uninterpolateNumber(a, b) { | |
b = (b -= a = +a) || 1 / b; | |
return function(x) { | |
return (x - a) / b; | |
}; | |
} | |
function d3_uninterpolateClamp(a, b) { | |
b = (b -= a = +a) || 1 / b; | |
return function(x) { | |
return Math.max(0, Math.min(1, (x - a) / b)); | |
}; | |
} | |
d3.layout = {}; | |
d3.layout.bundle = function() { | |
return function(links) { | |
var paths = [], i = -1, n = links.length; | |
while (++i < n) paths.push(d3_layout_bundlePath(links[i])); | |
return paths; | |
}; | |
}; | |
function d3_layout_bundlePath(link) { | |
var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; | |
while (start !== lca) { | |
start = start.parent; | |
points.push(start); | |
} | |
var k = points.length; | |
while (end !== lca) { | |
points.splice(k, 0, end); | |
end = end.parent; | |
} | |
return points; | |
} | |
function d3_layout_bundleAncestors(node) { | |
var ancestors = [], parent = node.parent; | |
while (parent != null) { | |
ancestors.push(node); | |
node = parent; | |
parent = parent.parent; | |
} | |
ancestors.push(node); | |
return ancestors; | |
} | |
function d3_layout_bundleLeastCommonAncestor(a, b) { | |
if (a === b) return a; | |
var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; | |
while (aNode === bNode) { | |
sharedNode = aNode; | |
aNode = aNodes.pop(); | |
bNode = bNodes.pop(); | |
} | |
return sharedNode; | |
} | |
d3.layout.chord = function() { | |
var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; | |
function relayout() { | |
var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; | |
chords = []; | |
groups = []; | |
k = 0, i = -1; | |
while (++i < n) { | |
x = 0, j = -1; | |
while (++j < n) { | |
x += matrix[i][j]; | |
} | |
groupSums.push(x); | |
subgroupIndex.push(d3.range(n)); | |
k += x; | |
} | |
if (sortGroups) { | |
groupIndex.sort(function(a, b) { | |
return sortGroups(groupSums[a], groupSums[b]); | |
}); | |
} | |
if (sortSubgroups) { | |
subgroupIndex.forEach(function(d, i) { | |
d.sort(function(a, b) { | |
return sortSubgroups(matrix[i][a], matrix[i][b]); | |
}); | |
}); | |
} | |
k = (τ - padding * n) / k; | |
x = 0, i = -1; | |
while (++i < n) { | |
x0 = x, j = -1; | |
while (++j < n) { | |
var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; | |
subgroups[di + "-" + dj] = { | |
index: di, | |
subindex: dj, | |
startAngle: a0, | |
endAngle: a1, | |
value: v | |
}; | |
} | |
groups[di] = { | |
index: di, | |
startAngle: x0, | |
endAngle: x, | |
value: (x - x0) / k | |
}; | |
x += padding; | |
} | |
i = -1; | |
while (++i < n) { | |
j = i - 1; | |
while (++j < n) { | |
var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; | |
if (source.value || target.value) { | |
chords.push(source.value < target.value ? { | |
source: target, | |
target: source | |
} : { | |
source: source, | |
target: target | |
}); | |
} | |
} | |
} | |
if (sortChords) resort(); | |
} | |
function resort() { | |
chords.sort(function(a, b) { | |
return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); | |
}); | |
} | |
chord.matrix = function(x) { | |
if (!arguments.length) return matrix; | |
n = (matrix = x) && matrix.length; | |
chords = groups = null; | |
return chord; | |
}; | |
chord.padding = function(x) { | |
if (!arguments.length) return padding; | |
padding = x; | |
chords = groups = null; | |
return chord; | |
}; | |
chord.sortGroups = function(x) { | |
if (!arguments.length) return sortGroups; | |
sortGroups = x; | |
chords = groups = null; | |
return chord; | |
}; | |
chord.sortSubgroups = function(x) { | |
if (!arguments.length) return sortSubgroups; | |
sortSubgroups = x; | |
chords = null; | |
return chord; | |
}; | |
chord.sortChords = function(x) { | |
if (!arguments.length) return sortChords; | |
sortChords = x; | |
if (chords) resort(); | |
return chord; | |
}; | |
chord.chords = function() { | |
if (!chords) relayout(); | |
return chords; | |
}; | |
chord.groups = function() { | |
if (!groups) relayout(); | |
return groups; | |
}; | |
return chord; | |
}; | |
d3.layout.force = function() { | |
var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; | |
function repulse(node) { | |
return function(quad, x1, _, x2) { | |
if (quad.point !== node) { | |
var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; | |
if (dw * dw / theta2 < dn) { | |
if (dn < chargeDistance2) { | |
var k = quad.charge / dn; | |
node.px -= dx * k; | |
node.py -= dy * k; | |
} | |
return true; | |
} | |
if (quad.point && dn && dn < chargeDistance2) { | |
var k = quad.pointCharge / dn; | |
node.px -= dx * k; | |
node.py -= dy * k; | |
} | |
} | |
return !quad.charge; | |
}; | |
} | |
force.tick = function() { | |
if ((alpha *= .99) < .005) { | |
event.end({ | |
type: "end", | |
alpha: alpha = 0 | |
}); | |
return true; | |
} | |
var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; | |
for (i = 0; i < m; ++i) { | |
o = links[i]; | |
s = o.source; | |
t = o.target; | |
x = t.x - s.x; | |
y = t.y - s.y; | |
if (l = x * x + y * y) { | |
l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; | |
x *= l; | |
y *= l; | |
t.x -= x * (k = s.weight / (t.weight + s.weight)); | |
t.y -= y * k; | |
s.x += x * (k = 1 - k); | |
s.y += y * k; | |
} | |
} | |
if (k = alpha * gravity) { | |
x = size[0] / 2; | |
y = size[1] / 2; | |
i = -1; | |
if (k) while (++i < n) { | |
o = nodes[i]; | |
o.x += (x - o.x) * k; | |
o.y += (y - o.y) * k; | |
} | |
} | |
if (charge) { | |
d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); | |
i = -1; | |
while (++i < n) { | |
if (!(o = nodes[i]).fixed) { | |
q.visit(repulse(o)); | |
} | |
} | |
} | |
i = -1; | |
while (++i < n) { | |
o = nodes[i]; | |
if (o.fixed) { | |
o.x = o.px; | |
o.y = o.py; | |
} else { | |
o.x -= (o.px - (o.px = o.x)) * friction; | |
o.y -= (o.py - (o.py = o.y)) * friction; | |
} | |
} | |
event.tick({ | |
type: "tick", | |
alpha: alpha | |
}); | |
}; | |
force.nodes = function(x) { | |
if (!arguments.length) return nodes; | |
nodes = x; | |
return force; | |
}; | |
force.links = function(x) { | |
if (!arguments.length) return links; | |
links = x; | |
return force; | |
}; | |
force.size = function(x) { | |
if (!arguments.length) return size; | |
size = x; | |
return force; | |
}; | |
force.linkDistance = function(x) { | |
if (!arguments.length) return linkDistance; | |
linkDistance = typeof x === "function" ? x : +x; | |
return force; | |
}; | |
force.distance = force.linkDistance; | |
force.linkStrength = function(x) { | |
if (!arguments.length) return linkStrength; | |
linkStrength = typeof x === "function" ? x : +x; | |
return force; | |
}; | |
force.friction = function(x) { | |
if (!arguments.length) return friction; | |
friction = +x; | |
return force; | |
}; | |
force.charge = function(x) { | |
if (!arguments.length) return charge; | |
charge = typeof x === "function" ? x : +x; | |
return force; | |
}; | |
force.chargeDistance = function(x) { | |
if (!arguments.length) return Math.sqrt(chargeDistance2); | |
chargeDistance2 = x * x; | |
return force; | |
}; | |
force.gravity = function(x) { | |
if (!arguments.length) return gravity; | |
gravity = +x; | |
return force; | |
}; | |
force.theta = function(x) { | |
if (!arguments.length) return Math.sqrt(theta2); | |
theta2 = x * x; | |
return force; | |
}; | |
force.alpha = function(x) { | |
if (!arguments.length) return alpha; | |
x = +x; | |
if (alpha) { | |
if (x > 0) alpha = x; else alpha = 0; | |
} else if (x > 0) { | |
event.start({ | |
type: "start", | |
alpha: alpha = x | |
}); | |
d3.timer(force.tick); | |
} | |
return force; | |
}; | |
force.start = function() { | |
var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; | |
for (i = 0; i < n; ++i) { | |
(o = nodes[i]).index = i; | |
o.weight = 0; | |
} | |
for (i = 0; i < m; ++i) { | |
o = links[i]; | |
if (typeof o.source == "number") o.source = nodes[o.source]; | |
if (typeof o.target == "number") o.target = nodes[o.target]; | |
++o.source.weight; | |
++o.target.weight; | |
} | |
for (i = 0; i < n; ++i) { | |
o = nodes[i]; | |
if (isNaN(o.x)) o.x = position("x", w); | |
if (isNaN(o.y)) o.y = position("y", h); | |
if (isNaN(o.px)) o.px = o.x; | |
if (isNaN(o.py)) o.py = o.y; | |
} | |
distances = []; | |
if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; | |
strengths = []; | |
if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; | |
charges = []; | |
if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; | |
function position(dimension, size) { | |
if (!neighbors) { | |
neighbors = new Array(n); | |
for (j = 0; j < n; ++j) { | |
neighbors[j] = []; | |
} | |
for (j = 0; j < m; ++j) { | |
var o = links[j]; | |
neighbors[o.source.index].push(o.target); | |
neighbors[o.target.index].push(o.source); | |
} | |
} | |
var candidates = neighbors[i], j = -1, l = candidates.length, x; | |
while (++j < l) if (!isNaN(x = candidates[j][dimension])) return x; | |
return Math.random() * size; | |
} | |
return force.resume(); | |
}; | |
force.resume = function() { | |
return force.alpha(.1); | |
}; | |
force.stop = function() { | |
return force.alpha(0); | |
}; | |
force.drag = function() { | |
if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); | |
if (!arguments.length) return drag; | |
this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); | |
}; | |
function dragmove(d) { | |
d.px = d3.event.x, d.py = d3.event.y; | |
force.resume(); | |
} | |
return d3.rebind(force, event, "on"); | |
}; | |
function d3_layout_forceDragstart(d) { | |
d.fixed |= 2; | |
} | |
function d3_layout_forceDragend(d) { | |
d.fixed &= ~6; | |
} | |
function d3_layout_forceMouseover(d) { | |
d.fixed |= 4; | |
d.px = d.x, d.py = d.y; | |
} | |
function d3_layout_forceMouseout(d) { | |
d.fixed &= ~4; | |
} | |
function d3_layout_forceAccumulate(quad, alpha, charges) { | |
var cx = 0, cy = 0; | |
quad.charge = 0; | |
if (!quad.leaf) { | |
var nodes = quad.nodes, n = nodes.length, i = -1, c; | |
while (++i < n) { | |
c = nodes[i]; | |
if (c == null) continue; | |
d3_layout_forceAccumulate(c, alpha, charges); | |
quad.charge += c.charge; | |
cx += c.charge * c.cx; | |
cy += c.charge * c.cy; | |
} | |
} | |
if (quad.point) { | |
if (!quad.leaf) { | |
quad.point.x += Math.random() - .5; | |
quad.point.y += Math.random() - .5; | |
} | |
var k = alpha * charges[quad.point.index]; | |
quad.charge += quad.pointCharge = k; | |
cx += k * quad.point.x; | |
cy += k * quad.point.y; | |
} | |
quad.cx = cx / quad.charge; | |
quad.cy = cy / quad.charge; | |
} | |
var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; | |
d3.layout.hierarchy = function() { | |
var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; | |
function hierarchy(root) { | |
var stack = [ root ], nodes = [], node; | |
root.depth = 0; | |
while ((node = stack.pop()) != null) { | |
nodes.push(node); | |
if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) { | |
var n, childs, child; | |
while (--n >= 0) { | |
stack.push(child = childs[n]); | |
child.parent = node; | |
child.depth = node.depth + 1; | |
} | |
if (value) node.value = 0; | |
node.children = childs; | |
} else { | |
if (value) node.value = +value.call(hierarchy, node, node.depth) || 0; | |
delete node.children; | |
} | |
} | |
d3_layout_hierarchyVisitAfter(root, function(node) { | |
var childs, parent; | |
if (sort && (childs = node.children)) childs.sort(sort); | |
if (value && (parent = node.parent)) parent.value += node.value; | |
}); | |
return nodes; | |
} | |
hierarchy.sort = function(x) { | |
if (!arguments.length) return sort; | |
sort = x; | |
return hierarchy; | |
}; | |
hierarchy.children = function(x) { | |
if (!arguments.length) return children; | |
children = x; | |
return hierarchy; | |
}; | |
hierarchy.value = function(x) { | |
if (!arguments.length) return value; | |
value = x; | |
return hierarchy; | |
}; | |
hierarchy.revalue = function(root) { | |
if (value) { | |
d3_layout_hierarchyVisitBefore(root, function(node) { | |
if (node.children) node.value = 0; | |
}); | |
d3_layout_hierarchyVisitAfter(root, function(node) { | |
var parent; | |
if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0; | |
if (parent = node.parent) parent.value += node.value; | |
}); | |
} | |
return root; | |
}; | |
return hierarchy; | |
}; | |
function d3_layout_hierarchyRebind(object, hierarchy) { | |
d3.rebind(object, hierarchy, "sort", "children", "value"); | |
object.nodes = object; | |
object.links = d3_layout_hierarchyLinks; | |
return object; | |
} | |
function d3_layout_hierarchyVisitBefore(node, callback) { | |
var nodes = [ node ]; | |
while ((node = nodes.pop()) != null) { | |
callback(node); | |
if ((children = node.children) && (n = children.length)) { | |
var n, children; | |
while (--n >= 0) nodes.push(children[n]); | |
} | |
} | |
} | |
function d3_layout_hierarchyVisitAfter(node, callback) { | |
var nodes = [ node ], nodes2 = []; | |
while ((node = nodes.pop()) != null) { | |
nodes2.push(node); | |
if ((children = node.children) && (n = children.length)) { | |
var i = -1, n, children; | |
while (++i < n) nodes.push(children[i]); | |
} | |
} | |
while ((node = nodes2.pop()) != null) { | |
callback(node); | |
} | |
} | |
function d3_layout_hierarchyChildren(d) { | |
return d.children; | |
} | |
function d3_layout_hierarchyValue(d) { | |
return d.value; | |
} | |
function d3_layout_hierarchySort(a, b) { | |
return b.value - a.value; | |
} | |
function d3_layout_hierarchyLinks(nodes) { | |
return d3.merge(nodes.map(function(parent) { | |
return (parent.children || []).map(function(child) { | |
return { | |
source: parent, | |
target: child | |
}; | |
}); | |
})); | |
} | |
d3.layout.partition = function() { | |
var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; | |
function position(node, x, dx, dy) { | |
var children = node.children; | |
node.x = x; | |
node.y = node.depth * dy; | |
node.dx = dx; | |
node.dy = dy; | |
if (children && (n = children.length)) { | |
var i = -1, n, c, d; | |
dx = node.value ? dx / node.value : 0; | |
while (++i < n) { | |
position(c = children[i], x, d = c.value * dx, dy); | |
x += d; | |
} | |
} | |
} | |
function depth(node) { | |
var children = node.children, d = 0; | |
if (children && (n = children.length)) { | |
var i = -1, n; | |
while (++i < n) d = Math.max(d, depth(children[i])); | |
} | |
return 1 + d; | |
} | |
function partition(d, i) { | |
var nodes = hierarchy.call(this, d, i); | |
position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); | |
return nodes; | |
} | |
partition.size = function(x) { | |
if (!arguments.length) return size; | |
size = x; | |
return partition; | |
}; | |
return d3_layout_hierarchyRebind(partition, hierarchy); | |
}; | |
d3.layout.pie = function() { | |
var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0; | |
function pie(data) { | |
var n = data.length, values = data.map(function(d, i) { | |
return +value.call(pie, d, i); | |
}), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), k = (da - n * pa) / d3.sum(values), index = d3.range(n), arcs = [], v; | |
if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { | |
return values[j] - values[i]; | |
} : function(i, j) { | |
return sort(data[i], data[j]); | |
}); | |
index.forEach(function(i) { | |
arcs[i] = { | |
data: data[i], | |
value: v = values[i], | |
startAngle: a, | |
endAngle: a += v * k + pa, | |
padAngle: p | |
}; | |
}); | |
return arcs; | |
} | |
pie.value = function(_) { | |
if (!arguments.length) return value; | |
value = _; | |
return pie; | |
}; | |
pie.sort = function(_) { | |
if (!arguments.length) return sort; | |
sort = _; | |
return pie; | |
}; | |
pie.startAngle = function(_) { | |
if (!arguments.length) return startAngle; | |
startAngle = _; | |
return pie; | |
}; | |
pie.endAngle = function(_) { | |
if (!arguments.length) return endAngle; | |
endAngle = _; | |
return pie; | |
}; | |
pie.padAngle = function(_) { | |
if (!arguments.length) return padAngle; | |
padAngle = _; | |
return pie; | |
}; | |
return pie; | |
}; | |
var d3_layout_pieSortByValue = {}; | |
d3.layout.stack = function() { | |
var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; | |
function stack(data, index) { | |
if (!(n = data.length)) return data; | |
var series = data.map(function(d, i) { | |
return values.call(stack, d, i); | |
}); | |
var points = series.map(function(d) { | |
return d.map(function(v, i) { | |
return [ x.call(stack, v, i), y.call(stack, v, i) ]; | |
}); | |
}); | |
var orders = order.call(stack, points, index); | |
series = d3.permute(series, orders); | |
points = d3.permute(points, orders); | |
var offsets = offset.call(stack, points, index); | |
var m = series[0].length, n, i, j, o; | |
for (j = 0; j < m; ++j) { | |
out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); | |
for (i = 1; i < n; ++i) { | |
out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); | |
} | |
} | |
return data; | |
} | |
stack.values = function(x) { | |
if (!arguments.length) return values; | |
values = x; | |
return stack; | |
}; | |
stack.order = function(x) { | |
if (!arguments.length) return order; | |
order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; | |
return stack; | |
}; | |
stack.offset = function(x) { | |
if (!arguments.length) return offset; | |
offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; | |
return stack; | |
}; | |
stack.x = function(z) { | |
if (!arguments.length) return x; | |
x = z; | |
return stack; | |
}; | |
stack.y = function(z) { | |
if (!arguments.length) return y; | |
y = z; | |
return stack; | |
}; | |
stack.out = function(z) { | |
if (!arguments.length) return out; | |
out = z; | |
return stack; | |
}; | |
return stack; | |
}; | |
function d3_layout_stackX(d) { | |
return d.x; | |
} | |
function d3_layout_stackY(d) { | |
return d.y; | |
} | |
function d3_layout_stackOut(d, y0, y) { | |
d.y0 = y0; | |
d.y = y; | |
} | |
var d3_layout_stackOrders = d3.map({ | |
"inside-out": function(data) { | |
var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { | |
return max[a] - max[b]; | |
}), top = 0, bottom = 0, tops = [], bottoms = []; | |
for (i = 0; i < n; ++i) { | |
j = index[i]; | |
if (top < bottom) { | |
top += sums[j]; | |
tops.push(j); | |
} else { | |
bottom += sums[j]; | |
bottoms.push(j); | |
} | |
} | |
return bottoms.reverse().concat(tops); | |
}, | |
reverse: function(data) { | |
return d3.range(data.length).reverse(); | |
}, | |
"default": d3_layout_stackOrderDefault | |
}); | |
var d3_layout_stackOffsets = d3.map({ | |
silhouette: function(data) { | |
var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; | |
for (j = 0; j < m; ++j) { | |
for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; | |
if (o > max) max = o; | |
sums.push(o); | |
} | |
for (j = 0; j < m; ++j) { | |
y0[j] = (max - sums[j]) / 2; | |
} | |
return y0; | |
}, | |
wiggle: function(data) { | |
var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; | |
y0[0] = o = o0 = 0; | |
for (j = 1; j < m; ++j) { | |
for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; | |
for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { | |
for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { | |
s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; | |
} | |
s2 += s3 * data[i][j][1]; | |
} | |
y0[j] = o -= s1 ? s2 / s1 * dx : 0; | |
if (o < o0) o0 = o; | |
} | |
for (j = 0; j < m; ++j) y0[j] -= o0; | |
return y0; | |
}, | |
expand: function(data) { | |
var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; | |
for (j = 0; j < m; ++j) { | |
for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; | |
if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; | |
} | |
for (j = 0; j < m; ++j) y0[j] = 0; | |
return y0; | |
}, | |
zero: d3_layout_stackOffsetZero | |
}); | |
function d3_layout_stackOrderDefault(data) { | |
return d3.range(data.length); | |
} | |
function d3_layout_stackOffsetZero(data) { | |
var j = -1, m = data[0].length, y0 = []; | |
while (++j < m) y0[j] = 0; | |
return y0; | |
} | |
function d3_layout_stackMaxIndex(array) { | |
var i = 1, j = 0, v = array[0][1], k, n = array.length; | |
for (;i < n; ++i) { | |
if ((k = array[i][1]) > v) { | |
j = i; | |
v = k; | |
} | |
} | |
return j; | |
} | |
function d3_layout_stackReduceSum(d) { | |
return d.reduce(d3_layout_stackSum, 0); | |
} | |
function d3_layout_stackSum(p, d) { | |
return p + d[1]; | |
} | |
d3.layout.histogram = function() { | |
var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; | |
function histogram(data, i) { | |
var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; | |
while (++i < m) { | |
bin = bins[i] = []; | |
bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); | |
bin.y = 0; | |
} | |
if (m > 0) { | |
i = -1; | |
while (++i < n) { | |
x = values[i]; | |
if (x >= range[0] && x <= range[1]) { | |
bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; | |
bin.y += k; | |
bin.push(data[i]); | |
} | |
} | |
} | |
return bins; | |
} | |
histogram.value = function(x) { | |
if (!arguments.length) return valuer; | |
valuer = x; | |
return histogram; | |
}; | |
histogram.range = function(x) { | |
if (!arguments.length) return ranger; | |
ranger = d3_functor(x); | |
return histogram; | |
}; | |
histogram.bins = function(x) { | |
if (!arguments.length) return binner; | |
binner = typeof x === "number" ? function(range) { | |
return d3_layout_histogramBinFixed(range, x); | |
} : d3_functor(x); | |
return histogram; | |
}; | |
histogram.frequency = function(x) { | |
if (!arguments.length) return frequency; | |
frequency = !!x; | |
return histogram; | |
}; | |
return histogram; | |
}; | |
function d3_layout_histogramBinSturges(range, values) { | |
return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); | |
} | |
function d3_layout_histogramBinFixed(range, n) { | |
var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; | |
while (++x <= n) f[x] = m * x + b; | |
return f; | |
} | |
function d3_layout_histogramRange(values) { | |
return [ d3.min(values), d3.max(values) ]; | |
} | |
d3.layout.pack = function() { | |
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; | |
function pack(d, i) { | |
var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { | |
return radius; | |
}; | |
root.x = root.y = 0; | |
d3_layout_hierarchyVisitAfter(root, function(d) { | |
d.r = +r(d.value); | |
}); | |
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); | |
if (padding) { | |
var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; | |
d3_layout_hierarchyVisitAfter(root, function(d) { | |
d.r += dr; | |
}); | |
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); | |
d3_layout_hierarchyVisitAfter(root, function(d) { | |
d.r -= dr; | |
}); | |
} | |
d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); | |
return nodes; | |
} | |
pack.size = function(_) { | |
if (!arguments.length) return size; | |
size = _; | |
return pack; | |
}; | |
pack.radius = function(_) { | |
if (!arguments.length) return radius; | |
radius = _ == null || typeof _ === "function" ? _ : +_; | |
return pack; | |
}; | |
pack.padding = function(_) { | |
if (!arguments.length) return padding; | |
padding = +_; | |
return pack; | |
}; | |
return d3_layout_hierarchyRebind(pack, hierarchy); | |
}; | |
function d3_layout_packSort(a, b) { | |
return a.value - b.value; | |
} | |
function d3_layout_packInsert(a, b) { | |
var c = a._pack_next; | |
a._pack_next = b; | |
b._pack_prev = a; | |
b._pack_next = c; | |
c._pack_prev = b; | |
} | |
function d3_layout_packSplice(a, b) { | |
a._pack_next = b; | |
b._pack_prev = a; | |
} | |
function d3_layout_packIntersects(a, b) { | |
var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; | |
return .999 * dr * dr > dx * dx + dy * dy; | |
} | |
function d3_layout_packSiblings(node) { | |
if (!(nodes = node.children) || !(n = nodes.length)) return; | |
var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; | |
function bound(node) { | |
xMin = Math.min(node.x - node.r, xMin); | |
xMax = Math.max(node.x + node.r, xMax); | |
yMin = Math.min(node.y - node.r, yMin); | |
yMax = Math.max(node.y + node.r, yMax); | |
} | |
nodes.forEach(d3_layout_packLink); | |
a = nodes[0]; | |
a.x = -a.r; | |
a.y = 0; | |
bound(a); | |
if (n > 1) { | |
b = nodes[1]; | |
b.x = b.r; | |
b.y = 0; | |
bound(b); | |
if (n > 2) { | |
c = nodes[2]; | |
d3_layout_packPlace(a, b, c); | |
bound(c); | |
d3_layout_packInsert(a, c); | |
a._pack_prev = c; | |
d3_layout_packInsert(c, b); | |
b = a._pack_next; | |
for (i = 3; i < n; i++) { | |
d3_layout_packPlace(a, b, c = nodes[i]); | |
var isect = 0, s1 = 1, s2 = 1; | |
for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { | |
if (d3_layout_packIntersects(j, c)) { | |
isect = 1; | |
break; | |
} | |
} | |
if (isect == 1) { | |
for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { | |
if (d3_layout_packIntersects(k, c)) { | |
break; | |
} | |
} | |
} | |
if (isect) { | |
if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); | |
i--; | |
} else { | |
d3_layout_packInsert(a, c); | |
b = c; | |
bound(c); | |
} | |
} | |
} | |
} | |
var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; | |
for (i = 0; i < n; i++) { | |
c = nodes[i]; | |
c.x -= cx; | |
c.y -= cy; | |
cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); | |
} | |
node.r = cr; | |
nodes.forEach(d3_layout_packUnlink); | |
} | |
function d3_layout_packLink(node) { | |
node._pack_next = node._pack_prev = node; | |
} | |
function d3_layout_packUnlink(node) { | |
delete node._pack_next; | |
delete node._pack_prev; | |
} | |
function d3_layout_packTransform(node, x, y, k) { | |
var children = node.children; | |
node.x = x += k * node.x; | |
node.y = y += k * node.y; | |
node.r *= k; | |
if (children) { | |
var i = -1, n = children.length; | |
while (++i < n) d3_layout_packTransform(children[i], x, y, k); | |
} | |
} | |
function d3_layout_packPlace(a, b, c) { | |
var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; | |
if (db && (dx || dy)) { | |
var da = b.r + c.r, dc = dx * dx + dy * dy; | |
da *= da; | |
db *= db; | |
var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); | |
c.x = a.x + x * dx + y * dy; | |
c.y = a.y + x * dy - y * dx; | |
} else { | |
c.x = a.x + db; | |
c.y = a.y; | |
} | |
} | |
d3.layout.tree = function() { | |
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null; | |
function tree(d, i) { | |
var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0); | |
d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z; | |
d3_layout_hierarchyVisitBefore(root1, secondWalk); | |
if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else { | |
var left = root0, right = root0, bottom = root0; | |
d3_layout_hierarchyVisitBefore(root0, function(node) { | |
if (node.x < left.x) left = node; | |
if (node.x > right.x) right = node; | |
if (node.depth > bottom.depth) bottom = node; | |
}); | |
var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1); | |
d3_layout_hierarchyVisitBefore(root0, function(node) { | |
node.x = (node.x + tx) * kx; | |
node.y = node.depth * ky; | |
}); | |
} | |
return nodes; | |
} | |
function wrapTree(root0) { | |
var root1 = { | |
A: null, | |
children: [ root0 ] | |
}, queue = [ root1 ], node1; | |
while ((node1 = queue.pop()) != null) { | |
for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) { | |
queue.push((children[i] = child = { | |
_: children[i], | |
parent: node1, | |
children: (child = children[i].children) && child.slice() || [], | |
A: null, | |
a: null, | |
z: 0, | |
m: 0, | |
c: 0, | |
s: 0, | |
t: null, | |
i: i | |
}).a = child); | |
} | |
} | |
return root1.children[0]; | |
} | |
function firstWalk(v) { | |
var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null; | |
if (children.length) { | |
d3_layout_treeShift(v); | |
var midpoint = (children[0].z + children[children.length - 1].z) / 2; | |
if (w) { | |
v.z = w.z + separation(v._, w._); | |
v.m = v.z - midpoint; | |
} else { | |
v.z = midpoint; | |
} | |
} else if (w) { | |
v.z = w.z + separation(v._, w._); | |
} | |
v.parent.A = apportion(v, w, v.parent.A || siblings[0]); | |
} | |
function secondWalk(v) { | |
v._.x = v.z + v.parent.m; | |
v.m += v.parent.m; | |
} | |
function apportion(v, w, ancestor) { | |
if (w) { | |
var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift; | |
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { | |
vom = d3_layout_treeLeft(vom); | |
vop = d3_layout_treeRight(vop); | |
vop.a = v; | |
shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); | |
if (shift > 0) { | |
d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift); | |
sip += shift; | |
sop += shift; | |
} | |
sim += vim.m; | |
sip += vip.m; | |
som += vom.m; | |
sop += vop.m; | |
} | |
if (vim && !d3_layout_treeRight(vop)) { | |
vop.t = vim; | |
vop.m += sim - sop; | |
} | |
if (vip && !d3_layout_treeLeft(vom)) { | |
vom.t = vip; | |
vom.m += sip - som; | |
ancestor = v; | |
} | |
} | |
return ancestor; | |
} | |
function sizeNode(node) { | |
node.x *= size[0]; | |
node.y = node.depth * size[1]; | |
} | |
tree.separation = function(x) { | |
if (!arguments.length) return separation; | |
separation = x; | |
return tree; | |
}; | |
tree.size = function(x) { | |
if (!arguments.length) return nodeSize ? null : size; | |
nodeSize = (size = x) == null ? sizeNode : null; | |
return tree; | |
}; | |
tree.nodeSize = function(x) { | |
if (!arguments.length) return nodeSize ? size : null; | |
nodeSize = (size = x) == null ? null : sizeNode; | |
return tree; | |
}; | |
return d3_layout_hierarchyRebind(tree, hierarchy); | |
}; | |
function d3_layout_treeSeparation(a, b) { | |
return a.parent == b.parent ? 1 : 2; | |
} | |
function d3_layout_treeLeft(v) { | |
var children = v.children; | |
return children.length ? children[0] : v.t; | |
} | |
function d3_layout_treeRight(v) { | |
var children = v.children, n; | |
return (n = children.length) ? children[n - 1] : v.t; | |
} | |
function d3_layout_treeMove(wm, wp, shift) { | |
var change = shift / (wp.i - wm.i); | |
wp.c -= change; | |
wp.s += shift; | |
wm.c += change; | |
wp.z += shift; | |
wp.m += shift; | |
} | |
function d3_layout_treeShift(v) { | |
var shift = 0, change = 0, children = v.children, i = children.length, w; | |
while (--i >= 0) { | |
w = children[i]; | |
w.z += shift; | |
w.m += shift; | |
shift += w.s + (change += w.c); | |
} | |
} | |
function d3_layout_treeAncestor(vim, v, ancestor) { | |
return vim.a.parent === v.parent ? vim.a : ancestor; | |
} | |
d3.layout.cluster = function() { | |
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; | |
function cluster(d, i) { | |
var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; | |
d3_layout_hierarchyVisitAfter(root, function(node) { | |
var children = node.children; | |
if (children && children.length) { | |
node.x = d3_layout_clusterX(children); | |
node.y = d3_layout_clusterY(children); | |
} else { | |
node.x = previousNode ? x += separation(node, previousNode) : 0; | |
node.y = 0; | |
previousNode = node; | |
} | |
}); | |
var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; | |
d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) { | |
node.x = (node.x - root.x) * size[0]; | |
node.y = (root.y - node.y) * size[1]; | |
} : function(node) { | |
node.x = (node.x - x0) / (x1 - x0) * size[0]; | |
node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; | |
}); | |
return nodes; | |
} | |
cluster.separation = function(x) { | |
if (!arguments.length) return separation; | |
separation = x; | |
return cluster; | |
}; | |
cluster.size = function(x) { | |
if (!arguments.length) return nodeSize ? null : size; | |
nodeSize = (size = x) == null; | |
return cluster; | |
}; | |
cluster.nodeSize = function(x) { | |
if (!arguments.length) return nodeSize ? size : null; | |
nodeSize = (size = x) != null; | |
return cluster; | |
}; | |
return d3_layout_hierarchyRebind(cluster, hierarchy); | |
}; | |
function d3_layout_clusterY(children) { | |
return 1 + d3.max(children, function(child) { | |
return child.y; | |
}); | |
} | |
function d3_layout_clusterX(children) { | |
return children.reduce(function(x, child) { | |
return x + child.x; | |
}, 0) / children.length; | |
} | |
function d3_layout_clusterLeft(node) { | |
var children = node.children; | |
return children && children.length ? d3_layout_clusterLeft(children[0]) : node; | |
} | |
function d3_layout_clusterRight(node) { | |
var children = node.children, n; | |
return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; | |
} | |
d3.layout.treemap = function() { | |
var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); | |
function scale(children, k) { | |
var i = -1, n = children.length, child, area; | |
while (++i < n) { | |
area = (child = children[i]).value * (k < 0 ? 0 : k); | |
child.area = isNaN(area) || area <= 0 ? 0 : area; | |
} | |
} | |
function squarify(node) { | |
var children = node.children; | |
if (children && children.length) { | |
var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; | |
scale(remaining, rect.dx * rect.dy / node.value); | |
row.area = 0; | |
while ((n = remaining.length) > 0) { | |
row.push(child = remaining[n - 1]); | |
row.area += child.area; | |
if (mode !== "squarify" || (score = worst(row, u)) <= best) { | |
remaining.pop(); | |
best = score; | |
} else { | |
row.area -= row.pop().area; | |
position(row, u, rect, false); | |
u = Math.min(rect.dx, rect.dy); | |
row.length = row.area = 0; | |
best = Infinity; | |
} | |
} | |
if (row.length) { | |
position(row, u, rect, true); | |
row.length = row.area = 0; | |
} | |
children.forEach(squarify); | |
} | |
} | |
function stickify(node) { | |
var children = node.children; | |
if (children && children.length) { | |
var rect = pad(node), remaining = children.slice(), child, row = []; | |
scale(remaining, rect.dx * rect.dy / node.value); | |
row.area = 0; | |
while (child = remaining.pop()) { | |
row.push(child); | |
row.area += child.area; | |
if (child.z != null) { | |
position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); | |
row.length = row.area = 0; | |
} | |
} | |
children.forEach(stickify); | |
} | |
} | |
function worst(row, u) { | |
var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; | |
while (++i < n) { | |
if (!(r = row[i].area)) continue; | |
if (r < rmin) rmin = r; | |
if (r > rmax) rmax = r; | |
} | |
s *= s; | |
u *= u; | |
return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; | |
} | |
function position(row, u, rect, flush) { | |
var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; | |
if (u == rect.dx) { | |
if (flush || v > rect.dy) v = rect.dy; | |
while (++i < n) { | |
o = row[i]; | |
o.x = x; | |
o.y = y; | |
o.dy = v; | |
x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); | |
} | |
o.z = true; | |
o.dx += rect.x + rect.dx - x; | |
rect.y += v; | |
rect.dy -= v; | |
} else { | |
if (flush || v > rect.dx) v = rect.dx; | |
while (++i < n) { | |
o = row[i]; | |
o.x = x; | |
o.y = y; | |
o.dx = v; | |
y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); | |
} | |
o.z = false; | |
o.dy += rect.y + rect.dy - y; | |
rect.x += v; | |
rect.dx -= v; | |
} | |
} | |
function treemap(d) { | |
var nodes = stickies || hierarchy(d), root = nodes[0]; | |
root.x = 0; | |
root.y = 0; | |
root.dx = size[0]; | |
root.dy = size[1]; | |
if (stickies) hierarchy.revalue(root); | |
scale([ root ], root.dx * root.dy / root.value); | |
(stickies ? stickify : squarify)(root); | |
if (sticky) stickies = nodes; | |
return nodes; | |
} | |
treemap.size = function(x) { | |
if (!arguments.length) return size; | |
size = x; | |
return treemap; | |
}; | |
treemap.padding = function(x) { | |
if (!arguments.length) return padding; | |
function padFunction(node) { | |
var p = x.call(treemap, node, node.depth); | |
return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); | |
} | |
function padConstant(node) { | |
return d3_layout_treemapPad(node, x); | |
} | |
var type; | |
pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], | |
padConstant) : padConstant; | |
return treemap; | |
}; | |
treemap.round = function(x) { | |
if (!arguments.length) return round != Number; | |
round = x ? Math.round : Number; | |
return treemap; | |
}; | |
treemap.sticky = function(x) { | |
if (!arguments.length) return sticky; | |
sticky = x; | |
stickies = null; | |
return treemap; | |
}; | |
treemap.ratio = function(x) { | |
if (!arguments.length) return ratio; | |
ratio = x; | |
return treemap; | |
}; | |
treemap.mode = function(x) { | |
if (!arguments.length) return mode; | |
mode = x + ""; | |
return treemap; | |
}; | |
return d3_layout_hierarchyRebind(treemap, hierarchy); | |
}; | |
function d3_layout_treemapPadNull(node) { | |
return { | |
x: node.x, | |
y: node.y, | |
dx: node.dx, | |
dy: node.dy | |
}; | |
} | |
function d3_layout_treemapPad(node, padding) { | |
var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; | |
if (dx < 0) { | |
x += dx / 2; | |
dx = 0; | |
} | |
if (dy < 0) { | |
y += dy / 2; | |
dy = 0; | |
} | |
return { | |
x: x, | |
y: y, | |
dx: dx, | |
dy: dy | |
}; | |
} | |
d3.random = { | |
normal: function(µ, σ) { | |
var n = arguments.length; | |
if (n < 2) σ = 1; | |
if (n < 1) µ = 0; | |
return function() { | |
var x, y, r; | |
do { | |
x = Math.random() * 2 - 1; | |
y = Math.random() * 2 - 1; | |
r = x * x + y * y; | |
} while (!r || r > 1); | |
return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); | |
}; | |
}, | |
logNormal: function() { | |
var random = d3.random.normal.apply(d3, arguments); | |
return function() { | |
return Math.exp(random()); | |
}; | |
}, | |
bates: function(m) { | |
var random = d3.random.irwinHall(m); | |
return function() { | |
return random() / m; | |
}; | |
}, | |
irwinHall: function(m) { | |
return function() { | |
for (var s = 0, j = 0; j < m; j++) s += Math.random(); | |
return s; | |
}; | |
} | |
}; | |
d3.scale = {}; | |
function d3_scaleExtent(domain) { | |
var start = domain[0], stop = domain[domain.length - 1]; | |
return start < stop ? [ start, stop ] : [ stop, start ]; | |
} | |
function d3_scaleRange(scale) { | |
return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); | |
} | |
function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { | |
var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); | |
return function(x) { | |
return i(u(x)); | |
}; | |
} | |
function d3_scale_nice(domain, nice) { | |
var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; | |
if (x1 < x0) { | |
dx = i0, i0 = i1, i1 = dx; | |
dx = x0, x0 = x1, x1 = dx; | |
} | |
domain[i0] = nice.floor(x0); | |
domain[i1] = nice.ceil(x1); | |
return domain; | |
} | |
function d3_scale_niceStep(step) { | |
return step ? { | |
floor: function(x) { | |
return Math.floor(x / step) * step; | |
}, | |
ceil: function(x) { | |
return Math.ceil(x / step) * step; | |
} | |
} : d3_scale_niceIdentity; | |
} | |
var d3_scale_niceIdentity = { | |
floor: d3_identity, | |
ceil: d3_identity | |
}; | |
function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { | |
var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; | |
if (domain[k] < domain[0]) { | |
domain = domain.slice().reverse(); | |
range = range.slice().reverse(); | |
} | |
while (++j <= k) { | |
u.push(uninterpolate(domain[j - 1], domain[j])); | |
i.push(interpolate(range[j - 1], range[j])); | |
} | |
return function(x) { | |
var j = d3.bisect(domain, x, 1, k) - 1; | |
return i[j](u[j](x)); | |
}; | |
} | |
d3.scale.linear = function() { | |
return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); | |
}; | |
function d3_scale_linear(domain, range, interpolate, clamp) { | |
var output, input; | |
function rescale() { | |
var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; | |
output = linear(domain, range, uninterpolate, interpolate); | |
input = linear(range, domain, uninterpolate, d3_interpolate); | |
return scale; | |
} | |
function scale(x) { | |
return output(x); | |
} | |
scale.invert = function(y) { | |
return input(y); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
domain = x.map(Number); | |
return rescale(); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
return rescale(); | |
}; | |
scale.rangeRound = function(x) { | |
return scale.range(x).interpolate(d3_interpolateRound); | |
}; | |
scale.clamp = function(x) { | |
if (!arguments.length) return clamp; | |
clamp = x; | |
return rescale(); | |
}; | |
scale.interpolate = function(x) { | |
if (!arguments.length) return interpolate; | |
interpolate = x; | |
return rescale(); | |
}; | |
scale.ticks = function(m) { | |
return d3_scale_linearTicks(domain, m); | |
}; | |
scale.tickFormat = function(m, format) { | |
return d3_scale_linearTickFormat(domain, m, format); | |
}; | |
scale.nice = function(m) { | |
d3_scale_linearNice(domain, m); | |
return rescale(); | |
}; | |
scale.copy = function() { | |
return d3_scale_linear(domain, range, interpolate, clamp); | |
}; | |
return rescale(); | |
} | |
function d3_scale_linearRebind(scale, linear) { | |
return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); | |
} | |
function d3_scale_linearNice(domain, m) { | |
return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); | |
} | |
function d3_scale_linearTickRange(domain, m) { | |
if (m == null) m = 10; | |
var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; | |
if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; | |
extent[0] = Math.ceil(extent[0] / step) * step; | |
extent[1] = Math.floor(extent[1] / step) * step + step * .5; | |
extent[2] = step; | |
return extent; | |
} | |
function d3_scale_linearTicks(domain, m) { | |
return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); | |
} | |
function d3_scale_linearTickFormat(domain, m, format) { | |
var range = d3_scale_linearTickRange(domain, m); | |
if (format) { | |
var match = d3_format_re.exec(format); | |
match.shift(); | |
if (match[8] === "s") { | |
var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1]))); | |
if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); | |
match[8] = "f"; | |
format = d3.format(match.join("")); | |
return function(d) { | |
return format(prefix.scale(d)) + prefix.symbol; | |
}; | |
} | |
if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); | |
format = match.join(""); | |
} else { | |
format = ",." + d3_scale_linearPrecision(range[2]) + "f"; | |
} | |
return d3.format(format); | |
} | |
var d3_scale_linearFormatSignificant = { | |
s: 1, | |
g: 1, | |
p: 1, | |
r: 1, | |
e: 1 | |
}; | |
function d3_scale_linearPrecision(value) { | |
return -Math.floor(Math.log(value) / Math.LN10 + .01); | |
} | |
function d3_scale_linearFormatPrecision(type, range) { | |
var p = d3_scale_linearPrecision(range[2]); | |
return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; | |
} | |
d3.scale.log = function() { | |
return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); | |
}; | |
function d3_scale_log(linear, base, positive, domain) { | |
function log(x) { | |
return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); | |
} | |
function pow(x) { | |
return positive ? Math.pow(base, x) : -Math.pow(base, -x); | |
} | |
function scale(x) { | |
return linear(log(x)); | |
} | |
scale.invert = function(x) { | |
return pow(linear.invert(x)); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
positive = x[0] >= 0; | |
linear.domain((domain = x.map(Number)).map(log)); | |
return scale; | |
}; | |
scale.base = function(_) { | |
if (!arguments.length) return base; | |
base = +_; | |
linear.domain(domain.map(log)); | |
return scale; | |
}; | |
scale.nice = function() { | |
var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); | |
linear.domain(niced); | |
domain = niced.map(pow); | |
return scale; | |
}; | |
scale.ticks = function() { | |
var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; | |
if (isFinite(j - i)) { | |
if (positive) { | |
for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); | |
ticks.push(pow(i)); | |
} else { | |
ticks.push(pow(i)); | |
for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); | |
} | |
for (i = 0; ticks[i] < u; i++) {} | |
for (j = ticks.length; ticks[j - 1] > v; j--) {} | |
ticks = ticks.slice(i, j); | |
} | |
return ticks; | |
}; | |
scale.tickFormat = function(n, format) { | |
if (!arguments.length) return d3_scale_logFormat; | |
if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); | |
var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, | |
Math.floor), e; | |
return function(d) { | |
return d / pow(f(log(d) + e)) <= k ? format(d) : ""; | |
}; | |
}; | |
scale.copy = function() { | |
return d3_scale_log(linear.copy(), base, positive, domain); | |
}; | |
return d3_scale_linearRebind(scale, linear); | |
} | |
var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { | |
floor: function(x) { | |
return -Math.ceil(-x); | |
}, | |
ceil: function(x) { | |
return -Math.floor(-x); | |
} | |
}; | |
d3.scale.pow = function() { | |
return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); | |
}; | |
function d3_scale_pow(linear, exponent, domain) { | |
var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); | |
function scale(x) { | |
return linear(powp(x)); | |
} | |
scale.invert = function(x) { | |
return powb(linear.invert(x)); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
linear.domain((domain = x.map(Number)).map(powp)); | |
return scale; | |
}; | |
scale.ticks = function(m) { | |
return d3_scale_linearTicks(domain, m); | |
}; | |
scale.tickFormat = function(m, format) { | |
return d3_scale_linearTickFormat(domain, m, format); | |
}; | |
scale.nice = function(m) { | |
return scale.domain(d3_scale_linearNice(domain, m)); | |
}; | |
scale.exponent = function(x) { | |
if (!arguments.length) return exponent; | |
powp = d3_scale_powPow(exponent = x); | |
powb = d3_scale_powPow(1 / exponent); | |
linear.domain(domain.map(powp)); | |
return scale; | |
}; | |
scale.copy = function() { | |
return d3_scale_pow(linear.copy(), exponent, domain); | |
}; | |
return d3_scale_linearRebind(scale, linear); | |
} | |
function d3_scale_powPow(e) { | |
return function(x) { | |
return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); | |
}; | |
} | |
d3.scale.sqrt = function() { | |
return d3.scale.pow().exponent(.5); | |
}; | |
d3.scale.ordinal = function() { | |
return d3_scale_ordinal([], { | |
t: "range", | |
a: [ [] ] | |
}); | |
}; | |
function d3_scale_ordinal(domain, ranger) { | |
var index, range, rangeBand; | |
function scale(x) { | |
return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length]; | |
} | |
function steps(start, step) { | |
return d3.range(domain.length).map(function(i) { | |
return start + step * i; | |
}); | |
} | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
domain = []; | |
index = new d3_Map(); | |
var i = -1, n = x.length, xi; | |
while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); | |
return scale[ranger.t].apply(scale, ranger.a); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
rangeBand = 0; | |
ranger = { | |
t: "range", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangePoints = function(x, padding) { | |
if (arguments.length < 2) padding = 0; | |
var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, | |
0) : (stop - start) / (domain.length - 1 + padding); | |
range = steps(start + step * padding / 2, step); | |
rangeBand = 0; | |
ranger = { | |
t: "rangePoints", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangeRoundPoints = function(x, padding) { | |
if (arguments.length < 2) padding = 0; | |
var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), | |
0) : (stop - start) / (domain.length - 1 + padding) | 0; | |
range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step); | |
rangeBand = 0; | |
ranger = { | |
t: "rangeRoundPoints", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangeBands = function(x, padding, outerPadding) { | |
if (arguments.length < 2) padding = 0; | |
if (arguments.length < 3) outerPadding = padding; | |
var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); | |
range = steps(start + step * outerPadding, step); | |
if (reverse) range.reverse(); | |
rangeBand = step * (1 - padding); | |
ranger = { | |
t: "rangeBands", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangeRoundBands = function(x, padding, outerPadding) { | |
if (arguments.length < 2) padding = 0; | |
if (arguments.length < 3) outerPadding = padding; | |
var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)); | |
range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step); | |
if (reverse) range.reverse(); | |
rangeBand = Math.round(step * (1 - padding)); | |
ranger = { | |
t: "rangeRoundBands", | |
a: arguments | |
}; | |
return scale; | |
}; | |
scale.rangeBand = function() { | |
return rangeBand; | |
}; | |
scale.rangeExtent = function() { | |
return d3_scaleExtent(ranger.a[0]); | |
}; | |
scale.copy = function() { | |
return d3_scale_ordinal(domain, ranger); | |
}; | |
return scale.domain(domain); | |
} | |
d3.scale.category10 = function() { | |
return d3.scale.ordinal().range(d3_category10); | |
}; | |
d3.scale.category20 = function() { | |
return d3.scale.ordinal().range(d3_category20); | |
}; | |
d3.scale.category20b = function() { | |
return d3.scale.ordinal().range(d3_category20b); | |
}; | |
d3.scale.category20c = function() { | |
return d3.scale.ordinal().range(d3_category20c); | |
}; | |
var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); | |
var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); | |
var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); | |
var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); | |
d3.scale.quantile = function() { | |
return d3_scale_quantile([], []); | |
}; | |
function d3_scale_quantile(domain, range) { | |
var thresholds; | |
function rescale() { | |
var k = 0, q = range.length; | |
thresholds = []; | |
while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); | |
return scale; | |
} | |
function scale(x) { | |
if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; | |
} | |
scale.domain = function(x) { | |
if (!arguments.length) return domain; | |
domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending); | |
return rescale(); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
return rescale(); | |
}; | |
scale.quantiles = function() { | |
return thresholds; | |
}; | |
scale.invertExtent = function(y) { | |
y = range.indexOf(y); | |
return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; | |
}; | |
scale.copy = function() { | |
return d3_scale_quantile(domain, range); | |
}; | |
return rescale(); | |
} | |
d3.scale.quantize = function() { | |
return d3_scale_quantize(0, 1, [ 0, 1 ]); | |
}; | |
function d3_scale_quantize(x0, x1, range) { | |
var kx, i; | |
function scale(x) { | |
return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; | |
} | |
function rescale() { | |
kx = range.length / (x1 - x0); | |
i = range.length - 1; | |
return scale; | |
} | |
scale.domain = function(x) { | |
if (!arguments.length) return [ x0, x1 ]; | |
x0 = +x[0]; | |
x1 = +x[x.length - 1]; | |
return rescale(); | |
}; | |
scale.range = function(x) { | |
if (!arguments.length) return range; | |
range = x; | |
return rescale(); | |
}; | |
scale.invertExtent = function(y) { | |
y = range.indexOf(y); | |
y = y < 0 ? NaN : y / kx + x0; | |
return [ y, y + 1 / kx ]; | |
}; | |
scale.copy = function() { | |
return d3_scale_quantize(x0, x1, range); | |
}; | |
return rescale(); | |
} | |
d3.scale.threshold = function() { | |
return d3_scale_threshold([ .5 ], [ 0, 1 ]); | |
}; | |
function d3_scale_threshold(domain, range) { | |
function scale(x) { | |
if (x <= x) return range[d3.bisect(domain, x)]; | |
} | |
scale.domain = function(_) { | |
if (!arguments.length) return domain; | |
domain = _; | |
return scale; | |
}; | |
scale.range = function(_) { | |
if (!arguments.length) return range; | |
range = _; | |
return scale; | |
}; | |
scale.invertExtent = function(y) { | |
y = range.indexOf(y); | |
return [ domain[y - 1], domain[y] ]; | |
}; | |
scale.copy = function() { | |
return d3_scale_threshold(domain, range); | |
}; | |
return scale; | |
} | |
d3.scale.identity = function() { | |
return d3_scale_identity([ 0, 1 ]); | |
}; | |
function d3_scale_identity(domain) { | |
function identity(x) { | |
return +x; | |
} | |
identity.invert = identity; | |
identity.domain = identity.range = function(x) { | |
if (!arguments.length) return domain; | |
domain = x.map(identity); | |
return identity; | |
}; | |
identity.ticks = function(m) { | |
return d3_scale_linearTicks(domain, m); | |
}; | |
identity.tickFormat = function(m, format) { | |
return d3_scale_linearTickFormat(domain, m, format); | |
}; | |
identity.copy = function() { | |
return d3_scale_identity(domain); | |
}; | |
return identity; | |
} | |
d3.svg = {}; | |
function d3_zero() { | |
return 0; | |
} | |
d3.svg.arc = function() { | |
var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle; | |
function arc() { | |
var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1; | |
if (r1 < r0) rc = r1, r1 = r0, r0 = rc; | |
if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : "") + "Z"; | |
var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = []; | |
if (ap = (+padAngle.apply(this, arguments) || 0) / 2) { | |
rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments); | |
if (!cw) p1 *= -1; | |
if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap)); | |
if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap)); | |
} | |
if (r1) { | |
x0 = r1 * Math.cos(a0 + p1); | |
y0 = r1 * Math.sin(a0 + p1); | |
x1 = r1 * Math.cos(a1 - p1); | |
y1 = r1 * Math.sin(a1 - p1); | |
var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1; | |
if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) { | |
var h1 = (a0 + a1) / 2; | |
x0 = r1 * Math.cos(h1); | |
y0 = r1 * Math.sin(h1); | |
x1 = y1 = null; | |
} | |
} else { | |
x0 = y0 = 0; | |
} | |
if (r0) { | |
x2 = r0 * Math.cos(a1 - p0); | |
y2 = r0 * Math.sin(a1 - p0); | |
x3 = r0 * Math.cos(a0 + p0); | |
y3 = r0 * Math.sin(a0 + p0); | |
var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1; | |
if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) { | |
var h0 = (a0 + a1) / 2; | |
x2 = r0 * Math.cos(h0); | |
y2 = r0 * Math.sin(h0); | |
x3 = y3 = null; | |
} | |
} else { | |
x2 = y2 = 0; | |
} | |
if ((rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) { | |
cr = r0 < r1 ^ cw ? 0 : 1; | |
var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]); | |
if (x1 != null) { | |
var rc1 = Math.min(rc, (r1 - lc) / (kc + 1)), t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw); | |
if (rc === rc1) { | |
path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]); | |
} else { | |
path.push("M", t30[0], "A", rc1, ",", rc1, " 0 1,", cr, " ", t12[0]); | |
} | |
} else { | |
path.push("M", x0, ",", y0); | |
} | |
if (x3 != null) { | |
var rc0 = Math.min(rc, (r0 - lc) / (kc - 1)), t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw); | |
if (rc === rc0) { | |
path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); | |
} else { | |
path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); | |
} | |
} else { | |
path.push("L", x2, ",", y2); | |
} | |
} else { | |
path.push("M", x0, ",", y0); | |
if (x1 != null) path.push("A", r1, ",", r1, " 0 ", l1, ",", cw, " ", x1, ",", y1); | |
path.push("L", x2, ",", y2); | |
if (x3 != null) path.push("A", r0, ",", r0, " 0 ", l0, ",", 1 - cw, " ", x3, ",", y3); | |
} | |
path.push("Z"); | |
return path.join(""); | |
} | |
function circleSegment(r1, cw) { | |
return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1; | |
} | |
arc.innerRadius = function(v) { | |
if (!arguments.length) return innerRadius; | |
innerRadius = d3_functor(v); | |
return arc; | |
}; | |
arc.outerRadius = function(v) { | |
if (!arguments.length) return outerRadius; | |
outerRadius = d3_functor(v); | |
return arc; | |
}; | |
arc.cornerRadius = function(v) { | |
if (!arguments.length) return cornerRadius; | |
cornerRadius = d3_functor(v); | |
return arc; | |
}; | |
arc.padRadius = function(v) { | |
if (!arguments.length) return padRadius; | |
padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v); | |
return arc; | |
}; | |
arc.startAngle = function(v) { | |
if (!arguments.length) return startAngle; | |
startAngle = d3_functor(v); | |
return arc; | |
}; | |
arc.endAngle = function(v) { | |
if (!arguments.length) return endAngle; | |
endAngle = d3_functor(v); | |
return arc; | |
}; | |
arc.padAngle = function(v) { | |
if (!arguments.length) return padAngle; | |
padAngle = d3_functor(v); | |
return arc; | |
}; | |
arc.centroid = function() { | |
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ; | |
return [ Math.cos(a) * r, Math.sin(a) * r ]; | |
}; | |
return arc; | |
}; | |
var d3_svg_arcAuto = "auto"; | |
function d3_svg_arcInnerRadius(d) { | |
return d.innerRadius; | |
} | |
function d3_svg_arcOuterRadius(d) { | |
return d.outerRadius; | |
} | |
function d3_svg_arcStartAngle(d) { | |
return d.startAngle; | |
} | |
function d3_svg_arcEndAngle(d) { | |
return d.endAngle; | |
} | |
function d3_svg_arcPadAngle(d) { | |
return d && d.padAngle; | |
} | |
function d3_svg_arcSweep(x0, y0, x1, y1) { | |
return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1; | |
} | |
function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) { | |
var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(r * r * d2 - D * D), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3; | |
if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; | |
return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ]; | |
} | |
function d3_svg_line(projection) { | |
var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; | |
function line(data) { | |
var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); | |
function segment() { | |
segments.push("M", interpolate(projection(points), tension)); | |
} | |
while (++i < n) { | |
if (defined.call(this, d = data[i], i)) { | |
points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); | |
} else if (points.length) { | |
segment(); | |
points = []; | |
} | |
} | |
if (points.length) segment(); | |
return segments.length ? segments.join("") : null; | |
} | |
line.x = function(_) { | |
if (!arguments.length) return x; | |
x = _; | |
return line; | |
}; | |
line.y = function(_) { | |
if (!arguments.length) return y; | |
y = _; | |
return line; | |
}; | |
line.defined = function(_) { | |
if (!arguments.length) return defined; | |
defined = _; | |
return line; | |
}; | |
line.interpolate = function(_) { | |
if (!arguments.length) return interpolateKey; | |
if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; | |
return line; | |
}; | |
line.tension = function(_) { | |
if (!arguments.length) return tension; | |
tension = _; | |
return line; | |
}; | |
return line; | |
} | |
d3.svg.line = function() { | |
return d3_svg_line(d3_identity); | |
}; | |
var d3_svg_lineInterpolators = d3.map({ | |
linear: d3_svg_lineLinear, | |
"linear-closed": d3_svg_lineLinearClosed, | |
step: d3_svg_lineStep, | |
"step-before": d3_svg_lineStepBefore, | |
"step-after": d3_svg_lineStepAfter, | |
basis: d3_svg_lineBasis, | |
"basis-open": d3_svg_lineBasisOpen, | |
"basis-closed": d3_svg_lineBasisClosed, | |
bundle: d3_svg_lineBundle, | |
cardinal: d3_svg_lineCardinal, | |
"cardinal-open": d3_svg_lineCardinalOpen, | |
"cardinal-closed": d3_svg_lineCardinalClosed, | |
monotone: d3_svg_lineMonotone | |
}); | |
d3_svg_lineInterpolators.forEach(function(key, value) { | |
value.key = key; | |
value.closed = /-closed$/.test(key); | |
}); | |
function d3_svg_lineLinear(points) { | |
return points.join("L"); | |
} | |
function d3_svg_lineLinearClosed(points) { | |
return d3_svg_lineLinear(points) + "Z"; | |
} | |
function d3_svg_lineStep(points) { | |
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; | |
while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); | |
if (n > 1) path.push("H", p[0]); | |
return path.join(""); | |
} | |
function d3_svg_lineStepBefore(points) { | |
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; | |
while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); | |
return path.join(""); | |
} | |
function d3_svg_lineStepAfter(points) { | |
var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; | |
while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); | |
return path.join(""); | |
} | |
function d3_svg_lineCardinalOpen(points, tension) { | |
return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension)); | |
} | |
function d3_svg_lineCardinalClosed(points, tension) { | |
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), | |
points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); | |
} | |
function d3_svg_lineCardinal(points, tension) { | |
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); | |
} | |
function d3_svg_lineHermite(points, tangents) { | |
if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { | |
return d3_svg_lineLinear(points); | |
} | |
var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; | |
if (quad) { | |
path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; | |
p0 = points[1]; | |
pi = 2; | |
} | |
if (tangents.length > 1) { | |
t = tangents[1]; | |
p = points[pi]; | |
pi++; | |
path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; | |
for (var i = 2; i < tangents.length; i++, pi++) { | |
p = points[pi]; | |
t = tangents[i]; | |
path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; | |
} | |
} | |
if (quad) { | |
var lp = points[pi]; | |
path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; | |
} | |
return path; | |
} | |
function d3_svg_lineCardinalTangents(points, tension) { | |
var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; | |
while (++i < n) { | |
p0 = p1; | |
p1 = p2; | |
p2 = points[i]; | |
tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); | |
} | |
return tangents; | |
} | |
function d3_svg_lineBasis(points) { | |
if (points.length < 3) return d3_svg_lineLinear(points); | |
var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; | |
points.push(points[n - 1]); | |
while (++i <= n) { | |
pi = points[i]; | |
px.shift(); | |
px.push(pi[0]); | |
py.shift(); | |
py.push(pi[1]); | |
d3_svg_lineBasisBezier(path, px, py); | |
} | |
points.pop(); | |
path.push("L", pi); | |
return path.join(""); | |
} | |
function d3_svg_lineBasisOpen(points) { | |
if (points.length < 4) return d3_svg_lineLinear(points); | |
var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; | |
while (++i < 3) { | |
pi = points[i]; | |
px.push(pi[0]); | |
py.push(pi[1]); | |
} | |
path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); | |
--i; | |
while (++i < n) { | |
pi = points[i]; | |
px.shift(); | |
px.push(pi[0]); | |
py.shift(); | |
py.push(pi[1]); | |
d3_svg_lineBasisBezier(path, px, py); | |
} | |
return path.join(""); | |
} | |
function d3_svg_lineBasisClosed(points) { | |
var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; | |
while (++i < 4) { | |
pi = points[i % n]; | |
px.push(pi[0]); | |
py.push(pi[1]); | |
} | |
path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; | |
--i; | |
while (++i < m) { | |
pi = points[i % n]; | |
px.shift(); | |
px.push(pi[0]); | |
py.shift(); | |
py.push(pi[1]); | |
d3_svg_lineBasisBezier(path, px, py); | |
} | |
return path.join(""); | |
} | |
function d3_svg_lineBundle(points, tension) { | |
var n = points.length - 1; | |
if (n) { | |
var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; | |
while (++i <= n) { | |
p = points[i]; | |
t = i / n; | |
p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); | |
p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); | |
} | |
} | |
return d3_svg_lineBasis(points); | |
} | |
function d3_svg_lineDot4(a, b) { | |
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; | |
} | |
var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; | |
function d3_svg_lineBasisBezier(path, x, y) { | |
path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); | |
} | |
function d3_svg_lineSlope(p0, p1) { | |
return (p1[1] - p0[1]) / (p1[0] - p0[0]); | |
} | |
function d3_svg_lineFiniteDifferences(points) { | |
var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); | |
while (++i < j) { | |
m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; | |
} | |
m[i] = d; | |
return m; | |
} | |
function d3_svg_lineMonotoneTangents(points) { | |
var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; | |
while (++i < j) { | |
d = d3_svg_lineSlope(points[i], points[i + 1]); | |
if (abs(d) < ε) { | |
m[i] = m[i + 1] = 0; | |
} else { | |
a = m[i] / d; | |
b = m[i + 1] / d; | |
s = a * a + b * b; | |
if (s > 9) { | |
s = d * 3 / Math.sqrt(s); | |
m[i] = s * a; | |
m[i + 1] = s * b; | |
} | |
} | |
} | |
i = -1; | |
while (++i <= j) { | |
s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); | |
tangents.push([ s || 0, m[i] * s || 0 ]); | |
} | |
return tangents; | |
} | |
function d3_svg_lineMonotone(points) { | |
return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); | |
} | |
d3.svg.line.radial = function() { | |
var line = d3_svg_line(d3_svg_lineRadial); | |
line.radius = line.x, delete line.x; | |
line.angle = line.y, delete line.y; | |
return line; | |
}; | |
function d3_svg_lineRadial(points) { | |
var point, i = -1, n = points.length, r, a; | |
while (++i < n) { | |
point = points[i]; | |
r = point[0]; | |
a = point[1] - halfπ; | |
point[0] = r * Math.cos(a); | |
point[1] = r * Math.sin(a); | |
} | |
return points; | |
} | |
function d3_svg_area(projection) { | |
var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; | |
function area(data) { | |
var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { | |
return x; | |
} : d3_functor(x1), fy1 = y0 === y1 ? function() { | |
return y; | |
} : d3_functor(y1), x, y; | |
function segment() { | |
segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); | |
} | |
while (++i < n) { | |
if (defined.call(this, d = data[i], i)) { | |
points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); | |
points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); | |
} else if (points0.length) { | |
segment(); | |
points0 = []; | |
points1 = []; | |
} | |
} | |
if (points0.length) segment(); | |
return segments.length ? segments.join("") : null; | |
} | |
area.x = function(_) { | |
if (!arguments.length) return x1; | |
x0 = x1 = _; | |
return area; | |
}; | |
area.x0 = function(_) { | |
if (!arguments.length) return x0; | |
x0 = _; | |
return area; | |
}; | |
area.x1 = function(_) { | |
if (!arguments.length) return x1; | |
x1 = _; | |
return area; | |
}; | |
area.y = function(_) { | |
if (!arguments.length) return y1; | |
y0 = y1 = _; | |
return area; | |
}; | |
area.y0 = function(_) { | |
if (!arguments.length) return y0; | |
y0 = _; | |
return area; | |
}; | |
area.y1 = function(_) { | |
if (!arguments.length) return y1; | |
y1 = _; | |
return area; | |
}; | |
area.defined = function(_) { | |
if (!arguments.length) return defined; | |
defined = _; | |
return area; | |
}; | |
area.interpolate = function(_) { | |
if (!arguments.length) return interpolateKey; | |
if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; | |
interpolateReverse = interpolate.reverse || interpolate; | |
L = interpolate.closed ? "M" : "L"; | |
return area; | |
}; | |
area.tension = function(_) { | |
if (!arguments.length) return tension; | |
tension = _; | |
return area; | |
}; | |
return area; | |
} | |
d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; | |
d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; | |
d3.svg.area = function() { | |
return d3_svg_area(d3_identity); | |
}; | |
d3.svg.area.radial = function() { | |
var area = d3_svg_area(d3_svg_lineRadial); | |
area.radius = area.x, delete area.x; | |
area.innerRadius = area.x0, delete area.x0; | |
area.outerRadius = area.x1, delete area.x1; | |
area.angle = area.y, delete area.y; | |
area.startAngle = area.y0, delete area.y0; | |
area.endAngle = area.y1, delete area.y1; | |
return area; | |
}; | |
d3.svg.chord = function() { | |
var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; | |
function chord(d, i) { | |
var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); | |
return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; | |
} | |
function subgroup(self, f, d, i) { | |
var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ; | |
return { | |
r: r, | |
a0: a0, | |
a1: a1, | |
p0: [ r * Math.cos(a0), r * Math.sin(a0) ], | |
p1: [ r * Math.cos(a1), r * Math.sin(a1) ] | |
}; | |
} | |
function equals(a, b) { | |
return a.a0 == b.a0 && a.a1 == b.a1; | |
} | |
function arc(r, p, a) { | |
return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; | |
} | |
function curve(r0, p0, r1, p1) { | |
return "Q 0,0 " + p1; | |
} | |
chord.radius = function(v) { | |
if (!arguments.length) return radius; | |
radius = d3_functor(v); | |
return chord; | |
}; | |
chord.source = function(v) { | |
if (!arguments.length) return source; | |
source = d3_functor(v); | |
return chord; | |
}; | |
chord.target = function(v) { | |
if (!arguments.length) return target; | |
target = d3_functor(v); | |
return chord; | |
}; | |
chord.startAngle = function(v) { | |
if (!arguments.length) return startAngle; | |
startAngle = d3_functor(v); | |
return chord; | |
}; | |
chord.endAngle = function(v) { | |
if (!arguments.length) return endAngle; | |
endAngle = d3_functor(v); | |
return chord; | |
}; | |
return chord; | |
}; | |
function d3_svg_chordRadius(d) { | |
return d.radius; | |
} | |
d3.svg.diagonal = function() { | |
var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; | |
function diagonal(d, i) { | |
var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { | |
x: p0.x, | |
y: m | |
}, { | |
x: p3.x, | |
y: m | |
}, p3 ]; | |
p = p.map(projection); | |
return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; | |
} | |
diagonal.source = function(x) { | |
if (!arguments.length) return source; | |
source = d3_functor(x); | |
return diagonal; | |
}; | |
diagonal.target = function(x) { | |
if (!arguments.length) return target; | |
target = d3_functor(x); | |
return diagonal; | |
}; | |
diagonal.projection = function(x) { | |
if (!arguments.length) return projection; | |
projection = x; | |
return diagonal; | |
}; | |
return diagonal; | |
}; | |
function d3_svg_diagonalProjection(d) { | |
return [ d.x, d.y ]; | |
} | |
d3.svg.diagonal.radial = function() { | |
var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; | |
diagonal.projection = function(x) { | |
return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; | |
}; | |
return diagonal; | |
}; | |
function d3_svg_diagonalRadialProjection(projection) { | |
return function() { | |
var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ; | |
return [ r * Math.cos(a), r * Math.sin(a) ]; | |
}; | |
} | |
d3.svg.symbol = function() { | |
var type = d3_svg_symbolType, size = d3_svg_symbolSize; | |
function symbol(d, i) { | |
return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); | |
} | |
symbol.type = function(x) { | |
if (!arguments.length) return type; | |
type = d3_functor(x); | |
return symbol; | |
}; | |
symbol.size = function(x) { | |
if (!arguments.length) return size; | |
size = d3_functor(x); | |
return symbol; | |
}; | |
return symbol; | |
}; | |
function d3_svg_symbolSize() { | |
return 64; | |
} | |
function d3_svg_symbolType() { | |
return "circle"; | |
} | |
function d3_svg_symbolCircle(size) { | |
var r = Math.sqrt(size / π); | |
return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; | |
} | |
var d3_svg_symbols = d3.map({ | |
circle: d3_svg_symbolCircle, | |
cross: function(size) { | |
var r = Math.sqrt(size / 5) / 2; | |
return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; | |
}, | |
diamond: function(size) { | |
var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; | |
return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; | |
}, | |
square: function(size) { | |
var r = Math.sqrt(size) / 2; | |
return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; | |
}, | |
"triangle-down": function(size) { | |
var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; | |
return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; | |
}, | |
"triangle-up": function(size) { | |
var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; | |
return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; | |
} | |
}); | |
d3.svg.symbolTypes = d3_svg_symbols.keys(); | |
var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); | |
d3_selectionPrototype.transition = function(name) { | |
var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || { | |
time: Date.now(), | |
ease: d3_ease_cubicInOut, | |
delay: 0, | |
duration: 250 | |
}; | |
for (var j = -1, m = this.length; ++j < m; ) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) d3_transitionNode(node, i, ns, id, transition); | |
subgroup.push(node); | |
} | |
} | |
return d3_transition(subgroups, ns, id); | |
}; | |
d3_selectionPrototype.interrupt = function(name) { | |
return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name))); | |
}; | |
var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace()); | |
function d3_selection_interruptNS(ns) { | |
return function() { | |
var lock, active; | |
if ((lock = this[ns]) && (active = lock[lock.active])) { | |
if (--lock.count) delete lock[lock.active]; else delete this[ns]; | |
lock.active += .5; | |
active.event && active.event.interrupt.call(this, this.__data__, active.index); | |
} | |
}; | |
} | |
function d3_transition(groups, ns, id) { | |
d3_subclass(groups, d3_transitionPrototype); | |
groups.namespace = ns; | |
groups.id = id; | |
return groups; | |
} | |
var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; | |
d3_transitionPrototype.call = d3_selectionPrototype.call; | |
d3_transitionPrototype.empty = d3_selectionPrototype.empty; | |
d3_transitionPrototype.node = d3_selectionPrototype.node; | |
d3_transitionPrototype.size = d3_selectionPrototype.size; | |
d3.transition = function(selection, name) { | |
return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3.selection().transition(selection); | |
}; | |
d3.transition.prototype = d3_transitionPrototype; | |
d3_transitionPrototype.select = function(selector) { | |
var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node; | |
selector = d3_selection_selector(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { | |
if ("__data__" in node) subnode.__data__ = node.__data__; | |
d3_transitionNode(subnode, i, ns, id, node[ns][id]); | |
subgroup.push(subnode); | |
} else { | |
subgroup.push(null); | |
} | |
} | |
} | |
return d3_transition(subgroups, ns, id); | |
}; | |
d3_transitionPrototype.selectAll = function(selector) { | |
var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition; | |
selector = d3_selection_selectorAll(selector); | |
for (var j = -1, m = this.length; ++j < m; ) { | |
for (var group = this[j], i = -1, n = group.length; ++i < n; ) { | |
if (node = group[i]) { | |
transition = node[ns][id]; | |
subnodes = selector.call(node, node.__data__, i, j); | |
subgroups.push(subgroup = []); | |
for (var k = -1, o = subnodes.length; ++k < o; ) { | |
if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition); | |
subgroup.push(subnode); | |
} | |
} | |
} | |
} | |
return d3_transition(subgroups, ns, id); | |
}; | |
d3_transitionPrototype.filter = function(filter) { | |
var subgroups = [], subgroup, group, node; | |
if (typeof filter !== "function") filter = d3_selection_filter(filter); | |
for (var j = 0, m = this.length; j < m; j++) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = 0, n = group.length; i < n; i++) { | |
if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { | |
subgroup.push(node); | |
} | |
} | |
} | |
return d3_transition(subgroups, this.namespace, this.id); | |
}; | |
d3_transitionPrototype.tween = function(name, tween) { | |
var id = this.id, ns = this.namespace; | |
if (arguments.length < 2) return this.node()[ns][id].tween.get(name); | |
return d3_selection_each(this, tween == null ? function(node) { | |
node[ns][id].tween.remove(name); | |
} : function(node) { | |
node[ns][id].tween.set(name, tween); | |
}); | |
}; | |
function d3_transition_tween(groups, name, value, tween) { | |
var id = groups.id, ns = groups.namespace; | |
return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { | |
node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j))); | |
} : (value = tween(value), function(node) { | |
node[ns][id].tween.set(name, value); | |
})); | |
} | |
d3_transitionPrototype.attr = function(nameNS, value) { | |
if (arguments.length < 2) { | |
for (value in nameNS) this.attr(value, nameNS[value]); | |
return this; | |
} | |
var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); | |
function attrNull() { | |
this.removeAttribute(name); | |
} | |
function attrNullNS() { | |
this.removeAttributeNS(name.space, name.local); | |
} | |
function attrTween(b) { | |
return b == null ? attrNull : (b += "", function() { | |
var a = this.getAttribute(name), i; | |
return a !== b && (i = interpolate(a, b), function(t) { | |
this.setAttribute(name, i(t)); | |
}); | |
}); | |
} | |
function attrTweenNS(b) { | |
return b == null ? attrNullNS : (b += "", function() { | |
var a = this.getAttributeNS(name.space, name.local), i; | |
return a !== b && (i = interpolate(a, b), function(t) { | |
this.setAttributeNS(name.space, name.local, i(t)); | |
}); | |
}); | |
} | |
return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); | |
}; | |
d3_transitionPrototype.attrTween = function(nameNS, tween) { | |
var name = d3.ns.qualify(nameNS); | |
function attrTween(d, i) { | |
var f = tween.call(this, d, i, this.getAttribute(name)); | |
return f && function(t) { | |
this.setAttribute(name, f(t)); | |
}; | |
} | |
function attrTweenNS(d, i) { | |
var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); | |
return f && function(t) { | |
this.setAttributeNS(name.space, name.local, f(t)); | |
}; | |
} | |
return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); | |
}; | |
d3_transitionPrototype.style = function(name, value, priority) { | |
var n = arguments.length; | |
if (n < 3) { | |
if (typeof name !== "string") { | |
if (n < 2) value = ""; | |
for (priority in name) this.style(priority, name[priority], value); | |
return this; | |
} | |
priority = ""; | |
} | |
function styleNull() { | |
this.style.removeProperty(name); | |
} | |
function styleString(b) { | |
return b == null ? styleNull : (b += "", function() { | |
var a = d3_window(this).getComputedStyle(this, null).getPropertyValue(name), i; | |
return a !== b && (i = d3_interpolate(a, b), function(t) { | |
this.style.setProperty(name, i(t), priority); | |
}); | |
}); | |
} | |
return d3_transition_tween(this, "style." + name, value, styleString); | |
}; | |
d3_transitionPrototype.styleTween = function(name, tween, priority) { | |
if (arguments.length < 3) priority = ""; | |
function styleTween(d, i) { | |
var f = tween.call(this, d, i, d3_window(this).getComputedStyle(this, null).getPropertyValue(name)); | |
return f && function(t) { | |
this.style.setProperty(name, f(t), priority); | |
}; | |
} | |
return this.tween("style." + name, styleTween); | |
}; | |
d3_transitionPrototype.text = function(value) { | |
return d3_transition_tween(this, "text", value, d3_transition_text); | |
}; | |
function d3_transition_text(b) { | |
if (b == null) b = ""; | |
return function() { | |
this.textContent = b; | |
}; | |
} | |
d3_transitionPrototype.remove = function() { | |
var ns = this.namespace; | |
return this.each("end.transition", function() { | |
var p; | |
if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this); | |
}); | |
}; | |
d3_transitionPrototype.ease = function(value) { | |
var id = this.id, ns = this.namespace; | |
if (arguments.length < 1) return this.node()[ns][id].ease; | |
if (typeof value !== "function") value = d3.ease.apply(d3, arguments); | |
return d3_selection_each(this, function(node) { | |
node[ns][id].ease = value; | |
}); | |
}; | |
d3_transitionPrototype.delay = function(value) { | |
var id = this.id, ns = this.namespace; | |
if (arguments.length < 1) return this.node()[ns][id].delay; | |
return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { | |
node[ns][id].delay = +value.call(node, node.__data__, i, j); | |
} : (value = +value, function(node) { | |
node[ns][id].delay = value; | |
})); | |
}; | |
d3_transitionPrototype.duration = function(value) { | |
var id = this.id, ns = this.namespace; | |
if (arguments.length < 1) return this.node()[ns][id].duration; | |
return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { | |
node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j)); | |
} : (value = Math.max(1, value), function(node) { | |
node[ns][id].duration = value; | |
})); | |
}; | |
d3_transitionPrototype.each = function(type, listener) { | |
var id = this.id, ns = this.namespace; | |
if (arguments.length < 2) { | |
var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; | |
try { | |
d3_transitionInheritId = id; | |
d3_selection_each(this, function(node, i, j) { | |
d3_transitionInherit = node[ns][id]; | |
type.call(node, node.__data__, i, j); | |
}); | |
} finally { | |
d3_transitionInherit = inherit; | |
d3_transitionInheritId = inheritId; | |
} | |
} else { | |
d3_selection_each(this, function(node) { | |
var transition = node[ns][id]; | |
(transition.event || (transition.event = d3.dispatch("start", "end", "interrupt"))).on(type, listener); | |
}); | |
} | |
return this; | |
}; | |
d3_transitionPrototype.transition = function() { | |
var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition; | |
for (var j = 0, m = this.length; j < m; j++) { | |
subgroups.push(subgroup = []); | |
for (var group = this[j], i = 0, n = group.length; i < n; i++) { | |
if (node = group[i]) { | |
transition = node[ns][id0]; | |
d3_transitionNode(node, i, ns, id1, { | |
time: transition.time, | |
ease: transition.ease, | |
delay: transition.delay + transition.duration, | |
duration: transition.duration | |
}); | |
} | |
subgroup.push(node); | |
} | |
} | |
return d3_transition(subgroups, ns, id1); | |
}; | |
function d3_transitionNamespace(name) { | |
return name == null ? "__transition__" : "__transition_" + name + "__"; | |
} | |
function d3_transitionNode(node, i, ns, id, inherit) { | |
var lock = node[ns] || (node[ns] = { | |
active: 0, | |
count: 0 | |
}), transition = lock[id]; | |
if (!transition) { | |
var time = inherit.time; | |
transition = lock[id] = { | |
tween: new d3_Map(), | |
time: time, | |
delay: inherit.delay, | |
duration: inherit.duration, | |
ease: inherit.ease, | |
index: i | |
}; | |
inherit = null; | |
++lock.count; | |
d3.timer(function(elapsed) { | |
var delay = transition.delay, duration, ease, timer = d3_timer_active, tweened = []; | |
timer.t = delay + time; | |
if (delay <= elapsed) return start(elapsed - delay); | |
timer.c = start; | |
function start(elapsed) { | |
if (lock.active > id) return stop(); | |
var active = lock[lock.active]; | |
if (active) { | |
--lock.count; | |
delete lock[lock.active]; | |
active.event && active.event.interrupt.call(node, node.__data__, active.index); | |
} | |
lock.active = id; | |
transition.event && transition.event.start.call(node, node.__data__, i); | |
transition.tween.forEach(function(key, value) { | |
if (value = value.call(node, node.__data__, i)) { | |
tweened.push(value); | |
} | |
}); | |
ease = transition.ease; | |
duration = transition.duration; | |
d3.timer(function() { | |
timer.c = tick(elapsed || 1) ? d3_true : tick; | |
return 1; | |
}, 0, time); | |
} | |
function tick(elapsed) { | |
if (lock.active !== id) return 1; | |
var t = elapsed / duration, e = ease(t), n = tweened.length; | |
while (n > 0) { | |
tweened[--n].call(node, e); | |
} | |
if (t >= 1) { | |
transition.event && transition.event.end.call(node, node.__data__, i); | |
return stop(); | |
} | |
} | |
function stop() { | |
if (--lock.count) delete lock[id]; else delete node[ns]; | |
return 1; | |
} | |
}, 0, time); | |
} | |
} | |
d3.svg.axis = function() { | |
var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; | |
function axis(g) { | |
g.each(function() { | |
var g = d3.select(this); | |
var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); | |
var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform; | |
var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), | |
d3.transition(path)); | |
tickEnter.append("line"); | |
tickEnter.append("text"); | |
var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"), sign = orient === "top" || orient === "left" ? -1 : 1, x1, x2, y1, y2; | |
if (orient === "bottom" || orient === "top") { | |
tickTransform = d3_svg_axisX, x1 = "x", y1 = "y", x2 = "x2", y2 = "y2"; | |
text.attr("dy", sign < 0 ? "0em" : ".71em").style("text-anchor", "middle"); | |
pathUpdate.attr("d", "M" + range[0] + "," + sign * outerTickSize + "V0H" + range[1] + "V" + sign * outerTickSize); | |
} else { | |
tickTransform = d3_svg_axisY, x1 = "y", y1 = "x", x2 = "y2", y2 = "x2"; | |
text.attr("dy", ".32em").style("text-anchor", sign < 0 ? "end" : "start"); | |
pathUpdate.attr("d", "M" + sign * outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + sign * outerTickSize); | |
} | |
lineEnter.attr(y2, sign * innerTickSize); | |
textEnter.attr(y1, sign * tickSpacing); | |
lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize); | |
textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing); | |
if (scale1.rangeBand) { | |
var x = scale1, dx = x.rangeBand() / 2; | |
scale0 = scale1 = function(d) { | |
return x(d) + dx; | |
}; | |
} else if (scale0.rangeBand) { | |
scale0 = scale1; | |
} else { | |
tickExit.call(tickTransform, scale1, scale0); | |
} | |
tickEnter.call(tickTransform, scale0, scale1); | |
tickUpdate.call(tickTransform, scale1, scale1); | |
}); | |
} | |
axis.scale = function(x) { | |
if (!arguments.length) return scale; | |
scale = x; | |
return axis; | |
}; | |
axis.orient = function(x) { | |
if (!arguments.length) return orient; | |
orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; | |
return axis; | |
}; | |
axis.ticks = function() { | |
if (!arguments.length) return tickArguments_; | |
tickArguments_ = arguments; | |
return axis; | |
}; | |
axis.tickValues = function(x) { | |
if (!arguments.length) return tickValues; | |
tickValues = x; | |
return axis; | |
}; | |
axis.tickFormat = function(x) { | |
if (!arguments.length) return tickFormat_; | |
tickFormat_ = x; | |
return axis; | |
}; | |
axis.tickSize = function(x) { | |
var n = arguments.length; | |
if (!n) return innerTickSize; | |
innerTickSize = +x; | |
outerTickSize = +arguments[n - 1]; | |
return axis; | |
}; | |
axis.innerTickSize = function(x) { | |
if (!arguments.length) return innerTickSize; | |
innerTickSize = +x; | |
return axis; | |
}; | |
axis.outerTickSize = function(x) { | |
if (!arguments.length) return outerTickSize; | |
outerTickSize = +x; | |
return axis; | |
}; | |
axis.tickPadding = function(x) { | |
if (!arguments.length) return tickPadding; | |
tickPadding = +x; | |
return axis; | |
}; | |
axis.tickSubdivide = function() { | |
return arguments.length && axis; | |
}; | |
return axis; | |
}; | |
var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { | |
top: 1, | |
right: 1, | |
bottom: 1, | |
left: 1 | |
}; | |
function d3_svg_axisX(selection, x0, x1) { | |
selection.attr("transform", function(d) { | |
var v0 = x0(d); | |
return "translate(" + (isFinite(v0) ? v0 : x1(d)) + ",0)"; | |
}); | |
} | |
function d3_svg_axisY(selection, y0, y1) { | |
selection.attr("transform", function(d) { | |
var v0 = y0(d); | |
return "translate(0," + (isFinite(v0) ? v0 : y1(d)) + ")"; | |
}); | |
} | |
d3.svg.brush = function() { | |
var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; | |
function brush(g) { | |
g.each(function() { | |
var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); | |
var background = g.selectAll(".background").data([ 0 ]); | |
background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); | |
g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); | |
var resize = g.selectAll(".resize").data(resizes, d3_identity); | |
resize.exit().remove(); | |
resize.enter().append("g").attr("class", function(d) { | |
return "resize " + d; | |
}).style("cursor", function(d) { | |
return d3_svg_brushCursor[d]; | |
}).append("rect").attr("x", function(d) { | |
return /[ew]$/.test(d) ? -3 : null; | |
}).attr("y", function(d) { | |
return /^[ns]/.test(d) ? -3 : null; | |
}).attr("width", 6).attr("height", 6).style("visibility", "hidden"); | |
resize.style("display", brush.empty() ? "none" : null); | |
var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; | |
if (x) { | |
range = d3_scaleRange(x); | |
backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); | |
redrawX(gUpdate); | |
} | |
if (y) { | |
range = d3_scaleRange(y); | |
backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); | |
redrawY(gUpdate); | |
} | |
redraw(gUpdate); | |
}); | |
} | |
brush.event = function(g) { | |
g.each(function() { | |
var event_ = event.of(this, arguments), extent1 = { | |
x: xExtent, | |
y: yExtent, | |
i: xExtentDomain, | |
j: yExtentDomain | |
}, extent0 = this.__chart__ || extent1; | |
this.__chart__ = extent1; | |
if (d3_transitionInheritId) { | |
d3.select(this).transition().each("start.brush", function() { | |
xExtentDomain = extent0.i; | |
yExtentDomain = extent0.j; | |
xExtent = extent0.x; | |
yExtent = extent0.y; | |
event_({ | |
type: "brushstart" | |
}); | |
}).tween("brush:brush", function() { | |
var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); | |
xExtentDomain = yExtentDomain = null; | |
return function(t) { | |
xExtent = extent1.x = xi(t); | |
yExtent = extent1.y = yi(t); | |
event_({ | |
type: "brush", | |
mode: "resize" | |
}); | |
}; | |
}).each("end.brush", function() { | |
xExtentDomain = extent1.i; | |
yExtentDomain = extent1.j; | |
event_({ | |
type: "brush", | |
mode: "resize" | |
}); | |
event_({ | |
type: "brushend" | |
}); | |
}); | |
} else { | |
event_({ | |
type: "brushstart" | |
}); | |
event_({ | |
type: "brush", | |
mode: "resize" | |
}); | |
event_({ | |
type: "brushend" | |
}); | |
} | |
}); | |
}; | |
function redraw(g) { | |
g.selectAll(".resize").attr("transform", function(d) { | |
return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; | |
}); | |
} | |
function redrawX(g) { | |
g.select(".extent").attr("x", xExtent[0]); | |
g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); | |
} | |
function redrawY(g) { | |
g.select(".extent").attr("y", yExtent[0]); | |
g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); | |
} | |
function brushstart() { | |
var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(target), center, origin = d3.mouse(target), offset; | |
var w = d3.select(d3_window(target)).on("keydown.brush", keydown).on("keyup.brush", keyup); | |
if (d3.event.changedTouches) { | |
w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); | |
} else { | |
w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); | |
} | |
g.interrupt().selectAll("*").interrupt(); | |
if (dragging) { | |
origin[0] = xExtent[0] - origin[0]; | |
origin[1] = yExtent[0] - origin[1]; | |
} else if (resizing) { | |
var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); | |
offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; | |
origin[0] = xExtent[ex]; | |
origin[1] = yExtent[ey]; | |
} else if (d3.event.altKey) center = origin.slice(); | |
g.style("pointer-events", "none").selectAll(".resize").style("display", null); | |
d3.select("body").style("cursor", eventTarget.style("cursor")); | |
event_({ | |
type: "brushstart" | |
}); | |
brushmove(); | |
function keydown() { | |
if (d3.event.keyCode == 32) { | |
if (!dragging) { | |
center = null; | |
origin[0] -= xExtent[1]; | |
origin[1] -= yExtent[1]; | |
dragging = 2; | |
} | |
d3_eventPreventDefault(); | |
} | |
} | |
function keyup() { | |
if (d3.event.keyCode == 32 && dragging == 2) { | |
origin[0] += xExtent[1]; | |
origin[1] += yExtent[1]; | |
dragging = 0; | |
d3_eventPreventDefault(); | |
} | |
} | |
function brushmove() { | |
var point = d3.mouse(target), moved = false; | |
if (offset) { | |
point[0] += offset[0]; | |
point[1] += offset[1]; | |
} | |
if (!dragging) { | |
if (d3.event.altKey) { | |
if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; | |
origin[0] = xExtent[+(point[0] < center[0])]; | |
origin[1] = yExtent[+(point[1] < center[1])]; | |
} else center = null; | |
} | |
if (resizingX && move1(point, x, 0)) { | |
redrawX(g); | |
moved = true; | |
} | |
if (resizingY && move1(point, y, 1)) { | |
redrawY(g); | |
moved = true; | |
} | |
if (moved) { | |
redraw(g); | |
event_({ | |
type: "brush", | |
mode: dragging ? "move" : "resize" | |
}); | |
} | |
} | |
function move1(point, scale, i) { | |
var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; | |
if (dragging) { | |
r0 -= position; | |
r1 -= size + position; | |
} | |
min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; | |
if (dragging) { | |
max = (min += position) + size; | |
} else { | |
if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); | |
if (position < min) { | |
max = min; | |
min = position; | |
} else { | |
max = position; | |
} | |
} | |
if (extent[0] != min || extent[1] != max) { | |
if (i) yExtentDomain = null; else xExtentDomain = null; | |
extent[0] = min; | |
extent[1] = max; | |
return true; | |
} | |
} | |
function brushend() { | |
brushmove(); | |
g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); | |
d3.select("body").style("cursor", null); | |
w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); | |
dragRestore(); | |
event_({ | |
type: "brushend" | |
}); | |
} | |
} | |
brush.x = function(z) { | |
if (!arguments.length) return x; | |
x = z; | |
resizes = d3_svg_brushResizes[!x << 1 | !y]; | |
return brush; | |
}; | |
brush.y = function(z) { | |
if (!arguments.length) return y; | |
y = z; | |
resizes = d3_svg_brushResizes[!x << 1 | !y]; | |
return brush; | |
}; | |
brush.clamp = function(z) { | |
if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; | |
if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; | |
return brush; | |
}; | |
brush.extent = function(z) { | |
var x0, x1, y0, y1, t; | |
if (!arguments.length) { | |
if (x) { | |
if (xExtentDomain) { | |
x0 = xExtentDomain[0], x1 = xExtentDomain[1]; | |
} else { | |
x0 = xExtent[0], x1 = xExtent[1]; | |
if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); | |
if (x1 < x0) t = x0, x0 = x1, x1 = t; | |
} | |
} | |
if (y) { | |
if (yExtentDomain) { | |
y0 = yExtentDomain[0], y1 = yExtentDomain[1]; | |
} else { | |
y0 = yExtent[0], y1 = yExtent[1]; | |
if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); | |
if (y1 < y0) t = y0, y0 = y1, y1 = t; | |
} | |
} | |
return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; | |
} | |
if (x) { | |
x0 = z[0], x1 = z[1]; | |
if (y) x0 = x0[0], x1 = x1[0]; | |
xExtentDomain = [ x0, x1 ]; | |
if (x.invert) x0 = x(x0), x1 = x(x1); | |
if (x1 < x0) t = x0, x0 = x1, x1 = t; | |
if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; | |
} | |
if (y) { | |
y0 = z[0], y1 = z[1]; | |
if (x) y0 = y0[1], y1 = y1[1]; | |
yExtentDomain = [ y0, y1 ]; | |
if (y.invert) y0 = y(y0), y1 = y(y1); | |
if (y1 < y0) t = y0, y0 = y1, y1 = t; | |
if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; | |
} | |
return brush; | |
}; | |
brush.clear = function() { | |
if (!brush.empty()) { | |
xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; | |
xExtentDomain = yExtentDomain = null; | |
} | |
return brush; | |
}; | |
brush.empty = function() { | |
return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; | |
}; | |
return d3.rebind(brush, event, "on"); | |
}; | |
var d3_svg_brushCursor = { | |
n: "ns-resize", | |
e: "ew-resize", | |
s: "ns-resize", | |
w: "ew-resize", | |
nw: "nwse-resize", | |
ne: "nesw-resize", | |
se: "nwse-resize", | |
sw: "nesw-resize" | |
}; | |
var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; | |
var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; | |
var d3_time_formatUtc = d3_time_format.utc; | |
var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); | |
d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; | |
function d3_time_formatIsoNative(date) { | |
return date.toISOString(); | |
} | |
d3_time_formatIsoNative.parse = function(string) { | |
var date = new Date(string); | |
return isNaN(date) ? null : date; | |
}; | |
d3_time_formatIsoNative.toString = d3_time_formatIso.toString; | |
d3_time.second = d3_time_interval(function(date) { | |
return new d3_date(Math.floor(date / 1e3) * 1e3); | |
}, function(date, offset) { | |
date.setTime(date.getTime() + Math.floor(offset) * 1e3); | |
}, function(date) { | |
return date.getSeconds(); | |
}); | |
d3_time.seconds = d3_time.second.range; | |
d3_time.seconds.utc = d3_time.second.utc.range; | |
d3_time.minute = d3_time_interval(function(date) { | |
return new d3_date(Math.floor(date / 6e4) * 6e4); | |
}, function(date, offset) { | |
date.setTime(date.getTime() + Math.floor(offset) * 6e4); | |
}, function(date) { | |
return date.getMinutes(); | |
}); | |
d3_time.minutes = d3_time.minute.range; | |
d3_time.minutes.utc = d3_time.minute.utc.range; | |
d3_time.hour = d3_time_interval(function(date) { | |
var timezone = date.getTimezoneOffset() / 60; | |
return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); | |
}, function(date, offset) { | |
date.setTime(date.getTime() + Math.floor(offset) * 36e5); | |
}, function(date) { | |
return date.getHours(); | |
}); | |
d3_time.hours = d3_time.hour.range; | |
d3_time.hours.utc = d3_time.hour.utc.range; | |
d3_time.month = d3_time_interval(function(date) { | |
date = d3_time.day(date); | |
date.setDate(1); | |
return date; | |
}, function(date, offset) { | |
date.setMonth(date.getMonth() + offset); | |
}, function(date) { | |
return date.getMonth(); | |
}); | |
d3_time.months = d3_time.month.range; | |
d3_time.months.utc = d3_time.month.utc.range; | |
function d3_time_scale(linear, methods, format) { | |
function scale(x) { | |
return linear(x); | |
} | |
scale.invert = function(x) { | |
return d3_time_scaleDate(linear.invert(x)); | |
}; | |
scale.domain = function(x) { | |
if (!arguments.length) return linear.domain().map(d3_time_scaleDate); | |
linear.domain(x); | |
return scale; | |
}; | |
function tickMethod(extent, count) { | |
var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); | |
return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { | |
return d / 31536e6; | |
}), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; | |
} | |
scale.nice = function(interval, skip) { | |
var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); | |
if (method) interval = method[0], skip = method[1]; | |
function skipped(date) { | |
return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; | |
} | |
return scale.domain(d3_scale_nice(domain, skip > 1 ? { | |
floor: function(date) { | |
while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); | |
return date; | |
}, | |
ceil: function(date) { | |
while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); | |
return date; | |
} | |
} : interval)); | |
}; | |
scale.ticks = function(interval, skip) { | |
var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { | |
range: interval | |
}, skip ]; | |
if (method) interval = method[0], skip = method[1]; | |
return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); | |
}; | |
scale.tickFormat = function() { | |
return format; | |
}; | |
scale.copy = function() { | |
return d3_time_scale(linear.copy(), methods, format); | |
}; | |
return d3_scale_linearRebind(scale, linear); | |
} | |
function d3_time_scaleDate(t) { | |
return new Date(t); | |
} | |
var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; | |
var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; | |
var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { | |
return d.getMilliseconds(); | |
} ], [ ":%S", function(d) { | |
return d.getSeconds(); | |
} ], [ "%I:%M", function(d) { | |
return d.getMinutes(); | |
} ], [ "%I %p", function(d) { | |
return d.getHours(); | |
} ], [ "%a %d", function(d) { | |
return d.getDay() && d.getDate() != 1; | |
} ], [ "%b %d", function(d) { | |
return d.getDate() != 1; | |
} ], [ "%B", function(d) { | |
return d.getMonth(); | |
} ], [ "%Y", d3_true ] ]); | |
var d3_time_scaleMilliseconds = { | |
range: function(start, stop, step) { | |
return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate); | |
}, | |
floor: d3_identity, | |
ceil: d3_identity | |
}; | |
d3_time_scaleLocalMethods.year = d3_time.year; | |
d3_time.scale = function() { | |
return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); | |
}; | |
var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { | |
return [ m[0].utc, m[1] ]; | |
}); | |
var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { | |
return d.getUTCMilliseconds(); | |
} ], [ ":%S", function(d) { | |
return d.getUTCSeconds(); | |
} ], [ "%I:%M", function(d) { | |
return d.getUTCMinutes(); | |
} ], [ "%I %p", function(d) { | |
return d.getUTCHours(); | |
} ], [ "%a %d", function(d) { | |
return d.getUTCDay() && d.getUTCDate() != 1; | |
} ], [ "%b %d", function(d) { | |
return d.getUTCDate() != 1; | |
} ], [ "%B", function(d) { | |
return d.getUTCMonth(); | |
} ], [ "%Y", d3_true ] ]); | |
d3_time_scaleUtcMethods.year = d3_time.year.utc; | |
d3_time.scale.utc = function() { | |
return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); | |
}; | |
d3.text = d3_xhrType(function(request) { | |
return request.responseText; | |
}); | |
d3.json = function(url, callback) { | |
return d3_xhr(url, "application/json", d3_json, callback); | |
}; | |
function d3_json(request) { | |
return JSON.parse(request.responseText); | |
} | |
d3.html = function(url, callback) { | |
return d3_xhr(url, "text/html", d3_html, callback); | |
}; | |
function d3_html(request) { | |
var range = d3_document.createRange(); | |
range.selectNode(d3_document.body); | |
return range.createContextualFragment(request.responseText); | |
} | |
d3.xml = d3_xhrType(function(request) { | |
return request.responseXML; | |
}); | |
if (true) !(__WEBPACK_AMD_DEFINE_FACTORY__ = (d3), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); else if (typeof module === "object" && module.exports) module.exports = d3; | |
this.d3 = d3; | |
}(); | |
/***/ }, | |
/* 360 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var $ = __webpack_require__(208); | |
var d3 = __webpack_require__(359); | |
var callEach = __webpack_require__(194).callEach; | |
var bindKey = __webpack_require__(194).bindKey; | |
var rest = __webpack_require__(194).rest; | |
function Binder($scope) { | |
this.disposal = []; | |
if ($scope) { | |
$scope.$on('$destroy', bindKey(this, 'destroy')); | |
} | |
} | |
Binder.prototype._bind = function (on, off, emitter, args) { | |
on.apply(emitter, args); | |
this.disposal.push(function () { | |
off.apply(emitter, args); | |
}); | |
}; | |
Binder.prototype.on = function (emitter /*, ...args */) { | |
this._bind(emitter.on, emitter.off || emitter.removeListener, emitter, rest(arguments)); | |
}; | |
Binder.prototype.jqOn = function (el /*, ...args */) { | |
var $el = $(el); | |
this._bind($el.on, $el.off, $el, rest(arguments)); | |
}; | |
Binder.prototype.fakeD3Bind = function (el, event, handler) { | |
this.jqOn(el, event, function (e) { | |
// mimick https://github.com/mbostock/d3/blob/3abb00113662463e5c19eb87cd33f6d0ddc23bc0/src/selection/on.js#L87-L94 | |
var o = d3.event; // Events can be reentrant (e.g., focus). | |
d3.event = e; | |
try { | |
handler.apply(this, [this.__data__]); | |
} finally { | |
d3.event = o; | |
} | |
}); | |
}; | |
Binder.prototype.destroy = function () { | |
var destroyers = this.disposal; | |
this.disposal = []; | |
callEach(destroyers); | |
}; | |
module.exports = Binder; | |
/***/ }, | |
/* 361 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(362); | |
__webpack_require__(363); | |
__webpack_require__(375); | |
__webpack_require__(383); | |
__webpack_require__(222); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function DataFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var injectZeros = Private(__webpack_require__(362)); | |
var orderKeys = Private(__webpack_require__(363)); | |
var getLabels = Private(__webpack_require__(375)); | |
var color = Private(__webpack_require__(383)); | |
var errors = __webpack_require__(222); | |
/** | |
* Provides an API for pulling values off the data | |
* and calculating values using the data | |
* | |
* @class Data | |
* @constructor | |
* @param data {Object} Elasticsearch query results | |
* @param attr {Object|*} Visualization options | |
*/ | |
function Data(data, attr) { | |
if (!(this instanceof Data)) { | |
return new Data(data, attr); | |
} | |
var self = this; | |
var offset; | |
if (attr.mode === 'stacked') { | |
offset = 'zero'; | |
} else if (attr.mode === 'percentage') { | |
offset = 'expand'; | |
} else if (attr.mode === 'grouped') { | |
offset = 'group'; | |
} else { | |
offset = attr.mode; | |
} | |
this.data = data; | |
this.type = this.getDataType(); | |
this.labels = this._getLabels(this.data); | |
this.color = this.labels ? color(this.labels) : undefined; | |
this._normalizeOrdered(); | |
this._attr = _.defaults(attr || {}, { | |
stack: d3.layout.stack().x(function (d) { | |
return d.x; | |
}).y(function (d) { | |
if (offset === 'expand') { | |
return Math.abs(d.y); | |
} | |
return d.y; | |
}).offset(offset || 'zero') | |
}); | |
if (attr.mode === 'stacked' && attr.type === 'histogram') { | |
this._attr.stack.out(function (d, y0, y) { | |
return self._stackNegAndPosVals(d, y0, y); | |
}); | |
} | |
} | |
Data.prototype._updateData = function () { | |
if (this.data.rows) { | |
_.map(this.data.rows, this._updateDataSeriesLabel, this); | |
} else if (this.data.columns) { | |
_.map(this.data.columns, this._updateDataSeriesLabel, this); | |
} else { | |
this._updateDataSeriesLabel(this.data); | |
} | |
}; | |
Data.prototype._updateDataSeriesLabel = function (eachData) { | |
if (eachData.series) { | |
eachData.series[0].label = this.get('yAxisLabel'); | |
} | |
}; | |
Data.prototype._getLabels = function (data) { | |
if (this.type === 'series') { | |
var noLabel = getLabels(data).length === 1 && getLabels(data)[0] === ''; | |
if (noLabel) { | |
this._updateData(); | |
return [this.get('yAxisLabel')]; | |
} | |
return getLabels(data); | |
} | |
return this.pieNames(); | |
}; | |
/** | |
* Returns true for positive numbers | |
*/ | |
Data.prototype._isPositive = function (num) { | |
return num >= 0; | |
}; | |
/** | |
* Returns true for negative numbers | |
*/ | |
Data.prototype._isNegative = function (num) { | |
return num < 0; | |
}; | |
/** | |
* Adds two input values | |
*/ | |
Data.prototype._addVals = function (a, b) { | |
return a + b; | |
}; | |
/** | |
* Returns the results of the addition of numbers in a filtered array. | |
*/ | |
Data.prototype._sumYs = function (arr, callback) { | |
var filteredArray = arr.filter(callback); | |
return filteredArray.length ? filteredArray.reduce(this._addVals) : 0; | |
}; | |
/** | |
* Calculates the d.y0 value for stacked data in D3. | |
*/ | |
Data.prototype._calcYZero = function (y, arr) { | |
if (y >= 0) return this._sumYs(arr, this._isPositive); | |
return this._sumYs(arr, this._isNegative); | |
}; | |
/** | |
* | |
*/ | |
Data.prototype._getCounts = function (i, j) { | |
var data = this.chartData(); | |
var dataLengths = {}; | |
dataLengths.charts = data.length; | |
dataLengths.stacks = dataLengths.charts ? data[i].series.length : 0; | |
dataLengths.values = dataLengths.stacks ? data[i].series[j].values.length : 0; | |
return dataLengths; | |
}; | |
/** | |
* | |
*/ | |
Data.prototype._createCache = function () { | |
var cache = { | |
index: { | |
chart: 0, | |
stack: 0, | |
value: 0 | |
}, | |
yValsArr: [] | |
}; | |
cache.count = this._getCounts(cache.index.chart, cache.index.stack); | |
return cache; | |
}; | |
/** | |
* Stacking function passed to the D3 Stack Layout `.out` API. | |
* See: https://github.com/mbostock/d3/wiki/Stack-Layout | |
* It is responsible for calculating the correct d.y0 value for | |
* mixed datasets containing both positive and negative values. | |
*/ | |
Data.prototype._stackNegAndPosVals = function (d, y0, y) { | |
var data = this.chartData(); | |
// Storing counters and data characteristics needed to stack values properly | |
if (!this._cache) { | |
this._cache = this._createCache(); | |
} | |
d.y0 = this._calcYZero(y, this._cache.yValsArr); | |
++this._cache.index.stack; | |
// last stack, or last value, reset the stack count and y value array | |
var lastStack = this._cache.index.stack >= this._cache.count.stacks; | |
if (lastStack) { | |
this._cache.index.stack = 0; | |
++this._cache.index.value; | |
this._cache.yValsArr = []; | |
// still building the stack collection, push v value to array | |
} else if (y !== 0) { | |
this._cache.yValsArr.push(y); | |
} | |
// last value, prepare for the next chart, if one exists | |
var lastValue = this._cache.index.value >= this._cache.count.values; | |
if (lastValue) { | |
this._cache.index.value = 0; | |
++this._cache.index.chart; | |
// no more charts, reset the queue and finish | |
if (this._cache.index.chart >= this._cache.count.charts) { | |
this._cache = this._createCache(); | |
return; | |
} | |
// get stack and value count for next chart | |
var chartSeries = data[this._cache.index.chart].series; | |
this._cache.count.stacks = chartSeries.length; | |
this._cache.count.values = chartSeries.length ? chartSeries[this._cache.index.stack].values.length : 0; | |
} | |
}; | |
Data.prototype.getDataType = function () { | |
var data = this.getVisData(); | |
var type; | |
data.forEach(function (obj) { | |
if (obj.series) { | |
type = 'series'; | |
} else if (obj.slices) { | |
type = 'slices'; | |
} else if (obj.geoJson) { | |
type = 'geoJson'; | |
} | |
}); | |
return type; | |
}; | |
/** | |
* Returns an array of the actual x and y data value objects | |
* from data with series keys | |
* | |
* @method chartData | |
* @returns {*} Array of data objects | |
*/ | |
Data.prototype.chartData = function () { | |
if (!this.data.series) { | |
var arr = this.data.rows ? this.data.rows : this.data.columns; | |
return _.toArray(arr); | |
} | |
return [this.data]; | |
}; | |
/** | |
* Returns an array of chart data objects | |
* | |
* @method getVisData | |
* @returns {*} Array of chart data objects | |
*/ | |
Data.prototype.getVisData = function () { | |
var visData; | |
if (this.data.rows) { | |
visData = this.data.rows; | |
} else if (this.data.columns) { | |
visData = this.data.columns; | |
} else { | |
visData = [this.data]; | |
} | |
return visData; | |
}; | |
/** | |
* get min and max for all cols, rows of data | |
* | |
* @method getMaxMin | |
* @return {Object} | |
*/ | |
Data.prototype.getGeoExtents = function () { | |
var visData = this.getVisData(); | |
return _.reduce(_.pluck(visData, 'geoJson.properties'), function (minMax, props) { | |
return { | |
min: Math.min(props.min, minMax.min), | |
max: Math.max(props.max, minMax.max) | |
}; | |
}, { min: Infinity, max: -Infinity }); | |
}; | |
/** | |
* Returns array of chart data objects for pie data objects | |
* | |
* @method pieData | |
* @returns {*} Array of chart data objects | |
*/ | |
Data.prototype.pieData = function () { | |
if (!this.data.slices) { | |
return this.data.rows ? this.data.rows : this.data.columns; | |
} | |
return [this.data]; | |
}; | |
/** | |
* Get attributes off the data, e.g. `tooltipFormatter` or `xAxisFormatter` | |
* pulls the value off the first item in the array | |
* these values are typically the same between data objects of the same chart | |
* TODO: May need to verify this or refactor | |
* | |
* @method get | |
* @param thing {String} Data object key | |
* @returns {*} Data object value | |
*/ | |
Data.prototype.get = function (thing, def) { | |
var source = (this.data.rows || this.data.columns || [this.data])[0]; | |
return _.get(source, thing, def); | |
}; | |
/** | |
* Returns true if null values are present | |
* @returns {*} | |
*/ | |
Data.prototype.hasNullValues = function () { | |
var chartData = this.chartData(); | |
return chartData.some(function (chart) { | |
return chart.series.some(function (obj) { | |
return obj.values.some(function (d) { | |
return d.y === null; | |
}); | |
}); | |
}); | |
}; | |
/** | |
* Return an array of all value objects | |
* Pluck the data.series array from each data object | |
* Create an array of all the value objects from the series array | |
* | |
* @method flatten | |
* @returns {Array} Value objects | |
*/ | |
Data.prototype.flatten = function () { | |
return _(this.chartData()).pluck('series').flattenDeep().pluck('values').flattenDeep().value(); | |
}; | |
/** | |
* Determines whether histogram charts should be stacked | |
* TODO: need to make this more generic | |
* | |
* @method shouldBeStacked | |
* @returns {boolean} | |
*/ | |
Data.prototype.shouldBeStacked = function () { | |
var isHistogram = this._attr.type === 'histogram'; | |
var isArea = this._attr.type === 'area'; | |
var isOverlapping = this._attr.mode === 'overlap'; | |
var grouped = this._attr.mode === 'grouped'; | |
var stackedHisto = isHistogram && !grouped; | |
var stackedArea = isArea && !isOverlapping; | |
return stackedHisto || stackedArea; | |
}; | |
/** | |
* Validates that the Y axis min value defined by user input | |
* is a number. | |
* | |
* @param val {Number} Y axis min value | |
* @returns {Number} Y axis min value | |
*/ | |
Data.prototype.validateUserDefinedYMin = function (val) { | |
if (!_.isNumber(val)) { | |
throw new Error('validateUserDefinedYMin expects a number'); | |
} | |
return val; | |
}; | |
/** | |
* Calculates the lowest Y value across all charts, taking | |
* stacking into consideration. | |
* | |
* @method getYMin | |
* @param {function} [getValue] - optional getter that will receive a | |
* point and should return the value that should | |
* be considered | |
* @returns {Number} Min y axis value | |
*/ | |
Data.prototype.getYMin = function (getValue) { | |
var self = this; | |
var arr = []; | |
if (this._attr.mode === 'percentage' || this._attr.mode === 'wiggle' || this._attr.mode === 'silhouette') { | |
return 0; | |
} | |
var flat = this.flatten(); | |
// if there is only one data point and its less than zero, | |
// return 0 as the yMax value. | |
if (!flat.length || flat.length === 1 && flat[0].y > 0) { | |
return 0; | |
} | |
var min = Infinity; | |
// for each object in the dataArray, | |
// push the calculated y value to the initialized array (arr) | |
_.each(this.chartData(), function (chart) { | |
var calculatedMin = self._getYExtent(chart, 'min', getValue); | |
if (!_.isUndefined(calculatedMin)) { | |
min = Math.min(min, calculatedMin); | |
} | |
}); | |
return min; | |
}; | |
/** | |
* Calculates the highest Y value across all charts, taking | |
* stacking into consideration. | |
* | |
* @method getYMax | |
* @param {function} [getValue] - optional getter that will receive a | |
* point and should return the value that should | |
* be considered | |
* @returns {Number} Max y axis value | |
*/ | |
Data.prototype.getYMax = function (getValue) { | |
var self = this; | |
var arr = []; | |
if (self._attr.mode === 'percentage') { | |
return 1; | |
} | |
var flat = this.flatten(); | |
// if there is only one data point and its less than zero, | |
// return 0 as the yMax value. | |
if (!flat.length || flat.length === 1 && flat[0].y < 0) { | |
return 0; | |
} | |
var max = -Infinity; | |
// for each object in the dataArray, | |
// push the calculated y value to the initialized array (arr) | |
_.each(this.chartData(), function (chart) { | |
var calculatedMax = self._getYExtent(chart, 'max', getValue); | |
if (!_.isUndefined(calculatedMax)) { | |
max = Math.max(max, calculatedMax); | |
} | |
}); | |
return max; | |
}; | |
/** | |
* Calculates the stacked values for each data object | |
* | |
* @method stackData | |
* @param series {Array} Array of data objects | |
* @returns {*} Array of data objects with x, y, y0 keys | |
*/ | |
Data.prototype.stackData = function (series) { | |
// Should not stack values on line chart | |
if (this._attr.type === 'line') return series; | |
return this._attr.stack(series); | |
}; | |
/** | |
* Returns the max Y axis value for a `series` array based on | |
* a specified callback function (calculation). | |
* @param {function} [getValue] - Optional getter that will be used to read | |
* values from points when calculating the extent. | |
* default is either this._getYStack or this.getY | |
* based on this.shouldBeStacked(). | |
*/ | |
Data.prototype._getYExtent = function (chart, extent, getValue) { | |
if (this.shouldBeStacked()) { | |
this.stackData(_.pluck(chart.series, 'values')); | |
getValue = getValue || this._getYStack; | |
} else { | |
getValue = getValue || this._getY; | |
} | |
var points = chart.series.reduce(function (points, series) { | |
return points.concat(series.values); | |
}, []).map(getValue); | |
return d3[extent](points); | |
}; | |
/** | |
* Calculates the y stack value for each data object | |
*/ | |
Data.prototype._getYStack = function (d) { | |
return d.y0 + d.y; | |
}; | |
/** | |
* Calculates the Y max value | |
*/ | |
Data.prototype._getY = function (d) { | |
return d.y; | |
}; | |
/** | |
* Helper function for getNames | |
* Returns an array of objects with a name (key) value and an index value. | |
* The index value allows us to sort the names in the correct nested order. | |
* | |
* @method returnNames | |
* @param array {Array} Array of data objects | |
* @param index {Number} Number of times the object is nested | |
* @param columns {Object} Contains name formatter information | |
* @returns {Array} Array of labels (strings) | |
*/ | |
Data.prototype.returnNames = function (array, index, columns) { | |
var names = []; | |
var self = this; | |
_.forEach(array, function (obj, i) { | |
names.push({ | |
label: obj.name, | |
values: obj, | |
index: index | |
}); | |
if (obj.children) { | |
var plusIndex = index + 1; | |
_.forEach(self.returnNames(obj.children, plusIndex, columns), function (namedObj) { | |
names.push(namedObj); | |
}); | |
} | |
}); | |
return names; | |
}; | |
/** | |
* Flattens hierarchical data into an array of objects with a name and index value. | |
* The indexed value determines the order of nesting in the data. | |
* Returns an array with names sorted by the index value. | |
* | |
* @method getNames | |
* @param data {Object} Chart data object | |
* @param columns {Object} Contains formatter information | |
* @returns {Array} Array of names (strings) | |
*/ | |
Data.prototype.getNames = function (data, columns) { | |
var slices = data.slices; | |
if (slices.children) { | |
var namedObj = this.returnNames(slices.children, 0, columns); | |
return _(namedObj).sortBy(function (obj) { | |
return obj.index; | |
}).unique(function (d) { | |
return d.label; | |
}).value(); | |
} | |
}; | |
/** | |
* Removes zeros from pie chart data | |
* @param slices | |
* @returns {*} | |
*/ | |
Data.prototype._removeZeroSlices = function (slices) { | |
var self = this; | |
if (!slices.children) return slices; | |
slices = _.clone(slices); | |
slices.children = slices.children.reduce(function (children, child) { | |
if (child.size !== 0) { | |
children.push(self._removeZeroSlices(child)); | |
} | |
return children; | |
}, []); | |
return slices; | |
}; | |
/** | |
* Returns an array of names ordered by appearance in the nested array | |
* of objects | |
* | |
* @method pieNames | |
* @returns {Array} Array of unique names (strings) | |
*/ | |
Data.prototype.pieNames = function (data) { | |
var self = this; | |
var names = []; | |
_.forEach(data, function (obj) { | |
var columns = obj.raw ? obj.raw.columns : undefined; | |
obj.slices = self._removeZeroSlices(obj.slices); | |
_.forEach(self.getNames(obj, columns), function (name) { | |
names.push(name); | |
}); | |
}); | |
return _.uniq(names, 'label'); | |
}; | |
/** | |
* Inject zeros into the data | |
* | |
* @method injectZeros | |
* @returns {Object} Data object with zeros injected | |
*/ | |
Data.prototype.injectZeros = function () { | |
return injectZeros(this.data); | |
}; | |
/** | |
* Returns an array of all x axis values from the data | |
* | |
* @method xValues | |
* @returns {Array} Array of x axis values | |
*/ | |
Data.prototype.xValues = function () { | |
return orderKeys(this.data); | |
}; | |
/** | |
* Return an array of unique labels | |
* Curently, only used for vertical bar and line charts, | |
* or any data object with series values | |
* | |
* @method getLabels | |
* @returns {Array} Array of labels (strings) | |
*/ | |
Data.prototype.getLabels = function () { | |
return getLabels(this.data); | |
}; | |
/** | |
* Returns a function that does color lookup on labels | |
* | |
* @method getColorFunc | |
* @returns {Function} Performs lookup on string and returns hex color | |
*/ | |
Data.prototype.getColorFunc = function () { | |
return color(this.getLabels()); | |
}; | |
/** | |
* Returns a function that does color lookup on names for pie charts | |
* | |
* @method getPieColorFunc | |
* @returns {Function} Performs lookup on string and returns hex color | |
*/ | |
Data.prototype.getPieColorFunc = function () { | |
return color(this.pieNames(this.getVisData()).map(function (d) { | |
return d.label; | |
})); | |
}; | |
/** | |
* ensure that the datas ordered property has a min and max | |
* if the data represents an ordered date range. | |
* | |
* @return {undefined} | |
*/ | |
Data.prototype._normalizeOrdered = function () { | |
var data = this.getVisData(); | |
var self = this; | |
data.forEach(function (d) { | |
if (!d.ordered || !d.ordered.date) return; | |
var missingMin = d.ordered.min == null; | |
var missingMax = d.ordered.max == null; | |
if (missingMax || missingMin) { | |
var extent = d3.extent(self.xValues()); | |
if (missingMin) d.ordered.min = extent[0]; | |
if (missingMax) d.ordered.max = extent[1]; | |
} | |
}); | |
}; | |
/** | |
* Calculates min and max values for all map data | |
* series.rows is an array of arrays | |
* each row is an array of values | |
* last value in row array is bucket count | |
* | |
* @method mapDataExtents | |
* @param series {Array} Array of data objects | |
* @returns {Array} min and max values | |
*/ | |
Data.prototype.mapDataExtents = function (series) { | |
var values; | |
values = _.map(series.rows, function (row) { | |
return row[row.length - 1]; | |
}); | |
var extents = [_.min(values), _.max(values)]; | |
return extents; | |
}; | |
/** | |
* Get the maximum number of series, considering each chart | |
* individually. | |
* | |
* @return {number} - the largest number of series from all charts | |
*/ | |
Data.prototype.maxNumberOfSeries = function () { | |
return this.chartData().reduce(function (max, chart) { | |
return Math.max(max, chart.series.length); | |
}, 0); | |
}; | |
return Data; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 362 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(363); | |
__webpack_require__(373); | |
__webpack_require__(374); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ZeroInjectionUtilService(Private) { | |
var _ = __webpack_require__(194); | |
var orderXValues = Private(__webpack_require__(363)); | |
var createZeroFilledArray = Private(__webpack_require__(373)); | |
var zeroFillDataArray = Private(__webpack_require__(374)); | |
/* | |
* A Kibana data object may have multiple series with different array lengths. | |
* This proves an impediment to stacking in the visualization library. | |
* Therefore, zero values must be injected wherever these arrays do not line up. | |
* That is, each array must have the same x values with zeros filled in where the | |
* x values were added. | |
* | |
* This function and its helper functions accepts a Kibana data object | |
* and injects zeros where needed. | |
*/ | |
function getDataArray(obj) { | |
if (obj.rows) { | |
return obj.rows; | |
} else if (obj.columns) { | |
return obj.columns; | |
} else if (obj.series) { | |
return [obj]; | |
} | |
} | |
return function (obj) { | |
if (!_.isObject(obj) || !obj.rows && !obj.columns && !obj.series) { | |
throw new TypeError('ZeroInjectionUtilService expects an object with a series, rows, or columns key'); | |
} | |
var keys = orderXValues(obj); | |
var arr = getDataArray(obj); | |
arr.forEach(function (object) { | |
object.series.forEach(function (series) { | |
var zeroArray = createZeroFilledArray(keys); | |
series.values = zeroFillDataArray(zeroArray, series.values); | |
}); | |
}); | |
return obj; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 363 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(325); | |
__webpack_require__(194); | |
__webpack_require__(228); | |
__webpack_require__(364); | |
'use strict'; | |
var _toConsumableArray = __webpack_require__(325)['default']; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function OrderedXKeysUtilService(Private) { | |
var _ = __webpack_require__(194); | |
var moment = __webpack_require__(228); | |
var getUniqKeys = Private(__webpack_require__(364)); | |
/* | |
* Accepts a Kibana data object and returns | |
* an array of x axis values. | |
* values sorted by timestamp if isDate and Date Histogram agg | |
* else values sorted by index | |
*/ | |
return function (obj) { | |
if (!_.isObject(obj)) { | |
throw new Error('OrderedXKeysUtilService expects an object'); | |
} | |
var uniqKeys = getUniqKeys(obj); | |
var uniqKeysPairs = [].concat(_toConsumableArray(uniqKeys.entries())); | |
var interval = _.get(obj, 'ordered.interval'); | |
var dateInterval = moment.isDuration(interval) ? interval : false; | |
return _(uniqKeysPairs).sortBy(function (d) { | |
if (d[1].isDate || d[1].isOrdered) { | |
return +d[0]; | |
} | |
return d[1].index; | |
}).map(function (d, i, list) { | |
if (!d[1].isNumber) return d[0]; | |
var val = +d[0]; | |
if (interval == null) return val; | |
var gapEdge = parseFloat(_.get(list, [i + 1, 0])); | |
if (isNaN(gapEdge)) return val; | |
var vals = []; | |
var next = val; | |
if (dateInterval) { | |
next = moment(val); | |
while (next < gapEdge) { | |
vals.push(next.valueOf()); | |
next.add(dateInterval); | |
} | |
} else { | |
while (next < gapEdge) { | |
vals.push(next); | |
next += interval; | |
} | |
} | |
return vals; | |
}).flatten().value(); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 364 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(365); | |
__webpack_require__(194); | |
__webpack_require__(372); | |
'use strict'; | |
var _Map = __webpack_require__(365)['default']; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function UniqueXValuesUtilService(Private) { | |
var _ = __webpack_require__(194); | |
var flattenDataArray = Private(__webpack_require__(372)); | |
/* | |
* Accepts a Kibana data object. | |
* Returns an object with unique x axis values as keys with an object of | |
* their index numbers and an isNumber boolean as their values. | |
* e.g. { 'xAxisValue': { index: 1, isNumber: false }}, ... | |
*/ | |
return function (obj) { | |
if (!_.isObject(obj)) { | |
throw new TypeError('UniqueXValuesUtilService expects an object'); | |
} | |
var flattenedData = flattenDataArray(obj); | |
var uniqueXValues = new _Map(); | |
var charts; | |
if (!obj.series) { | |
charts = obj.rows ? obj.rows : obj.columns; | |
} else { | |
charts = [obj]; | |
} | |
var isDate = charts.every(function (chart) { | |
return chart.ordered && chart.ordered.date; | |
}); | |
var isOrdered = charts.every(function (chart) { | |
return chart.ordered; | |
}); | |
flattenedData.forEach(function (d, i) { | |
var key = d.x; | |
var prev = uniqueXValues.get(key); | |
if (d.xi != null) { | |
i = d.xi; | |
} | |
if (prev) { | |
i = Math.min(i, prev.index); | |
} | |
uniqueXValues.set(key, { | |
index: i, | |
isDate: isDate, | |
isOrdered: isOrdered, | |
isNumber: _.isNumber(key) | |
}); | |
}); | |
return uniqueXValues; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 365 */ | |
/***/ function(module, exports, __webpack_require__) { | |
module.exports = { "default": __webpack_require__(366), __esModule: true }; | |
/***/ }, | |
/* 366 */ | |
/***/ function(module, exports, __webpack_require__) { | |
__webpack_require__(339); | |
__webpack_require__(298); | |
__webpack_require__(278); | |
__webpack_require__(367); | |
__webpack_require__(370); | |
module.exports = __webpack_require__(238).Map; | |
/***/ }, | |
/* 367 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var strong = __webpack_require__(368); | |
// 23.1 Map Objects | |
__webpack_require__(369)('Map', function(get){ | |
return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); }; | |
}, { | |
// 23.1.3.6 Map.prototype.get(key) | |
get: function get(key){ | |
var entry = strong.getEntry(this, key); | |
return entry && entry.v; | |
}, | |
// 23.1.3.9 Map.prototype.set(key, value) | |
set: function set(key, value){ | |
return strong.def(this, key === 0 ? 0 : key, value); | |
} | |
}, strong, true); | |
/***/ }, | |
/* 368 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var $ = __webpack_require__(205) | |
, hide = __webpack_require__(289) | |
, redefineAll = __webpack_require__(351) | |
, ctx = __webpack_require__(239) | |
, strictNew = __webpack_require__(341) | |
, defined = __webpack_require__(249) | |
, forOf = __webpack_require__(342) | |
, $iterDefine = __webpack_require__(286) | |
, step = __webpack_require__(281) | |
, ID = __webpack_require__(297)('id') | |
, $has = __webpack_require__(292) | |
, isObject = __webpack_require__(234) | |
, setSpecies = __webpack_require__(352) | |
, DESCRIPTORS = __webpack_require__(291) | |
, isExtensible = Object.isExtensible || isObject | |
, SIZE = DESCRIPTORS ? '_s' : 'size' | |
, id = 0; | |
var fastKey = function(it, create){ | |
// return primitive with prefix | |
if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; | |
if(!$has(it, ID)){ | |
// can't set id to frozen object | |
if(!isExtensible(it))return 'F'; | |
// not necessary to add id | |
if(!create)return 'E'; | |
// add missing object id | |
hide(it, ID, ++id); | |
// return object id with prefix | |
} return 'O' + it[ID]; | |
}; | |
var getEntry = function(that, key){ | |
// fast case | |
var index = fastKey(key), entry; | |
if(index !== 'F')return that._i[index]; | |
// frozen object case | |
for(entry = that._f; entry; entry = entry.n){ | |
if(entry.k == key)return entry; | |
} | |
}; | |
module.exports = { | |
getConstructor: function(wrapper, NAME, IS_MAP, ADDER){ | |
var C = wrapper(function(that, iterable){ | |
strictNew(that, C, NAME); | |
that._i = $.create(null); // index | |
that._f = undefined; // first entry | |
that._l = undefined; // last entry | |
that[SIZE] = 0; // size | |
if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that); | |
}); | |
redefineAll(C.prototype, { | |
// 23.1.3.1 Map.prototype.clear() | |
// 23.2.3.2 Set.prototype.clear() | |
clear: function clear(){ | |
for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){ | |
entry.r = true; | |
if(entry.p)entry.p = entry.p.n = undefined; | |
delete data[entry.i]; | |
} | |
that._f = that._l = undefined; | |
that[SIZE] = 0; | |
}, | |
// 23.1.3.3 Map.prototype.delete(key) | |
// 23.2.3.4 Set.prototype.delete(value) | |
'delete': function(key){ | |
var that = this | |
, entry = getEntry(that, key); | |
if(entry){ | |
var next = entry.n | |
, prev = entry.p; | |
delete that._i[entry.i]; | |
entry.r = true; | |
if(prev)prev.n = next; | |
if(next)next.p = prev; | |
if(that._f == entry)that._f = next; | |
if(that._l == entry)that._l = prev; | |
that[SIZE]--; | |
} return !!entry; | |
}, | |
// 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined) | |
// 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined) | |
forEach: function forEach(callbackfn /*, that = undefined */){ | |
var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3) | |
, entry; | |
while(entry = entry ? entry.n : this._f){ | |
f(entry.v, entry.k, this); | |
// revert to the last existing entry | |
while(entry && entry.r)entry = entry.p; | |
} | |
}, | |
// 23.1.3.7 Map.prototype.has(key) | |
// 23.2.3.7 Set.prototype.has(value) | |
has: function has(key){ | |
return !!getEntry(this, key); | |
} | |
}); | |
if(DESCRIPTORS)$.setDesc(C.prototype, 'size', { | |
get: function(){ | |
return defined(this[SIZE]); | |
} | |
}); | |
return C; | |
}, | |
def: function(that, key, value){ | |
var entry = getEntry(that, key) | |
, prev, index; | |
// change existing entry | |
if(entry){ | |
entry.v = value; | |
// create new entry | |
} else { | |
that._l = entry = { | |
i: index = fastKey(key, true), // <- index | |
k: key, // <- key | |
v: value, // <- value | |
p: prev = that._l, // <- previous entry | |
n: undefined, // <- next entry | |
r: false // <- removed | |
}; | |
if(!that._f)that._f = entry; | |
if(prev)prev.n = entry; | |
that[SIZE]++; | |
// add to index | |
if(index !== 'F')that._i[index] = entry; | |
} return that; | |
}, | |
getEntry: getEntry, | |
setStrong: function(C, NAME, IS_MAP){ | |
// add .keys, .values, .entries, [@@iterator] | |
// 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11 | |
$iterDefine(C, NAME, function(iterated, kind){ | |
this._t = iterated; // target | |
this._k = kind; // kind | |
this._l = undefined; // previous | |
}, function(){ | |
var that = this | |
, kind = that._k | |
, entry = that._l; | |
// revert to the last existing entry | |
while(entry && entry.r)entry = entry.p; | |
// get next entry | |
if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){ | |
// or finish the iteration | |
that._t = undefined; | |
return step(1); | |
} | |
// return step by kind | |
if(kind == 'keys' )return step(0, entry.k); | |
if(kind == 'values')return step(0, entry.v); | |
return step(0, [entry.k, entry.v]); | |
}, IS_MAP ? 'entries' : 'values' , !IS_MAP, true); | |
// add [@@species], 23.1.2.2, 23.2.2.2 | |
setSpecies(NAME); | |
} | |
}; | |
/***/ }, | |
/* 369 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var $ = __webpack_require__(205) | |
, global = __webpack_require__(237) | |
, $export = __webpack_require__(236) | |
, fails = __webpack_require__(241) | |
, hide = __webpack_require__(289) | |
, redefineAll = __webpack_require__(351) | |
, forOf = __webpack_require__(342) | |
, strictNew = __webpack_require__(341) | |
, isObject = __webpack_require__(234) | |
, setToStringTag = __webpack_require__(294) | |
, DESCRIPTORS = __webpack_require__(291); | |
module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ | |
var Base = global[NAME] | |
, C = Base | |
, ADDER = IS_MAP ? 'set' : 'add' | |
, proto = C && C.prototype | |
, O = {}; | |
if(!DESCRIPTORS || typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){ | |
new C().entries().next(); | |
}))){ | |
// create collection constructor | |
C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER); | |
redefineAll(C.prototype, methods); | |
} else { | |
C = wrapper(function(target, iterable){ | |
strictNew(target, C, NAME); | |
target._c = new Base; | |
if(iterable != undefined)forOf(iterable, IS_MAP, target[ADDER], target); | |
}); | |
$.each.call('add,clear,delete,forEach,get,has,set,keys,values,entries'.split(','),function(KEY){ | |
var IS_ADDER = KEY == 'add' || KEY == 'set'; | |
if(KEY in proto && !(IS_WEAK && KEY == 'clear'))hide(C.prototype, KEY, function(a, b){ | |
if(!IS_ADDER && IS_WEAK && !isObject(a))return KEY == 'get' ? undefined : false; | |
var result = this._c[KEY](a === 0 ? 0 : a, b); | |
return IS_ADDER ? this : result; | |
}); | |
}); | |
if('size' in proto)$.setDesc(C.prototype, 'size', { | |
get: function(){ | |
return this._c.size; | |
} | |
}); | |
} | |
setToStringTag(C, NAME); | |
O[NAME] = C; | |
$export($export.G + $export.W + $export.F, O); | |
if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP); | |
return C; | |
}; | |
/***/ }, | |
/* 370 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// https://github.com/DavidBruant/Map-Set.prototype.toJSON | |
var $export = __webpack_require__(236); | |
$export($export.P, 'Map', {toJSON: __webpack_require__(371)('Map')}); | |
/***/ }, | |
/* 371 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// https://github.com/DavidBruant/Map-Set.prototype.toJSON | |
var forOf = __webpack_require__(342) | |
, classof = __webpack_require__(304); | |
module.exports = function(NAME){ | |
return function toJSON(){ | |
if(classof(this) != NAME)throw TypeError(NAME + "#toJSON isn't generic"); | |
var arr = []; | |
forOf(this, false, arr.push, arr); | |
return arr; | |
}; | |
}; | |
/***/ }, | |
/* 372 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function FlattenDataObjectUtilService() { | |
var _ = __webpack_require__(194); | |
/* | |
* Accepts a Kibana data object, flattens the data.series values array, | |
* and returns an array of values objects. | |
*/ | |
return function (obj) { | |
var charts; | |
if (!_.isObject(obj) || !obj.rows && !obj.columns && !obj.series) { | |
throw new TypeError('FlattenDataObjUtilService expects an object with a series, rows, or columns key'); | |
} | |
if (!obj.series) { | |
charts = obj.rows ? obj.rows : obj.columns; | |
} | |
return _(charts ? charts : [obj]).pluck('series').flattenDeep().pluck('values').flattenDeep().filter(Boolean).value(); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 373 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function ZeroFilledArrayUtilService() { | |
var _ = __webpack_require__(194); | |
/* | |
* Accepts an array of x axis values (strings or numbers). | |
* Returns a zero filled array. | |
*/ | |
return function (arr) { | |
if (!_.isArray(arr)) { | |
throw new Error('ZeroFilledArrayUtilService expects an array of strings or numbers'); | |
} | |
var zeroFilledArray = []; | |
arr.forEach(function (val) { | |
zeroFilledArray.push({ | |
x: val, | |
xi: Infinity, | |
y: 0 | |
}); | |
}); | |
return zeroFilledArray; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 374 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ZeroFillDataArrayUtilService(Private) { | |
var _ = __webpack_require__(194); | |
/* | |
* Accepts an array of zero-filled y value objects (arr1) | |
* and a kibana data.series[i].values array of objects (arr2). | |
* Return a zero-filled array of objects (arr1). | |
*/ | |
return function (arr1, arr2) { | |
if (!_.isArray(arr1) || !_.isArray(arr2)) { | |
throw new TypeError('ZeroFillDataArrayUtilService expects 2 arrays'); | |
} | |
var i; | |
var val; | |
var index; | |
var max = arr2.length; | |
var getX = function getX(d) { | |
return d.x === val.x; | |
}; | |
for (i = 0; i < max; i++) { | |
val = arr2[i]; | |
index = _.findIndex(arr1, getX); | |
arr1.splice(index, 1, val); | |
} | |
return arr1; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 375 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(376); | |
__webpack_require__(378); | |
__webpack_require__(379); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function LabelUtilService(Private) { | |
var _ = __webpack_require__(194); | |
var createArr = Private(__webpack_require__(376)); | |
var getArrOfUniqLabels = Private(__webpack_require__(378)); | |
var getPieLabels = Private(__webpack_require__(379)); | |
/* | |
* Accepts a Kibana data object and returns an array of unique labels (strings). | |
* Extracts the field formatter from the raw object and passes it to the | |
* getArrOfUniqLabels function. | |
* | |
* Currently, this service is only used for vertical bar charts and line charts. | |
*/ | |
return function (obj, chartType) { | |
if (!_.isObject(obj)) { | |
throw new TypeError('LabelUtil expects an object'); | |
} | |
if (chartType === 'pie') { | |
return getPieLabels(obj); | |
} | |
return getArrOfUniqLabels(createArr(obj)); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 376 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(377); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function GetArrayUtilService(Private) { | |
var _ = __webpack_require__(194); | |
var flattenSeries = Private(__webpack_require__(377)); | |
/* | |
* Accepts a Kibana data object and returns an array of values objects. | |
*/ | |
return function (obj) { | |
if (!_.isObject(obj) || !obj.rows && !obj.columns && !obj.series) { | |
throw new TypeError('GetArrayUtilService expects an object with a series, rows, or columns key'); | |
} | |
if (!obj.series) return flattenSeries(obj); | |
return obj.series; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 377 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function GetSeriesUtilService() { | |
var _ = __webpack_require__(194); | |
/* | |
* Accepts a Kibana data object with a rows or columns key | |
* and returns an array of flattened series values. | |
*/ | |
return function (obj) { | |
if (!_.isObject(obj) || !obj.rows && !obj.columns) { | |
throw new TypeError('GetSeriesUtilService expects an object with either a rows or columns key'); | |
} | |
obj = obj.rows ? obj.rows : obj.columns; | |
return _.chain(obj).pluck('series').flattenDeep().value(); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 378 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function UniqLabelUtilService() { | |
var _ = __webpack_require__(194); | |
/* | |
* Accepts an array of data objects and a formatter function. | |
* Returns a unique list of formatted labels (strings). | |
*/ | |
return function (arr) { | |
if (!_.isArray(arr)) { | |
throw new TypeError('UniqLabelUtil expects an array of objects'); | |
} | |
return _(arr).pluck('label').unique().value(); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 379 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(380); | |
__webpack_require__(381); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
return function PieLabels(Private) { | |
var removeZeroSlices = Private(__webpack_require__(380)); | |
var getNames = Private(__webpack_require__(381)); | |
return function (obj) { | |
if (!_.isObject(obj)) { | |
throw new TypeError('PieLabel expects an object'); | |
} | |
var data = obj.columns || obj.rows || [obj]; | |
var names = []; | |
data.forEach(function (obj) { | |
var columns = obj.raw ? obj.raw.columns : undefined; | |
obj.slices = removeZeroSlices(obj.slices); | |
getNames(obj, columns).forEach(function (name) { | |
names.push(name); | |
}); | |
}); | |
return _.uniq(names); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 380 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
return function RemoveZeroSlices() { | |
return function removeZeroSlices(slices) { | |
if (!slices.children) return slices; | |
slices = _.clone(slices); | |
slices.children = slices.children.reduce(function (children, child) { | |
if (child.size !== 0) { | |
children.push(removeZeroSlices(child)); | |
} | |
return children; | |
}, []); | |
return slices; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 381 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(382); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
return function GetPieNames(Private) { | |
var returnNames = Private(__webpack_require__(382)); | |
return function (data, columns) { | |
var slices = data.slices; | |
if (slices.children) { | |
return _(returnNames(slices.children, 0, columns)).sortBy(function (obj) { | |
return obj.index; | |
}).pluck('key').unique().value(); | |
} | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 382 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;"use strict"; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function ReturnPieNames() { | |
return function returnNames(array, index, columns) { | |
var names = []; | |
array.forEach(function (obj) { | |
names.push({ key: obj.name, index: index }); | |
if (obj.children) { | |
returnNames(obj.children, index + 1, columns).forEach(function (namedObj) { | |
names.push(namedObj); | |
}); | |
} | |
}); | |
return names; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 383 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(384); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ColorUtilService(Private) { | |
var _ = __webpack_require__(194); | |
var mappedColors = Private(__webpack_require__(384)); | |
/* | |
* Accepts an array of strings or numbers that are used to create a | |
* a lookup table that associates the values (key) with a hex color (value). | |
* Returns a function that accepts a value (i.e. a string or number) | |
* and returns a hex color associated with that value. | |
*/ | |
return function (arrayOfStringsOrNumbers) { | |
if (!_.isArray(arrayOfStringsOrNumbers)) { | |
throw new Error('ColorUtil expects an array'); | |
} | |
arrayOfStringsOrNumbers.forEach(function (val) { | |
if (!_.isString(val) && !_.isNumber(val) && !_.isUndefined(val)) { | |
throw new TypeError('ColorUtil expects an array of strings, numbers, or undefined values'); | |
} | |
}); | |
mappedColors.mapKeys(arrayOfStringsOrNumbers); | |
return function (value) { | |
return mappedColors.get(value); | |
}; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 384 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(224); | |
__webpack_require__(227); | |
__webpack_require__(194); | |
__webpack_require__(359); | |
__webpack_require__(385); | |
'use strict'; | |
var _createClass = __webpack_require__(224)['default']; | |
var _classCallCheck = __webpack_require__(227)['default']; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function (Private, config) { | |
var _ = __webpack_require__(194); | |
var d3 = __webpack_require__(359); | |
var createColorPalette = Private(__webpack_require__(385)); | |
var standardizeColor = function standardizeColor(color) { | |
return d3.rgb(color).toString(); | |
}; | |
function getConfigColorMapping() { | |
return _.mapValues(config.get('visualization:colorMapping'), standardizeColor); | |
} | |
/* | |
* Maintains a lookup table that associates the value (key) with a hex color (value) | |
* across the visualizations. | |
* Provides functions to interact with the lookup table | |
*/ | |
var MappedColors = (function () { | |
function MappedColors() { | |
_classCallCheck(this, MappedColors); | |
this.mapping = {}; | |
} | |
_createClass(MappedColors, [{ | |
key: 'get', | |
value: function get(key) { | |
return getConfigColorMapping()[key] || this.mapping[key]; | |
} | |
}, { | |
key: 'mapKeys', | |
value: function mapKeys(keys) { | |
var _this = this; | |
var configMapping = getConfigColorMapping(); | |
var configColors = _.values(configMapping); | |
var keysToMap = []; | |
_.each(keys, function (key) { | |
// If this key is mapped in the config, it's unnecessary to have it mapped here | |
if (configMapping[key]) delete _this.mapping[key]; | |
// If this key is mapped to a color used by the config color mapping, we need to remap it | |
if (_.contains(configColors, _this.mapping[key])) keysToMap.push(key); | |
// If this key isn't mapped, we need to map it | |
if (_this.get(key) == null) keysToMap.push(key); | |
}); | |
// Generate a color palette big enough that all new keys can have unique color values | |
var allColors = _(this.mapping).values().union(configColors).value(); | |
var colorPalette = createColorPalette(allColors.length + keysToMap.length); | |
var newColors = _.difference(colorPalette, allColors); | |
_.merge(this.mapping, _.zipObject(keysToMap, newColors)); | |
} | |
}]); | |
return MappedColors; | |
})(); | |
return new MappedColors(); | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 385 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(386); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ColorPaletteUtilService(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var seedColors = Private(__webpack_require__(386)); | |
/* | |
* Generates an array of hex colors the length of the input number. | |
* If the number is greater than the length of seed colors available, | |
* new colors are generated up to the value of the input number. | |
*/ | |
var offset = 300; // Hue offset to start at | |
var fraction = function fraction(goal) { | |
var walkTree = function walkTree(_x, _x2, _x3) { | |
var _again = true; | |
_function: while (_again) { | |
var numerator = _x, | |
denominator = _x2, | |
bytes = _x3; | |
_again = false; | |
if (bytes.length) { | |
_x = numerator * 2 + (bytes.pop() ? 1 : -1); | |
_x2 = denominator * 2; | |
_x3 = bytes; | |
_again = true; | |
continue _function; | |
} else { | |
return numerator / denominator; | |
} | |
} | |
}; | |
var b = (goal + 2).toString(2).split('').map(function (num) { | |
return parseInt(num, 10); | |
}); | |
b.shift(); | |
return walkTree(1, 2, b); | |
}; | |
return function (num) { | |
if (!_.isNumber(num)) { | |
throw new TypeError('ColorPaletteUtilService expects a number'); | |
} | |
var colors = seedColors; | |
var seedLength = seedColors.length; | |
_.times(num - seedLength, function (i) { | |
colors.push(d3.hsl((fraction(i + seedLength + 1) * 360 + offset) % 360, 0.5, 0.5).toString()); | |
}); | |
return colors; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 386 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
/* | |
* Using a random color generator presented awful colors and unpredictable color schemes. | |
* So we needed to come up with a color scheme of our own that creates consistent, pleasing color patterns. | |
* The order allows us to guarantee that 1st, 2nd, 3rd, etc values always get the same color. | |
* Returns an array of 72 colors. | |
*/ | |
return function SeedColorUtilService() { | |
return ['#57c17b', '#006e8a', '#6f87d8', '#663db8', '#bc52bc', '#9e3533', '#daa05d']; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 387 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(388); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function LayoutFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var layoutType = Private(__webpack_require__(388)); | |
/** | |
* Builds the visualization DOM layout | |
* | |
* The Layout Constructor is responsible for rendering the visualization | |
* layout, which includes all the DOM div elements. | |
* Input: | |
* 1. DOM div - parent element for which the layout is attached | |
* 2. data - data is bound to the div element | |
* 3. chartType (e.g. 'histogram') - specifies the layout type to grab | |
* | |
* @class Layout | |
* @constructor | |
* @param el {HTMLElement} HTML element to which the chart will be appended | |
* @param data {Object} Elasticsearch query results for this specific chart | |
* @param chartType {Object} Reference to chart functions, i.e. Pie | |
*/ | |
function Layout(el, data, chartType, opts) { | |
if (!(this instanceof Layout)) { | |
return new Layout(el, data, chartType, opts); | |
} | |
this.el = el; | |
this.data = data; | |
this.opts = opts; | |
this.layoutType = layoutType[chartType](this.el, this.data); | |
} | |
// Render the layout | |
/** | |
* Renders visualization HTML layout | |
* Remove all elements from the current visualization and creates the layout | |
* | |
* @method render | |
*/ | |
Layout.prototype.render = function () { | |
this.removeAll(this.el); | |
this.createLayout(this.layoutType); | |
}; | |
/** | |
* Create the layout based on the json array provided | |
* for each object in the layout array, call the layout function | |
* | |
* @method createLayout | |
* @param arr {Array} Json array | |
* @returns {*} Creates the visualization layout | |
*/ | |
Layout.prototype.createLayout = function (arr) { | |
var self = this; | |
return _.each(arr, function (obj) { | |
self.layout(obj); | |
}); | |
}; | |
/** | |
* Appends a DOM element based on the object keys | |
* check to see if reference to DOM element is string but not class selector | |
* Create a class selector | |
* | |
* @method layout | |
* @param obj {Object} Instructions for creating the layout of a DOM Element | |
* @returns {*} DOM Element | |
*/ | |
Layout.prototype.layout = function (obj) { | |
if (!obj.parent) { | |
throw new Error('No parent element provided'); | |
} | |
if (!obj.type) { | |
throw new Error('No element type provided'); | |
} | |
if (typeof obj.type !== 'string') { | |
throw new Error(obj.type + ' must be a string'); | |
} | |
if (typeof obj.parent === 'string' && obj.parent.charAt(0) !== '.') { | |
obj.parent = '.' + obj.parent; | |
} | |
var childEl = this.appendElem(obj.parent, obj.type, obj['class']); | |
if (obj.datum) { | |
childEl.datum(obj.datum); | |
} | |
if (obj.splits) { | |
childEl.call(obj.splits, obj.parent, this.opts); | |
} | |
if (obj.children) { | |
var newParent = childEl[0][0]; | |
_.forEach(obj.children, function (obj) { | |
if (!obj.parent) { | |
obj.parent = newParent; | |
} | |
}); | |
this.createLayout(obj.children); | |
} | |
return childEl; | |
}; | |
/** | |
* Appends a `type` of DOM element to `el` and gives it a class name attribute `className` | |
* | |
* @method appendElem | |
* @param el {HTMLElement} Reference to a DOM Element | |
* @param type {String} DOM element type | |
* @param className {String} CSS class name | |
* @returns {*} Reference to D3 Selection | |
*/ | |
Layout.prototype.appendElem = function (el, type, className) { | |
if (!el || !type || !className) { | |
throw new Error('Function requires that an el, type, and class be provided'); | |
} | |
if (typeof el === 'string') { | |
// Create a DOM reference with a d3 selection | |
// Need to make sure that the `el` is bound to this object | |
// to prevent it from being appended to another Layout | |
el = d3.select(this.el).select(el)[0][0]; | |
} | |
return d3.select(el).append(type).attr('class', className); | |
}; | |
/** | |
* Removes all DOM elements from DOM element | |
* | |
* @method removeAll | |
* @param el {HTMLElement} Reference to DOM element | |
* @returns {D3.Selection|D3.Transition.Transition} Reference to an empty DOM element | |
*/ | |
Layout.prototype.removeAll = function (el) { | |
return d3.select(el).selectAll('*').remove(); | |
}; | |
return Layout; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 388 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(389); | |
__webpack_require__(394); | |
__webpack_require__(397); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function LayoutTypeFactory(Private) { | |
/** | |
* Provides the HTML layouts for each visualization class | |
* | |
* @module vislib | |
* @submodule LayoutTypeFactory | |
* @param Private {Service} Loads any function as an angular module | |
* @return {Function} Returns an Object of HTML layouts for each visualization class | |
*/ | |
return { | |
histogram: Private(__webpack_require__(389)), | |
line: Private(__webpack_require__(389)), | |
area: Private(__webpack_require__(389)), | |
pie: Private(__webpack_require__(394)), | |
tile_map: Private(__webpack_require__(397)) | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 389 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(390); | |
__webpack_require__(391); | |
__webpack_require__(392); | |
__webpack_require__(393); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ColumnLayoutFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var chartSplit = Private(__webpack_require__(390)); | |
var yAxisSplit = Private(__webpack_require__(391)); | |
var xAxisSplit = Private(__webpack_require__(392)); | |
var chartTitleSplit = Private(__webpack_require__(393)); | |
/** | |
* Specifies the visualization layout for column charts. | |
* | |
* This is done using an array of objects. The first object has | |
* a `parent` DOM element, a DOM `type` (e.g. div, svg, etc), | |
* and a `class` (required). Each child can omit the parent object, | |
* but must include a type and class. | |
* | |
* Optionally, you can specify `datum` to be bound to the DOM | |
* element, a `splits` function that divides the selected element | |
* into more DOM elements based on a callback function provided, or | |
* a children array which nests other layout objects. | |
* | |
* Objects in children arrays are children of the current object and return | |
* DOM elements which are children of their respective parent element. | |
*/ | |
return function (el, data) { | |
if (!el || !data) { | |
throw new Error('Both an el and data need to be specified'); | |
} | |
return [{ | |
parent: el, | |
type: 'div', | |
'class': 'vis-wrapper', | |
datum: data, | |
children: [{ | |
type: 'div', | |
'class': 'y-axis-col-wrapper', | |
children: [{ | |
type: 'div', | |
'class': 'y-axis-col', | |
children: [{ | |
type: 'div', | |
'class': 'y-axis-title' | |
}, { | |
type: 'div', | |
'class': 'y-axis-chart-title', | |
splits: chartTitleSplit | |
}, { | |
type: 'div', | |
'class': 'y-axis-div-wrapper', | |
splits: yAxisSplit | |
}] | |
}, { | |
type: 'div', | |
'class': 'y-axis-spacer-block' | |
}] | |
}, { | |
type: 'div', | |
'class': 'vis-col-wrapper', | |
children: [{ | |
type: 'div', | |
'class': 'chart-wrapper', | |
splits: chartSplit | |
}, { | |
type: 'div', | |
'class': 'vis-alerts' | |
}, { | |
type: 'div', | |
'class': 'x-axis-wrapper', | |
children: [{ | |
type: 'div', | |
'class': 'x-axis-div-wrapper', | |
splits: xAxisSplit | |
}, { | |
type: 'div', | |
'class': 'x-axis-chart-title', | |
splits: chartTitleSplit | |
}, { | |
type: 'div', | |
'class': 'x-axis-title' | |
}] | |
}] | |
}, { | |
type: 'div', | |
'class': 'legend-col-wrapper' | |
}] | |
}]; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 390 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function ChartSplitFactory() { | |
var d3 = __webpack_require__(359); | |
/* | |
* Adds div DOM elements to the `.chart-wrapper` element based on the data layout. | |
* For example, if the data has rows, it returns the same number of | |
* `.chart` elements as row objects. | |
*/ | |
return function split(selection) { | |
selection.each(function (data) { | |
var div = d3.select(this).attr('class', function () { | |
if (data.rows) { | |
return 'chart-wrapper-row'; | |
} else if (data.columns) { | |
return 'chart-wrapper-column'; | |
} else { | |
return 'chart-wrapper'; | |
} | |
}); | |
var divClass; | |
var charts = div.selectAll('charts').append('div').data(function (d) { | |
if (d.rows) { | |
divClass = 'chart-row'; | |
return d.rows; | |
} else if (d.columns) { | |
divClass = 'chart-column'; | |
return d.columns; | |
} else { | |
divClass = 'chart'; | |
return [d]; | |
} | |
}).enter().append('div').attr('class', function () { | |
return divClass; | |
}); | |
if (!data.series) { | |
charts.call(split); | |
} | |
}); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 391 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function YAxisSplitFactory() { | |
var d3 = __webpack_require__(359); | |
/* | |
* Adds div DOM elements to the `.y-axis-div-wrapper` element based on the data layout. | |
* For example, if the data has rows, it returns the same number of | |
* `.y-axis-div` elements as row objects. | |
*/ | |
// render and get bounding box width | |
return function (selection, parent, opts) { | |
var yAxis = opts && opts.yAxis; | |
selection.each(function () { | |
var div = d3.select(this); | |
div.call(setWidth, yAxis); | |
div.selectAll('.y-axis-div').append('div').data(function (d) { | |
return d.rows ? d.rows : [d]; | |
}).enter().append('div').attr('class', 'y-axis-div'); | |
}); | |
}; | |
function setWidth(el, yAxis) { | |
if (!yAxis) return; | |
var padding = 5; | |
var height = parseInt(el.node().clientHeight, 10); | |
// render svg and get the width of the bounding box | |
var svg = d3.select('body').append('svg').attr('style', 'position:absolute; top:-10000; left:-10000'); | |
var width = svg.append('g').call(yAxis.getYAxis(height)).node().getBBox().width + padding; | |
svg.remove(); | |
el.style('width', width + padding + 'px'); | |
} | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 392 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function XAxisSplitFactory() { | |
var d3 = __webpack_require__(359); | |
/* | |
* Adds div DOM elements to the `.x-axis-div-wrapper` element based on the data layout. | |
* For example, if the data has rows, it returns the same number of | |
* `.x-axis-div` elements as row objects. | |
*/ | |
return function (selection) { | |
selection.each(function () { | |
var div = d3.select(this); | |
div.selectAll('.x-axis-div').append('div').data(function (d) { | |
return d.columns ? d.columns : [d]; | |
}).enter().append('div').attr('class', 'x-axis-div'); | |
}); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 393 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function ChartTitleSplitFactory() { | |
var d3 = __webpack_require__(359); | |
/* | |
* Adds div DOM elements to either the `.y-axis-chart-title` element or the | |
* `.x-axis-chart-title` element based on the data layout. | |
* For example, if the data has rows, it returns the same number of | |
* `.chart-title` elements as row objects. | |
* if not data.rows or data.columns, return no chart titles | |
*/ | |
return function (selection) { | |
selection.each(function (data) { | |
var div = d3.select(this); | |
if (!data.series) { | |
div.selectAll('.chart-title').append('div').data(function (d) { | |
return d.rows ? d.rows : d.columns; | |
}).enter().append('div').attr('class', 'chart-title'); | |
if (data.rows) { | |
d3.select('.x-axis-chart-title').remove(); | |
} else { | |
d3.select('.y-axis-chart-title').remove(); | |
} | |
return div; | |
} | |
return d3.select(this).remove(); | |
}); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 394 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(395); | |
__webpack_require__(396); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ColumnLayoutFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var chartSplit = Private(__webpack_require__(395)); | |
var chartTitleSplit = Private(__webpack_require__(396)); | |
/** | |
* Specifies the visualization layout for column charts. | |
* | |
* This is done using an array of objects. The first object has | |
* a `parent` DOM element, a DOM `type` (e.g. div, svg, etc), | |
* and a `class` (required). Each child can omit the parent object, | |
* but must include a type and class. | |
* | |
* Optionally, you can specify `datum` to be bound to the DOM | |
* element, a `splits` function that divides the selected element | |
* into more DOM elements based on a callback function provided, or | |
* a children array which nests other layout objects. | |
* | |
* Objects in children arrays are children of the current object and return | |
* DOM elements which are children of their respective parent element. | |
*/ | |
return function (el, data) { | |
if (!el || !data) { | |
throw new Error('Both an el and data need to be specified'); | |
} | |
return [{ | |
parent: el, | |
type: 'div', | |
'class': 'vis-wrapper', | |
datum: data, | |
children: [{ | |
type: 'div', | |
'class': 'y-axis-chart-title', | |
splits: chartTitleSplit | |
}, { | |
type: 'div', | |
'class': 'vis-col-wrapper', | |
children: [{ | |
type: 'div', | |
'class': 'chart-wrapper', | |
splits: chartSplit | |
}, { | |
type: 'div', | |
'class': 'x-axis-chart-title', | |
splits: chartTitleSplit | |
}] | |
}, { | |
type: 'div', | |
'class': 'legend-col-wrapper' | |
}] | |
}]; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 395 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function ChartSplitFactory() { | |
var d3 = __webpack_require__(359); | |
/* | |
* Adds div DOM elements to the `.chart-wrapper` element based on the data layout. | |
* For example, if the data has rows, it returns the same number of | |
* `.chart` elements as row objects. | |
*/ | |
return function split(selection) { | |
selection.each(function (data) { | |
var div = d3.select(this).attr('class', function () { | |
if (data.rows) { | |
return 'chart-wrapper-row'; | |
} else if (data.columns) { | |
return 'chart-wrapper-column'; | |
} else { | |
return 'chart-wrapper'; | |
} | |
}); | |
var divClass; | |
var charts = div.selectAll('charts').append('div').data(function (d) { | |
if (d.rows) { | |
divClass = 'chart-row'; | |
return d.rows; | |
} else if (d.columns) { | |
divClass = 'chart-column'; | |
return d.columns; | |
} else { | |
divClass = 'chart'; | |
return [d]; | |
} | |
}).enter().append('div').attr('class', function () { | |
return divClass; | |
}); | |
if (!data.slices) { | |
charts.call(split); | |
} | |
}); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 396 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function ChartTitleSplitFactory() { | |
var d3 = __webpack_require__(359); | |
/* | |
* Adds div DOM elements to either the `.y-axis-chart-title` element or the | |
* `.x-axis-chart-title` element based on the data layout. | |
* For example, if the data has rows, it returns the same number of | |
* `.chart-title` elements as row objects. | |
* if not data.rows or data.columns, return no chart titles | |
*/ | |
return function (selection, parent) { | |
selection.each(function (data) { | |
var div = d3.select(this); | |
if (!data.slices) { | |
div.selectAll('.chart-title').append('div').data(function (d) { | |
return d.rows ? d.rows : d.columns; | |
}).enter().append('div').attr('class', 'chart-title'); | |
if (data.rows) { | |
d3.select(parent).select('.x-axis-chart-title').remove(); | |
} else { | |
d3.select(parent).select('.y-axis-chart-title').remove(); | |
} | |
return div; | |
} | |
return d3.select(this).remove(); | |
}); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 397 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(398); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ColumnLayoutFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var mapSplit = Private(__webpack_require__(398)); | |
/* | |
* Specifies the visualization layout for tile maps. | |
* | |
* This is done using an array of objects. The first object has | |
* a `parent` DOM element, a DOM `type` (e.g. div, svg, etc), | |
* and a `class` (required). Each child can omit the parent object, | |
* but must include a type and class. | |
* | |
* Optionally, you can specify `datum` to be bound to the DOM | |
* element, a `splits` function that divides the selected element | |
* into more DOM elements based on a callback function provided, or | |
* a children array which nests other layout objects. | |
* | |
* Objects in children arrays are children of the current object and return | |
* DOM elements which are children of their respective parent element. | |
*/ | |
return function (el, data) { | |
if (!el || !data) { | |
throw new Error('Both an el and data need to be specified'); | |
} | |
return [{ | |
parent: el, | |
type: 'div', | |
'class': 'vis-wrapper', | |
datum: data, | |
children: [{ | |
type: 'div', | |
'class': 'vis-col-wrapper', | |
children: [{ | |
type: 'div', | |
'class': 'chart-wrapper', | |
splits: mapSplit | |
}] | |
}] | |
}]; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 398 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { | |
return function ChartSplitFactory() { | |
var d3 = __webpack_require__(359); | |
/* | |
* Adds div DOM elements to the `.chart-wrapper` element based on the data layout. | |
* For example, if the data has rows, it returns the same number of | |
* `.chart` elements as row objects. | |
*/ | |
return function split(selection) { | |
selection.each(function (data) { | |
var div = d3.select(this).attr('class', function () { | |
// Determine the parent class | |
if (data.rows) { | |
return 'chart-wrapper-row'; | |
} else if (data.columns) { | |
return 'chart-wrapper-column'; | |
} else { | |
return 'chart-wrapper'; | |
} | |
}); | |
var divClass; | |
var charts = div.selectAll('charts').append('div').data(function (d) { | |
// Determine the child class | |
if (d.rows) { | |
divClass = 'chart-row'; | |
return d.rows; | |
} else if (d.columns) { | |
divClass = 'chart-column'; | |
return d.columns; | |
} else { | |
divClass = 'chart'; | |
return [d]; | |
} | |
}).enter().append('div').attr('class', function () { | |
return divClass; | |
}); | |
if (!data.geoJson) { | |
charts.call(split); | |
} | |
}); | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 399 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(400); | |
__webpack_require__(361); | |
__webpack_require__(403); | |
__webpack_require__(404); | |
__webpack_require__(383); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function LegendFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var Dispatch = Private(__webpack_require__(400)); | |
var Data = Private(__webpack_require__(361)); | |
var legendHeaderTemplate = _.template(__webpack_require__(403)); | |
var dataLabel = __webpack_require__(404); | |
var color = Private(__webpack_require__(383)); | |
/** | |
* Appends legend to the visualization | |
* | |
* @class Legend | |
* @constructor | |
* @param vis {Object} Reference to Vis Constructor | |
*/ | |
function Legend(vis) { | |
if (!(this instanceof Legend)) { | |
return new Legend(vis); | |
} | |
var data = vis.data.columns || vis.data.rows || [vis.data]; | |
var type = vis._attr.type; | |
var labels = this.labels = this._getLabels(data, type); | |
var labelsArray = labels.map(function (obj) { | |
return obj.label; | |
}); | |
this.events = new Dispatch(); | |
this.vis = vis; | |
this.el = vis.el; | |
this.color = color(labelsArray); | |
this._attr = _.defaults({}, vis._attr || {}, { | |
'legendClass': 'legend-col-wrapper', | |
'blurredOpacity': 0.3, | |
'focusOpacity': 1, | |
'defaultOpacity': 1, | |
'legendDefaultOpacity': 1 | |
}); | |
} | |
Legend.prototype._getPieLabels = function (data) { | |
return Data.prototype.pieNames(data); | |
}; | |
Legend.prototype._getSeriesLabels = function (data) { | |
var values = data.map(function (chart) { | |
return chart.series; | |
}).reduce(function (a, b) { | |
return a.concat(b); | |
}, []); | |
return _.uniq(values, 'label'); | |
}; | |
Legend.prototype._getLabels = function (data, type) { | |
if (type === 'pie') return this._getPieLabels(data); | |
return this._getSeriesLabels(data); | |
}; | |
/** | |
* Adds legend header | |
* | |
* @method header | |
* @param el {HTMLElement} Reference to DOM element | |
* @param args {Object|*} Legend options | |
* @returns {*} HTML element | |
*/ | |
Legend.prototype._header = function (el, args) { | |
var self = this; | |
return el.append('div').attr('class', 'header').append('div').attr('class', 'column-labels').html(function () { | |
return legendHeaderTemplate({ isOpen: self.vis.get('legendOpen') }); | |
}); | |
}; | |
/** | |
* Adds list to legend | |
* | |
* @method list | |
* @param el {HTMLElement} Reference to DOM element | |
* @param arrOfLabels {Array} Array of labels | |
* @param args {Object|*} Legend options | |
* @returns {D3.Selection} HTML element with list of labels attached | |
*/ | |
Legend.prototype._list = function (el, data, args) { | |
var self = this; | |
return el.append('ul').attr('class', function () { | |
var className = 'legend-ul'; | |
if (self.vis && !self.vis.get('legendOpen')) className += ' hidden'; | |
return className; | |
}).selectAll('li').data(data).enter().append('li').attr('class', 'color').each(function (d) { | |
var li = d3.select(this); | |
self._addIdentifier.call(this, d); | |
li.append('i').attr('class', 'fa fa-circle dots').attr('style', 'color:' + args.color(d.label)); | |
li.append('span').text(d.label); | |
}); | |
}; | |
/** | |
* Append the data label to the element | |
* | |
* @method _addIdentifier | |
* @param label {string} label to use | |
*/ | |
Legend.prototype._addIdentifier = function (d) { | |
dataLabel(this, d.label); | |
}; | |
/** | |
* Renders legend | |
* | |
* @method render | |
* @return {HTMLElement} Legend | |
*/ | |
Legend.prototype.render = function () { | |
var self = this; | |
var visEl = d3.select(this.el); | |
var legendDiv = visEl.select('.' + this._attr.legendClass); | |
var items = this.labels; | |
this._header(legendDiv, this); | |
this._list(legendDiv, items, this); | |
var headerIcon = visEl.select('.legend-toggle'); | |
// toggle legend open and closed | |
headerIcon.on('click', function legendClick() { | |
var legendOpen = !self.vis.get('legendOpen'); | |
self.vis.set('legendOpen', legendOpen); | |
visEl.select('ul.legend-ul').classed('hidden', legendOpen); | |
self.vis.resize(); | |
}); | |
legendDiv.select('.legend-ul').selectAll('li').on('mouseover', function (d) { | |
var label = d.label; | |
var charts = visEl.selectAll('.chart'); | |
function filterLabel() { | |
var pointLabel = this.getAttribute('data-label'); | |
return pointLabel !== label.toString(); | |
} | |
if (label && label !== 'Count') { | |
d3.select(this).style('cursor', 'pointer'); | |
} | |
// legend | |
legendDiv.selectAll('li').filter(filterLabel).classed('blur_shape', true); | |
// all data-label attribute | |
charts.selectAll('[data-label]').filter(filterLabel).classed('blur_shape', true); | |
var eventEl = d3.select(this); | |
eventEl.style('white-space', 'inherit'); | |
eventEl.style('word-break', 'break-all'); | |
}).on('mouseout', function () { | |
/* | |
* The default opacity of elements in charts may be modified by the | |
* chart constructor, and so may differ from that of the legend | |
*/ | |
var charts = visEl.selectAll('.chart'); | |
// legend | |
legendDiv.selectAll('li').classed('blur_shape', false); | |
// all data-label attribute | |
charts.selectAll('[data-label]').classed('blur_shape', false); | |
var eventEl = d3.select(this); | |
eventEl.style('white-space', 'nowrap'); | |
eventEl.style('word-break', 'inherit'); | |
}); | |
legendDiv.selectAll('li.color').each(function (d) { | |
var label = d.label; | |
if (label !== undefined && label !== 'Count') { | |
d3.select(this).call(self.events.addClickEvent()); | |
} | |
}); | |
}; | |
return Legend; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 400 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(401); | |
__webpack_require__(254); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function DispatchClass(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var Tooltip = Private(__webpack_require__(401)); | |
var SimpleEmitter = __webpack_require__(254); | |
/** | |
* Handles event responses | |
* | |
* @class Dispatch | |
* @constructor | |
* @param handler {Object} Reference to Handler Class Object | |
*/ | |
_['class'](Dispatch).inherits(SimpleEmitter); | |
function Dispatch(handler) { | |
if (!(this instanceof Dispatch)) { | |
return new Dispatch(handler); | |
} | |
Dispatch.Super.call(this); | |
this.handler = handler; | |
this._listeners = {}; | |
} | |
/** | |
* Response to click and hover events | |
* | |
* @param d {Object} Data point | |
* @param i {Number} Index number of data point | |
* @returns {{value: *, point: *, label: *, color: *, pointIndex: *, | |
* series: *, config: *, data: (Object|*), | |
* e: (d3.event|*), handler: (Object|*)}} Event response object | |
*/ | |
Dispatch.prototype.eventResponse = function (d, i) { | |
var datum = d._input || d; | |
var data = d3.event.target.nearestViewportElement ? d3.event.target.nearestViewportElement.__data__ : d3.event.target.__data__; | |
var label = d.label ? d.label : d.name; | |
var isSeries = !!(data && data.series); | |
var isSlices = !!(data && data.slices); | |
var series = isSeries ? data.series : undefined; | |
var slices = isSlices ? data.slices : undefined; | |
var handler = this.handler; | |
var color = _.get(handler, 'data.color'); | |
var isPercentage = handler && handler._attr.mode === 'percentage'; | |
var eventData = { | |
value: d.y, | |
point: datum, | |
datum: datum, | |
label: label, | |
color: color ? color(label) : undefined, | |
pointIndex: i, | |
series: series, | |
slices: slices, | |
config: handler && handler._attr, | |
data: data, | |
e: d3.event, | |
handler: handler | |
}; | |
if (isSeries) { | |
// Find object with the actual d value and add it to the point object | |
var object = _.find(series, { 'label': d.label }); | |
eventData.value = +object.values[i].y; | |
if (isPercentage) { | |
// Add the formatted percentage to the point object | |
eventData.percent = (100 * d.y).toFixed(1) + '%'; | |
} | |
} | |
return eventData; | |
}; | |
/** | |
* Returns a function that adds events and listeners to a D3 selection | |
* | |
* @method addEvent | |
* @param event {String} | |
* @param callback {Function} | |
* @returns {Function} | |
*/ | |
Dispatch.prototype.addEvent = function (event, callback) { | |
return function (selection) { | |
selection.each(function () { | |
var element = d3.select(this); | |
if (typeof callback === 'function') { | |
return element.on(event, callback); | |
} | |
}); | |
}; | |
}; | |
/** | |
* | |
* @method addHoverEvent | |
* @returns {Function} | |
*/ | |
Dispatch.prototype.addHoverEvent = function () { | |
var self = this; | |
var isClickable = this.listenerCount('click') > 0; | |
var addEvent = this.addEvent; | |
var $el = this.handler.el; | |
function hover(d, i) { | |
// Add pointer if item is clickable | |
if (isClickable) { | |
self.addMousePointer.call(this, arguments); | |
} | |
self.highlightLegend.call(this, $el); | |
self.emit('hover', self.eventResponse(d, i)); | |
} | |
return addEvent('mouseover', hover); | |
}; | |
/** | |
* | |
* @method addMouseoutEvent | |
* @returns {Function} | |
*/ | |
Dispatch.prototype.addMouseoutEvent = function () { | |
var self = this; | |
var addEvent = this.addEvent; | |
var $el = this.handler.el; | |
function mouseout() { | |
self.unHighlightLegend.call(this, $el); | |
} | |
return addEvent('mouseout', mouseout); | |
}; | |
/** | |
* | |
* @method addClickEvent | |
* @returns {Function} | |
*/ | |
Dispatch.prototype.addClickEvent = function () { | |
var self = this; | |
var addEvent = this.addEvent; | |
function click(d, i) { | |
self.emit('click', self.eventResponse(d, i)); | |
} | |
return addEvent('click', click); | |
}; | |
/** | |
* Determine if we will allow brushing | |
* | |
* @method allowBrushing | |
* @returns {Boolean} | |
*/ | |
Dispatch.prototype.allowBrushing = function () { | |
var xAxis = this.handler.xAxis; | |
// Don't allow brushing for time based charts from non-time-based indices | |
var hasTimeField = this.handler.vis._attr.hasTimeField; | |
return Boolean(hasTimeField && xAxis.ordered && xAxis.xScale && _.isFunction(xAxis.xScale.invert)); | |
}; | |
/** | |
* Determine if brushing is currently enabled | |
* | |
* @method isBrushable | |
* @returns {Boolean} | |
*/ | |
Dispatch.prototype.isBrushable = function () { | |
return this.allowBrushing() && this.listenerCount('brush') > 0; | |
}; | |
/** | |
* | |
* @param svg | |
* @returns {Function} | |
*/ | |
Dispatch.prototype.addBrushEvent = function (svg) { | |
if (!this.isBrushable()) return; | |
var xScale = this.handler.xAxis.xScale; | |
var yScale = this.handler.xAxis.yScale; | |
var brush = this.createBrush(xScale, svg); | |
function brushEnd() { | |
if (!validBrushClick(d3.event)) return; | |
var bar = d3.select(this); | |
var startX = d3.mouse(svg.node()); | |
var startXInv = xScale.invert(startX[0]); | |
// Reset the brush value | |
brush.extent([startXInv, startXInv]); | |
// Magic! | |
// Need to call brush on svg to see brush when brushing | |
// while on top of bars. | |
// Need to call brush on bar to allow the click event to be registered | |
svg.call(brush); | |
bar.call(brush); | |
} | |
return this.addEvent('mousedown', brushEnd); | |
}; | |
/** | |
* Mouseover Behavior | |
* | |
* @method addMousePointer | |
* @returns {D3.Selection} | |
*/ | |
Dispatch.prototype.addMousePointer = function () { | |
return d3.select(this).style('cursor', 'pointer'); | |
}; | |
/** | |
* Mouseover Behavior | |
* | |
* @param element {D3.Selection} | |
* @method highlightLegend | |
*/ | |
Dispatch.prototype.highlightLegend = function (element) { | |
var label = this.getAttribute('data-label'); | |
if (!label) return; | |
d3.select(element).select('.legend-ul').selectAll('li.color').filter(function (d, i) { | |
return String(d.label) !== label; | |
}).classed('blur_shape', true); | |
}; | |
/** | |
* Mouseout Behavior | |
* | |
* @param element {D3.Selection} | |
* @method unHighlightLegend | |
*/ | |
Dispatch.prototype.unHighlightLegend = function (element) { | |
d3.select(element).select('.legend-ul').selectAll('li.color').classed('blur_shape', false); | |
}; | |
/** | |
* Adds D3 brush to SVG and returns the brush function | |
* | |
* @param xScale {Function} D3 xScale function | |
* @param svg {HTMLElement} Reference to SVG | |
* @returns {*} Returns a D3 brush function and a SVG with a brush group attached | |
*/ | |
Dispatch.prototype.createBrush = function (xScale, svg) { | |
var self = this; | |
var attr = self.handler._attr; | |
var height = attr.height; | |
var margin = attr.margin; | |
// Brush scale | |
var brush = d3.svg.brush().x(xScale).on('brushend', function brushEnd() { | |
// Assumes data is selected at the chart level | |
// In this case, the number of data objects should always be 1 | |
var data = d3.select(this).data()[0]; | |
var isTimeSeries = data.ordered && data.ordered.date; | |
// Allows for brushing on d3.scale.ordinal() | |
var selected = xScale.domain().filter(function (d) { | |
return brush.extent()[0] <= xScale(d) && xScale(d) <= brush.extent()[1]; | |
}); | |
var range = isTimeSeries ? brush.extent() : selected; | |
return self.emit('brush', { | |
range: range, | |
config: attr, | |
e: d3.event, | |
data: data | |
}); | |
}); | |
// if `addBrushing` is true, add brush canvas | |
if (self.listenerCount('brush')) { | |
svg.insert('g', 'g').attr('class', 'brush').call(brush).call(function (brushG) { | |
// hijack the brush start event to filter out right/middle clicks | |
var brushHandler = brushG.on('mousedown.brush'); | |
if (!brushHandler) return; // touch events in use | |
brushG.on('mousedown.brush', function () { | |
if (validBrushClick(d3.event)) brushHandler.apply(this, arguments); | |
}); | |
}).selectAll('rect').attr('height', height - margin.top - margin.bottom); | |
return brush; | |
} | |
}; | |
function validBrushClick(event) { | |
return event.button === 0; | |
} | |
return Dispatch; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 401 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var Binder = __webpack_require__(360); | |
var positionTooltip = __webpack_require__(402); | |
var allContents = []; | |
/** | |
* Add tooltip and listeners to visualization elements | |
* | |
* @class Tooltip | |
* @constructor | |
* @param el {HTMLElement} Reference to DOM element | |
* @param formatter {Function} Tooltip formatter | |
* @param events {Constructor} Allows tooltip to return event response data | |
*/ | |
function Tooltip(id, el, formatter, events) { | |
if (!(this instanceof Tooltip)) { | |
return new Tooltip(id, el, formatter, events); | |
} | |
this.id = id; // unique id for this tooltip type | |
this.el = el; | |
this.order = 100; // higher ordered contents are rendered below the others | |
this.formatter = formatter; | |
this.events = events; | |
this.containerClass = 'vis-wrapper'; | |
this.tooltipClass = 'vis-tooltip'; | |
this.tooltipSizerClass = 'vis-tooltip-sizing-clone'; | |
this.showCondition = _.constant(true); | |
this.binder = new Binder(); | |
} | |
/** | |
* Get jquery reference to the tooltip node | |
* | |
* @return {Object} jQuery node object | |
*/ | |
Tooltip.prototype.$get = _.once(function () { | |
return $('<div>').addClass(this.tooltipClass).appendTo(document.body); | |
}); | |
/** | |
* Get jquery reference to the tooltip sizer node | |
* | |
* @return {Object} jQuery node object | |
*/ | |
Tooltip.prototype.$getSizer = _.once(function () { | |
return this.$get().clone().removeClass(this.tooltipClass).addClass(this.tooltipSizerClass).appendTo(document.body); | |
}); | |
/** | |
* Show the tooltip, positioning it based on the content and chart container | |
*/ | |
Tooltip.prototype.show = function () { | |
var $tooltip = this.$get(); | |
var $chart = this.$getChart(); | |
var html = $tooltip.html(); | |
if (!$chart) return; | |
var placement = positionTooltip({ | |
$window: $(window), | |
$chart: $chart, | |
$el: $tooltip, | |
$sizer: this.$getSizer(), | |
event: d3.event | |
}, html); | |
$tooltip.css({ | |
visibility: 'visible', | |
left: placement.left, | |
top: placement.top | |
}); | |
}; | |
/** | |
* Hide the tooltip, clearing its contents | |
*/ | |
Tooltip.prototype.hide = function () { | |
var $tooltip = this.$get(); | |
allContents = []; | |
$tooltip.css({ | |
visibility: 'hidden', | |
left: '-500px', | |
top: '-500px' | |
}); | |
}; | |
/** | |
* Get the jQuery chart node, based on the container object | |
* NOTE: the container is a d3 selection | |
* | |
* @return {Object} jQuery node for the chart | |
*/ | |
Tooltip.prototype.$getChart = function () { | |
var chart = $(this.container && this.container.node()); | |
return chart.size() ? chart : false; | |
}; | |
/** | |
* Renders tooltip | |
* | |
* @method render | |
* @return {Function} Renders tooltip on a D3 selection | |
*/ | |
Tooltip.prototype.render = function () { | |
var self = this; | |
/** | |
* Calculates values for the tooltip placement | |
* | |
* @param {Object} selection D3 selection object | |
*/ | |
return function (selection) { | |
var $tooltip = self.$get(); | |
var id = self.id; | |
var order = self.order; | |
var tooltipSelection = d3.select($tooltip.get(0)); | |
if (self.container === undefined || self.container !== d3.select(self.el).select('.' + self.containerClass)) { | |
self.container = d3.select(self.el).select('.' + self.containerClass); | |
} | |
var $chart = self.$getChart(); | |
if ($chart) { | |
self.binder.jqOn($chart, 'mouseleave', function (event) { | |
// only clear when we leave the chart, so that | |
// moving between points doesn't make it reposition | |
$chart.removeData('previousPlacement'); | |
}); | |
} | |
selection.each(function (d, i) { | |
var element = d3.select(this); | |
function render(html) { | |
allContents = _.filter(allContents, function (content) { | |
return content.id !== id; | |
}); | |
if (html) allContents.push({ id: id, html: html, order: order }); | |
var allHtml = _(allContents).sortBy('order').pluck('html').compact().join('\n'); | |
if (allHtml) { | |
$tooltip.html(allHtml); | |
self.show(); | |
} else { | |
self.hide(); | |
} | |
} | |
self.binder.fakeD3Bind(this, 'mousemove', function () { | |
if (!self.showCondition.call(element, d, i)) { | |
return render(); | |
} | |
var events = self.events ? self.events.eventResponse(d, i) : d; | |
return render(self.formatter(events)); | |
}); | |
self.binder.fakeD3Bind(this, 'mouseleave', function () { | |
render(); | |
}); | |
}); | |
}; | |
}; | |
Tooltip.prototype.destroy = function () { | |
this.binder.destroy(); | |
}; | |
module.exports = function TooltipFactoryProvider() { | |
return Tooltip; | |
}; | |
/***/ }, | |
/* 402 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var OFFSET = 10; | |
var $clone; | |
// translate css properties into their basic direction | |
var propDirs = { | |
top: 'north', | |
left: 'west' | |
}; | |
function positionTooltip(opts, html) { | |
if (!opts) return; | |
var $chart = $(opts.$chart); | |
var $el = $(opts.$el); | |
var $window = $(opts.$window || window); | |
var $sizer = $(opts.$sizer); | |
var prev = $chart.data('previousPlacement') || {}; | |
var event = opts.event; | |
if (!$chart.size() || !$el.size()) return; | |
var size = getTtSize(html || $el.html(), $sizer); | |
var pos = getBasePosition(size, event); | |
var overflow = getOverflow(size, pos, [$chart, $window]); | |
var placement = placeToAvoidOverflow(pos, prev, overflow); | |
$chart.data('previousPlacement', placement); | |
return placement; | |
} | |
function getTtSize(ttHtml, $sizer) { | |
if ($sizer.html() !== ttHtml) { | |
$sizer.html(ttHtml); | |
} | |
var size = { | |
width: $sizer.outerWidth(), | |
height: $sizer.outerHeight() | |
}; | |
return size; | |
} | |
function getBasePosition(size, event) { | |
return { | |
east: event.clientX + OFFSET, | |
west: event.clientX - size.width - OFFSET, | |
south: event.clientY + OFFSET, | |
north: event.clientY - size.height - OFFSET | |
}; | |
} | |
function getBounds($el) { | |
// in testing, $window is not actually a window, so we need to add | |
// the offsets to make it work right. | |
var bounds = $el.offset() || { top: 0, left: 0 }; | |
bounds.top += $el.scrollTop(); | |
bounds.left += $el.scrollLeft(); | |
bounds.bottom = bounds.top + $el.outerHeight(); | |
bounds.right = bounds.left + $el.outerWidth(); | |
return bounds; | |
} | |
function getOverflow(size, pos, containers) { | |
var overflow = {}; | |
containers.map(getBounds).forEach(function (bounds) { | |
// number of pixels that the toolip would overflow it's far | |
// side, if we placed it that way. (negative === no overflow) | |
mergeOverflows(overflow, { | |
north: bounds.top - pos.north, | |
east: pos.east + size.width - bounds.right, | |
south: pos.south + size.height - bounds.bottom, | |
west: bounds.left - pos.west | |
}); | |
}); | |
(window.overflows || (window.overflows = [])).push(overflow); | |
return overflow; | |
} | |
function mergeOverflows(dest, src) { | |
return _.merge(dest, src, function (a, b) { | |
if (a == null || b == null) return a || b; | |
if (a < 0 && b < 0) return Math.min(a, b); | |
return Math.max(a, b); | |
}); | |
} | |
function pickPlacement(prop, pos, overflow, prev, pref, fallback, placement) { | |
var stash = '_' + prop; | |
// list of directions in order of preference | |
var dirs = _.unique([prev[stash], pref, fallback].filter(Boolean)); | |
var dir; | |
var value; | |
// find the first direction that doesn't overflow | |
for (var i = 0; i < dirs.length; i++) { | |
dir = dirs[i]; | |
if (overflow[dir] > 0) continue; | |
value = pos[dir]; | |
break; | |
} | |
// if we don't find one that doesn't overflow, use | |
// the first choice and offset based on overflo | |
if (value == null) { | |
dir = dirs[0]; | |
var offset = overflow[dir]; | |
if (propDirs[prop] === dir) { | |
// when the property represents the same direction | |
// as dir, we flip the overflow | |
offset = offset * -1; | |
} | |
value = pos[dir] - offset; | |
} | |
placement[prop] = value; | |
placement[stash] = dir; | |
} | |
function placeToAvoidOverflow(pos, prev, overflow) { | |
var placement = {}; | |
pickPlacement('top', pos, overflow, prev, 'south', 'north', placement); | |
pickPlacement('left', pos, overflow, prev, 'east', 'west', placement); | |
return placement; | |
} | |
// expose units/helpers for testing | |
positionTooltip.getTtSize = getTtSize; | |
positionTooltip.getBasePosition = getBasePosition; | |
positionTooltip.getOverflow = getOverflow; | |
positionTooltip.getBounds = getBounds; | |
positionTooltip.placeToAvoidOverflow = placeToAvoidOverflow; | |
positionTooltip.removeClone = function () { | |
$clone && $clone.remove(); | |
$clone = null; | |
}; | |
module.exports = positionTooltip; | |
/***/ }, | |
/* 403 */ | |
/***/ function(module, exports) { | |
module.exports = "<div class=\"legend-toggle\">\n <strong>\n <%= (isOpen) ?\n '<span class=\"legend-open\">Legend <i class=\"fa fa-arrow-circle-right\"></i></span>' :\n '<span class=\"legend-closed\"><i class=\"fa fa-arrow-circle-left\"></i></span>'\n %>\n </strong>\n</div>" | |
/***/ }, | |
/* 404 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var d3 = __webpack_require__(359); | |
/** | |
* Creates a string based on the hex color passed in | |
* | |
* @method dataLabel | |
* @param d {Object} object to wrap in d3.select | |
* @returns {string} label value | |
*/ | |
function dataLabel(selection, label) { | |
d3.select(selection).attr('data-label', label); | |
} | |
return dataLabel; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 405 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(208); | |
__webpack_require__(194); | |
__webpack_require__(406); | |
__webpack_require__(401); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ChartTitleFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var $ = __webpack_require__(208); | |
var _ = __webpack_require__(194); | |
var ErrorHandler = Private(__webpack_require__(406)); | |
var Tooltip = Private(__webpack_require__(401)); | |
/** | |
* Appends chart titles to the visualization | |
* | |
* @class ChartTitle | |
* @constructor | |
* @param el {HTMLElement} Reference to DOM element | |
*/ | |
_['class'](ChartTitle).inherits(ErrorHandler); | |
function ChartTitle(el) { | |
if (!(this instanceof ChartTitle)) { | |
return new ChartTitle(el); | |
} | |
this.el = el; | |
this.tooltip = new Tooltip('chart-title', el, function (d) { | |
return '<p>' + _.escape(d.label) + '</p>'; | |
}); | |
} | |
/** | |
* Renders chart titles | |
* | |
* @method render | |
* @returns {D3.Selection|D3.Transition.Transition} DOM element with chart titles | |
*/ | |
ChartTitle.prototype.render = function () { | |
var el = d3.select(this.el).select('.chart-title').node(); | |
var width = el ? el.clientWidth : 0; | |
var height = el ? el.clientHeight : 0; | |
return d3.select(this.el).selectAll('.chart-title').call(this.draw(width, height)); | |
}; | |
/** | |
* Truncates chart title text | |
* | |
* @method truncate | |
* @param size {Number} Height or width of the HTML Element | |
* @returns {Function} Truncates text | |
*/ | |
ChartTitle.prototype.truncate = function (size) { | |
var self = this; | |
return function (selection) { | |
selection.each(function () { | |
var text = d3.select(this); | |
var n = text[0].length; | |
var maxWidth = size / n * 0.9; | |
var length = this.getComputedTextLength(); | |
var str; | |
var avg; | |
var end; | |
if (length > maxWidth) { | |
str = text.text(); | |
avg = length / str.length; | |
end = Math.floor(maxWidth / avg) - 5; | |
str = str.substr(0, end) + '...'; | |
self.addMouseEvents(text); | |
return text.text(str); | |
} | |
return text.text(); | |
}); | |
}; | |
}; | |
/** | |
* Adds tooltip events on truncated chart titles | |
* | |
* @method addMouseEvents | |
* @param target {HTMLElement} DOM element to attach event listeners | |
* @returns {*} DOM element with event listeners attached | |
*/ | |
ChartTitle.prototype.addMouseEvents = function (target) { | |
if (this.tooltip) { | |
return target.call(this.tooltip.render()); | |
} | |
}; | |
/** | |
* Appends chart titles to the visualization | |
* | |
* @method draw | |
* @returns {Function} Appends chart titles to a D3 selection | |
*/ | |
ChartTitle.prototype.draw = function (width, height) { | |
var self = this; | |
return function (selection) { | |
selection.each(function () { | |
var div = d3.select(this); | |
var dataType = this.parentNode.__data__.rows ? 'rows' : 'columns'; | |
var size = dataType === 'rows' ? height : width; | |
var txtHtOffset = 11; | |
self.validateWidthandHeight(width, height); | |
div.append('svg').attr('width', width).attr('height', height).append('text').attr('transform', function () { | |
if (dataType === 'rows') { | |
return 'translate(' + txtHtOffset + ',' + height / 2 + ')rotate(270)'; | |
} | |
return 'translate(' + width / 2 + ',' + txtHtOffset + ')'; | |
}).attr('text-anchor', 'middle').text(function (d) { | |
return d.label; | |
}); | |
// truncate long chart titles | |
div.selectAll('text').call(self.truncate(size)); | |
}); | |
}; | |
}; | |
return ChartTitle; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 406 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(222); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var errors = __webpack_require__(222); | |
return function ErrorHandlerFactory() { | |
/** | |
* Common errors shared between constructors | |
* | |
* @class ErrorHandler | |
* @constructor | |
*/ | |
function ErrorHandler() {} | |
/** | |
* Validates the height and width are > 0 | |
* min size must be at least 1 px | |
* | |
* @method validateWidthandHeight | |
* @param width {Number} HTMLElement width | |
* @param height {Number} HTMLElement height | |
* @returns {HTMLElement} HTML div with an error message | |
*/ | |
ErrorHandler.prototype.validateWidthandHeight = function (width, height) { | |
var badWidth = _.isNaN(width) || width <= 0; | |
var badHeight = _.isNaN(height) || height <= 0; | |
if (badWidth || badHeight) { | |
throw new errors.ContainerTooSmall(); | |
} | |
}; | |
return ErrorHandler; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 407 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(362); | |
__webpack_require__(358); | |
__webpack_require__(361); | |
__webpack_require__(399); | |
__webpack_require__(408); | |
__webpack_require__(409); | |
__webpack_require__(410); | |
__webpack_require__(405); | |
__webpack_require__(411); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ColumnHandler(Private) { | |
var injectZeros = Private(__webpack_require__(362)); | |
var Handler = Private(__webpack_require__(358)); | |
var Data = Private(__webpack_require__(361)); | |
var Legend = Private(__webpack_require__(399)); | |
var XAxis = Private(__webpack_require__(408)); | |
var YAxis = Private(__webpack_require__(409)); | |
var AxisTitle = Private(__webpack_require__(410)); | |
var ChartTitle = Private(__webpack_require__(405)); | |
var Alerts = Private(__webpack_require__(411)); | |
/* | |
* Create handlers for Area, Column, and Line charts which | |
* are all nearly the same minus a few details | |
*/ | |
function create(opts) { | |
opts = opts || {}; | |
return function (vis) { | |
var isUserDefinedYAxis = vis._attr.setYExtents; | |
var data; | |
if (opts.zeroFill) { | |
data = new Data(injectZeros(vis.data), vis._attr); | |
} else { | |
data = new Data(vis.data, vis._attr); | |
} | |
return new Handler(vis, { | |
data: data, | |
legend: new Legend(vis, vis.data), | |
axisTitle: new AxisTitle(vis.el, data.get('xAxisLabel'), data.get('yAxisLabel')), | |
chartTitle: new ChartTitle(vis.el), | |
xAxis: new XAxis({ | |
el: vis.el, | |
xValues: data.xValues(), | |
ordered: data.get('ordered'), | |
xAxisFormatter: data.get('xAxisFormatter'), | |
expandLastBucket: opts.expandLastBucket, | |
_attr: vis._attr | |
}), | |
alerts: new Alerts(vis, data, opts.alerts), | |
yAxis: new YAxis({ | |
el: vis.el, | |
yMin: isUserDefinedYAxis ? vis._attr.yAxis.min : data.getYMin(), | |
yMax: isUserDefinedYAxis ? vis._attr.yAxis.max : data.getYMax(), | |
yAxisFormatter: data.get('yAxisFormatter'), | |
_attr: vis._attr | |
}) | |
}); | |
}; | |
} | |
return { | |
line: create(), | |
column: create({ | |
zeroFill: true, | |
expandLastBucket: true | |
}), | |
area: create({ | |
zeroFill: true, | |
alerts: [{ | |
type: 'warning', | |
msg: 'Positive and negative values are not accurately represented by stacked ' + 'area charts. Either changing the chart mode to "overlap" or using a ' + 'bar chart is recommended.', | |
test: function test(vis, data) { | |
if (!data.shouldBeStacked() || data.maxNumberOfSeries() < 2) return; | |
var hasPos = data.getYMax(data._getY) > 0; | |
var hasNeg = data.getYMin(data._getY) < 0; | |
return hasPos && hasNeg; | |
} | |
}, { | |
type: 'warning', | |
msg: 'Parts of or the entire area chart might not be displayed due to null ' + 'values in the data. A line chart is recommended when displaying data ' + 'with null values.', | |
test: function test(vis, data) { | |
return data.hasNullValues(); | |
} | |
}] | |
}) | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 408 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(208); | |
__webpack_require__(194); | |
__webpack_require__(228); | |
__webpack_require__(406); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function XAxisFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var $ = __webpack_require__(208); | |
var _ = __webpack_require__(194); | |
var moment = __webpack_require__(228); | |
var ErrorHandler = Private(__webpack_require__(406)); | |
/** | |
* Adds an x axis to the visualization | |
* | |
* @class XAxis | |
* @constructor | |
* @param args {{el: (HTMLElement), xValues: (Array), ordered: (Object|*), | |
* xAxisFormatter: (Function), _attr: (Object|*)}} | |
*/ | |
_['class'](XAxis).inherits(ErrorHandler); | |
function XAxis(args) { | |
if (!(this instanceof XAxis)) { | |
return new XAxis(args); | |
} | |
this.el = args.el; | |
this.xValues = args.xValues; | |
this.ordered = args.ordered; | |
this.xAxisFormatter = args.xAxisFormatter; | |
this.expandLastBucket = args.expandLastBucket == null ? true : args.expandLastBucket; | |
this._attr = _.defaults(args._attr || {}); | |
} | |
/** | |
* Renders the x axis | |
* | |
* @method render | |
* @returns {D3.UpdateSelection} Appends x axis to visualization | |
*/ | |
XAxis.prototype.render = function () { | |
d3.select(this.el).selectAll('.x-axis-div').call(this.draw()); | |
}; | |
/** | |
* Returns d3 x axis scale function. | |
* If time, return time scale, else return d3 ordinal scale for nominal data | |
* | |
* @method getScale | |
* @returns {*} D3 scale function | |
*/ | |
XAxis.prototype.getScale = function () { | |
var ordered = this.ordered; | |
if (ordered && ordered.date) { | |
return d3.time.scale.utc(); | |
} | |
return d3.scale.ordinal(); | |
}; | |
/** | |
* Add domain to the x axis scale. | |
* if time, return a time domain, and calculate the min date, max date, and time interval | |
* else, return a nominal (d3.scale.ordinal) domain, i.e. array of x axis values | |
* | |
* @method getDomain | |
* @param scale {Function} D3 scale | |
* @returns {*} D3 scale function | |
*/ | |
XAxis.prototype.getDomain = function (scale) { | |
var ordered = this.ordered; | |
if (ordered && ordered.date) { | |
return this.getTimeDomain(scale, this.xValues); | |
} | |
return this.getOrdinalDomain(scale, this.xValues); | |
}; | |
/** | |
* Returns D3 time domain | |
* | |
* @method getTimeDomain | |
* @param scale {Function} D3 scale function | |
* @param data {Array} | |
* @returns {*} D3 scale function | |
*/ | |
XAxis.prototype.getTimeDomain = function (scale, data) { | |
return scale.domain([this.minExtent(data), this.maxExtent(data)]); | |
}; | |
XAxis.prototype.minExtent = function (data) { | |
return this._calculateExtent(data || this.xValues, 'min'); | |
}; | |
XAxis.prototype.maxExtent = function (data) { | |
return this._calculateExtent(data || this.xValues, 'max'); | |
}; | |
/** | |
* | |
* @param data | |
* @param extent | |
*/ | |
XAxis.prototype._calculateExtent = function (data, extent) { | |
var ordered = this.ordered; | |
var opts = [ordered[extent]]; | |
var point = d3[extent](data); | |
if (this.expandLastBucket && extent === 'max') { | |
point = this.addInterval(point); | |
} | |
opts.push(point); | |
return d3[extent](opts.reduce(function (opts, v) { | |
if (!_.isNumber(v)) v = +v; | |
if (!isNaN(v)) opts.push(v); | |
return opts; | |
}, [])); | |
}; | |
/** | |
* Add the interval to a point on the x axis, | |
* this properly adds dates if needed. | |
* | |
* @param {number} x - a value on the x-axis | |
* @returns {number} - x + the ordered interval | |
*/ | |
XAxis.prototype.addInterval = function (x) { | |
return this.modByInterval(x, +1); | |
}; | |
/** | |
* Subtract the interval to a point on the x axis, | |
* this properly subtracts dates if needed. | |
* | |
* @param {number} x - a value on the x-axis | |
* @returns {number} - x - the ordered interval | |
*/ | |
XAxis.prototype.subtractInterval = function (x) { | |
return this.modByInterval(x, -1); | |
}; | |
/** | |
* Modify the x value by n intervals, properly | |
* handling dates if needed. | |
* | |
* @param {number} x - a value on the x-axis | |
* @param {number} n - the number of intervals | |
* @returns {number} - x + n intervals | |
*/ | |
XAxis.prototype.modByInterval = function (x, n) { | |
var ordered = this.ordered; | |
if (!ordered) return x; | |
var interval = ordered.interval; | |
if (!interval) return x; | |
if (!ordered.date) { | |
return x += ordered.interval * n; | |
} | |
var y = moment(x); | |
var method = n > 0 ? 'add' : 'subtract'; | |
_.times(Math.abs(n), function () { | |
y[method](interval); | |
}); | |
return y.valueOf(); | |
}; | |
/** | |
* Return a nominal(d3 ordinal) domain | |
* | |
* @method getOrdinalDomain | |
* @param scale {Function} D3 scale function | |
* @param xValues {Array} Array of x axis values | |
* @returns {*} D3 scale function | |
*/ | |
XAxis.prototype.getOrdinalDomain = function (scale, xValues) { | |
return scale.domain(xValues); | |
}; | |
/** | |
* Return the range for the x axis scale | |
* if time, return a normal range, else if nominal, return rangeBands with a default (0.1) spacer specified | |
* | |
* @method getRange | |
* @param scale {Function} D3 scale function | |
* @param width {Number} HTML Element width | |
* @returns {*} D3 scale function | |
*/ | |
XAxis.prototype.getRange = function (domain, width) { | |
var ordered = this.ordered; | |
if (ordered && ordered.date) { | |
return domain.range([0, width]); | |
} | |
return domain.rangeBands([0, width], 0.1); | |
}; | |
/** | |
* Return the x axis scale | |
* | |
* @method getXScale | |
* @param width {Number} HTML Element width | |
* @returns {*} D3 x scale function | |
*/ | |
XAxis.prototype.getXScale = function (width) { | |
var domain = this.getDomain(this.getScale()); | |
return this.getRange(domain, width); | |
}; | |
/** | |
* Creates d3 xAxis function | |
* | |
* @method getXAxis | |
* @param width {Number} HTML Element width | |
*/ | |
XAxis.prototype.getXAxis = function (width) { | |
this.xScale = this.getXScale(width); | |
if (!this.xScale || _.isNaN(this.xScale)) { | |
throw new Error('xScale is ' + this.xScale); | |
} | |
this.xAxis = d3.svg.axis().scale(this.xScale).ticks(10).tickFormat(this.xAxisFormatter).orient('bottom'); | |
}; | |
/** | |
* Renders the x axis | |
* | |
* @method draw | |
* @returns {Function} Renders the x axis to a D3 selection | |
*/ | |
XAxis.prototype.draw = function () { | |
var self = this; | |
var div; | |
var width; | |
var height; | |
var svg; | |
var parentWidth; | |
var n; | |
this._attr.isRotated = false; | |
return function (selection) { | |
n = selection[0].length; | |
parentWidth = $(self.el).find('.x-axis-div-wrapper').width(); | |
selection.each(function () { | |
div = d3.select(this); | |
width = parentWidth / n; | |
height = $(this.parentElement).height(); | |
self.validateWidthandHeight(width, height); | |
self.getXAxis(width); | |
svg = div.append('svg').attr('width', width).attr('height', height); | |
svg.append('g').attr('class', 'x axis').attr('transform', 'translate(0,0)').call(self.xAxis); | |
}); | |
selection.call(self.filterOrRotate()); | |
}; | |
}; | |
/** | |
* Returns a function that evaluates scale type and | |
* applies filter to tick labels on time scales | |
* rotates and truncates tick labels on nominal/ordinal scales | |
* | |
* @method filterOrRotate | |
* @returns {Function} Filters or rotates x axis tick labels | |
*/ | |
XAxis.prototype.filterOrRotate = function () { | |
var self = this; | |
var ordered = self.ordered; | |
var axis; | |
var labels; | |
return function (selection) { | |
selection.each(function () { | |
axis = d3.select(this); | |
labels = axis.selectAll('.tick text'); | |
if (ordered && ordered.date) { | |
axis.call(self.filterAxisLabels()); | |
} else { | |
axis.call(self.rotateAxisLabels()); | |
} | |
}); | |
self.updateXaxisHeight(); | |
selection.call(self.fitTitles()); | |
}; | |
}; | |
/** | |
* Rotate the axis tick labels within selection | |
* | |
* @returns {Function} Rotates x axis tick labels of a D3 selection | |
*/ | |
XAxis.prototype.rotateAxisLabels = function () { | |
var self = this; | |
var text; | |
var barWidth = self.xScale.rangeBand(); | |
var maxRotatedLength = 180; | |
var xAxisPadding = 15; | |
var svg; | |
var lengths = []; | |
var length; | |
self._attr.isRotated = false; | |
return function (selection) { | |
text = selection.selectAll('.tick text'); | |
text.each(function textWidths() { | |
lengths.push(d3.select(this).node().getBBox().width); | |
}); | |
length = _.max(lengths); | |
self._attr.xAxisLabelHt = length + xAxisPadding; | |
// if longer than bar width, rotate | |
if (length > barWidth) { | |
self._attr.isRotated = true; | |
} | |
// if longer than maxRotatedLength, truncate | |
if (length > maxRotatedLength) { | |
self._attr.xAxisLabelHt = maxRotatedLength; | |
} | |
if (self._attr.isRotated) { | |
text.text(function truncate() { | |
return self.truncateLabel(this, self._attr.xAxisLabelHt); | |
}).style('text-anchor', 'end').attr('dx', '-.8em').attr('dy', '-.60em').attr('transform', function rotate() { | |
return 'rotate(-90)'; | |
}); | |
selection.select('svg').attr('height', self._attr.xAxisLabelHt); | |
} | |
}; | |
}; | |
/** | |
* Returns a string that is truncated to fit size | |
* | |
* @method truncateLabel | |
* @param text {HTMLElement} | |
* @param size {Number} | |
* @returns {*|jQuery} | |
*/ | |
XAxis.prototype.truncateLabel = function (text, size) { | |
var node = d3.select(text).node(); | |
var str = $(node).text(); | |
var width = node.getBBox().width; | |
var chars = str.length; | |
var pxPerChar = width / chars; | |
var endChar = 0; | |
var ellipsesPad = 4; | |
if (width > size) { | |
endChar = Math.floor(size / pxPerChar - ellipsesPad); | |
while (str[endChar - 1] === ' ' || str[endChar - 1] === '-' || str[endChar - 1] === ',') { | |
endChar = endChar - 1; | |
} | |
str = str.substr(0, endChar) + '...'; | |
} | |
return str; | |
}; | |
/** | |
* Filter out text labels by width and position on axis | |
* trims labels that would overlap each other | |
* or extend past left or right edges | |
* if prev label pos (or 0) + half of label width is < label pos | |
* and label pos + half width is not > width of axis | |
* | |
* @method filterAxisLabels | |
* @returns {Function} | |
*/ | |
XAxis.prototype.filterAxisLabels = function () { | |
var self = this; | |
var startX = 0; | |
var maxW; | |
var par; | |
var myX; | |
var myWidth; | |
var halfWidth; | |
var padding = 1.1; | |
return function (selection) { | |
selection.selectAll('.tick text').text(function (d) { | |
par = d3.select(this.parentNode).node(); | |
myX = self.xScale(d); | |
myWidth = par.getBBox().width * padding; | |
halfWidth = myWidth / 2; | |
maxW = $(self.el).find('.x-axis-div').width(); | |
if (startX + halfWidth < myX && maxW > myX + halfWidth) { | |
startX = myX + halfWidth; | |
return self.xAxisFormatter(d); | |
} else { | |
d3.select(this.parentNode).remove(); | |
} | |
}); | |
}; | |
}; | |
/** | |
* Returns a function that adjusts axis titles and | |
* chart title transforms to fit axis label divs. | |
* Sets transform of x-axis-title to fit .x-axis-title div width | |
* if x-axis-chart-titles, set transform of x-axis-chart-titles | |
* to fit .chart-title div width | |
* | |
* @method fitTitles | |
* @returns {Function} | |
*/ | |
XAxis.prototype.fitTitles = function () { | |
var visEls = $('.vis-wrapper'); | |
var xAxisChartTitle; | |
var yAxisChartTitle; | |
var text; | |
var titles; | |
return function () { | |
visEls.each(function () { | |
var visEl = d3.select(this); | |
var $visEl = $(this); | |
var xAxisTitle = $visEl.find('.x-axis-title'); | |
var yAxisTitle = $visEl.find('.y-axis-title'); | |
var titleWidth = xAxisTitle.width(); | |
var titleHeight = yAxisTitle.height(); | |
text = visEl.select('.x-axis-title').select('svg').attr('width', titleWidth).select('text').attr('transform', 'translate(' + titleWidth / 2 + ',11)'); | |
text = visEl.select('.y-axis-title').select('svg').attr('height', titleHeight).select('text').attr('transform', 'translate(11,' + titleHeight / 2 + ')rotate(-90)'); | |
if ($visEl.find('.x-axis-chart-title').length) { | |
xAxisChartTitle = $visEl.find('.x-axis-chart-title'); | |
titleWidth = xAxisChartTitle.find('.chart-title').width(); | |
titles = visEl.select('.x-axis-chart-title').selectAll('.chart-title'); | |
titles.each(function () { | |
text = d3.select(this).select('svg').attr('width', titleWidth).select('text').attr('transform', 'translate(' + titleWidth / 2 + ',11)'); | |
}); | |
} | |
if ($visEl.find('.y-axis-chart-title').length) { | |
yAxisChartTitle = $visEl.find('.y-axis-chart-title'); | |
titleHeight = yAxisChartTitle.find('.chart-title').height(); | |
titles = visEl.select('.y-axis-chart-title').selectAll('.chart-title'); | |
titles.each(function () { | |
text = d3.select(this).select('svg').attr('height', titleHeight).select('text').attr('transform', 'translate(11,' + titleHeight / 2 + ')rotate(-90)'); | |
}); | |
} | |
}); | |
}; | |
}; | |
/** | |
* Appends div to make .y-axis-spacer-block | |
* match height of .x-axis-wrapper | |
* | |
* @method updateXaxisHeight | |
*/ | |
XAxis.prototype.updateXaxisHeight = function () { | |
var selection = d3.select(this.el).selectAll('.vis-wrapper'); | |
selection.each(function () { | |
var visEl = d3.select(this); | |
if (visEl.select('.inner-spacer-block').node() === null) { | |
visEl.select('.y-axis-spacer-block').append('div').attr('class', 'inner-spacer-block'); | |
} | |
var xAxisHt = visEl.select('.x-axis-wrapper').style('height'); | |
visEl.select('.inner-spacer-block').style('height', xAxisHt); | |
}); | |
}; | |
return XAxis; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 409 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(222); | |
__webpack_require__(406); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function YAxisFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var errors = __webpack_require__(222); | |
var ErrorHandler = Private(__webpack_require__(406)); | |
/** | |
* Appends y axis to the visualization | |
* | |
* @class YAxis | |
* @constructor | |
* @param args {{el: (HTMLElement), yMax: (Number), _attr: (Object|*)}} | |
*/ | |
_['class'](YAxis).inherits(ErrorHandler); | |
function YAxis(args) { | |
this.el = args.el; | |
this.scale = null; | |
this.domain = [args.yMin, args.yMax]; | |
this.yAxisFormatter = args.yAxisFormatter; | |
this._attr = args._attr || {}; | |
} | |
/** | |
* Renders the y axis | |
* | |
* @method render | |
* @return {D3.UpdateSelection} Renders y axis to visualization | |
*/ | |
YAxis.prototype.render = function () { | |
d3.select(this.el).selectAll('.y-axis-div').call(this.draw()); | |
}; | |
YAxis.prototype._isPercentage = function () { | |
return this._attr.mode === 'percentage'; | |
}; | |
YAxis.prototype._isUserDefined = function () { | |
return this._attr.setYExtents; | |
}; | |
YAxis.prototype._isYExtents = function () { | |
return this._attr.defaultYExtents; | |
}; | |
YAxis.prototype._validateUserExtents = function (domain) { | |
var self = this; | |
return domain.map(function (val) { | |
val = parseInt(val, 10); | |
if (isNaN(val)) throw new Error(val + ' is not a valid number'); | |
if (self._isPercentage() && self._attr.setYExtents) return val / 100; | |
return val; | |
}); | |
}; | |
YAxis.prototype._getExtents = function (domain) { | |
var min = domain[0]; | |
var max = domain[1]; | |
if (this._isUserDefined()) return this._validateUserExtents(domain); | |
if (this._isYExtents()) return domain; | |
if (this._attr.scale === 'log') return this._logDomain(min, max); // Negative values cannot be displayed with a log scale. | |
if (!this._isYExtents() && !this._isUserDefined()) return [Math.min(0, min), Math.max(0, max)]; | |
return domain; | |
}; | |
YAxis.prototype._throwCustomError = function (message) { | |
throw new Error(message); | |
}; | |
YAxis.prototype._throwLogScaleValuesError = function () { | |
throw new errors.InvalidLogScaleValues(); | |
}; | |
/** | |
* Returns the appropriate D3 scale | |
* | |
* @param fnName {String} D3 scale | |
* @returns {*} | |
*/ | |
YAxis.prototype._getScaleType = function (fnName) { | |
if (fnName === 'square root') fnName = 'sqrt'; // Rename 'square root' to 'sqrt' | |
fnName = fnName || 'linear'; | |
if (typeof d3.scale[fnName] !== 'function') return this._throwCustomError('YAxis.getScaleType: ' + fnName + ' is not a function'); | |
return d3.scale[fnName](); | |
}; | |
/** | |
* Return the domain for log scale, i.e. the extent of the log scale. | |
* Log scales must begin at 1 since the log(0) = -Infinity | |
* | |
* @param scale | |
* @param yMin | |
* @param yMax | |
* @returns {*[]} | |
*/ | |
YAxis.prototype._logDomain = function (min, max) { | |
if (min < 0 || max < 0) return this._throwLogScaleValuesError(); | |
return [1, max]; | |
}; | |
/** | |
* Creates the d3 y scale function | |
* | |
* @method getYScale | |
* @param height {Number} DOM Element height | |
* @returns {D3.Scale.QuantitiveScale|*} D3 yScale function | |
*/ | |
YAxis.prototype.getYScale = function (height) { | |
var scale = this._getScaleType(this._attr.scale); | |
var domain = this._getExtents(this.domain); | |
this.yScale = scale.domain(domain).range([height, 0]); | |
if (!this._isUserDefined()) this.yScale.nice(); // round extents when not user defined | |
// Prevents bars from going off the chart when the y extents are within the domain range | |
if (this._attr.type === 'histogram') this.yScale.clamp(true); | |
return this.yScale; | |
}; | |
YAxis.prototype.getScaleType = function () { | |
return this._attr.scale; | |
}; | |
YAxis.prototype.tickFormat = function () { | |
var isPercentage = this._attr.mode === 'percentage'; | |
if (isPercentage) return d3.format('%'); | |
if (this.yAxisFormatter) return this.yAxisFormatter; | |
return d3.format('n'); | |
}; | |
YAxis.prototype._validateYScale = function (yScale) { | |
if (!yScale || _.isNaN(yScale)) throw new Error('yScale is ' + yScale); | |
}; | |
/** | |
* Creates the d3 y axis function | |
* | |
* @method getYAxis | |
* @param height {Number} DOM Element height | |
* @returns {D3.Svg.Axis|*} D3 yAxis function | |
*/ | |
YAxis.prototype.getYAxis = function (height) { | |
var yScale = this.getYScale(height); | |
this._validateYScale(yScale); | |
// Create the d3 yAxis function | |
this.yAxis = d3.svg.axis().scale(yScale).tickFormat(this.tickFormat(this.domain)).ticks(this.tickScale(height)).orient('left'); | |
return this.yAxis; | |
}; | |
/** | |
* Create a tick scale for the y axis that modifies the number of ticks | |
* based on the height of the wrapping DOM element | |
* Avoid using even numbers in the yTickScale.range | |
* Causes the top most tickValue in the chart to be missing | |
* | |
* @method tickScale | |
* @param height {Number} DOM element height | |
* @returns {number} Number of y axis ticks | |
*/ | |
YAxis.prototype.tickScale = function (height) { | |
var yTickScale = d3.scale.linear().clamp(true).domain([20, 40, 1000]).range([0, 3, 11]); | |
return Math.ceil(yTickScale(height)); | |
}; | |
/** | |
* Renders the y axis to the visualization | |
* | |
* @method draw | |
* @returns {Function} Renders y axis to visualization | |
*/ | |
YAxis.prototype.draw = function () { | |
var self = this; | |
var margin = this._attr.margin; | |
var mode = this._attr.mode; | |
var isWiggleOrSilhouette = mode === 'wiggle' || mode === 'silhouette'; | |
return function (selection) { | |
selection.each(function () { | |
var el = this; | |
var div = d3.select(el); | |
var width = $(el).parent().width(); | |
var height = $(el).height(); | |
var adjustedHeight = height - margin.top - margin.bottom; | |
// Validate whether width and height are not 0 or `NaN` | |
self.validateWidthandHeight(width, adjustedHeight); | |
var yAxis = self.getYAxis(adjustedHeight); | |
// The yAxis should not appear if mode is set to 'wiggle' or 'silhouette' | |
if (!isWiggleOrSilhouette) { | |
// Append svg and y axis | |
var svg = div.append('svg').attr('width', width).attr('height', height); | |
svg.append('g').attr('class', 'y axis').attr('transform', 'translate(' + (width - 2) + ',' + margin.top + ')').call(yAxis); | |
var container = svg.select('g.y.axis').node(); | |
if (container) { | |
var cWidth = Math.max(width, container.getBBox().width); | |
svg.attr('width', cWidth); | |
svg.select('g').attr('transform', 'translate(' + (cWidth - 2) + ',' + margin.top + ')'); | |
} | |
} | |
}); | |
}; | |
}; | |
return YAxis; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 410 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(208); | |
__webpack_require__(194); | |
__webpack_require__(406); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function AxisTitleFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var $ = __webpack_require__(208); | |
var _ = __webpack_require__(194); | |
var ErrorHandler = Private(__webpack_require__(406)); | |
/** | |
* Appends axis title(s) to the visualization | |
* | |
* @class AxisTitle | |
* @constructor | |
* @param el {HTMLElement} DOM element | |
* @param xTitle {String} X-axis title | |
* @param yTitle {String} Y-axis title | |
*/ | |
_['class'](AxisTitle).inherits(ErrorHandler); | |
function AxisTitle(el, xTitle, yTitle) { | |
if (!(this instanceof AxisTitle)) { | |
return new AxisTitle(el, xTitle, yTitle); | |
} | |
this.el = el; | |
this.xTitle = xTitle; | |
this.yTitle = yTitle; | |
} | |
/** | |
* Renders both x and y axis titles | |
* | |
* @method render | |
* @returns {HTMLElement} DOM Element with axis titles | |
*/ | |
AxisTitle.prototype.render = function () { | |
d3.select(this.el).select('.x-axis-title').call(this.draw(this.xTitle)); | |
d3.select(this.el).select('.y-axis-title').call(this.draw(this.yTitle)); | |
}; | |
/** | |
* Appends an SVG with title text | |
* | |
* @method draw | |
* @param title {String} Axis title | |
* @returns {Function} Appends axis title to a D3 selection | |
*/ | |
AxisTitle.prototype.draw = function (title) { | |
var self = this; | |
return function (selection) { | |
selection.each(function () { | |
var el = this; | |
var div = d3.select(el); | |
var width = $(el).width(); | |
var height = $(el).height(); | |
self.validateWidthandHeight(width, height); | |
div.append('svg').attr('width', width).attr('height', height).append('text').attr('transform', function () { | |
if (div.attr('class') === 'x-axis-title') { | |
return 'translate(' + width / 2 + ',11)'; | |
} | |
return 'translate(11,' + height / 2 + ')rotate(270)'; | |
}).attr('text-anchor', 'middle').text(title); | |
}); | |
}; | |
}; | |
return AxisTitle; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 411 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(208); | |
__webpack_require__(194); | |
__webpack_require__(360); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function AlertsFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var $ = __webpack_require__(208); | |
var _ = __webpack_require__(194); | |
var Binder = __webpack_require__(360); | |
/** | |
* Adds allerts that float in front of a visualization | |
* | |
* @class Alerts | |
* @constructor | |
* @param el {HTMLElement} Reference to DOM element | |
*/ | |
function Alerts(vis, data, alertDefs) { | |
if (!(this instanceof Alerts)) { | |
return new Alerts(vis, data, alertDefs); | |
} | |
this.vis = vis; | |
this.data = data; | |
this.binder = new Binder(); | |
this.alertDefs = alertDefs || []; | |
this.binder.jqOn(vis.el, 'mouseenter', '.vis-alerts-tray', function () { | |
var $tray = $(this); | |
hide(); | |
$(vis.el).on('mousemove', checkForExit); | |
function hide() { | |
$tray.css({ | |
'pointer-events': 'none', | |
opacity: 0.3 | |
}); | |
} | |
function show() { | |
$(vis.el).off('mousemove', checkForExit); | |
$tray.css({ | |
'pointer-events': 'auto', | |
opacity: 1 | |
}); | |
} | |
function checkForExit(event) { | |
var pos = $tray.offset(); | |
if (pos.top > event.clientY || pos.left > event.clientX) return show(); | |
var bottom = pos.top + $tray.height(); | |
if (event.clientY > bottom) return show(); | |
var right = pos.left + $tray.width(); | |
if (event.clientX > right) return show(); | |
} | |
}); | |
} | |
/** | |
* Renders chart titles | |
* | |
* @method render | |
* @returns {D3.Selection|D3.Transition.Transition} DOM element with chart titles | |
*/ | |
Alerts.prototype.render = function () { | |
var vis = this.vis; | |
var data = this.data; | |
var alerts = _(this.alertDefs).map(function (alertDef) { | |
if (!alertDef) return; | |
if (alertDef.test && !alertDef.test(vis, data)) return; | |
var type = alertDef.type || 'info'; | |
var icon = alertDef.icon || type; | |
var msg = alertDef.msg; | |
// alert container | |
var $icon = $('<i>').addClass('vis-alerts-icon fa fa-' + icon); | |
var $text = $('<p>').addClass('vis-alerts-text').text(msg); | |
return $('<div>').addClass('vis-alert vis-alert-' + type).append([$icon, $text]); | |
}).compact(); | |
if (!alerts.size()) return; | |
$(vis.el).find('.vis-alerts').append($('<div>').addClass('vis-alerts-tray').append(alerts.value())); | |
}; | |
/** | |
* Tear down the Alerts | |
* @return {undefined} | |
*/ | |
Alerts.prototype.destroy = function () { | |
this.binder.destroy(); | |
}; | |
return Alerts; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 412 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(358); | |
__webpack_require__(361); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function MapHandlerProvider(Private) { | |
var _ = __webpack_require__(194); | |
var Handler = Private(__webpack_require__(358)); | |
var Data = Private(__webpack_require__(361)); | |
return function (vis) { | |
var data = new Data(vis.data, vis._attr); | |
var MapHandler = new Handler(vis, { | |
data: data | |
}); | |
MapHandler.resize = function () { | |
this.charts.forEach(function (chart) { | |
chart.resizeArea(); | |
}); | |
}; | |
return MapHandler; | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 413 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(407); | |
__webpack_require__(357); | |
__webpack_require__(412); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function HandlerTypeFactory(Private) { | |
var pointSeries = Private(__webpack_require__(407)); | |
/** | |
* Handles the building of each visualization | |
* | |
* @return {Function} Returns an Object of Handler types | |
*/ | |
return { | |
histogram: pointSeries.column, | |
line: pointSeries.line, | |
pie: Private(__webpack_require__(357)), | |
area: pointSeries.area, | |
tile_map: Private(__webpack_require__(412)) | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 414 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(415); | |
__webpack_require__(422); | |
__webpack_require__(424); | |
__webpack_require__(425); | |
__webpack_require__(426); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function MapFactory(Private) { | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var L = __webpack_require__(415); | |
var defaultMapZoom = 2; | |
var defaultMapCenter = [15, 5]; | |
var defaultMarkerType = 'Scaled Circle Markers'; | |
var mapTiles = { | |
url: 'https://otile{s}-s.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpeg', | |
options: { | |
attribution: 'Tiles by <a href="http://www.mapquest.com/">MapQuest</a> — ' + 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>', | |
subdomains: '1234' | |
} | |
}; | |
var markerTypes = { | |
'Scaled Circle Markers': Private(__webpack_require__(422)), | |
'Shaded Circle Markers': Private(__webpack_require__(424)), | |
'Shaded Geohash Grid': Private(__webpack_require__(425)), | |
'Heatmap': Private(__webpack_require__(426)) | |
}; | |
/** | |
* Tile Map Maps | |
* | |
* @class Map | |
* @constructor | |
* @param container {HTML Element} Element to render map into | |
* @param chartData {Object} Elasticsearch query results for this map | |
* @param params {Object} Parameters used to build a map | |
*/ | |
function TileMapMap(container, chartData, params) { | |
this._container = $(container).get(0); | |
this._chartData = chartData; | |
// keep a reference to all of the optional params | |
this._events = _.get(params, 'events'); | |
this._markerType = markerTypes[params.markerType] ? params.markerType : defaultMarkerType; | |
this._valueFormatter = params.valueFormatter || _.identity; | |
this._tooltipFormatter = params.tooltipFormatter || _.identity; | |
this._geoJson = _.get(this._chartData, 'geoJson'); | |
this._attr = params.attr || {}; | |
var mapOptions = { | |
minZoom: 1, | |
maxZoom: 18, | |
noWrap: true, | |
maxBounds: L.latLngBounds([-90, -220], [90, 220]), | |
scrollWheelZoom: false, | |
fadeAnimation: false | |
}; | |
this._createMap(mapOptions); | |
} | |
TileMapMap.prototype.addBoundingControl = function () { | |
if (this._boundingControl) return; | |
var self = this; | |
var drawOptions = { draw: {} }; | |
_.each(['polyline', 'polygon', 'circle', 'marker', 'rectangle'], function (drawShape) { | |
if (self._events && !self._events.listenerCount(drawShape)) { | |
drawOptions.draw[drawShape] = false; | |
} else { | |
drawOptions.draw[drawShape] = { | |
shapeOptions: { | |
stroke: false, | |
color: '#000' | |
} | |
}; | |
} | |
}); | |
this._boundingControl = new L.Control.Draw(drawOptions); | |
this.map.addControl(this._boundingControl); | |
}; | |
TileMapMap.prototype.addFitControl = function () { | |
if (this._fitControl) return; | |
var self = this; | |
var fitContainer = L.DomUtil.create('div', 'leaflet-control leaflet-bar leaflet-control-fit'); | |
// Add button to fit container to points | |
var FitControl = L.Control.extend({ | |
options: { | |
position: 'topleft' | |
}, | |
onAdd: function onAdd(map) { | |
$(fitContainer).html('<a class="fa fa-crop" href="#" title="Fit Data Bounds"></a>').on('click', function (e) { | |
e.preventDefault(); | |
self._fitBounds(); | |
}); | |
return fitContainer; | |
}, | |
onRemove: function onRemove(map) { | |
$(fitContainer).off('click'); | |
} | |
}); | |
this._fitControl = new FitControl(); | |
this.map.addControl(this._fitControl); | |
}; | |
/** | |
* Adds label div to each map when data is split | |
* | |
* @method addTitle | |
* @param mapLabel {String} | |
* @return {undefined} | |
*/ | |
TileMapMap.prototype.addTitle = function (mapLabel) { | |
if (this._label) return; | |
var label = this._label = L.control(); | |
label.onAdd = function () { | |
this._div = L.DomUtil.create('div', 'tilemap-info tilemap-label'); | |
this.update(); | |
return this._div; | |
}; | |
label.update = function () { | |
this._div.innerHTML = '<h2>' + _.escape(mapLabel) + '</h2>'; | |
}; | |
// label.addTo(this.map); | |
this.map.addControl(label); | |
}; | |
/** | |
* remove css class for desat filters on map tiles | |
* | |
* @method saturateTiles | |
* @return undefined | |
*/ | |
TileMapMap.prototype.saturateTiles = function () { | |
if (!this._attr.isDesaturated) { | |
$('img.leaflet-tile-loaded').addClass('filters-off'); | |
} | |
}; | |
TileMapMap.prototype.updateSize = function () { | |
this.map.invalidateSize({ | |
debounceMoveend: true | |
}); | |
}; | |
TileMapMap.prototype.destroy = function () { | |
if (this._label) this._label.removeFrom(this.map); | |
if (this._fitControl) this._fitControl.removeFrom(this.map); | |
if (this._boundingControl) this._boundingControl.removeFrom(this.map); | |
if (this._markers) this._markers.destroy(); | |
this.map.remove(); | |
this.map = undefined; | |
}; | |
/** | |
* Switch type of data overlay for map: | |
* creates featurelayer from mapData (geoJson) | |
* | |
* @method _addMarkers | |
*/ | |
TileMapMap.prototype._addMarkers = function () { | |
if (!this._geoJson) return; | |
if (this._markers) this._markers.destroy(); | |
this._markers = this._createMarkers({ | |
tooltipFormatter: this._tooltipFormatter, | |
valueFormatter: this._valueFormatter, | |
attr: this._attr | |
}); | |
if (this._geoJson.features.length > 1) { | |
this._markers.addLegend(); | |
} | |
}; | |
/** | |
* Create the marker instance using the given options | |
* | |
* @method _createMarkers | |
* @param options {Object} options to give to marker class | |
* @return {Object} marker layer | |
*/ | |
TileMapMap.prototype._createMarkers = function (options) { | |
var MarkerType = markerTypes[this._markerType]; | |
return new MarkerType(this.map, this._geoJson, options); | |
}; | |
TileMapMap.prototype._attachEvents = function () { | |
var self = this; | |
var saturateTiles = self.saturateTiles.bind(self); | |
this._tileLayer.on('tileload', saturateTiles); | |
this.map.on('unload', function () { | |
self._tileLayer.off('tileload', saturateTiles); | |
}); | |
this.map.on('moveend', function setZoomCenter(ev) { | |
if (!self.map) return; | |
// update internal center and zoom references | |
self._mapCenter = self.map.getCenter(); | |
self._mapZoom = self.map.getZoom(); | |
self._addMarkers(); | |
if (!self._events) return; | |
self._events.emit('mapMoveEnd', { | |
chart: self._chartData, | |
map: self.map, | |
center: self._mapCenter, | |
zoom: self._mapZoom | |
}); | |
}); | |
this.map.on('draw:created', function (e) { | |
var drawType = e.layerType; | |
if (!self._events || !self._events.listenerCount(drawType)) return; | |
// TODO: Different drawTypes need differ info. Need a switch on the object creation | |
var bounds = e.layer.getBounds(); | |
self._events.emit(drawType, { | |
e: e, | |
chart: self._chartData, | |
bounds: { | |
top_left: { | |
lat: bounds.getNorthWest().lat, | |
lon: bounds.getNorthWest().lng | |
}, | |
bottom_right: { | |
lat: bounds.getSouthEast().lat, | |
lon: bounds.getSouthEast().lng | |
} | |
} | |
}); | |
}); | |
this.map.on('zoomend', function () { | |
if (!self.map) return; | |
self._mapZoom = self.map.getZoom(); | |
if (!self._events) return; | |
self._events.emit('mapZoomEnd', { | |
chart: self._chartData, | |
map: self.map, | |
zoom: self._mapZoom | |
}); | |
}); | |
}; | |
TileMapMap.prototype._createMap = function (mapOptions) { | |
if (this.map) this.destroy(); | |
// get center and zoom from mapdata, or use defaults | |
this._mapCenter = _.get(this._geoJson, 'properties.center') || defaultMapCenter; | |
this._mapZoom = _.get(this._geoJson, 'properties.zoom') || defaultMapZoom; | |
// add map tiles layer, using the mapTiles object settings | |
if (this._attr.wms && this._attr.wms.enabled) { | |
this._tileLayer = L.tileLayer.wms(this._attr.wms.url, this._attr.wms.options); | |
} else { | |
this._tileLayer = L.tileLayer(mapTiles.url, mapTiles.options); | |
} | |
// append tile layers, center and zoom to the map options | |
mapOptions.layers = this._tileLayer; | |
mapOptions.center = this._mapCenter; | |
mapOptions.zoom = this._mapZoom; | |
this.map = L.map(this._container, mapOptions); | |
this._attachEvents(); | |
this._addMarkers(); | |
}; | |
/** | |
* zoom map to fit all features in featureLayer | |
* | |
* @method _fitBounds | |
* @param map {Leaflet Object} | |
* @return {boolean} | |
*/ | |
TileMapMap.prototype._fitBounds = function () { | |
this.map.fitBounds(this._getDataRectangles()); | |
}; | |
/** | |
* Get the Rectangles representing the geohash grid | |
* | |
* @return {LatLngRectangles[]} | |
*/ | |
TileMapMap.prototype._getDataRectangles = function () { | |
if (!this._geoJson) return []; | |
return _.pluck(this._geoJson.features, 'properties.rectangle'); | |
}; | |
return TileMapMap; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 415 */ | |
/***/ function(module, exports, __webpack_require__) { | |
'use strict'; | |
__webpack_require__(416); | |
window.L = module.exports = __webpack_require__(417); | |
__webpack_require__(419); | |
__webpack_require__(420); | |
__webpack_require__(421); | |
/***/ }, | |
/* 416 */ | |
/***/ function(module, exports) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 417 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* | |
Leaflet, a JavaScript library for mobile-friendly interactive maps. http://leafletjs.com | |
(c) 2010-2013, Vladimir Agafonkin | |
(c) 2010-2011, CloudMade | |
*/ | |
!function(t,e,i){var n=t.L,o={};o.version="0.7.5","object"==typeof module&&"object"==typeof module.exports?module.exports=o:"function"=="function"&&__webpack_require__(418)&&!(__WEBPACK_AMD_DEFINE_FACTORY__ = (o), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)),o.noConflict=function(){return t.L=n,this},t.L=o,o.Util={extend:function(t){var e,i,n,o,s=Array.prototype.slice.call(arguments,1);for(i=0,n=s.length;n>i;i++){o=s[i]||{};for(e in o)o.hasOwnProperty(e)&&(t[e]=o[e])}return t},bind:function(t,e){var i=arguments.length>2?Array.prototype.slice.call(arguments,2):null;return function(){return t.apply(e,i||arguments)}},stamp:function(){var t=0,e="_leaflet_id";return function(i){return i[e]=i[e]||++t,i[e]}}(),invokeEach:function(t,e,i){var n,o;if("object"==typeof t){o=Array.prototype.slice.call(arguments,3);for(n in t)e.apply(i,[n,t[n]].concat(o));return!0}return!1},limitExecByInterval:function(t,e,i){var n,o;return function s(){var a=arguments;return n?void(o=!0):(n=!0,setTimeout(function(){n=!1,o&&(s.apply(i,a),o=!1)},e),void t.apply(i,a))}},falseFn:function(){return!1},formatNum:function(t,e){var i=Math.pow(10,e||5);return Math.round(t*i)/i},trim:function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")},splitWords:function(t){return o.Util.trim(t).split(/\s+/)},setOptions:function(t,e){return t.options=o.extend({},t.options,e),t.options},getParamString:function(t,e,i){var n=[];for(var o in t)n.push(encodeURIComponent(i?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(e&&-1!==e.indexOf("?")?"&":"?")+n.join("&")},template:function(t,e){return t.replace(/\{ *([\w_]+) *\}/g,function(t,n){var o=e[n];if(o===i)throw new Error("No value provided for variable "+t);return"function"==typeof o&&(o=o(e)),o})},isArray:Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},emptyImageUrl:"data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="},function(){function e(e){var i,n,o=["webkit","moz","o","ms"];for(i=0;i<o.length&&!n;i++)n=t[o[i]+e];return n}function i(e){var i=+new Date,o=Math.max(0,16-(i-n));return n=i+o,t.setTimeout(e,o)}var n=0,s=t.requestAnimationFrame||e("RequestAnimationFrame")||i,a=t.cancelAnimationFrame||e("CancelAnimationFrame")||e("CancelRequestAnimationFrame")||function(e){t.clearTimeout(e)};o.Util.requestAnimFrame=function(e,n,a,r){return e=o.bind(e,n),a&&s===i?void e():s.call(t,e,r)},o.Util.cancelAnimFrame=function(e){e&&a.call(t,e)}}(),o.extend=o.Util.extend,o.bind=o.Util.bind,o.stamp=o.Util.stamp,o.setOptions=o.Util.setOptions,o.Class=function(){},o.Class.extend=function(t){var e=function(){this.initialize&&this.initialize.apply(this,arguments),this._initHooks&&this.callInitHooks()},i=function(){};i.prototype=this.prototype;var n=new i;n.constructor=e,e.prototype=n;for(var s in this)this.hasOwnProperty(s)&&"prototype"!==s&&(e[s]=this[s]);t.statics&&(o.extend(e,t.statics),delete t.statics),t.includes&&(o.Util.extend.apply(null,[n].concat(t.includes)),delete t.includes),t.options&&n.options&&(t.options=o.extend({},n.options,t.options)),o.extend(n,t),n._initHooks=[];var a=this;return e.__super__=a.prototype,n.callInitHooks=function(){if(!this._initHooksCalled){a.prototype.callInitHooks&&a.prototype.callInitHooks.call(this),this._initHooksCalled=!0;for(var t=0,e=n._initHooks.length;e>t;t++)n._initHooks[t].call(this)}},e},o.Class.include=function(t){o.extend(this.prototype,t)},o.Class.mergeOptions=function(t){o.extend(this.prototype.options,t)},o.Class.addInitHook=function(t){var e=Array.prototype.slice.call(arguments,1),i="function"==typeof t?t:function(){this[t].apply(this,e)};this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(i)};var s="_leaflet_events";o.Mixin={},o.Mixin.Events={addEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d=this[s]=this[s]||{},p=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)r={action:e,context:i||this},h=t[n],p?(l=h+"_idx",u=l+"_len",c=d[l]=d[l]||{},c[p]||(c[p]=[],d[u]=(d[u]||0)+1),c[p].push(r)):(d[h]=d[h]||[],d[h].push(r));return this},hasEventListeners:function(t){var e=this[s];return!!e&&(t in e&&e[t].length>0||t+"_idx"in e&&e[t+"_idx_len"]>0)},removeEventListener:function(t,e,i){if(!this[s])return this;if(!t)return this.clearAllEventListeners();if(o.Util.invokeEach(t,this.removeEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d,p,_=this[s],m=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)if(r=t[n],u=r+"_idx",c=u+"_len",d=_[u],e){if(h=m&&d?d[m]:_[r]){for(l=h.length-1;l>=0;l--)h[l].action!==e||i&&h[l].context!==i||(p=h.splice(l,1),p[0].action=o.Util.falseFn);i&&d&&0===h.length&&(delete d[m],_[c]--)}}else delete _[r],delete _[u],delete _[c];return this},clearAllEventListeners:function(){return delete this[s],this},fireEvent:function(t,e){if(!this.hasEventListeners(t))return this;var i,n,a,r,h,l=o.Util.extend({},e,{type:t,target:this}),u=this[s];if(u[t])for(i=u[t].slice(),n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);r=u[t+"_idx"];for(h in r)if(i=r[h].slice())for(n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);return this},addOneTimeEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addOneTimeEventListener,this,e,i))return this;var n=o.bind(function(){this.removeEventListener(t,e,i).removeEventListener(t,n,i)},this);return this.addEventListener(t,e,i).addEventListener(t,n,i)}},o.Mixin.Events.on=o.Mixin.Events.addEventListener,o.Mixin.Events.off=o.Mixin.Events.removeEventListener,o.Mixin.Events.once=o.Mixin.Events.addOneTimeEventListener,o.Mixin.Events.fire=o.Mixin.Events.fireEvent,function(){var n="ActiveXObject"in t,s=n&&!e.addEventListener,a=navigator.userAgent.toLowerCase(),r=-1!==a.indexOf("webkit"),h=-1!==a.indexOf("chrome"),l=-1!==a.indexOf("phantom"),u=-1!==a.indexOf("android"),c=-1!==a.search("android [23]"),d=-1!==a.indexOf("gecko"),p=typeof orientation!=i+"",_=!t.PointerEvent&&t.MSPointerEvent,m=t.PointerEvent&&t.navigator.pointerEnabled&&t.navigator.maxTouchPoints||_,f="devicePixelRatio"in t&&t.devicePixelRatio>1||"matchMedia"in t&&t.matchMedia("(min-resolution:144dpi)")&&t.matchMedia("(min-resolution:144dpi)").matches,g=e.documentElement,v=n&&"transition"in g.style,y="WebKitCSSMatrix"in t&&"m11"in new t.WebKitCSSMatrix&&!c,P="MozPerspective"in g.style,L="OTransition"in g.style,x=!t.L_DISABLE_3D&&(v||y||P||L)&&!l,w=!t.L_NO_TOUCH&&!l&&(m||"ontouchstart"in t||t.DocumentTouch&&e instanceof t.DocumentTouch);o.Browser={ie:n,ielt9:s,webkit:r,gecko:d&&!r&&!t.opera&&!n,android:u,android23:c,chrome:h,ie3d:v,webkit3d:y,gecko3d:P,opera3d:L,any3d:x,mobile:p,mobileWebkit:p&&r,mobileWebkit3d:p&&y,mobileOpera:p&&t.opera,touch:w,msPointer:_,pointer:m,retina:f}}(),o.Point=function(t,e,i){this.x=i?Math.round(t):t,this.y=i?Math.round(e):e},o.Point.prototype={clone:function(){return new o.Point(this.x,this.y)},add:function(t){return this.clone()._add(o.point(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(o.point(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},distanceTo:function(t){t=o.point(t);var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},equals:function(t){return t=o.point(t),t.x===this.x&&t.y===this.y},contains:function(t){return t=o.point(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+o.Util.formatNum(this.x)+", "+o.Util.formatNum(this.y)+")"}},o.point=function(t,e,n){return t instanceof o.Point?t:o.Util.isArray(t)?new o.Point(t[0],t[1]):t===i||null===t?t:new o.Point(t,e,n)},o.Bounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.Bounds.prototype={extend:function(t){return t=o.point(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new o.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new o.Point(this.min.x,this.max.y)},getTopRight:function(){return new o.Point(this.max.x,this.min.y)},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var e,i;return t="number"==typeof t[0]||t instanceof o.Point?o.point(t):o.bounds(t),t instanceof o.Bounds?(e=t.min,i=t.max):e=i=t,e.x>=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,a=s.x>=e.x&&n.x<=i.x,r=s.y>=e.y&&n.y<=i.y;return a&&r},isValid:function(){return!(!this.min||!this.max)}},o.bounds=function(t,e){return!t||t instanceof o.Bounds?t:new o.Bounds(t,e)},o.Transformation=function(t,e,i,n){this._a=t,this._b=e,this._c=i,this._d=n},o.Transformation.prototype={transform:function(t,e){return this._transform(t.clone(),e)},_transform:function(t,e){return e=e||1,t.x=e*(this._a*t.x+this._b),t.y=e*(this._c*t.y+this._d),t},untransform:function(t,e){return e=e||1,new o.Point((t.x/e-this._b)/this._a,(t.y/e-this._d)/this._c)}},o.DomUtil={get:function(t){return"string"==typeof t?e.getElementById(t):t},getStyle:function(t,i){var n=t.style[i];if(!n&&t.currentStyle&&(n=t.currentStyle[i]),(!n||"auto"===n)&&e.defaultView){var o=e.defaultView.getComputedStyle(t,null);n=o?o[i]:null}return"auto"===n?null:n},getViewportOffset:function(t){var i,n=0,s=0,a=t,r=e.body,h=e.documentElement;do{if(n+=a.offsetTop||0,s+=a.offsetLeft||0,n+=parseInt(o.DomUtil.getStyle(a,"borderTopWidth"),10)||0,s+=parseInt(o.DomUtil.getStyle(a,"borderLeftWidth"),10)||0,i=o.DomUtil.getStyle(a,"position"),a.offsetParent===r&&"absolute"===i)break;if("fixed"===i){n+=r.scrollTop||h.scrollTop||0,s+=r.scrollLeft||h.scrollLeft||0;break}if("relative"===i&&!a.offsetLeft){var l=o.DomUtil.getStyle(a,"width"),u=o.DomUtil.getStyle(a,"max-width"),c=a.getBoundingClientRect();("none"!==l||"none"!==u)&&(s+=c.left+a.clientLeft),n+=c.top+(r.scrollTop||h.scrollTop||0);break}a=a.offsetParent}while(a);a=t;do{if(a===r)break;n-=a.scrollTop||0,s-=a.scrollLeft||0,a=a.parentNode}while(a);return new o.Point(s,n)},documentIsLtr:function(){return o.DomUtil._docIsLtrCached||(o.DomUtil._docIsLtrCached=!0,o.DomUtil._docIsLtr="ltr"===o.DomUtil.getStyle(e.body,"direction")),o.DomUtil._docIsLtr},create:function(t,i,n){var o=e.createElement(t);return o.className=i,n&&n.appendChild(o),o},hasClass:function(t,e){if(t.classList!==i)return t.classList.contains(e);var n=o.DomUtil._getClass(t);return n.length>0&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(n)},addClass:function(t,e){if(t.classList!==i)for(var n=o.Util.splitWords(e),s=0,a=n.length;a>s;s++)t.classList.add(n[s]);else if(!o.DomUtil.hasClass(t,e)){var r=o.DomUtil._getClass(t);o.DomUtil._setClass(t,(r?r+" ":"")+e)}},removeClass:function(t,e){t.classList!==i?t.classList.remove(e):o.DomUtil._setClass(t,o.Util.trim((" "+o.DomUtil._getClass(t)+" ").replace(" "+e+" "," ")))},_setClass:function(t,e){t.className.baseVal===i?t.className=e:t.className.baseVal=e},_getClass:function(t){return t.className.baseVal===i?t.className:t.className.baseVal},setOpacity:function(t,e){if("opacity"in t.style)t.style.opacity=e;else if("filter"in t.style){var i=!1,n="DXImageTransform.Microsoft.Alpha";try{i=t.filters.item(n)}catch(o){if(1===e)return}e=Math.round(100*e),i?(i.Enabled=100!==e,i.Opacity=e):t.style.filter+=" progid:"+n+"(opacity="+e+")"}},testProp:function(t){for(var i=e.documentElement.style,n=0;n<t.length;n++)if(t[n]in i)return t[n];return!1},getTranslateString:function(t){var e=o.Browser.webkit3d,i="translate"+(e?"3d":"")+"(",n=(e?",0":"")+")";return i+t.x+"px,"+t.y+"px"+n},getScaleString:function(t,e){var i=o.DomUtil.getTranslateString(e.add(e.multiplyBy(-1*t))),n=" scale("+t+") ";return i+n},setPosition:function(t,e,i){t._leaflet_pos=e,!i&&o.Browser.any3d?t.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(e):(t.style.left=e.x+"px",t.style.top=e.y+"px")},getPosition:function(t){return t._leaflet_pos}},o.DomUtil.TRANSFORM=o.DomUtil.testProp(["transform","WebkitTransform","OTransform","MozTransform","msTransform"]),o.DomUtil.TRANSITION=o.DomUtil.testProp(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),o.DomUtil.TRANSITION_END="webkitTransition"===o.DomUtil.TRANSITION||"OTransition"===o.DomUtil.TRANSITION?o.DomUtil.TRANSITION+"End":"transitionend",function(){if("onselectstart"in e)o.extend(o.DomUtil,{disableTextSelection:function(){o.DomEvent.on(t,"selectstart",o.DomEvent.preventDefault)},enableTextSelection:function(){o.DomEvent.off(t,"selectstart",o.DomEvent.preventDefault)}});else{var i=o.DomUtil.testProp(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);o.extend(o.DomUtil,{disableTextSelection:function(){if(i){var t=e.documentElement.style;this._userSelect=t[i],t[i]="none"}},enableTextSelection:function(){i&&(e.documentElement.style[i]=this._userSelect,delete this._userSelect)}})}o.extend(o.DomUtil,{disableImageDrag:function(){o.DomEvent.on(t,"dragstart",o.DomEvent.preventDefault)},enableImageDrag:function(){o.DomEvent.off(t,"dragstart",o.DomEvent.preventDefault)}})}(),o.LatLng=function(t,e,n){if(t=parseFloat(t),e=parseFloat(e),isNaN(t)||isNaN(e))throw new Error("Invalid LatLng object: ("+t+", "+e+")");this.lat=t,this.lng=e,n!==i&&(this.alt=parseFloat(n))},o.extend(o.LatLng,{DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,MAX_MARGIN:1e-9}),o.LatLng.prototype={equals:function(t){if(!t)return!1;t=o.latLng(t);var e=Math.max(Math.abs(this.lat-t.lat),Math.abs(this.lng-t.lng));return e<=o.LatLng.MAX_MARGIN},toString:function(t){return"LatLng("+o.Util.formatNum(this.lat,t)+", "+o.Util.formatNum(this.lng,t)+")"},distanceTo:function(t){t=o.latLng(t);var e=6378137,i=o.LatLng.DEG_TO_RAD,n=(t.lat-this.lat)*i,s=(t.lng-this.lng)*i,a=this.lat*i,r=t.lat*i,h=Math.sin(n/2),l=Math.sin(s/2),u=h*h+l*l*Math.cos(a)*Math.cos(r);return 2*e*Math.atan2(Math.sqrt(u),Math.sqrt(1-u))},wrap:function(t,e){var i=this.lng;return t=t||-180,e=e||180,i=(i+e)%(e-t)+(t>i||i===e?e:t),new o.LatLng(this.lat,i)}},o.latLng=function(t,e){return t instanceof o.LatLng?t:o.Util.isArray(t)?"number"==typeof t[0]||"string"==typeof t[0]?new o.LatLng(t[0],t[1],t[2]):null:t===i||null===t?t:"object"==typeof t&&"lat"in t?new o.LatLng(t.lat,"lng"in t?t.lng:t.lon):e===i?null:new o.LatLng(t,e)},o.LatLngBounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.LatLngBounds.prototype={extend:function(t){if(!t)return this;var e=o.latLng(t);return t=null!==e?e:o.latLngBounds(t),t instanceof o.LatLng?this._southWest||this._northEast?(this._southWest.lat=Math.min(t.lat,this._southWest.lat),this._southWest.lng=Math.min(t.lng,this._southWest.lng),this._northEast.lat=Math.max(t.lat,this._northEast.lat),this._northEast.lng=Math.max(t.lng,this._northEast.lng)):(this._southWest=new o.LatLng(t.lat,t.lng),this._northEast=new o.LatLng(t.lat,t.lng)):t instanceof o.LatLngBounds&&(this.extend(t._southWest),this.extend(t._northEast)),this},pad:function(t){var e=this._southWest,i=this._northEast,n=Math.abs(e.lat-i.lat)*t,s=Math.abs(e.lng-i.lng)*t;return new o.LatLngBounds(new o.LatLng(e.lat-n,e.lng-s),new o.LatLng(i.lat+n,i.lng+s))},getCenter:function(){return new o.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new o.LatLng(this.getNorth(),this.getWest())},getSouthEast:function(){return new o.LatLng(this.getSouth(),this.getEast())},getWest:function(){return this._southWest.lng},getSouth:function(){return this._southWest.lat},getEast:function(){return this._northEast.lng},getNorth:function(){return this._northEast.lat},contains:function(t){t="number"==typeof t[0]||t instanceof o.LatLng?o.latLng(t):o.latLngBounds(t);var e,i,n=this._southWest,s=this._northEast;return t instanceof o.LatLngBounds?(e=t.getSouthWest(),i=t.getNorthEast()):e=i=t,e.lat>=n.lat&&i.lat<=s.lat&&e.lng>=n.lng&&i.lng<=s.lng},intersects:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),a=s.lat>=e.lat&&n.lat<=i.lat,r=s.lng>=e.lng&&n.lng<=i.lng;return a&&r},toBBoxString:function(){return[this.getWest(),this.getSouth(),this.getEast(),this.getNorth()].join(",")},equals:function(t){return t?(t=o.latLngBounds(t),this._southWest.equals(t.getSouthWest())&&this._northEast.equals(t.getNorthEast())):!1},isValid:function(){return!(!this._southWest||!this._northEast)}},o.latLngBounds=function(t,e){return!t||t instanceof o.LatLngBounds?t:new o.LatLngBounds(t,e)},o.Projection={},o.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=t.lng*e,a=n*e;return a=Math.log(Math.tan(Math.PI/4+a/2)),new o.Point(s,a)},unproject:function(t){var e=o.LatLng.RAD_TO_DEG,i=t.x*e,n=(2*Math.atan(Math.exp(t.y))-Math.PI/2)*e;return new o.LatLng(n,i)}},o.Projection.LonLat={project:function(t){return new o.Point(t.lng,t.lat)},unproject:function(t){return new o.LatLng(t.y,t.x)}},o.CRS={latLngToPoint:function(t,e){var i=this.projection.project(t),n=this.scale(e);return this.transformation._transform(i,n)},pointToLatLng:function(t,e){var i=this.scale(e),n=this.transformation.untransform(t,i);return this.projection.unproject(n)},project:function(t){return this.projection.project(t)},scale:function(t){return 256*Math.pow(2,t)},getSize:function(t){var e=this.scale(t);return o.point(e,e)}},o.CRS.Simple=o.extend({},o.CRS,{projection:o.Projection.LonLat,transformation:new o.Transformation(1,0,-1,0),scale:function(t){return Math.pow(2,t)}}),o.CRS.EPSG3857=o.extend({},o.CRS,{code:"EPSG:3857",projection:o.Projection.SphericalMercator,transformation:new o.Transformation(.5/Math.PI,.5,-.5/Math.PI,.5),project:function(t){var e=this.projection.project(t),i=6378137;return e.multiplyBy(i)}}),o.CRS.EPSG900913=o.extend({},o.CRS.EPSG3857,{code:"EPSG:900913"}),o.CRS.EPSG4326=o.extend({},o.CRS,{code:"EPSG:4326",projection:o.Projection.LonLat,transformation:new o.Transformation(1/360,.5,-1/360,.5)}),o.Map=o.Class.extend({includes:o.Mixin.Events,options:{crs:o.CRS.EPSG3857,fadeAnimation:o.DomUtil.TRANSITION&&!o.Browser.android23,trackResize:!0,markerZoomAnimation:o.DomUtil.TRANSITION&&o.Browser.any3d},initialize:function(t,e){e=o.setOptions(this,e),this._initContainer(t),this._initLayout(),this._onResize=o.bind(this._onResize,this),this._initEvents(),e.maxBounds&&this.setMaxBounds(e.maxBounds),e.center&&e.zoom!==i&&this.setView(o.latLng(e.center),e.zoom,{reset:!0}),this._handlers=[],this._layers={},this._zoomBoundLayers={},this._tileLayersNum=0,this.callInitHooks(),this._addLayers(e.layers)},setView:function(t,e){return e=e===i?this.getZoom():e,this._resetView(o.latLng(t),this._limitZoom(e)),this},setZoom:function(t,e){return this._loaded?this.setView(this.getCenter(),t,{zoom:e}):(this._zoom=this._limitZoom(t),this)},zoomIn:function(t,e){return this.setZoom(this._zoom+(t||1),e)},zoomOut:function(t,e){return this.setZoom(this._zoom-(t||1),e)},setZoomAround:function(t,e,i){var n=this.getZoomScale(e),s=this.getSize().divideBy(2),a=t instanceof o.Point?t:this.latLngToContainerPoint(t),r=a.subtract(s).multiplyBy(1-1/n),h=this.containerPointToLatLng(s.add(r));return this.setView(h,e,{zoom:i})},fitBounds:function(t,e){e=e||{},t=t.getBounds?t.getBounds():o.latLngBounds(t);var i=o.point(e.paddingTopLeft||e.padding||[0,0]),n=o.point(e.paddingBottomRight||e.padding||[0,0]),s=this.getBoundsZoom(t,!1,i.add(n));s=e.maxZoom?Math.min(e.maxZoom,s):s;var a=n.subtract(i).divideBy(2),r=this.project(t.getSouthWest(),s),h=this.project(t.getNorthEast(),s),l=this.unproject(r.add(h).divideBy(2).add(a),s);return this.setView(l,s,e)},fitWorld:function(t){return this.fitBounds([[-90,-180],[90,180]],t)},panTo:function(t,e){return this.setView(t,this._zoom,{pan:e})},panBy:function(t){return this.fire("movestart"),this._rawPanBy(o.point(t)),this.fire("move"),this.fire("moveend")},setMaxBounds:function(t){return t=o.latLngBounds(t),this.options.maxBounds=t,t?(this._loaded&&this._panInsideMaxBounds(),this.on("moveend",this._panInsideMaxBounds,this)):this.off("moveend",this._panInsideMaxBounds,this)},panInsideBounds:function(t,e){var i=this.getCenter(),n=this._limitCenter(i,this._zoom,t);return i.equals(n)?this:this.panTo(n,e)},addLayer:function(t){var e=o.stamp(t);return this._layers[e]?this:(this._layers[e]=t,!t.options||isNaN(t.options.maxZoom)&&isNaN(t.options.minZoom)||(this._zoomBoundLayers[e]=t,this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum++,this._tileLayersToLoad++,t.on("load",this._onTileLayerLoad,this)),this._loaded&&this._layerAdd(t),this)},removeLayer:function(t){var e=o.stamp(t);return this._layers[e]?(this._loaded&&t.onRemove(this),delete this._layers[e],this._loaded&&this.fire("layerremove",{layer:t}),this._zoomBoundLayers[e]&&(delete this._zoomBoundLayers[e],this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum--,this._tileLayersToLoad--,t.off("load",this._onTileLayerLoad,this)),this):this},hasLayer:function(t){return t?o.stamp(t)in this._layers:!1},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},invalidateSize:function(t){if(!this._loaded)return this;t=o.extend({animate:!1,pan:!0},t===!0?{animate:!0}:t);var e=this.getSize();this._sizeChanged=!0,this._initialCenter=null;var i=this.getSize(),n=e.divideBy(2).round(),s=i.divideBy(2).round(),a=n.subtract(s);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(o.bind(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},addHandler:function(t,e){if(!e)return this;var i=this[t]=new e(this);return this._handlers.push(i),this.options[t]&&i.enable(),this},remove:function(){this._loaded&&this.fire("unload"),this._initEvents("off");try{delete this._container._leaflet}catch(t){this._container._leaflet=i}return this._clearPanes(),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this},getCenter:function(){return this._checkIfLoaded(),this._initialCenter&&!this._moved()?this._initialCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds(),e=this.unproject(t.getBottomLeft()),i=this.unproject(t.getTopRight());return new o.LatLngBounds(e,i)},getMinZoom:function(){return this.options.minZoom===i?this._layersMinZoom===i?0:this._layersMinZoom:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===i?this._layersMaxZoom===i?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=o.latLngBounds(t);var n,s=this.getMinZoom()-(e?1:0),a=this.getMaxZoom(),r=this.getSize(),h=t.getNorthWest(),l=t.getSouthEast(),u=!0;i=o.point(i||[0,0]);do s++,n=this.project(l,s).subtract(this.project(h,s)).add(i),u=e?n.x<r.x||n.y<r.y:r.contains(n);while(u&&a>=s);return u&&e?null:e?s:s-1},getSize:function(){return(!this._size||this._sizeChanged)&&(this._size=new o.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(){var t=this._getTopLeftPoint();return new o.Bounds(t,t.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._initialTopLeftPoint},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t){var e=this.options.crs;return e.scale(t)/e.scale(this._zoom)},getScaleZoom:function(t){return this._zoom+Math.log(t)/Math.LN2},project:function(t,e){return e=e===i?this._zoom:e,this.options.crs.latLngToPoint(o.latLng(t),e)},unproject:function(t,e){return e=e===i?this._zoom:e,this.options.crs.pointToLatLng(o.point(t),e)},layerPointToLatLng:function(t){var e=o.point(t).add(this.getPixelOrigin());return this.unproject(e)},latLngToLayerPoint:function(t){var e=this.project(o.latLng(t))._round();return e._subtract(this.getPixelOrigin())},containerPointToLayerPoint:function(t){return o.point(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return o.point(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var e=this.containerPointToLayerPoint(o.point(t));return this.layerPointToLatLng(e)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(o.latLng(t)))},mouseEventToContainerPoint:function(t){return o.DomEvent.getMousePosition(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var e=this._container=o.DomUtil.get(t);if(!e)throw new Error("Map container not found.");if(e._leaflet)throw new Error("Map container is already initialized.");e._leaflet=!0},_initLayout:function(){var t=this._container;o.DomUtil.addClass(t,"leaflet-container"+(o.Browser.touch?" leaflet-touch":"")+(o.Browser.retina?" leaflet-retina":"")+(o.Browser.ielt9?" leaflet-oldie":"")+(this.options.fadeAnimation?" leaflet-fade-anim":""));var e=o.DomUtil.getStyle(t,"position");"absolute"!==e&&"relative"!==e&&"fixed"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._mapPane=t.mapPane=this._createPane("leaflet-map-pane",this._container),this._tilePane=t.tilePane=this._createPane("leaflet-tile-pane",this._mapPane),t.objectsPane=this._createPane("leaflet-objects-pane",this._mapPane),t.shadowPane=this._createPane("leaflet-shadow-pane"),t.overlayPane=this._createPane("leaflet-overlay-pane"),t.markerPane=this._createPane("leaflet-marker-pane"),t.popupPane=this._createPane("leaflet-popup-pane");var e=" leaflet-zoom-hide";this.options.markerZoomAnimation||(o.DomUtil.addClass(t.markerPane,e),o.DomUtil.addClass(t.shadowPane,e),o.DomUtil.addClass(t.popupPane,e))},_createPane:function(t,e){return o.DomUtil.create("div",t,e||this._panes.objectsPane)},_clearPanes:function(){this._container.removeChild(this._mapPane)},_addLayers:function(t){t=t?o.Util.isArray(t)?t:[t]:[];for(var e=0,i=t.length;i>e;e++)this.addLayer(t[e])},_resetView:function(t,e,i,n){var s=this._zoom!==e;n||(this.fire("movestart"),s&&this.fire("zoomstart")),this._zoom=e,this._initialCenter=t,this._initialTopLeftPoint=this._getNewTopLeftPoint(t),i?this._initialTopLeftPoint._add(this._getMapPanePos()):o.DomUtil.setPosition(this._mapPane,new o.Point(0,0)),this._tileLayersToLoad=this._tileLayersNum;var a=!this._loaded;this._loaded=!0,this.fire("viewreset",{hard:!i}),a&&(this.fire("load"),this.eachLayer(this._layerAdd,this)),this.fire("move"),(s||n)&&this.fire("zoomend"),this.fire("moveend",{hard:!i})},_rawPanBy:function(t){o.DomUtil.setPosition(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_updateZoomLevels:function(){var t,e=1/0,n=-(1/0),o=this._getZoomSpan();for(t in this._zoomBoundLayers){var s=this._zoomBoundLayers[t];isNaN(s.options.minZoom)||(e=Math.min(e,s.options.minZoom)),isNaN(s.options.maxZoom)||(n=Math.max(n,s.options.maxZoom))}t===i?this._layersMaxZoom=this._layersMinZoom=i:(this._layersMaxZoom=n,this._layersMinZoom=e),o!==this._getZoomSpan()&&this.fire("zoomlevelschange")},_panInsideMaxBounds:function(){this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(e){if(o.DomEvent){e=e||"on",o.DomEvent[e](this._container,"click",this._onMouseClick,this);var i,n,s=["dblclick","mousedown","mouseup","mouseenter","mouseleave","mousemove","contextmenu"];for(i=0,n=s.length;n>i;i++)o.DomEvent[e](this._container,s[i],this._fireMouseEvent,this);this.options.trackResize&&o.DomEvent[e](t,"resize",this._onResize,this)}},_onResize:function(){o.Util.cancelAnimFrame(this._resizeRequest),this._resizeRequest=o.Util.requestAnimFrame(function(){this.invalidateSize({debounceMoveend:!0})},this,!1,this._container)},_onMouseClick:function(t){!this._loaded||!t._simulated&&(this.dragging&&this.dragging.moved()||this.boxZoom&&this.boxZoom.moved())||o.DomEvent._skipped(t)||(this.fire("preclick"),this._fireMouseEvent(t))},_fireMouseEvent:function(t){if(this._loaded&&!o.DomEvent._skipped(t)){var e=t.type;if(e="mouseenter"===e?"mouseover":"mouseleave"===e?"mouseout":e,this.hasEventListeners(e)){"contextmenu"===e&&o.DomEvent.preventDefault(t);var i=this.mouseEventToContainerPoint(t),n=this.containerPointToLayerPoint(i),s=this.layerPointToLatLng(n);this.fire(e,{latlng:s,layerPoint:n,containerPoint:i,originalEvent:t})}}},_onTileLayerLoad:function(){this._tileLayersToLoad--,this._tileLayersNum&&!this._tileLayersToLoad&&this.fire("tilelayersload")},_clearHandlers:function(){for(var t=0,e=this._handlers.length;e>t;t++)this._handlers[t].disable()},whenReady:function(t,e){return this._loaded?t.call(e||this,this):this.on("load",t,e),this},_layerAdd:function(t){t.onAdd(this),this.fire("layeradd",{layer:t})},_getMapPanePos:function(){return o.DomUtil.getPosition(this._mapPane)},_moved:function(){var t=this._getMapPanePos();return t&&!t.equals([0,0])},_getTopLeftPoint:function(){return this.getPixelOrigin().subtract(this._getMapPanePos())},_getNewTopLeftPoint:function(t,e){var i=this.getSize()._divideBy(2);return this.project(t,e)._subtract(i)._round()},_latLngToNewLayerPoint:function(t,e,i){var n=this._getNewTopLeftPoint(i,e).add(this._getMapPanePos());return this.project(t,e)._subtract(n)},_getCenterLayerPoint:function(){return this.containerPointToLayerPoint(this.getSize()._divideBy(2))},_getCenterOffset:function(t){return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint())},_limitCenter:function(t,e,i){if(!i)return t;var n=this.project(t,e),s=this.getSize().divideBy(2),a=new o.Bounds(n.subtract(s),n.add(s)),r=this._getBoundsOffset(a,i,e);return this.unproject(n.add(r),e)},_limitOffset:function(t,e){if(!e)return t;var i=this.getPixelBounds(),n=new o.Bounds(i.min.add(t),i.max.add(t));return t.add(this._getBoundsOffset(n,e))},_getBoundsOffset:function(t,e,i){var n=this.project(e.getNorthWest(),i).subtract(t.min),s=this.project(e.getSouthEast(),i).subtract(t.max),a=this._rebound(n.x,-s.x),r=this._rebound(n.y,-s.y);return new o.Point(a,r)},_rebound:function(t,e){return t+e>0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom();return Math.max(e,Math.min(i,t))}}),o.map=function(t,e){return new o.Map(t,e)},o.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.314245179,R_MAJOR:6378137,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=this.R_MAJOR,a=this.R_MINOR,r=t.lng*e*s,h=n*e,l=a/s,u=Math.sqrt(1-l*l),c=u*Math.sin(h);c=Math.pow((1-c)/(1+c),.5*u);var d=Math.tan(.5*(.5*Math.PI-h))/c;return h=-s*Math.log(d),new o.Point(r,h)},unproject:function(t){for(var e,i=o.LatLng.RAD_TO_DEG,n=this.R_MAJOR,s=this.R_MINOR,a=t.x*i/n,r=s/n,h=Math.sqrt(1-r*r),l=Math.exp(-t.y/n),u=Math.PI/2-2*Math.atan(l),c=15,d=1e-7,p=c,_=.1;Math.abs(_)>d&&--p>0;)e=h*Math.sin(u),_=Math.PI/2-2*Math.atan(l*Math.pow((1-e)/(1+e),.5*h))-u,u+=_;return new o.LatLng(u*i,a)}},o.CRS.EPSG3395=o.extend({},o.CRS,{code:"EPSG:3395", | |
projection:o.Projection.Mercator,transformation:function(){var t=o.Projection.Mercator,e=t.R_MAJOR,i=.5/(Math.PI*e);return new o.Transformation(i,.5,-i,.5)}()}),o.TileLayer=o.Class.extend({includes:o.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",zoomOffset:0,opacity:1,unloadInvisibleTiles:o.Browser.mobile,updateWhenIdle:o.Browser.mobile},initialize:function(t,e){e=o.setOptions(this,e),e.detectRetina&&o.Browser.retina&&e.maxZoom>0&&(e.tileSize=Math.floor(e.tileSize/2),e.zoomOffset++,e.minZoom>0&&e.minZoom--,this.options.maxZoom--),e.bounds&&(e.bounds=o.latLngBounds(e.bounds)),this._url=t;var i=this.options.subdomains;"string"==typeof i&&(this.options.subdomains=i.split(""))},onAdd:function(t){this._map=t,this._animated=t._zoomAnimated,this._initContainer(),t.on({viewreset:this._reset,moveend:this._update},this),this._animated&&t.on({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||(this._limitedUpdate=o.Util.limitExecByInterval(this._update,150,this),t.on("move",this._limitedUpdate,this)),this._reset(),this._update()},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this._container.parentNode.removeChild(this._container),t.off({viewreset:this._reset,moveend:this._update},this),this._animated&&t.off({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||t.off("move",this._limitedUpdate,this),this._container=null,this._map=null},bringToFront:function(){var t=this._map._panes.tilePane;return this._container&&(t.appendChild(this._container),this._setAutoZIndex(t,Math.max)),this},bringToBack:function(){var t=this._map._panes.tilePane;return this._container&&(t.insertBefore(this._container,t.firstChild),this._setAutoZIndex(t,Math.min)),this},getAttribution:function(){return this.options.attribution},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},setUrl:function(t,e){return this._url=t,e||this.redraw(),this},redraw:function(){return this._map&&(this._reset({hard:!0}),this._update()),this},_updateZIndex:function(){this._container&&this.options.zIndex!==i&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t,e){var i,n,o,s=t.children,a=-e(1/0,-(1/0));for(n=0,o=s.length;o>n;n++)s[n]!==this._container&&(i=parseInt(s[n].style.zIndex,10),isNaN(i)||(a=e(a,i)));this.options.zIndex=this._container.style.zIndex=(isFinite(a)?a:0)+e(1,-1)},_updateOpacity:function(){var t,e=this._tiles;if(o.Browser.ielt9)for(t in e)o.DomUtil.setOpacity(e[t],this.options.opacity);else o.DomUtil.setOpacity(this._container,this.options.opacity)},_initContainer:function(){var t=this._map._panes.tilePane;if(!this._container){if(this._container=o.DomUtil.create("div","leaflet-layer"),this._updateZIndex(),this._animated){var e="leaflet-tile-container";this._bgBuffer=o.DomUtil.create("div",e,this._container),this._tileContainer=o.DomUtil.create("div",e,this._container)}else this._tileContainer=this._container;t.appendChild(this._container),this.options.opacity<1&&this._updateOpacity()}},_reset:function(t){for(var e in this._tiles)this.fire("tileunload",{tile:this._tiles[e]});this._tiles={},this._tilesToLoad=0,this.options.reuseTiles&&(this._unusedTiles=[]),this._tileContainer.innerHTML="",this._animated&&t&&t.hard&&this._clearBgBuffer(),this._initContainer()},_getTileSize:function(){var t=this._map,e=t.getZoom()+this.options.zoomOffset,i=this.options.maxNativeZoom,n=this.options.tileSize;return i&&e>i&&(n=Math.round(t.getZoomScale(e)/t.getZoomScale(i)*n)),n},_update:function(){if(this._map){var t=this._map,e=t.getPixelBounds(),i=t.getZoom(),n=this._getTileSize();if(!(i>this.options.maxZoom||i<this.options.minZoom)){var s=o.bounds(e.min.divideBy(n)._floor(),e.max.divideBy(n)._floor());this._addTilesFromCenterOut(s),(this.options.unloadInvisibleTiles||this.options.reuseTiles)&&this._removeOtherTiles(s)}}},_addTilesFromCenterOut:function(t){var i,n,s,a=[],r=t.getCenter();for(i=t.min.y;i<=t.max.y;i++)for(n=t.min.x;n<=t.max.x;n++)s=new o.Point(n,i),this._tileShouldBeLoaded(s)&&a.push(s);var h=a.length;if(0!==h){a.sort(function(t,e){return t.distanceTo(r)-e.distanceTo(r)});var l=e.createDocumentFragment();for(this._tilesToLoad||this.fire("loading"),this._tilesToLoad+=h,n=0;h>n;n++)this._addTile(a[n],l);this._tileContainer.appendChild(l)}},_tileShouldBeLoaded:function(t){if(t.x+":"+t.y in this._tiles)return!1;var e=this.options;if(!e.continuousWorld){var i=this._getWrapTileNum();if(e.noWrap&&(t.x<0||t.x>=i.x)||t.y<0||t.y>=i.y)return!1}if(e.bounds){var n=this._getTileSize(),o=t.multiplyBy(n),s=o.add([n,n]),a=this._map.unproject(o),r=this._map.unproject(s);if(e.continuousWorld||e.noWrap||(a=a.wrap(),r=r.wrap()),!e.bounds.intersects([a,r]))return!1}return!0},_removeOtherTiles:function(t){var e,i,n,o;for(o in this._tiles)e=o.split(":"),i=parseInt(e[0],10),n=parseInt(e[1],10),(i<t.min.x||i>t.max.x||n<t.min.y||n>t.max.y)&&this._removeTile(o)},_removeTile:function(t){var e=this._tiles[t];this.fire("tileunload",{tile:e,url:e.src}),this.options.reuseTiles?(o.DomUtil.removeClass(e,"leaflet-tile-loaded"),this._unusedTiles.push(e)):e.parentNode===this._tileContainer&&this._tileContainer.removeChild(e),o.Browser.android||(e.onload=null,e.src=o.Util.emptyImageUrl),delete this._tiles[t]},_addTile:function(t,e){var i=this._getTilePos(t),n=this._getTile();o.DomUtil.setPosition(n,i,o.Browser.chrome),this._tiles[t.x+":"+t.y]=n,this._loadTile(n,t),n.parentNode!==this._tileContainer&&e.appendChild(n)},_getZoomForUrl:function(){var t=this.options,e=this._map.getZoom();return t.zoomReverse&&(e=t.maxZoom-e),e+=t.zoomOffset,t.maxNativeZoom?Math.min(e,t.maxNativeZoom):e},_getTilePos:function(t){var e=this._map.getPixelOrigin(),i=this._getTileSize();return t.multiplyBy(i).subtract(e)},getTileUrl:function(t){return o.Util.template(this._url,o.extend({s:this._getSubdomain(t),z:t.z,x:t.x,y:t.y},this.options))},_getWrapTileNum:function(){var t=this._map.options.crs,e=t.getSize(this._map.getZoom());return e.divideBy(this._getTileSize())._floor()},_adjustTilePoint:function(t){var e=this._getWrapTileNum();this.options.continuousWorld||this.options.noWrap||(t.x=(t.x%e.x+e.x)%e.x),this.options.tms&&(t.y=e.y-t.y-1),t.z=this._getZoomForUrl()},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_getTile:function(){if(this.options.reuseTiles&&this._unusedTiles.length>0){var t=this._unusedTiles.pop();return this._resetTile(t),t}return this._createTile()},_resetTile:function(){},_createTile:function(){var t=o.DomUtil.create("img","leaflet-tile");return t.style.width=t.style.height=this._getTileSize()+"px",t.galleryimg="no",t.onselectstart=t.onmousemove=o.Util.falseFn,o.Browser.ielt9&&this.options.opacity!==i&&o.DomUtil.setOpacity(t,this.options.opacity),o.Browser.mobileWebkit3d&&(t.style.WebkitBackfaceVisibility="hidden"),t},_loadTile:function(t,e){t._layer=this,t.onload=this._tileOnLoad,t.onerror=this._tileOnError,this._adjustTilePoint(e),t.src=this.getTileUrl(e),this.fire("tileloadstart",{tile:t,url:t.src})},_tileLoaded:function(){this._tilesToLoad--,this._animated&&o.DomUtil.addClass(this._tileContainer,"leaflet-zoom-animated"),this._tilesToLoad||(this.fire("load"),this._animated&&(clearTimeout(this._clearBgBufferTimer),this._clearBgBufferTimer=setTimeout(o.bind(this._clearBgBuffer,this),500)))},_tileOnLoad:function(){var t=this._layer;this.src!==o.Util.emptyImageUrl&&(o.DomUtil.addClass(this,"leaflet-tile-loaded"),t.fire("tileload",{tile:this,url:this.src})),t._tileLoaded()},_tileOnError:function(){var t=this._layer;t.fire("tileerror",{tile:this,url:this.src});var e=t.options.errorTileUrl;e&&(this.src=e),t._tileLoaded()}}),o.tileLayer=function(t,e){return new o.TileLayer(t,e)},o.TileLayer.WMS=o.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",version:"1.1.1",layers:"",styles:"",format:"image/jpeg",transparent:!1},initialize:function(t,e){this._url=t;var i=o.extend({},this.defaultWmsParams),n=e.tileSize||this.options.tileSize;e.detectRetina&&o.Browser.retina?i.width=i.height=2*n:i.width=i.height=n;for(var s in e)this.options.hasOwnProperty(s)||"crs"===s||(i[s]=e[s]);this.wmsParams=i,o.setOptions(this,e)},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,o.TileLayer.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._map,i=this.options.tileSize,n=t.multiplyBy(i),s=n.add([i,i]),a=this._crs.project(e.unproject(n,t.z)),r=this._crs.project(e.unproject(s,t.z)),h=this._wmsVersion>=1.3&&this._crs===o.CRS.EPSG4326?[r.y,a.x,a.y,r.x].join(","):[a.x,r.y,r.x,a.y].join(","),l=o.Util.template(this._url,{s:this._getSubdomain(t)});return l+o.Util.getParamString(this.wmsParams,l,!0)+"&BBOX="+h},setParams:function(t,e){return o.extend(this.wmsParams,t),e||this.redraw(),this}}),o.tileLayer.wms=function(t,e){return new o.TileLayer.WMS(t,e)},o.TileLayer.Canvas=o.TileLayer.extend({options:{async:!1},initialize:function(t){o.setOptions(this,t)},redraw:function(){this._map&&(this._reset({hard:!0}),this._update());for(var t in this._tiles)this._redrawTile(this._tiles[t]);return this},_redrawTile:function(t){this.drawTile(t,t._tilePoint,this._map._zoom)},_createTile:function(){var t=o.DomUtil.create("canvas","leaflet-tile");return t.width=t.height=this.options.tileSize,t.onselectstart=t.onmousemove=o.Util.falseFn,t},_loadTile:function(t,e){t._layer=this,t._tilePoint=e,this._redrawTile(t),this.options.async||this.tileDrawn(t)},drawTile:function(){},tileDrawn:function(t){this._tileOnLoad.call(t)}}),o.tileLayer.canvas=function(t){return new o.TileLayer.Canvas(t)},o.ImageOverlay=o.Class.extend({includes:o.Mixin.Events,options:{opacity:1},initialize:function(t,e,i){this._url=t,this._bounds=o.latLngBounds(e),o.setOptions(this,i)},onAdd:function(t){this._map=t,this._image||this._initImage(),t._panes.overlayPane.appendChild(this._image),t.on("viewreset",this._reset,this),t.options.zoomAnimation&&o.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._image),t.off("viewreset",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},bringToFront:function(){return this._image&&this._map._panes.overlayPane.appendChild(this._image),this},bringToBack:function(){var t=this._map._panes.overlayPane;return this._image&&t.insertBefore(this._image,t.firstChild),this},setUrl:function(t){this._url=t,this._image.src=this._url},getAttribution:function(){return this.options.attribution},_initImage:function(){this._image=o.DomUtil.create("img","leaflet-image-layer"),this._map.options.zoomAnimation&&o.Browser.any3d?o.DomUtil.addClass(this._image,"leaflet-zoom-animated"):o.DomUtil.addClass(this._image,"leaflet-zoom-hide"),this._updateOpacity(),o.extend(this._image,{galleryimg:"no",onselectstart:o.Util.falseFn,onmousemove:o.Util.falseFn,onload:o.bind(this._onImageLoad,this),src:this._url})},_animateZoom:function(t){var e=this._map,i=this._image,n=e.getZoomScale(t.zoom),s=this._bounds.getNorthWest(),a=this._bounds.getSouthEast(),r=e._latLngToNewLayerPoint(s,t.zoom,t.center),h=e._latLngToNewLayerPoint(a,t.zoom,t.center)._subtract(r),l=r._add(h._multiplyBy(.5*(1-1/n)));i.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(l)+" scale("+n+") "},_reset:function(){var t=this._image,e=this._map.latLngToLayerPoint(this._bounds.getNorthWest()),i=this._map.latLngToLayerPoint(this._bounds.getSouthEast())._subtract(e);o.DomUtil.setPosition(t,e),t.style.width=i.x+"px",t.style.height=i.y+"px"},_onImageLoad:function(){this.fire("load")},_updateOpacity:function(){o.DomUtil.setOpacity(this._image,this.options.opacity)}}),o.imageOverlay=function(t,e,i){return new o.ImageOverlay(t,e,i)},o.Icon=o.Class.extend({options:{className:""},initialize:function(t){o.setOptions(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,e){var i=this._getIconUrl(t);if(!i){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n;return n=e&&"IMG"===e.tagName?this._createImg(i,e):this._createImg(i),this._setIconStyles(n,t),n},_setIconStyles:function(t,e){var i,n=this.options,s=o.point(n[e+"Size"]);i="shadow"===e?o.point(n.shadowAnchor||n.iconAnchor):o.point(n.iconAnchor),!i&&s&&(i=s.divideBy(2,!0)),t.className="leaflet-marker-"+e+" "+n.className,i&&(t.style.marginLeft=-i.x+"px",t.style.marginTop=-i.y+"px"),s&&(t.style.width=s.x+"px",t.style.height=s.y+"px")},_createImg:function(t,i){return i=i||e.createElement("img"),i.src=t,i},_getIconUrl:function(t){return o.Browser.retina&&this.options[t+"RetinaUrl"]?this.options[t+"RetinaUrl"]:this.options[t+"Url"]}}),o.icon=function(t){return new o.Icon(t)},o.Icon.Default=o.Icon.extend({options:{iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],shadowSize:[41,41]},_getIconUrl:function(t){var e=t+"Url";if(this.options[e])return this.options[e];o.Browser.retina&&"icon"===t&&(t+="-2x");var i=o.Icon.Default.imagePath;if(!i)throw new Error("Couldn't autodetect L.Icon.Default.imagePath, set it manually.");return i+"/marker-"+t+".png"}}),o.Icon.Default.imagePath=function(){var t,i,n,o,s,a=e.getElementsByTagName("script"),r=/[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/;for(t=0,i=a.length;i>t;t++)if(n=a[t].src,o=n.match(r))return s=n.split(r)[0],(s?s+"/":"")+"images"}(),o.Marker=o.Class.extend({includes:o.Mixin.Events,options:{icon:new o.Icon.Default,title:"",alt:"",clickable:!0,draggable:!1,keyboard:!0,zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250},initialize:function(t,e){o.setOptions(this,e),this._latlng=o.latLng(t)},onAdd:function(t){this._map=t,t.on("viewreset",this.update,this),this._initIcon(),this.update(),this.fire("add"),t.options.zoomAnimation&&t.options.markerZoomAnimation&&t.on("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this.dragging&&this.dragging.disable(),this._removeIcon(),this._removeShadow(),this.fire("remove"),t.off({viewreset:this.update,zoomanim:this._animateZoom},this),this._map=null},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this.update(),this.fire("move",{latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update(),this},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup),this},update:function(){return this._icon&&this._setPos(this._map.latLngToLayerPoint(this._latlng).round()),this},_initIcon:function(){var t=this.options,e=this._map,i=e.options.zoomAnimation&&e.options.markerZoomAnimation,n=i?"leaflet-zoom-animated":"leaflet-zoom-hide",s=t.icon.createIcon(this._icon),a=!1;s!==this._icon&&(this._icon&&this._removeIcon(),a=!0,t.title&&(s.title=t.title),t.alt&&(s.alt=t.alt)),o.DomUtil.addClass(s,n),t.keyboard&&(s.tabIndex="0"),this._icon=s,this._initInteraction(),t.riseOnHover&&o.DomEvent.on(s,"mouseover",this._bringToFront,this).on(s,"mouseout",this._resetZIndex,this);var r=t.icon.createShadow(this._shadow),h=!1;r!==this._shadow&&(this._removeShadow(),h=!0),r&&o.DomUtil.addClass(r,n),this._shadow=r,t.opacity<1&&this._updateOpacity();var l=this._map._panes;a&&l.markerPane.appendChild(this._icon),r&&h&&l.shadowPane.appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&o.DomEvent.off(this._icon,"mouseover",this._bringToFront).off(this._icon,"mouseout",this._resetZIndex),this._map._panes.markerPane.removeChild(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&this._map._panes.shadowPane.removeChild(this._shadow),this._shadow=null},_setPos:function(t){o.DomUtil.setPosition(this._icon,t),this._shadow&&o.DomUtil.setPosition(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(e)},_initInteraction:function(){if(this.options.clickable){var t=this._icon,e=["dblclick","mousedown","mouseover","mouseout","contextmenu"];o.DomUtil.addClass(t,"leaflet-clickable"),o.DomEvent.on(t,"click",this._onMouseClick,this),o.DomEvent.on(t,"keypress",this._onKeyPress,this);for(var i=0;i<e.length;i++)o.DomEvent.on(t,e[i],this._fireMouseEvent,this);o.Handler.MarkerDrag&&(this.dragging=new o.Handler.MarkerDrag(this),this.options.draggable&&this.dragging.enable())}},_onMouseClick:function(t){var e=this.dragging&&this.dragging.moved();(this.hasEventListeners(t.type)||e)&&o.DomEvent.stopPropagation(t),e||(this.dragging&&this.dragging._enabled||!this._map.dragging||!this._map.dragging.moved())&&this.fire(t.type,{originalEvent:t,latlng:this._latlng})},_onKeyPress:function(t){13===t.keyCode&&this.fire("click",{originalEvent:t,latlng:this._latlng})},_fireMouseEvent:function(t){this.fire(t.type,{originalEvent:t,latlng:this._latlng}),"contextmenu"===t.type&&this.hasEventListeners(t.type)&&o.DomEvent.preventDefault(t),"mousedown"!==t.type?o.DomEvent.stopPropagation(t):o.DomEvent.preventDefault(t)},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},_updateOpacity:function(){o.DomUtil.setOpacity(this._icon,this.options.opacity),this._shadow&&o.DomUtil.setOpacity(this._shadow,this.options.opacity)},_bringToFront:function(){this._updateZIndex(this.options.riseOffset)},_resetZIndex:function(){this._updateZIndex(0)}}),o.marker=function(t,e){return new o.Marker(t,e)},o.DivIcon=o.Icon.extend({options:{iconSize:[12,12],className:"leaflet-div-icon",html:!1},createIcon:function(t){var i=t&&"DIV"===t.tagName?t:e.createElement("div"),n=this.options;return n.html!==!1?i.innerHTML=n.html:i.innerHTML="",n.bgPos&&(i.style.backgroundPosition=-n.bgPos.x+"px "+-n.bgPos.y+"px"),this._setIconStyles(i,"icon"),i},createShadow:function(){return null}}),o.divIcon=function(t){return new o.DivIcon(t)},o.Map.mergeOptions({closePopupOnClick:!0}),o.Popup=o.Class.extend({includes:o.Mixin.Events,options:{minWidth:50,maxWidth:300,autoPan:!0,closeButton:!0,offset:[0,7],autoPanPadding:[5,5],keepInView:!1,className:"",zoomAnimation:!0},initialize:function(t,e){o.setOptions(this,t),this._source=e,this._animated=o.Browser.any3d&&this.options.zoomAnimation,this._isOpen=!1},onAdd:function(t){this._map=t,this._container||this._initLayout();var e=t.options.fadeAnimation;e&&o.DomUtil.setOpacity(this._container,0),t._panes.popupPane.appendChild(this._container),t.on(this._getEvents(),this),this.update(),e&&o.DomUtil.setOpacity(this._container,1),this.fire("open"),t.fire("popupopen",{popup:this}),this._source&&this._source.fire("popupopen",{popup:this})},addTo:function(t){return t.addLayer(this),this},openOn:function(t){return t.openPopup(this),this},onRemove:function(t){t._panes.popupPane.removeChild(this._container),o.Util.falseFn(this._container.offsetWidth),t.off(this._getEvents(),this),t.options.fadeAnimation&&o.DomUtil.setOpacity(this._container,0),this._map=null,this.fire("close"),t.fire("popupclose",{popup:this}),this._source&&this._source.fire("popupclose",{popup:this})},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this._map&&(this._updatePosition(),this._adjustPan()),this},getContent:function(){return this._content},setContent:function(t){return this._content=t,this.update(),this},update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updateLayout(),this._updatePosition(),this._container.style.visibility="",this._adjustPan())},_getEvents:function(){var t={viewreset:this._updatePosition};return this._animated&&(t.zoomanim=this._zoomAnimation),("closeOnClick"in this.options?this.options.closeOnClick:this._map.options.closePopupOnClick)&&(t.preclick=this._close),this.options.keepInView&&(t.moveend=this._adjustPan),t},_close:function(){this._map&&this._map.closePopup(this)},_initLayout:function(){var t,e="leaflet-popup",i=e+" "+this.options.className+" leaflet-zoom-"+(this._animated?"animated":"hide"),n=this._container=o.DomUtil.create("div",i);this.options.closeButton&&(t=this._closeButton=o.DomUtil.create("a",e+"-close-button",n),t.href="#close",t.innerHTML="×",o.DomEvent.disableClickPropagation(t),o.DomEvent.on(t,"click",this._onCloseButtonClick,this));var s=this._wrapper=o.DomUtil.create("div",e+"-content-wrapper",n);o.DomEvent.disableClickPropagation(s),this._contentNode=o.DomUtil.create("div",e+"-content",s),o.DomEvent.disableScrollPropagation(this._contentNode),o.DomEvent.on(s,"contextmenu",o.DomEvent.stopPropagation),this._tipContainer=o.DomUtil.create("div",e+"-tip-container",n),this._tip=o.DomUtil.create("div",e+"-tip",this._tipContainer)},_updateContent:function(){if(this._content){if("string"==typeof this._content)this._contentNode.innerHTML=this._content;else{for(;this._contentNode.hasChildNodes();)this._contentNode.removeChild(this._contentNode.firstChild);this._contentNode.appendChild(this._content)}this.fire("contentupdate")}},_updateLayout:function(){var t=this._contentNode,e=t.style;e.width="",e.whiteSpace="nowrap";var i=t.offsetWidth;i=Math.min(i,this.options.maxWidth),i=Math.max(i,this.options.minWidth),e.width=i+1+"px",e.whiteSpace="",e.height="";var n=t.offsetHeight,s=this.options.maxHeight,a="leaflet-popup-scrolled";s&&n>s?(e.height=s+"px",o.DomUtil.addClass(t,a)):o.DomUtil.removeClass(t,a),this._containerWidth=this._container.offsetWidth},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),e=this._animated,i=o.point(this.options.offset);e&&o.DomUtil.setPosition(this._container,t),this._containerBottom=-i.y-(e?0:t.y),this._containerLeft=-Math.round(this._containerWidth/2)+i.x+(e?0:t.x),this._container.style.bottom=this._containerBottom+"px",this._container.style.left=this._containerLeft+"px"}},_zoomAnimation:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);o.DomUtil.setPosition(this._container,e)},_adjustPan:function(){if(this.options.autoPan){var t=this._map,e=this._container.offsetHeight,i=this._containerWidth,n=new o.Point(this._containerLeft,-e-this._containerBottom);this._animated&&n._add(o.DomUtil.getPosition(this._container));var s=t.layerPointToContainerPoint(n),a=o.point(this.options.autoPanPadding),r=o.point(this.options.autoPanPaddingTopLeft||a),h=o.point(this.options.autoPanPaddingBottomRight||a),l=t.getSize(),u=0,c=0;s.x+i+h.x>l.x&&(u=s.x+i-l.x+h.x),s.x-u-r.x<0&&(u=s.x-r.x),s.y+e+h.y>l.y&&(c=s.y+e-l.y+h.y),s.y-c-r.y<0&&(c=s.y-r.y),(u||c)&&t.fire("autopanstart").panBy([u,c])}},_onCloseButtonClick:function(t){this._close(),o.DomEvent.stop(t)}}),o.popup=function(t,e){return new o.Popup(t,e)},o.Map.include({openPopup:function(t,e,i){if(this.closePopup(),!(t instanceof o.Popup)){var n=t;t=new o.Popup(i).setLatLng(e).setContent(n)}return t._isOpen=!0,this._popup=t,this.addLayer(t)},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&(this.removeLayer(t),t._isOpen=!1),this}}),o.Marker.include({openPopup:function(){return this._popup&&this._map&&!this._map.hasLayer(this._popup)&&(this._popup.setLatLng(this._latlng),this._map.openPopup(this._popup)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(){return this._popup&&(this._popup._isOpen?this.closePopup():this.openPopup()),this},bindPopup:function(t,e){var i=o.point(this.options.icon.options.popupAnchor||[0,0]);return i=i.add(o.Popup.prototype.options.offset),e&&e.offset&&(i=i.add(e.offset)),e=o.extend({offset:i},e),this._popupHandlersAdded||(this.on("click",this.togglePopup,this).on("remove",this.closePopup,this).on("move",this._movePopup,this),this._popupHandlersAdded=!0),t instanceof o.Popup?(o.setOptions(t,e),this._popup=t,t._source=this):this._popup=new o.Popup(e,this).setContent(t),this},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},unbindPopup:function(){return this._popup&&(this._popup=null,this.off("click",this.togglePopup,this).off("remove",this.closePopup,this).off("move",this._movePopup,this),this._popupHandlersAdded=!1),this},getPopup:function(){return this._popup},_movePopup:function(t){this._popup.setLatLng(t.latlng)}}),o.LayerGroup=o.Class.extend({initialize:function(t){this._layers={};var e,i;if(t)for(e=0,i=t.length;i>e;e++)this.addLayer(t[e])},addLayer:function(t){var e=this.getLayerId(t);return this._layers[e]=t,this._map&&this._map.addLayer(t),this},removeLayer:function(t){var e=t in this._layers?t:this.getLayerId(t);return this._map&&this._layers[e]&&this._map.removeLayer(this._layers[e]),delete this._layers[e],this},hasLayer:function(t){return t?t in this._layers||this.getLayerId(t)in this._layers:!1},clearLayers:function(){return this.eachLayer(this.removeLayer,this),this},invoke:function(t){var e,i,n=Array.prototype.slice.call(arguments,1);for(e in this._layers)i=this._layers[e],i[t]&&i[t].apply(i,n);return this},onAdd:function(t){this._map=t,this.eachLayer(t.addLayer,t)},onRemove:function(t){this.eachLayer(t.removeLayer,t),this._map=null},addTo:function(t){return t.addLayer(this),this},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},getLayer:function(t){return this._layers[t]},getLayers:function(){var t=[];for(var e in this._layers)t.push(this._layers[e]);return t},setZIndex:function(t){return this.invoke("setZIndex",t)},getLayerId:function(t){return o.stamp(t)}}),o.layerGroup=function(t){return new o.LayerGroup(t)},o.FeatureGroup=o.LayerGroup.extend({includes:o.Mixin.Events,statics:{EVENTS:"click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose"},addLayer:function(t){return this.hasLayer(t)?this:("on"in t&&t.on(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.addLayer.call(this,t),this._popupContent&&t.bindPopup&&t.bindPopup(this._popupContent,this._popupOptions),this.fire("layeradd",{layer:t}))},removeLayer:function(t){return this.hasLayer(t)?(t in this._layers&&(t=this._layers[t]),t.off(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.removeLayer.call(this,t),this._popupContent&&this.invoke("unbindPopup"),this.fire("layerremove",{layer:t})):this},bindPopup:function(t,e){return this._popupContent=t,this._popupOptions=e,this.invoke("bindPopup",t,e)},openPopup:function(t){for(var e in this._layers){this._layers[e].openPopup(t);break}return this},setStyle:function(t){return this.invoke("setStyle",t)},bringToFront:function(){return this.invoke("bringToFront")},bringToBack:function(){return this.invoke("bringToBack")},getBounds:function(){var t=new o.LatLngBounds;return this.eachLayer(function(e){t.extend(e instanceof o.Marker?e.getLatLng():e.getBounds())}),t},_propagateEvent:function(t){t=o.extend({layer:t.target,target:this},t),this.fire(t.type,t)}}),o.featureGroup=function(t){return new o.FeatureGroup(t)},o.Path=o.Class.extend({includes:[o.Mixin.Events],statics:{CLIP_PADDING:function(){var e=o.Browser.mobile?1280:2e3,i=(e/Math.max(t.outerWidth,t.outerHeight)-1)/2;return Math.max(0,Math.min(.5,i))}()},options:{stroke:!0,color:"#0033ff",dashArray:null,lineCap:null,lineJoin:null,weight:5,opacity:.5,fill:!1,fillColor:null,fillOpacity:.2,clickable:!0},initialize:function(t){o.setOptions(this,t)},onAdd:function(t){this._map=t,this._container||(this._initElements(),this._initEvents()),this.projectLatlngs(),this._updatePath(),this._container&&this._map._pathRoot.appendChild(this._container),this.fire("add"),t.on({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){t._pathRoot.removeChild(this._container),this.fire("remove"),this._map=null,o.Browser.vml&&(this._container=null,this._stroke=null,this._fill=null),t.off({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},projectLatlngs:function(){},setStyle:function(t){return o.setOptions(this,t),this._container&&this._updateStyle(),this},redraw:function(){return this._map&&(this.projectLatlngs(),this._updatePath()),this}}),o.Map.include({_updatePathViewport:function(){var t=o.Path.CLIP_PADDING,e=this.getSize(),i=o.DomUtil.getPosition(this._mapPane),n=i.multiplyBy(-1)._subtract(e.multiplyBy(t)._round()),s=n.add(e.multiplyBy(1+2*t)._round());this._pathViewport=new o.Bounds(n,s)}}),o.Path.SVG_NS="http://www.w3.org/2000/svg",o.Browser.svg=!(!e.createElementNS||!e.createElementNS(o.Path.SVG_NS,"svg").createSVGRect),o.Path=o.Path.extend({statics:{SVG:o.Browser.svg},bringToFront:function(){var t=this._map._pathRoot,e=this._container;return e&&t.lastChild!==e&&t.appendChild(e),this},bringToBack:function(){var t=this._map._pathRoot,e=this._container,i=t.firstChild;return e&&i!==e&&t.insertBefore(e,i),this},getPathString:function(){},_createElement:function(t){return e.createElementNS(o.Path.SVG_NS,t)},_initElements:function(){this._map._initPathRoot(),this._initPath(),this._initStyle()},_initPath:function(){this._container=this._createElement("g"),this._path=this._createElement("path"),this.options.className&&o.DomUtil.addClass(this._path,this.options.className),this._container.appendChild(this._path)},_initStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke-linejoin","round"),this._path.setAttribute("stroke-linecap","round")),this.options.fill&&this._path.setAttribute("fill-rule","evenodd"),this.options.pointerEvents&&this._path.setAttribute("pointer-events",this.options.pointerEvents),this.options.clickable||this.options.pointerEvents||this._path.setAttribute("pointer-events","none"),this._updateStyle()},_updateStyle:function(){this.options.stroke?(this._path.setAttribute("stroke",this.options.color),this._path.setAttribute("stroke-opacity",this.options.opacity),this._path.setAttribute("stroke-width",this.options.weight),this.options.dashArray?this._path.setAttribute("stroke-dasharray",this.options.dashArray):this._path.removeAttribute("stroke-dasharray"),this.options.lineCap&&this._path.setAttribute("stroke-linecap",this.options.lineCap),this.options.lineJoin&&this._path.setAttribute("stroke-linejoin",this.options.lineJoin)):this._path.setAttribute("stroke","none"),this.options.fill?(this._path.setAttribute("fill",this.options.fillColor||this.options.color),this._path.setAttribute("fill-opacity",this.options.fillOpacity)):this._path.setAttribute("fill","none")},_updatePath:function(){var t=this.getPathString();t||(t="M0 0"),this._path.setAttribute("d",t)},_initEvents:function(){if(this.options.clickable){(o.Browser.svg||!o.Browser.vml)&&o.DomUtil.addClass(this._path,"leaflet-clickable"),o.DomEvent.on(this._container,"click",this._onMouseClick,this);for(var t=["dblclick","mousedown","mouseover","mouseout","mousemove","contextmenu"],e=0;e<t.length;e++)o.DomEvent.on(this._container,t[e],this._fireMouseEvent,this)}},_onMouseClick:function(t){this._map.dragging&&this._map.dragging.moved()||this._fireMouseEvent(t)},_fireMouseEvent:function(t){if(this.hasEventListeners(t.type)){var e=this._map,i=e.mouseEventToContainerPoint(t),n=e.containerPointToLayerPoint(i),s=e.layerPointToLatLng(n);this.fire(t.type,{latlng:s,layerPoint:n,containerPoint:i,originalEvent:t}),"contextmenu"===t.type&&o.DomEvent.preventDefault(t),"mousemove"!==t.type&&o.DomEvent.stopPropagation(t)}}}),o.Map.include({_initPathRoot:function(){this._pathRoot||(this._pathRoot=o.Path.prototype._createElement("svg"),this._panes.overlayPane.appendChild(this._pathRoot),this.options.zoomAnimation&&o.Browser.any3d?(o.DomUtil.addClass(this._pathRoot,"leaflet-zoom-animated"), | |
this.on({zoomanim:this._animatePathZoom,zoomend:this._endPathZoom})):o.DomUtil.addClass(this._pathRoot,"leaflet-zoom-hide"),this.on("moveend",this._updateSvgViewport),this._updateSvgViewport())},_animatePathZoom:function(t){var e=this.getZoomScale(t.zoom),i=this._getCenterOffset(t.center)._multiplyBy(-e)._add(this._pathViewport.min);this._pathRoot.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(i)+" scale("+e+") ",this._pathZooming=!0},_endPathZoom:function(){this._pathZooming=!1},_updateSvgViewport:function(){if(!this._pathZooming){this._updatePathViewport();var t=this._pathViewport,e=t.min,i=t.max,n=i.x-e.x,s=i.y-e.y,a=this._pathRoot,r=this._panes.overlayPane;o.Browser.mobileWebkit&&r.removeChild(a),o.DomUtil.setPosition(a,e),a.setAttribute("width",n),a.setAttribute("height",s),a.setAttribute("viewBox",[e.x,e.y,n,s].join(" ")),o.Browser.mobileWebkit&&r.appendChild(a)}}}),o.Path.include({bindPopup:function(t,e){return t instanceof o.Popup?this._popup=t:((!this._popup||e)&&(this._popup=new o.Popup(e,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on("click",this._openPopup,this).on("remove",this.closePopup,this),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this._popup=null,this.off("click",this._openPopup).off("remove",this.closePopup),this._popupHandlersAdded=!1),this},openPopup:function(t){return this._popup&&(t=t||this._latlng||this._latlngs[Math.floor(this._latlngs.length/2)],this._openPopup({latlng:t})),this},closePopup:function(){return this._popup&&this._popup._close(),this},_openPopup:function(t){this._popup.setLatLng(t.latlng),this._map.openPopup(this._popup)}}),o.Browser.vml=!o.Browser.svg&&function(){try{var t=e.createElement("div");t.innerHTML='<v:shape adj="1"/>';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(n){return!1}}(),o.Path=o.Browser.svg||!o.Browser.vml?o.Path:o.Path.extend({statics:{VML:!0,CLIP_PADDING:.02},_createElement:function(){try{return e.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return e.createElement("<lvml:"+t+' class="lvml">')}}catch(t){return function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),_initPath:function(){var t=this._container=this._createElement("shape");o.DomUtil.addClass(t,"leaflet-vml-shape"+(this.options.className?" "+this.options.className:"")),this.options.clickable&&o.DomUtil.addClass(t,"leaflet-clickable"),t.coordsize="1 1",this._path=this._createElement("path"),t.appendChild(this._path),this._map._pathRoot.appendChild(t)},_initStyle:function(){this._updateStyle()},_updateStyle:function(){var t=this._stroke,e=this._fill,i=this.options,n=this._container;n.stroked=i.stroke,n.filled=i.fill,i.stroke?(t||(t=this._stroke=this._createElement("stroke"),t.endcap="round",n.appendChild(t)),t.weight=i.weight+"px",t.color=i.color,t.opacity=i.opacity,i.dashArray?t.dashStyle=o.Util.isArray(i.dashArray)?i.dashArray.join(" "):i.dashArray.replace(/( *, *)/g," "):t.dashStyle="",i.lineCap&&(t.endcap=i.lineCap.replace("butt","flat")),i.lineJoin&&(t.joinstyle=i.lineJoin)):t&&(n.removeChild(t),this._stroke=null),i.fill?(e||(e=this._fill=this._createElement("fill"),n.appendChild(e)),e.color=i.fillColor||i.color,e.opacity=i.fillOpacity):e&&(n.removeChild(e),this._fill=null)},_updatePath:function(){var t=this._container.style;t.display="none",this._path.v=this.getPathString()+" ",t.display=""}}),o.Map.include(o.Browser.svg||!o.Browser.vml?{}:{_initPathRoot:function(){if(!this._pathRoot){var t=this._pathRoot=e.createElement("div");t.className="leaflet-vml-container",this._panes.overlayPane.appendChild(t),this.on("moveend",this._updatePathViewport),this._updatePathViewport()}}}),o.Browser.canvas=function(){return!!e.createElement("canvas").getContext}(),o.Path=o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?o.Path:o.Path.extend({statics:{CANVAS:!0,SVG:!1},redraw:function(){return this._map&&(this.projectLatlngs(),this._requestUpdate()),this},setStyle:function(t){return o.setOptions(this,t),this._map&&(this._updateStyle(),this._requestUpdate()),this},onRemove:function(t){t.off("viewreset",this.projectLatlngs,this).off("moveend",this._updatePath,this),this.options.clickable&&(this._map.off("click",this._onClick,this),this._map.off("mousemove",this._onMouseMove,this)),this._requestUpdate(),this.fire("remove"),this._map=null},_requestUpdate:function(){this._map&&!o.Path._updateRequest&&(o.Path._updateRequest=o.Util.requestAnimFrame(this._fireMapMoveEnd,this._map))},_fireMapMoveEnd:function(){o.Path._updateRequest=null,this.fire("moveend")},_initElements:function(){this._map._initPathRoot(),this._ctx=this._map._canvasCtx},_updateStyle:function(){var t=this.options;t.stroke&&(this._ctx.lineWidth=t.weight,this._ctx.strokeStyle=t.color),t.fill&&(this._ctx.fillStyle=t.fillColor||t.color),t.lineCap&&(this._ctx.lineCap=t.lineCap),t.lineJoin&&(this._ctx.lineJoin=t.lineJoin)},_drawPath:function(){var t,e,i,n,s,a;for(this._ctx.beginPath(),t=0,i=this._parts.length;i>t;t++){for(e=0,n=this._parts[t].length;n>e;e++)s=this._parts[t][e],a=(0===e?"move":"line")+"To",this._ctx[a](s.x,s.y);this instanceof o.Polygon&&this._ctx.closePath()}},_checkIfEmpty:function(){return!this._parts.length},_updatePath:function(){if(!this._checkIfEmpty()){var t=this._ctx,e=this.options;this._drawPath(),t.save(),this._updateStyle(),e.fill&&(t.globalAlpha=e.fillOpacity,t.fill(e.fillRule||"evenodd")),e.stroke&&(t.globalAlpha=e.opacity,t.stroke()),t.restore()}},_initEvents:function(){this.options.clickable&&(this._map.on("mousemove",this._onMouseMove,this),this._map.on("click dblclick contextmenu",this._fireMouseEvent,this))},_fireMouseEvent:function(t){this._containsPoint(t.layerPoint)&&this.fire(t.type,t)},_onMouseMove:function(t){this._map&&!this._map._animatingZoom&&(this._containsPoint(t.layerPoint)?(this._ctx.canvas.style.cursor="pointer",this._mouseInside=!0,this.fire("mouseover",t)):this._mouseInside&&(this._ctx.canvas.style.cursor="",this._mouseInside=!1,this.fire("mouseout",t)))}}),o.Map.include(o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?{}:{_initPathRoot:function(){var t,i=this._pathRoot;i||(i=this._pathRoot=e.createElement("canvas"),i.style.position="absolute",t=this._canvasCtx=i.getContext("2d"),t.lineCap="round",t.lineJoin="round",this._panes.overlayPane.appendChild(i),this.options.zoomAnimation&&(this._pathRoot.className="leaflet-zoom-animated",this.on("zoomanim",this._animatePathZoom),this.on("zoomend",this._endPathZoom)),this.on("moveend",this._updateCanvasViewport),this._updateCanvasViewport())},_updateCanvasViewport:function(){if(!this._pathZooming){this._updatePathViewport();var t=this._pathViewport,e=t.min,i=t.max.subtract(e),n=this._pathRoot;o.DomUtil.setPosition(n,e),n.width=i.x,n.height=i.y,n.getContext("2d").translate(-e.x,-e.y)}}}),o.LineUtil={simplify:function(t,e){if(!e||!t.length)return t.slice();var i=e*e;return t=this._reducePoints(t,i),t=this._simplifyDP(t,i)},pointToSegmentDistance:function(t,e,i){return Math.sqrt(this._sqClosestPointOnSegment(t,e,i,!0))},closestPointOnSegment:function(t,e,i){return this._sqClosestPointOnSegment(t,e,i)},_simplifyDP:function(t,e){var n=t.length,o=typeof Uint8Array!=i+""?Uint8Array:Array,s=new o(n);s[0]=s[n-1]=1,this._simplifyDPStep(t,s,e,0,n-1);var a,r=[];for(a=0;n>a;a++)s[a]&&r.push(t[a]);return r},_simplifyDPStep:function(t,e,i,n,o){var s,a,r,h=0;for(a=n+1;o-1>=a;a++)r=this._sqClosestPointOnSegment(t[a],t[n],t[o],!0),r>h&&(s=a,h=r);h>i&&(e[s]=1,this._simplifyDPStep(t,e,i,n,s),this._simplifyDPStep(t,e,i,s,o))},_reducePoints:function(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;s>n;n++)this._sqDist(t[n],t[o])>e&&(i.push(t[n]),o=n);return s-1>o&&i.push(t[s-1]),i},clipSegment:function(t,e,i,n){var o,s,a,r=n?this._lastCode:this._getBitCode(t,i),h=this._getBitCode(e,i);for(this._lastCode=h;;){if(!(r|h))return[t,e];if(r&h)return!1;o=r||h,s=this._getEdgeIntersection(t,e,o,i),a=this._getBitCode(s,i),o===r?(t=s,r=a):(e=s,h=a)}},_getEdgeIntersection:function(t,e,i,n){var s=e.x-t.x,a=e.y-t.y,r=n.min,h=n.max;return 8&i?new o.Point(t.x+s*(h.y-t.y)/a,h.y):4&i?new o.Point(t.x+s*(r.y-t.y)/a,r.y):2&i?new o.Point(h.x,t.y+a*(h.x-t.x)/s):1&i?new o.Point(r.x,t.y+a*(r.x-t.x)/s):void 0},_getBitCode:function(t,e){var i=0;return t.x<e.min.x?i|=1:t.x>e.max.x&&(i|=2),t.y<e.min.y?i|=4:t.y>e.max.y&&(i|=8),i},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},_sqClosestPointOnSegment:function(t,e,i,n){var s,a=e.x,r=e.y,h=i.x-a,l=i.y-r,u=h*h+l*l;return u>0&&(s=((t.x-a)*h+(t.y-r)*l)/u,s>1?(a=i.x,r=i.y):s>0&&(a+=h*s,r+=l*s)),h=t.x-a,l=t.y-r,n?h*h+l*l:new o.Point(a,r)}},o.Polyline=o.Path.extend({initialize:function(t,e){o.Path.prototype.initialize.call(this,e),this._latlngs=this._convertLatLngs(t)},options:{smoothFactor:1,noClip:!1},projectLatlngs:function(){this._originalPoints=[];for(var t=0,e=this._latlngs.length;e>t;t++)this._originalPoints[t]=this._map.latLngToLayerPoint(this._latlngs[t])},getPathString:function(){for(var t=0,e=this._parts.length,i="";e>t;t++)i+=this._getPathPartStr(this._parts[t]);return i},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._latlngs=this._convertLatLngs(t),this.redraw()},addLatLng:function(t){return this._latlngs.push(o.latLng(t)),this.redraw()},spliceLatLngs:function(){var t=[].splice.apply(this._latlngs,arguments);return this._convertLatLngs(this._latlngs,!0),this.redraw(),t},closestLayerPoint:function(t){for(var e,i,n=1/0,s=this._parts,a=null,r=0,h=s.length;h>r;r++)for(var l=s[r],u=1,c=l.length;c>u;u++){e=l[u-1],i=l[u];var d=o.LineUtil._sqClosestPointOnSegment(t,e,i,!0);n>d&&(n=d,a=o.LineUtil._sqClosestPointOnSegment(t,e,i))}return a&&(a.distance=Math.sqrt(n)),a},getBounds:function(){return new o.LatLngBounds(this.getLatLngs())},_convertLatLngs:function(t,e){var i,n,s=e?t:[];for(i=0,n=t.length;n>i;i++){if(o.Util.isArray(t[i])&&"number"!=typeof t[i][0])return;s[i]=o.latLng(t[i])}return s},_initEvents:function(){o.Path.prototype._initEvents.call(this)},_getPathPartStr:function(t){for(var e,i=o.Path.VML,n=0,s=t.length,a="";s>n;n++)e=t[n],i&&e._round(),a+=(n?"L":"M")+e.x+" "+e.y;return a},_clipPoints:function(){var t,e,i,n=this._originalPoints,s=n.length;if(this.options.noClip)return void(this._parts=[n]);this._parts=[];var a=this._parts,r=this._map._pathViewport,h=o.LineUtil;for(t=0,e=0;s-1>t;t++)i=h.clipSegment(n[t],n[t+1],r,t),i&&(a[e]=a[e]||[],a[e].push(i[0]),(i[1]!==n[t+1]||t===s-2)&&(a[e].push(i[1]),e++))},_simplifyPoints:function(){for(var t=this._parts,e=o.LineUtil,i=0,n=t.length;n>i;i++)t[i]=e.simplify(t[i],this.options.smoothFactor)},_updatePath:function(){this._map&&(this._clipPoints(),this._simplifyPoints(),o.Path.prototype._updatePath.call(this))}}),o.polyline=function(t,e){return new o.Polyline(t,e)},o.PolyUtil={},o.PolyUtil.clipPolygon=function(t,e){var i,n,s,a,r,h,l,u,c,d=[1,4,2,8],p=o.LineUtil;for(n=0,l=t.length;l>n;n++)t[n]._code=p._getBitCode(t[n],e);for(a=0;4>a;a++){for(u=d[a],i=[],n=0,l=t.length,s=l-1;l>n;s=n++)r=t[n],h=t[s],r._code&u?h._code&u||(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)):(h._code&u&&(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)),i.push(r));t=i}return t},o.Polygon=o.Polyline.extend({options:{fill:!0},initialize:function(t,e){o.Polyline.prototype.initialize.call(this,t,e),this._initWithHoles(t)},_initWithHoles:function(t){var e,i,n;if(t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0])for(this._latlngs=this._convertLatLngs(t[0]),this._holes=t.slice(1),e=0,i=this._holes.length;i>e;e++)n=this._holes[e]=this._convertLatLngs(this._holes[e]),n[0].equals(n[n.length-1])&&n.pop();t=this._latlngs,t.length>=2&&t[0].equals(t[t.length-1])&&t.pop()},projectLatlngs:function(){if(o.Polyline.prototype.projectLatlngs.call(this),this._holePoints=[],this._holes){var t,e,i,n;for(t=0,i=this._holes.length;i>t;t++)for(this._holePoints[t]=[],e=0,n=this._holes[t].length;n>e;e++)this._holePoints[t][e]=this._map.latLngToLayerPoint(this._holes[t][e])}},setLatLngs:function(t){return t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0]?(this._initWithHoles(t),this.redraw()):o.Polyline.prototype.setLatLngs.call(this,t)},_clipPoints:function(){var t=this._originalPoints,e=[];if(this._parts=[t].concat(this._holePoints),!this.options.noClip){for(var i=0,n=this._parts.length;n>i;i++){var s=o.PolyUtil.clipPolygon(this._parts[i],this._map._pathViewport);s.length&&e.push(s)}this._parts=e}},_getPathPartStr:function(t){var e=o.Polyline.prototype._getPathPartStr.call(this,t);return e+(o.Browser.svg?"z":"x")}}),o.polygon=function(t,e){return new o.Polygon(t,e)},function(){function t(t){return o.FeatureGroup.extend({initialize:function(t,e){this._layers={},this._options=e,this.setLatLngs(t)},setLatLngs:function(e){var i=0,n=e.length;for(this.eachLayer(function(t){n>i?t.setLatLngs(e[i++]):this.removeLayer(t)},this);n>i;)this.addLayer(new t(e[i++],this._options));return this},getLatLngs:function(){var t=[];return this.eachLayer(function(e){t.push(e.getLatLngs())}),t}})}o.MultiPolyline=t(o.Polyline),o.MultiPolygon=t(o.Polygon),o.multiPolyline=function(t,e){return new o.MultiPolyline(t,e)},o.multiPolygon=function(t,e){return new o.MultiPolygon(t,e)}}(),o.Rectangle=o.Polygon.extend({initialize:function(t,e){o.Polygon.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=o.latLngBounds(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}}),o.rectangle=function(t,e){return new o.Rectangle(t,e)},o.Circle=o.Path.extend({initialize:function(t,e,i){o.Path.prototype.initialize.call(this,i),this._latlng=o.latLng(t),this._mRadius=e},options:{fill:!0},setLatLng:function(t){return this._latlng=o.latLng(t),this.redraw()},setRadius:function(t){return this._mRadius=t,this.redraw()},projectLatlngs:function(){var t=this._getLngRadius(),e=this._latlng,i=this._map.latLngToLayerPoint([e.lat,e.lng-t]);this._point=this._map.latLngToLayerPoint(e),this._radius=Math.max(this._point.x-i.x,1)},getBounds:function(){var t=this._getLngRadius(),e=this._mRadius/40075017*360,i=this._latlng;return new o.LatLngBounds([i.lat-e,i.lng-t],[i.lat+e,i.lng+t])},getLatLng:function(){return this._latlng},getPathString:function(){var t=this._point,e=this._radius;return this._checkIfEmpty()?"":o.Browser.svg?"M"+t.x+","+(t.y-e)+"A"+e+","+e+",0,1,1,"+(t.x-.1)+","+(t.y-e)+" z":(t._round(),e=Math.round(e),"AL "+t.x+","+t.y+" "+e+","+e+" 0,23592600")},getRadius:function(){return this._mRadius},_getLatRadius:function(){return this._mRadius/40075017*360},_getLngRadius:function(){return this._getLatRadius()/Math.cos(o.LatLng.DEG_TO_RAD*this._latlng.lat)},_checkIfEmpty:function(){if(!this._map)return!1;var t=this._map._pathViewport,e=this._radius,i=this._point;return i.x-e>t.max.x||i.y-e>t.max.y||i.x+e<t.min.x||i.y+e<t.min.y}}),o.circle=function(t,e,i){return new o.Circle(t,e,i)},o.CircleMarker=o.Circle.extend({options:{radius:10,weight:2},initialize:function(t,e){o.Circle.prototype.initialize.call(this,t,null,e),this._radius=this.options.radius},projectLatlngs:function(){this._point=this._map.latLngToLayerPoint(this._latlng)},_updateStyle:function(){o.Circle.prototype._updateStyle.call(this),this.setRadius(this.options.radius)},setLatLng:function(t){return o.Circle.prototype.setLatLng.call(this,t),this._popup&&this._popup._isOpen&&this._popup.setLatLng(t),this},setRadius:function(t){return this.options.radius=this._radius=t,this.redraw()},getRadius:function(){return this._radius}}),o.circleMarker=function(t,e){return new o.CircleMarker(t,e)},o.Polyline.include(o.Path.CANVAS?{_containsPoint:function(t,e){var i,n,s,a,r,h,l,u=this.options.weight/2;for(o.Browser.touch&&(u+=10),i=0,a=this._parts.length;a>i;i++)for(l=this._parts[i],n=0,r=l.length,s=r-1;r>n;s=n++)if((e||0!==n)&&(h=o.LineUtil.pointToSegmentDistance(t,l[s],l[n]),u>=h))return!0;return!1}}:{}),o.Polygon.include(o.Path.CANVAS?{_containsPoint:function(t){var e,i,n,s,a,r,h,l,u=!1;if(o.Polyline.prototype._containsPoint.call(this,t,!0))return!0;for(s=0,h=this._parts.length;h>s;s++)for(e=this._parts[s],a=0,l=e.length,r=l-1;l>a;r=a++)i=e[a],n=e[r],i.y>t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(u=!u);return u}}:{}),o.Circle.include(o.Path.CANVAS?{_drawPath:function(){var t=this._point;this._ctx.beginPath(),this._ctx.arc(t.x,t.y,this._radius,0,2*Math.PI,!1)},_containsPoint:function(t){var e=this._point,i=this.options.stroke?this.options.weight/2:0;return t.distanceTo(e)<=this._radius+i}}:{}),o.CircleMarker.include(o.Path.CANVAS?{_updateStyle:function(){o.Path.prototype._updateStyle.call(this)}}:{}),o.GeoJSON=o.FeatureGroup.extend({initialize:function(t,e){o.setOptions(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,s=o.Util.isArray(t)?t:t.features;if(s){for(e=0,i=s.length;i>e;e++)n=s[e],(n.geometries||n.geometry||n.features||n.coordinates)&&this.addData(s[e]);return this}var a=this.options;if(!a.filter||a.filter(t)){var r=o.GeoJSON.geometryToLayer(t,a.pointToLayer,a.coordsToLatLng,a);return r.feature=o.GeoJSON.asFeature(t),r.defaultOptions=r.options,this.resetStyle(r),a.onEachFeature&&a.onEachFeature(t,r),this.addLayer(r)}},resetStyle:function(t){var e=this.options.style;e&&(o.Util.extend(t.options,t.defaultOptions),this._setLayerStyle(t,e))},setStyle:function(t){this.eachLayer(function(e){this._setLayerStyle(e,t)},this)},_setLayerStyle:function(t,e){"function"==typeof e&&(e=e(t.feature)),t.setStyle&&t.setStyle(e)}}),o.extend(o.GeoJSON,{geometryToLayer:function(t,e,i,n){var s,a,r,h,l="Feature"===t.type?t.geometry:t,u=l.coordinates,c=[];switch(i=i||this.coordsToLatLng,l.type){case"Point":return s=i(u),e?e(t,s):new o.Marker(s);case"MultiPoint":for(r=0,h=u.length;h>r;r++)s=i(u[r]),c.push(e?e(t,s):new o.Marker(s));return new o.FeatureGroup(c);case"LineString":return a=this.coordsToLatLngs(u,0,i),new o.Polyline(a,n);case"Polygon":if(2===u.length&&!u[1].length)throw new Error("Invalid GeoJSON object.");return a=this.coordsToLatLngs(u,1,i),new o.Polygon(a,n);case"MultiLineString":return a=this.coordsToLatLngs(u,1,i),new o.MultiPolyline(a,n);case"MultiPolygon":return a=this.coordsToLatLngs(u,2,i),new o.MultiPolygon(a,n);case"GeometryCollection":for(r=0,h=l.geometries.length;h>r;r++)c.push(this.geometryToLayer({geometry:l.geometries[r],type:"Feature",properties:t.properties},e,i,n));return new o.FeatureGroup(c);default:throw new Error("Invalid GeoJSON object.")}},coordsToLatLng:function(t){return new o.LatLng(t[1],t[0],t[2])},coordsToLatLngs:function(t,e,i){var n,o,s,a=[];for(o=0,s=t.length;s>o;o++)n=e?this.coordsToLatLngs(t[o],e-1,i):(i||this.coordsToLatLng)(t[o]),a.push(n);return a},latLngToCoords:function(t){var e=[t.lng,t.lat];return t.alt!==i&&e.push(t.alt),e},latLngsToCoords:function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(o.GeoJSON.latLngToCoords(t[i]));return e},getFeature:function(t,e){return t.feature?o.extend({},t.feature,{geometry:e}):o.GeoJSON.asFeature(e)},asFeature:function(t){return"Feature"===t.type?t:{type:"Feature",properties:{},geometry:t}}});var a={toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"Point",coordinates:o.GeoJSON.latLngToCoords(this.getLatLng())})}};o.Marker.include(a),o.Circle.include(a),o.CircleMarker.include(a),o.Polyline.include({toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"LineString",coordinates:o.GeoJSON.latLngsToCoords(this.getLatLngs())})}}),o.Polygon.include({toGeoJSON:function(){var t,e,i,n=[o.GeoJSON.latLngsToCoords(this.getLatLngs())];if(n[0].push(n[0][0]),this._holes)for(t=0,e=this._holes.length;e>t;t++)i=o.GeoJSON.latLngsToCoords(this._holes[t]),i.push(i[0]),n.push(i);return o.GeoJSON.getFeature(this,{type:"Polygon",coordinates:n})}}),function(){function t(t){return function(){var e=[];return this.eachLayer(function(t){e.push(t.toGeoJSON().geometry.coordinates)}),o.GeoJSON.getFeature(this,{type:t,coordinates:e})}}o.MultiPolyline.include({toGeoJSON:t("MultiLineString")}),o.MultiPolygon.include({toGeoJSON:t("MultiPolygon")}),o.LayerGroup.include({toGeoJSON:function(){var e,i=this.feature&&this.feature.geometry,n=[];if(i&&"MultiPoint"===i.type)return t("MultiPoint").call(this);var s=i&&"GeometryCollection"===i.type;return this.eachLayer(function(t){t.toGeoJSON&&(e=t.toGeoJSON(),n.push(s?e.geometry:o.GeoJSON.asFeature(e)))}),s?o.GeoJSON.getFeature(this,{geometries:n,type:"GeometryCollection"}):{type:"FeatureCollection",features:n}}})}(),o.geoJson=function(t,e){return new o.GeoJSON(t,e)},o.DomEvent={addListener:function(t,e,i,n){var s,a,r,h=o.stamp(i),l="_leaflet_"+e+h;return t[l]?this:(s=function(e){return i.call(n||t,e||o.DomEvent._getEvent())},o.Browser.pointer&&0===e.indexOf("touch")?this.addPointerListener(t,e,s,h):(o.Browser.touch&&"dblclick"===e&&this.addDoubleTapListener&&this.addDoubleTapListener(t,s,h),"addEventListener"in t?"mousewheel"===e?(t.addEventListener("DOMMouseScroll",s,!1),t.addEventListener(e,s,!1)):"mouseenter"===e||"mouseleave"===e?(a=s,r="mouseenter"===e?"mouseover":"mouseout",s=function(e){return o.DomEvent._checkMouse(t,e)?a(e):void 0},t.addEventListener(r,s,!1)):"click"===e&&o.Browser.android?(a=s,s=function(t){return o.DomEvent._filterClick(t,a)},t.addEventListener(e,s,!1)):t.addEventListener(e,s,!1):"attachEvent"in t&&t.attachEvent("on"+e,s),t[l]=s,this))},removeListener:function(t,e,i){var n=o.stamp(i),s="_leaflet_"+e+n,a=t[s];return a?(o.Browser.pointer&&0===e.indexOf("touch")?this.removePointerListener(t,e,n):o.Browser.touch&&"dblclick"===e&&this.removeDoubleTapListener?this.removeDoubleTapListener(t,n):"removeEventListener"in t?"mousewheel"===e?(t.removeEventListener("DOMMouseScroll",a,!1),t.removeEventListener(e,a,!1)):"mouseenter"===e||"mouseleave"===e?t.removeEventListener("mouseenter"===e?"mouseover":"mouseout",a,!1):t.removeEventListener(e,a,!1):"detachEvent"in t&&t.detachEvent("on"+e,a),t[s]=null,this):this},stopPropagation:function(t){return t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,o.DomEvent._skipped(t),this},disableScrollPropagation:function(t){var e=o.DomEvent.stopPropagation;return o.DomEvent.on(t,"mousewheel",e).on(t,"MozMousePixelScroll",e)},disableClickPropagation:function(t){for(var e=o.DomEvent.stopPropagation,i=o.Draggable.START.length-1;i>=0;i--)o.DomEvent.on(t,o.Draggable.START[i],e);return o.DomEvent.on(t,"click",o.DomEvent._fakeStop).on(t,"dblclick",e)},preventDefault:function(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,this},stop:function(t){return o.DomEvent.preventDefault(t).stopPropagation(t)},getMousePosition:function(t,e){if(!e)return new o.Point(t.clientX,t.clientY);var i=e.getBoundingClientRect();return new o.Point(t.clientX-i.left-e.clientLeft,t.clientY-i.top-e.clientTop)},getWheelDelta:function(t){var e=0;return t.wheelDelta&&(e=t.wheelDelta/120),t.detail&&(e=-t.detail/3),e},_skipEvents:{},_fakeStop:function(t){o.DomEvent._skipEvents[t.type]=!0},_skipped:function(t){var e=this._skipEvents[t.type];return this._skipEvents[t.type]=!1,e},_checkMouse:function(t,e){var i=e.relatedTarget;if(!i)return!0;try{for(;i&&i!==t;)i=i.parentNode}catch(n){return!1}return i!==t},_getEvent:function(){var e=t.event;if(!e)for(var i=arguments.callee.caller;i&&(e=i.arguments[0],!e||t.Event!==e.constructor);)i=i.caller;return e},_filterClick:function(t,e){var i=t.timeStamp||t.originalEvent.timeStamp,n=o.DomEvent._lastClick&&i-o.DomEvent._lastClick;return n&&n>100&&500>n||t.target._simulatedClick&&!t._simulated?void o.DomEvent.stop(t):(o.DomEvent._lastClick=i,e(t))}},o.DomEvent.on=o.DomEvent.addListener,o.DomEvent.off=o.DomEvent.removeListener,o.Draggable=o.Class.extend({includes:o.Mixin.Events,statics:{START:o.Browser.touch?["touchstart","mousedown"]:["mousedown"],END:{mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},MOVE:{mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"}},initialize:function(t,e){this._element=t,this._dragStartTarget=e||t},enable:function(){if(!this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.on(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!0}},disable:function(){if(this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.off(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!1,this._moved=!1}},_onDown:function(t){if(this._moved=!1,!(t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(o.DomEvent.stopPropagation(t),o.Draggable._disabled||(o.DomUtil.disableImageDrag(),o.DomUtil.disableTextSelection(),this._moving)))){var i=t.touches?t.touches[0]:t;this._startPoint=new o.Point(i.clientX,i.clientY),this._startPos=this._newPos=o.DomUtil.getPosition(this._element),o.DomEvent.on(e,o.Draggable.MOVE[t.type],this._onMove,this).on(e,o.Draggable.END[t.type],this._onUp,this)}},_onMove:function(t){if(t.touches&&t.touches.length>1)return void(this._moved=!0);var i=t.touches&&1===t.touches.length?t.touches[0]:t,n=new o.Point(i.clientX,i.clientY),s=n.subtract(this._startPoint);(s.x||s.y)&&(o.Browser.touch&&Math.abs(s.x)+Math.abs(s.y)<3||(o.DomEvent.preventDefault(t),this._moved||(this.fire("dragstart"),this._moved=!0,this._startPos=o.DomUtil.getPosition(this._element).subtract(s),o.DomUtil.addClass(e.body,"leaflet-dragging"),this._lastTarget=t.target||t.srcElement,o.DomUtil.addClass(this._lastTarget,"leaflet-drag-target")),this._newPos=this._startPos.add(s),this._moving=!0,o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updatePosition,this,!0,this._dragStartTarget)))},_updatePosition:function(){this.fire("predrag"),o.DomUtil.setPosition(this._element,this._newPos),this.fire("drag")},_onUp:function(){o.DomUtil.removeClass(e.body,"leaflet-dragging"),this._lastTarget&&(o.DomUtil.removeClass(this._lastTarget,"leaflet-drag-target"),this._lastTarget=null);for(var t in o.Draggable.MOVE)o.DomEvent.off(e,o.Draggable.MOVE[t],this._onMove).off(e,o.Draggable.END[t],this._onUp);o.DomUtil.enableImageDrag(),o.DomUtil.enableTextSelection(),this._moved&&this._moving&&(o.Util.cancelAnimFrame(this._animRequest),this.fire("dragend",{distance:this._newPos.distanceTo(this._startPos)})),this._moving=!1}}),o.Handler=o.Class.extend({initialize:function(t){this._map=t},enable:function(){this._enabled||(this._enabled=!0,this.addHooks())},disable:function(){this._enabled&&(this._enabled=!1,this.removeHooks())},enabled:function(){return!!this._enabled}}),o.Map.mergeOptions({dragging:!0,inertia:!o.Browser.android23,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,inertiaThreshold:o.Browser.touch?32:18,easeLinearity:.25,worldCopyJump:!1}),o.Map.Drag=o.Handler.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new o.Draggable(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDrag,this),t.on("viewreset",this._onViewReset,this),t.whenReady(this._onViewReset,this))}this._draggable.enable()},removeHooks:function(){this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){var t=this._map;t._panAnim&&t._panAnim.stop(),t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(){if(this._map.options.inertia){var t=this._lastTime=+new Date,e=this._lastPos=this._draggable._newPos;this._positions.push(e),this._times.push(t),t-this._times[0]>200&&(this._positions.shift(),this._times.shift())}this._map.fire("move").fire("drag")},_onViewReset:function(){var t=this._map.getSize()._divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.project([0,180]).x},_onPreDrag:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,a=Math.abs(o+i)<Math.abs(s+i)?o:s;this._draggable._newPos.x=a},_onDragEnd:function(t){var e=this._map,i=e.options,n=+new Date-this._lastTime,s=!i.inertia||n>i.inertiaThreshold||!this._positions[0];if(e.fire("dragend",t),s)e.fire("moveend");else{var a=this._lastPos.subtract(this._positions[0]),r=(this._lastTime+n-this._times[0])/1e3,h=i.easeLinearity,l=a.multiplyBy(h/r),u=l.distanceTo([0,0]),c=Math.min(i.inertiaMaxSpeed,u),d=l.multiplyBy(c/u),p=c/(i.inertiaDeceleration*h),_=d.multiplyBy(-p/2).round();_.x&&_.y?(_=e._limitOffset(_,e.options.maxBounds),o.Util.requestAnimFrame(function(){e.panBy(_,{duration:p,easeLinearity:h,noMoveStart:!0})})):e.fire("moveend")}}}),o.Map.addInitHook("addHandler","dragging",o.Map.Drag),o.Map.mergeOptions({doubleClickZoom:!0}),o.Map.DoubleClickZoom=o.Handler.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom()+(t.originalEvent.shiftKey?-1:1);"center"===e.options.doubleClickZoom?e.setZoom(i):e.setZoomAround(t.containerPoint,i)}}),o.Map.addInitHook("addHandler","doubleClickZoom",o.Map.DoubleClickZoom),o.Map.mergeOptions({scrollWheelZoom:!0}),o.Map.ScrollWheelZoom=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"mousewheel",this._onWheelScroll,this),o.DomEvent.on(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault),this._delta=0},removeHooks:function(){o.DomEvent.off(this._map._container,"mousewheel",this._onWheelScroll),o.DomEvent.off(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault)},_onWheelScroll:function(t){var e=o.DomEvent.getWheelDelta(t);this._delta+=e,this._lastMousePos=this._map.mouseEventToContainerPoint(t),this._startTime||(this._startTime=+new Date);var i=Math.max(40-(+new Date-this._startTime),0);clearTimeout(this._timer),this._timer=setTimeout(o.bind(this._performZoom,this),i),o.DomEvent.preventDefault(t),o.DomEvent.stopPropagation(t)},_performZoom:function(){var t=this._map,e=this._delta,i=t.getZoom();e=e>0?Math.ceil(e):Math.floor(e),e=Math.max(Math.min(e,4),-4),e=t._limitZoom(i+e)-i,this._delta=0,this._startTime=null,e&&("center"===t.options.scrollWheelZoom?t.setZoom(i+e):t.setZoomAround(this._lastMousePos,i+e))}}),o.Map.addInitHook("addHandler","scrollWheelZoom",o.Map.ScrollWheelZoom),o.extend(o.DomEvent,{_touchstart:o.Browser.msPointer?"MSPointerDown":o.Browser.pointer?"pointerdown":"touchstart",_touchend:o.Browser.msPointer?"MSPointerUp":o.Browser.pointer?"pointerup":"touchend",addDoubleTapListener:function(t,i,n){function s(t){var e;if(o.Browser.pointer?(_.push(t.pointerId),e=_.length):e=t.touches.length,!(e>1)){var i=Date.now(),n=i-(r||i);h=t.touches?t.touches[0]:t,l=n>0&&u>=n,r=i}}function a(t){if(o.Browser.pointer){var e=_.indexOf(t.pointerId);if(-1===e)return;_.splice(e,1)}if(l){if(o.Browser.pointer){var n,s={};for(var a in h)n=h[a],"function"==typeof n?s[a]=n.bind(h):s[a]=n;h=s}h.type="dblclick",i(h),r=null}}var r,h,l=!1,u=250,c="_leaflet_",d=this._touchstart,p=this._touchend,_=[];t[c+d+n]=s,t[c+p+n]=a;var m=o.Browser.pointer?e.documentElement:t;return t.addEventListener(d,s,!1),m.addEventListener(p,a,!1),o.Browser.pointer&&m.addEventListener(o.DomEvent.POINTER_CANCEL,a,!1),this},removeDoubleTapListener:function(t,i){var n="_leaflet_";return t.removeEventListener(this._touchstart,t[n+this._touchstart+i],!1),(o.Browser.pointer?e.documentElement:t).removeEventListener(this._touchend,t[n+this._touchend+i],!1),o.Browser.pointer&&e.documentElement.removeEventListener(o.DomEvent.POINTER_CANCEL,t[n+this._touchend+i],!1),this}}),o.extend(o.DomEvent,{POINTER_DOWN:o.Browser.msPointer?"MSPointerDown":"pointerdown",POINTER_MOVE:o.Browser.msPointer?"MSPointerMove":"pointermove",POINTER_UP:o.Browser.msPointer?"MSPointerUp":"pointerup",POINTER_CANCEL:o.Browser.msPointer?"MSPointerCancel":"pointercancel",_pointers:[],_pointerDocumentListener:!1,addPointerListener:function(t,e,i,n){switch(e){case"touchstart":return this.addPointerListenerStart(t,e,i,n); | |
case"touchend":return this.addPointerListenerEnd(t,e,i,n);case"touchmove":return this.addPointerListenerMove(t,e,i,n);default:throw"Unknown touch event type"}},addPointerListenerStart:function(t,i,n,s){var a="_leaflet_",r=this._pointers,h=function(t){o.DomEvent.preventDefault(t);for(var e=!1,i=0;i<r.length;i++)if(r[i].pointerId===t.pointerId){e=!0;break}e||r.push(t),t.touches=r.slice(),t.changedTouches=[t],n(t)};if(t[a+"touchstart"+s]=h,t.addEventListener(this.POINTER_DOWN,h,!1),!this._pointerDocumentListener){var l=function(t){for(var e=0;e<r.length;e++)if(r[e].pointerId===t.pointerId){r.splice(e,1);break}};e.documentElement.addEventListener(this.POINTER_UP,l,!1),e.documentElement.addEventListener(this.POINTER_CANCEL,l,!1),this._pointerDocumentListener=!0}return this},addPointerListenerMove:function(t,e,i,n){function o(t){if(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons){for(var e=0;e<a.length;e++)if(a[e].pointerId===t.pointerId){a[e]=t;break}t.touches=a.slice(),t.changedTouches=[t],i(t)}}var s="_leaflet_",a=this._pointers;return t[s+"touchmove"+n]=o,t.addEventListener(this.POINTER_MOVE,o,!1),this},addPointerListenerEnd:function(t,e,i,n){var o="_leaflet_",s=this._pointers,a=function(t){for(var e=0;e<s.length;e++)if(s[e].pointerId===t.pointerId){s.splice(e,1);break}t.touches=s.slice(),t.changedTouches=[t],i(t)};return t[o+"touchend"+n]=a,t.addEventListener(this.POINTER_UP,a,!1),t.addEventListener(this.POINTER_CANCEL,a,!1),this},removePointerListener:function(t,e,i){var n="_leaflet_",o=t[n+e+i];switch(e){case"touchstart":t.removeEventListener(this.POINTER_DOWN,o,!1);break;case"touchmove":t.removeEventListener(this.POINTER_MOVE,o,!1);break;case"touchend":t.removeEventListener(this.POINTER_UP,o,!1),t.removeEventListener(this.POINTER_CANCEL,o,!1)}return this}}),o.Map.mergeOptions({touchZoom:o.Browser.touch&&!o.Browser.android23,bounceAtZoomLimits:!0}),o.Map.TouchZoom=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var n=i.mouseEventToLayerPoint(t.touches[0]),s=i.mouseEventToLayerPoint(t.touches[1]),a=i._getCenterLayerPoint();this._startCenter=n.add(s)._divideBy(2),this._startDist=n.distanceTo(s),this._moved=!1,this._zooming=!0,this._centerOffset=a.subtract(this._startCenter),i._panAnim&&i._panAnim.stop(),o.DomEvent.on(e,"touchmove",this._onTouchMove,this).on(e,"touchend",this._onTouchEnd,this),o.DomEvent.preventDefault(t)}},_onTouchMove:function(t){var e=this._map;if(t.touches&&2===t.touches.length&&this._zooming){var i=e.mouseEventToLayerPoint(t.touches[0]),n=e.mouseEventToLayerPoint(t.touches[1]);this._scale=i.distanceTo(n)/this._startDist,this._delta=i._add(n)._divideBy(2)._subtract(this._startCenter),1!==this._scale&&(e.options.bounceAtZoomLimits||!(e.getZoom()===e.getMinZoom()&&this._scale<1||e.getZoom()===e.getMaxZoom()&&this._scale>1))&&(this._moved||(o.DomUtil.addClass(e._mapPane,"leaflet-touching"),e.fire("movestart").fire("zoomstart"),this._moved=!0),o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updateOnMove,this,!0,this._map._container),o.DomEvent.preventDefault(t))}},_updateOnMove:function(){var t=this._map,e=this._getScaleOrigin(),i=t.layerPointToLatLng(e),n=t.getScaleZoom(this._scale);t._animateZoom(i,n,this._startCenter,this._scale,this._delta,!1,!0)},_onTouchEnd:function(){if(!this._moved||!this._zooming)return void(this._zooming=!1);var t=this._map;this._zooming=!1,o.DomUtil.removeClass(t._mapPane,"leaflet-touching"),o.Util.cancelAnimFrame(this._animRequest),o.DomEvent.off(e,"touchmove",this._onTouchMove).off(e,"touchend",this._onTouchEnd);var i=this._getScaleOrigin(),n=t.layerPointToLatLng(i),s=t.getZoom(),a=t.getScaleZoom(this._scale)-s,r=a>0?Math.ceil(a):Math.floor(a),h=t._limitZoom(s+r),l=t.getZoomScale(h)/this._scale;t._animateZoom(n,h,i,l)},_getScaleOrigin:function(){var t=this._centerOffset.subtract(this._delta).divideBy(this._scale);return this._startCenter.add(t)}}),o.Map.addInitHook("addHandler","touchZoom",o.Map.TouchZoom),o.Map.mergeOptions({tap:!0,tapTolerance:15}),o.Map.Tap=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(o.DomEvent.preventDefault(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new o.Point(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.addClass(n,"leaflet-active"),this._holdTimeout=setTimeout(o.bind(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),o.DomEvent.on(e,"touchmove",this._onMove,this).on(e,"touchend",this._onUp,this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),o.DomEvent.off(e,"touchmove",this._onMove,this).off(e,"touchend",this._onUp,this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],n=i.target;n&&n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.removeClass(n,"leaflet-active"),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var e=t.touches[0];this._newPos=new o.Point(e.clientX,e.clientY)},_simulateEvent:function(i,n){var o=e.createEvent("MouseEvents");o._simulated=!0,n.target._simulatedClick=!0,o.initMouseEvent(i,!0,!0,t,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(o)}}),o.Browser.touch&&!o.Browser.pointer&&o.Map.addInitHook("addHandler","tap",o.Map.Tap),o.Map.mergeOptions({boxZoom:!0}),o.Map.BoxZoom=o.Handler.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._moved=!1},addHooks:function(){o.DomEvent.on(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){o.DomEvent.off(this._container,"mousedown",this._onMouseDown),this._moved=!1},moved:function(){return this._moved},_onMouseDown:function(t){return this._moved=!1,!t.shiftKey||1!==t.which&&1!==t.button?!1:(o.DomUtil.disableTextSelection(),o.DomUtil.disableImageDrag(),this._startLayerPoint=this._map.mouseEventToLayerPoint(t),void o.DomEvent.on(e,"mousemove",this._onMouseMove,this).on(e,"mouseup",this._onMouseUp,this).on(e,"keydown",this._onKeyDown,this))},_onMouseMove:function(t){this._moved||(this._box=o.DomUtil.create("div","leaflet-zoom-box",this._pane),o.DomUtil.setPosition(this._box,this._startLayerPoint),this._container.style.cursor="crosshair",this._map.fire("boxzoomstart"));var e=this._startLayerPoint,i=this._box,n=this._map.mouseEventToLayerPoint(t),s=n.subtract(e),a=new o.Point(Math.min(n.x,e.x),Math.min(n.y,e.y));o.DomUtil.setPosition(i,a),this._moved=!0,i.style.width=Math.max(0,Math.abs(s.x)-4)+"px",i.style.height=Math.max(0,Math.abs(s.y)-4)+"px"},_finish:function(){this._moved&&(this._pane.removeChild(this._box),this._container.style.cursor=""),o.DomUtil.enableTextSelection(),o.DomUtil.enableImageDrag(),o.DomEvent.off(e,"mousemove",this._onMouseMove).off(e,"mouseup",this._onMouseUp).off(e,"keydown",this._onKeyDown)},_onMouseUp:function(t){this._finish();var e=this._map,i=e.mouseEventToLayerPoint(t);if(!this._startLayerPoint.equals(i)){var n=new o.LatLngBounds(e.layerPointToLatLng(this._startLayerPoint),e.layerPointToLatLng(i));e.fitBounds(n),e.fire("boxzoomend",{boxZoomBounds:n})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}}),o.Map.addInitHook("addHandler","boxZoom",o.Map.BoxZoom),o.Map.mergeOptions({keyboard:!0,keyboardPanOffset:80,keyboardZoomOffset:1}),o.Map.Keyboard=o.Handler.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,173]},initialize:function(t){this._map=t,this._setPanOffset(t.options.keyboardPanOffset),this._setZoomOffset(t.options.keyboardZoomOffset)},addHooks:function(){var t=this._map._container;-1===t.tabIndex&&(t.tabIndex="0"),o.DomEvent.on(t,"focus",this._onFocus,this).on(t,"blur",this._onBlur,this).on(t,"mousedown",this._onMouseDown,this),this._map.on("focus",this._addHooks,this).on("blur",this._removeHooks,this)},removeHooks:function(){this._removeHooks();var t=this._map._container;o.DomEvent.off(t,"focus",this._onFocus,this).off(t,"blur",this._onBlur,this).off(t,"mousedown",this._onMouseDown,this),this._map.off("focus",this._addHooks,this).off("blur",this._removeHooks,this)},_onMouseDown:function(){if(!this._focused){var i=e.body,n=e.documentElement,o=i.scrollTop||n.scrollTop,s=i.scrollLeft||n.scrollLeft;this._map._container.focus(),t.scrollTo(s,o)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanOffset:function(t){var e,i,n=this._panKeys={},o=this.keyCodes;for(e=0,i=o.left.length;i>e;e++)n[o.left[e]]=[-1*t,0];for(e=0,i=o.right.length;i>e;e++)n[o.right[e]]=[t,0];for(e=0,i=o.down.length;i>e;e++)n[o.down[e]]=[0,t];for(e=0,i=o.up.length;i>e;e++)n[o.up[e]]=[0,-1*t]},_setZoomOffset:function(t){var e,i,n=this._zoomKeys={},o=this.keyCodes;for(e=0,i=o.zoomIn.length;i>e;e++)n[o.zoomIn[e]]=t;for(e=0,i=o.zoomOut.length;i>e;e++)n[o.zoomOut[e]]=-t},_addHooks:function(){o.DomEvent.on(e,"keydown",this._onKeyDown,this)},_removeHooks:function(){o.DomEvent.off(e,"keydown",this._onKeyDown,this)},_onKeyDown:function(t){var e=t.keyCode,i=this._map;if(e in this._panKeys){if(i._panAnim&&i._panAnim._inProgress)return;i.panBy(this._panKeys[e]),i.options.maxBounds&&i.panInsideBounds(i.options.maxBounds)}else{if(!(e in this._zoomKeys))return;i.setZoom(i.getZoom()+this._zoomKeys[e])}o.DomEvent.stop(t)}}),o.Map.addInitHook("addHandler","keyboard",o.Map.Keyboard),o.Handler.MarkerDrag=o.Handler.extend({initialize:function(t){this._marker=t},addHooks:function(){var t=this._marker._icon;this._draggable||(this._draggable=new o.Draggable(t,t)),this._draggable.on("dragstart",this._onDragStart,this).on("drag",this._onDrag,this).on("dragend",this._onDragEnd,this),this._draggable.enable(),o.DomUtil.addClass(this._marker._icon,"leaflet-marker-draggable")},removeHooks:function(){this._draggable.off("dragstart",this._onDragStart,this).off("drag",this._onDrag,this).off("dragend",this._onDragEnd,this),this._draggable.disable(),o.DomUtil.removeClass(this._marker._icon,"leaflet-marker-draggable")},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){this._marker.closePopup().fire("movestart").fire("dragstart")},_onDrag:function(){var t=this._marker,e=t._shadow,i=o.DomUtil.getPosition(t._icon),n=t._map.layerPointToLatLng(i);e&&o.DomUtil.setPosition(e,i),t._latlng=n,t.fire("move",{latlng:n}).fire("drag")},_onDragEnd:function(t){this._marker.fire("moveend").fire("dragend",t)}}),o.Control=o.Class.extend({options:{position:"topright"},initialize:function(t){o.setOptions(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),n=t._controlCorners[i];return o.DomUtil.addClass(e,"leaflet-control"),-1!==i.indexOf("bottom")?n.insertBefore(e,n.firstChild):n.appendChild(e),this},removeFrom:function(t){var e=this.getPosition(),i=t._controlCorners[e];return i.removeChild(this._container),this._map=null,this.onRemove&&this.onRemove(t),this},_refocusOnMap:function(){this._map&&this._map.getContainer().focus()}}),o.control=function(t){return new o.Control(t)},o.Map.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.removeFrom(this),this},_initControlPos:function(){function t(t,s){var a=i+t+" "+i+s;e[t+s]=o.DomUtil.create("div",a,n)}var e=this._controlCorners={},i="leaflet-",n=this._controlContainer=o.DomUtil.create("div",i+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){this._container.removeChild(this._controlContainer)}}),o.Control.Zoom=o.Control.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"-",zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=o.DomUtil.create("div",e+" leaflet-bar");return this._map=t,this._zoomInButton=this._createButton(this.options.zoomInText,this.options.zoomInTitle,e+"-in",i,this._zoomIn,this),this._zoomOutButton=this._createButton(this.options.zoomOutText,this.options.zoomOutTitle,e+"-out",i,this._zoomOut,this),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},_zoomIn:function(t){this._map.zoomIn(t.shiftKey?3:1)},_zoomOut:function(t){this._map.zoomOut(t.shiftKey?3:1)},_createButton:function(t,e,i,n,s,a){var r=o.DomUtil.create("a",i,n);r.innerHTML=t,r.href="#",r.title=e;var h=o.DomEvent.stopPropagation;return o.DomEvent.on(r,"click",h).on(r,"mousedown",h).on(r,"dblclick",h).on(r,"click",o.DomEvent.preventDefault).on(r,"click",s,a).on(r,"click",this._refocusOnMap,a),r},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";o.DomUtil.removeClass(this._zoomInButton,e),o.DomUtil.removeClass(this._zoomOutButton,e),t._zoom===t.getMinZoom()&&o.DomUtil.addClass(this._zoomOutButton,e),t._zoom===t.getMaxZoom()&&o.DomUtil.addClass(this._zoomInButton,e)}}),o.Map.mergeOptions({zoomControl:!0}),o.Map.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new o.Control.Zoom,this.addControl(this.zoomControl))}),o.control.zoom=function(t){return new o.Control.Zoom(t)},o.Control.Attribution=o.Control.extend({options:{position:"bottomright",prefix:'<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'},initialize:function(t){o.setOptions(this,t),this._attributions={}},onAdd:function(t){this._container=o.DomUtil.create("div","leaflet-control-attribution"),o.DomEvent.disableClickPropagation(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return t.on("layeradd",this._onLayerAdd,this).on("layerremove",this._onLayerRemove,this),this._update(),this._container},onRemove:function(t){t.off("layeradd",this._onLayerAdd).off("layerremove",this._onLayerRemove)},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):void 0},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):void 0},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(" | ")}},_onLayerAdd:function(t){t.layer.getAttribution&&this.addAttribution(t.layer.getAttribution())},_onLayerRemove:function(t){t.layer.getAttribution&&this.removeAttribution(t.layer.getAttribution())}}),o.Map.mergeOptions({attributionControl:!0}),o.Map.addInitHook(function(){this.options.attributionControl&&(this.attributionControl=(new o.Control.Attribution).addTo(this))}),o.control.attribution=function(t){return new o.Control.Attribution(t)},o.Control.Scale=o.Control.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0,updateWhenIdle:!1},onAdd:function(t){this._map=t;var e="leaflet-control-scale",i=o.DomUtil.create("div",e),n=this.options;return this._addScales(n,e,i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=o.DomUtil.create("div",e+"-line",i)),t.imperial&&(this._iScale=o.DomUtil.create("div",e+"-line",i))},_update:function(){var t=this._map.getBounds(),e=t.getCenter().lat,i=6378137*Math.PI*Math.cos(e*Math.PI/180),n=i*(t.getNorthEast().lng-t.getSouthWest().lng)/180,o=this._map.getSize(),s=this.options,a=0;o.x>0&&(a=n*(s.maxWidth/o.x)),this._updateScales(s,a)},_updateScales:function(t,e){t.metric&&e&&this._updateMetric(e),t.imperial&&e&&this._updateImperial(e)},_updateMetric:function(t){var e=this._getRoundNum(t);this._mScale.style.width=this._getScaleWidth(e/t)+"px",this._mScale.innerHTML=1e3>e?e+" m":e/1e3+" km"},_updateImperial:function(t){var e,i,n,o=3.2808399*t,s=this._iScale;o>5280?(e=o/5280,i=this._getRoundNum(e),s.style.width=this._getScaleWidth(i/e)+"px",s.innerHTML=i+" mi"):(n=this._getRoundNum(o),s.style.width=this._getScaleWidth(n/o)+"px",s.innerHTML=n+" ft")},_getScaleWidth:function(t){return Math.round(this.options.maxWidth*t)-10},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),o.control.scale=function(t){return new o.Control.Scale(t)},o.Control.Layers=o.Control.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0},initialize:function(t,e,i){o.setOptions(this,i),this._layers={},this._lastZIndex=0,this._handlingClick=!1;for(var n in t)this._addLayer(t[n],n);for(n in e)this._addLayer(e[n],n,!0)},onAdd:function(t){return this._initLayout(),this._update(),t.on("layeradd",this._onLayerChange,this).on("layerremove",this._onLayerChange,this),this._container},onRemove:function(t){t.off("layeradd",this._onLayerChange,this).off("layerremove",this._onLayerChange,this)},addBaseLayer:function(t,e){return this._addLayer(t,e),this._update(),this},addOverlay:function(t,e){return this._addLayer(t,e,!0),this._update(),this},removeLayer:function(t){var e=o.stamp(t);return delete this._layers[e],this._update(),this},_initLayout:function(){var t="leaflet-control-layers",e=this._container=o.DomUtil.create("div",t);e.setAttribute("aria-haspopup",!0),o.Browser.touch?o.DomEvent.on(e,"click",o.DomEvent.stopPropagation):o.DomEvent.disableClickPropagation(e).disableScrollPropagation(e);var i=this._form=o.DomUtil.create("form",t+"-list");if(this.options.collapsed){o.Browser.android||o.DomEvent.on(e,"mouseover",this._expand,this).on(e,"mouseout",this._collapse,this);var n=this._layersLink=o.DomUtil.create("a",t+"-toggle",e);n.href="#",n.title="Layers",o.Browser.touch?o.DomEvent.on(n,"click",o.DomEvent.stop).on(n,"click",this._expand,this):o.DomEvent.on(n,"focus",this._expand,this),o.DomEvent.on(i,"click",function(){setTimeout(o.bind(this._onInputClick,this),0)},this),this._map.on("click",this._collapse,this)}else this._expand();this._baseLayersList=o.DomUtil.create("div",t+"-base",i),this._separator=o.DomUtil.create("div",t+"-separator",i),this._overlaysList=o.DomUtil.create("div",t+"-overlays",i),e.appendChild(i)},_addLayer:function(t,e,i){var n=o.stamp(t);this._layers[n]={layer:t,name:e,overlay:i},this.options.autoZIndex&&t.setZIndex&&(this._lastZIndex++,t.setZIndex(this._lastZIndex))},_update:function(){if(this._container){this._baseLayersList.innerHTML="",this._overlaysList.innerHTML="";var t,e,i=!1,n=!1;for(t in this._layers)e=this._layers[t],this._addItem(e),n=n||e.overlay,i=i||!e.overlay;this._separator.style.display=n&&i?"":"none"}},_onLayerChange:function(t){var e=this._layers[o.stamp(t.layer)];if(e){this._handlingClick||this._update();var i=e.overlay?"layeradd"===t.type?"overlayadd":"overlayremove":"layeradd"===t.type?"baselayerchange":null;i&&this._map.fire(i,e)}},_createRadioElement:function(t,i){var n='<input type="radio" class="leaflet-control-layers-selector" name="'+t+'"';i&&(n+=' checked="checked"'),n+="/>";var o=e.createElement("div");return o.innerHTML=n,o.firstChild},_addItem:function(t){var i,n=e.createElement("label"),s=this._map.hasLayer(t.layer);t.overlay?(i=e.createElement("input"),i.type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=s):i=this._createRadioElement("leaflet-base-layers",s),i.layerId=o.stamp(t.layer),o.DomEvent.on(i,"click",this._onInputClick,this);var a=e.createElement("span");a.innerHTML=" "+t.name,n.appendChild(i),n.appendChild(a);var r=t.overlay?this._overlaysList:this._baseLayersList;return r.appendChild(n),n},_onInputClick:function(){var t,e,i,n=this._form.getElementsByTagName("input"),o=n.length;for(this._handlingClick=!0,t=0;o>t;t++)e=n[t],i=this._layers[e.layerId],e.checked&&!this._map.hasLayer(i.layer)?this._map.addLayer(i.layer):!e.checked&&this._map.hasLayer(i.layer)&&this._map.removeLayer(i.layer);this._handlingClick=!1,this._refocusOnMap()},_expand:function(){o.DomUtil.addClass(this._container,"leaflet-control-layers-expanded")},_collapse:function(){this._container.className=this._container.className.replace(" leaflet-control-layers-expanded","")}}),o.control.layers=function(t,e,i){return new o.Control.Layers(t,e,i)},o.PosAnimation=o.Class.extend({includes:o.Mixin.Events,run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._newPos=e,this.fire("start"),t.style[o.DomUtil.TRANSITION]="all "+(i||.25)+"s cubic-bezier(0,0,"+(n||.5)+",1)",o.DomEvent.on(t,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),o.DomUtil.setPosition(t,e),o.Util.falseFn(t.offsetWidth),this._stepTimer=setInterval(o.bind(this._onStep,this),50)},stop:function(){this._inProgress&&(o.DomUtil.setPosition(this._el,this._getPos()),this._onTransitionEnd(),o.Util.falseFn(this._el.offsetWidth))},_onStep:function(){var t=this._getPos();return t?(this._el._leaflet_pos=t,void this.fire("step")):void this._onTransitionEnd()},_transformRe:/([-+]?(?:\d*\.)?\d+)\D*, ([-+]?(?:\d*\.)?\d+)\D*\)/,_getPos:function(){var e,i,n,s=this._el,a=t.getComputedStyle(s);if(o.Browser.any3d){if(n=a[o.DomUtil.TRANSFORM].match(this._transformRe),!n)return;e=parseFloat(n[1]),i=parseFloat(n[2])}else e=parseFloat(a.left),i=parseFloat(a.top);return new o.Point(e,i,!0)},_onTransitionEnd:function(){o.DomEvent.off(this._el,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),this._inProgress&&(this._inProgress=!1,this._el.style[o.DomUtil.TRANSITION]="",this._el._leaflet_pos=this._newPos,clearInterval(this._stepTimer),this.fire("step").fire("end"))}}),o.Map.include({setView:function(t,e,n){if(e=e===i?this._zoom:this._limitZoom(e),t=this._limitCenter(o.latLng(t),e,this.options.maxBounds),n=n||{},this._panAnim&&this._panAnim.stop(),this._loaded&&!n.reset&&n!==!0){n.animate!==i&&(n.zoom=o.extend({animate:n.animate},n.zoom),n.pan=o.extend({animate:n.animate},n.pan));var s=this._zoom!==e?this._tryAnimatedZoom&&this._tryAnimatedZoom(t,e,n.zoom):this._tryAnimatedPan(t,n.pan);if(s)return clearTimeout(this._sizeTimer),this}return this._resetView(t,e),this},panBy:function(t,e){if(t=o.point(t).round(),e=e||{},!t.x&&!t.y)return this;if(this._panAnim||(this._panAnim=new o.PosAnimation,this._panAnim.on({step:this._onPanTransitionStep,end:this._onPanTransitionEnd},this)),e.noMoveStart||this.fire("movestart"),e.animate!==!1){o.DomUtil.addClass(this._mapPane,"leaflet-pan-anim");var i=this._getMapPanePos().subtract(t);this._panAnim.run(this._mapPane,i,e.duration||.25,e.easeLinearity)}else this._rawPanBy(t),this.fire("move").fire("moveend");return this},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){o.DomUtil.removeClass(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._floor();return(e&&e.animate)===!0||this.getSize().contains(i)?(this.panBy(i,e),!0):!1}}),o.PosAnimation=o.DomUtil.TRANSITION?o.PosAnimation:o.PosAnimation.extend({run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=o.DomUtil.getPosition(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(),this._complete())},_animate:function(){this._animId=o.Util.requestAnimFrame(this._animate,this),this._step()},_step:function(){var t=+new Date-this._startTime,e=1e3*this._duration;e>t?this._runFrame(this._easeOut(t/e)):(this._runFrame(1),this._complete())},_runFrame:function(t){var e=this._startPos.add(this._offset.multiplyBy(t));o.DomUtil.setPosition(this._el,e),this.fire("step")},_complete:function(){o.Util.cancelAnimFrame(this._animId),this._inProgress=!1,this.fire("end")},_easeOut:function(t){return 1-Math.pow(1-t,this._easeOutPower)}}),o.Map.mergeOptions({zoomAnimation:!0,zoomAnimationThreshold:4}),o.DomUtil.TRANSITION&&o.Map.addInitHook(function(){this._zoomAnimated=this.options.zoomAnimation&&o.DomUtil.TRANSITION&&o.Browser.any3d&&!o.Browser.android23&&!o.Browser.mobileOpera,this._zoomAnimated&&o.DomEvent.on(this._mapPane,o.DomUtil.TRANSITION_END,this._catchTransitionEnd,this)}),o.Map.include(o.DomUtil.TRANSITION?{_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),o=this._getCenterOffset(t)._divideBy(1-1/n),s=this._getCenterLayerPoint()._add(o);return i.animate===!0||this.getSize().contains(o)?(this.fire("movestart").fire("zoomstart"),this._animateZoom(t,e,s,n,null,!0),!0):!1},_animateZoom:function(t,e,i,n,s,a,r){r||(this._animatingZoom=!0),o.DomUtil.addClass(this._mapPane,"leaflet-zoom-anim"),this._animateToCenter=t,this._animateToZoom=e,o.Draggable&&(o.Draggable._disabled=!0),o.Util.requestAnimFrame(function(){this.fire("zoomanim",{center:t,zoom:e,origin:i,scale:n,delta:s,backwards:a}),setTimeout(o.bind(this._onZoomTransitionEnd,this),250)},this)},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._animatingZoom=!1,o.DomUtil.removeClass(this._mapPane,"leaflet-zoom-anim"),this._resetView(this._animateToCenter,this._animateToZoom,!0,!0),o.Draggable&&(o.Draggable._disabled=!1))}}:{}),o.TileLayer.include({_animateZoom:function(t){this._animating||(this._animating=!0,this._prepareBgBuffer());var e=this._bgBuffer,i=o.DomUtil.TRANSFORM,n=t.delta?o.DomUtil.getTranslateString(t.delta):e.style[i],s=o.DomUtil.getScaleString(t.scale,t.origin);e.style[i]=t.backwards?s+" "+n:n+" "+s},_endZoomAnim:function(){var t=this._tileContainer,e=this._bgBuffer;t.style.visibility="",t.parentNode.appendChild(t),o.Util.falseFn(e.offsetWidth);var i=this._map.getZoom();(i>this.options.maxZoom||i<this.options.minZoom)&&this._clearBgBuffer(),this._animating=!1},_clearBgBuffer:function(){var t=this._map;!t||t._animatingZoom||t.touchZoom._zooming||(this._bgBuffer.innerHTML="",this._bgBuffer.style[o.DomUtil.TRANSFORM]="")},_prepareBgBuffer:function(){var t=this._tileContainer,e=this._bgBuffer,i=this._getLoadedTilesPercentage(e),n=this._getLoadedTilesPercentage(t);return e&&i>.5&&.5>n?(t.style.visibility="hidden",void this._stopLoadingImages(t)):(e.style.visibility="hidden",e.style[o.DomUtil.TRANSFORM]="",this._tileContainer=e,e=this._bgBuffer=t,this._stopLoadingImages(e),void clearTimeout(this._clearBgBufferTimer))},_getLoadedTilesPercentage:function(t){var e,i,n=t.getElementsByTagName("img"),o=0;for(e=0,i=n.length;i>e;e++)n[e].complete&&o++;return o/i},_stopLoadingImages:function(t){var e,i,n,s=Array.prototype.slice.call(t.getElementsByTagName("img"));for(e=0,i=s.length;i>e;e++)n=s[e],n.complete||(n.onload=o.Util.falseFn,n.onerror=o.Util.falseFn,n.src=o.Util.emptyImageUrl,n.parentNode.removeChild(n))}}),o.Map.include({_defaultLocateOptions:{watch:!1,setView:!1,maxZoom:1/0,timeout:1e4,maximumAge:0,enableHighAccuracy:!1},locate:function(t){if(t=this._locateOptions=o.extend(this._defaultLocateOptions,t),!navigator.geolocation)return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var e=o.bind(this._handleGeolocationResponse,this),i=o.bind(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e=t.code,i=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+i+"."})},_handleGeolocationResponse:function(t){var e=t.coords.latitude,i=t.coords.longitude,n=new o.LatLng(e,i),s=180*t.coords.accuracy/40075017,a=s/Math.cos(o.LatLng.DEG_TO_RAD*e),r=o.latLngBounds([e-s,i-a],[e+s,i+a]),h=this._locateOptions;if(h.setView){var l=Math.min(this.getBoundsZoom(r),h.maxZoom);this.setView(n,l)}var u={latlng:n,bounds:r,timestamp:t.timestamp};for(var c in t.coords)"number"==typeof t.coords[c]&&(u[c]=t.coords[c]);this.fire("locationfound",u)}})}(window,document); | |
/***/ }, | |
/* 418 */ | |
/***/ function(module, exports) { | |
/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {module.exports = __webpack_amd_options__; | |
/* WEBPACK VAR INJECTION */}.call(exports, {})) | |
/***/ }, | |
/* 419 */ | |
/***/ function(module, exports) { | |
/* | |
(c) 2014, Vladimir Agafonkin | |
simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas | |
https://github.com/mourner/simpleheat | |
*/ | |
!function(){"use strict";function t(i){return this instanceof t?(this._canvas=i="string"==typeof i?document.getElementById(i):i,this._ctx=i.getContext("2d"),this._width=i.width,this._height=i.height,this._max=1,void this.clear()):new t(i)}t.prototype={defaultRadius:25,defaultGradient:{.4:"blue",.6:"cyan",.7:"lime",.8:"yellow",1:"red"},data:function(t){return this._data=t,this},max:function(t){return this._max=t,this},add:function(t){return this._data.push(t),this},clear:function(){return this._data=[],this},radius:function(t,i){i=i||15;var a=this._circle=document.createElement("canvas"),s=a.getContext("2d"),e=this._r=t+i;return a.width=a.height=2*e,s.shadowOffsetX=s.shadowOffsetY=200,s.shadowBlur=i,s.shadowColor="black",s.beginPath(),s.arc(e-200,e-200,t,0,2*Math.PI,!0),s.closePath(),s.fill(),this},gradient:function(t){var i=document.createElement("canvas"),a=i.getContext("2d"),s=a.createLinearGradient(0,0,0,256);i.width=1,i.height=256;for(var e in t)s.addColorStop(e,t[e]);return a.fillStyle=s,a.fillRect(0,0,1,256),this._grad=a.getImageData(0,0,1,256).data,this},draw:function(t){this._circle||this.radius(this.defaultRadius),this._grad||this.gradient(this.defaultGradient);var i=this._ctx;i.clearRect(0,0,this._width,this._height);for(var a,s=0,e=this._data.length;e>s;s++)a=this._data[s],i.globalAlpha=Math.max(a[2]/this._max,t||.05),i.drawImage(this._circle,a[0]-this._r,a[1]-this._r);var n=i.getImageData(0,0,this._width,this._height);return this._colorize(n.data,this._grad),i.putImageData(n,0,0),this},_colorize:function(t,i){for(var a,s=3,e=t.length;e>s;s+=4)a=4*t[s],a&&(t[s-3]=i[a],t[s-2]=i[a+1],t[s-1]=i[a+2])}},window.simpleheat=t}(),/* | |
(c) 2014, Vladimir Agafonkin | |
Leaflet.heat, a tiny and fast heatmap plugin for Leaflet. | |
https://github.com/Leaflet/Leaflet.heat | |
*/ | |
L.HeatLayer=(L.Layer?L.Layer:L.Class).extend({initialize:function(t,i){this._latlngs=t,L.setOptions(this,i)},setLatLngs:function(t){return this._latlngs=t,this.redraw()},addLatLng:function(t){return this._latlngs.push(t),this.redraw()},setOptions:function(t){return L.setOptions(this,t),this._heat&&this._updateOptions(),this.redraw()},redraw:function(){return!this._heat||this._frame||this._map._animating||(this._frame=L.Util.requestAnimFrame(this._redraw,this)),this},onAdd:function(t){this._map=t,this._canvas||this._initCanvas(),t._panes.overlayPane.appendChild(this._canvas),t.on("moveend",this._reset,this),t.options.zoomAnimation&&L.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._canvas),t.off("moveend",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},_initCanvas:function(){var t=this._canvas=L.DomUtil.create("canvas","leaflet-heatmap-layer leaflet-layer"),i=this._map.getSize();t.width=i.x,t.height=i.y;var a=this._map.options.zoomAnimation&&L.Browser.any3d;L.DomUtil.addClass(t,"leaflet-zoom-"+(a?"animated":"hide")),this._heat=simpleheat(t),this._updateOptions()},_updateOptions:function(){this._heat.radius(this.options.radius||this._heat.defaultRadius,this.options.blur),this.options.gradient&&this._heat.gradient(this.options.gradient),this.options.max&&this._heat.max(this.options.max)},_reset:function(){var t=this._map.containerPointToLayerPoint([0,0]);L.DomUtil.setPosition(this._canvas,t);var i=this._map.getSize();this._heat._width!==i.x&&(this._canvas.width=this._heat._width=i.x),this._heat._height!==i.y&&(this._canvas.height=this._heat._height=i.y),this._redraw()},_redraw:function(){var t,i,a,s,e,n,h,o,r,_=[],d=this._heat._r,l=this._map.getSize(),m=new L.LatLngBounds(this._map.containerPointToLatLng(L.point([-d,-d])),this._map.containerPointToLatLng(l.add([d,d]))),c=void 0===this.options.maxZoom?this._map.getMaxZoom():this.options.maxZoom,u=1/Math.pow(2,Math.max(0,Math.min(c-this._map.getZoom(),12))),g=d/2,f=[],p=this._map._getMapPanePos(),v=p.x%g,w=p.y%g;for(t=0,i=this._latlngs.length;i>t;t++)if(m.contains(this._latlngs[t])){a=this._map.latLngToContainerPoint(this._latlngs[t]),e=Math.floor((a.x-v)/g)+2,n=Math.floor((a.y-w)/g)+2;var y=void 0!==this._latlngs[t].alt?this._latlngs[t].alt:void 0!==this._latlngs[t][2]?+this._latlngs[t][2]:1;r=y*u,f[n]=f[n]||[],s=f[n][e],s?(s[0]=(s[0]*s[2]+a.x*r)/(s[2]+r),s[1]=(s[1]*s[2]+a.y*r)/(s[2]+r),s[2]+=r):f[n][e]=[a.x,a.y,r]}for(t=0,i=f.length;i>t;t++)if(f[t])for(h=0,o=f[t].length;o>h;h++)s=f[t][h],s&&_.push([Math.round(s[0]),Math.round(s[1]),Math.min(s[2],1)]);this._heat.data(_).draw(this.options.minOpacity),this._frame=null},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),a=this._map._getCenterOffset(t.center)._multiplyBy(-i).subtract(this._map._getMapPanePos());L.DomUtil.setTransform?L.DomUtil.setTransform(this._canvas,a,i):this._canvas.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(a)+" scale("+i+")"}}),L.heatLayer=function(t,i){return new L.HeatLayer(t,i)}; | |
/***/ }, | |
/* 420 */ | |
/***/ function(module, exports) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 421 */ | |
/***/ function(module, exports) { | |
/* | |
Leaflet.draw, a plugin that adds drawing and editing tools to Leaflet powered maps. | |
(c) 2012-2013, Jacob Toye, Smartrak | |
https://github.com/Leaflet/Leaflet.draw | |
http://leafletjs.com | |
https://github.com/jacobtoye | |
*/ | |
!function(t,e){L.drawVersion="0.2.4-dev",L.drawLocal={draw:{toolbar:{actions:{title:"Cancel drawing",text:"Cancel"},undo:{title:"Delete last point drawn",text:"Delete last point"},buttons:{polyline:"Draw a polyline",polygon:"Draw a polygon",rectangle:"Draw a rectangle",circle:"Draw a circle",marker:"Draw a marker"}},handlers:{circle:{tooltip:{start:"Click and drag to draw circle."},radius:"Radius"},marker:{tooltip:{start:"Click map to place marker."}},polygon:{tooltip:{start:"Click to start drawing shape.",cont:"Click to continue drawing shape.",end:"Click first point to close this shape."}},polyline:{error:"<strong>Error:</strong> shape edges cannot cross!",tooltip:{start:"Click to start drawing line.",cont:"Click to continue drawing line.",end:"Click last point to finish line."}},rectangle:{tooltip:{start:"Click and drag to draw rectangle."}},simpleshape:{tooltip:{end:"Release mouse to finish drawing."}}}},edit:{toolbar:{actions:{save:{title:"Save changes.",text:"Save"},cancel:{title:"Cancel editing, discards all changes.",text:"Cancel"}},buttons:{edit:"Edit layers.",editDisabled:"No layers to edit.",remove:"Delete layers.",removeDisabled:"No layers to delete."}},handlers:{edit:{tooltip:{text:"Drag handles, or marker to edit feature.",subtext:"Click cancel to undo changes."}},remove:{tooltip:{text:"Click on a feature to remove"}}}}},L.Draw={},L.Draw.Feature=L.Handler.extend({includes:L.Mixin.Events,initialize:function(t,e){this._map=t,this._container=t._container,this._overlayPane=t._panes.overlayPane,this._popupPane=t._panes.popupPane,e&&e.shapeOptions&&(e.shapeOptions=L.Util.extend({},this.options.shapeOptions,e.shapeOptions)),L.setOptions(this,e)},enable:function(){this._enabled||(L.Handler.prototype.enable.call(this),this.fire("enabled",{handler:this.type}),this._map.fire("draw:drawstart",{layerType:this.type}))},disable:function(){this._enabled&&(L.Handler.prototype.disable.call(this),this._map.fire("draw:drawstop",{layerType:this.type}),this.fire("disabled",{handler:this.type}))},addHooks:function(){var t=this._map;t&&(L.DomUtil.disableTextSelection(),t.getContainer().focus(),this._tooltip=new L.Tooltip(this._map),L.DomEvent.on(this._container,"keyup",this._cancelDrawing,this))},removeHooks:function(){this._map&&(L.DomUtil.enableTextSelection(),this._tooltip.dispose(),this._tooltip=null,L.DomEvent.off(this._container,"keyup",this._cancelDrawing,this))},setOptions:function(t){L.setOptions(this,t)},_fireCreatedEvent:function(t){this._map.fire("draw:created",{layer:t,layerType:this.type})},_cancelDrawing:function(t){27===t.keyCode&&this.disable()}}),L.Draw.Polyline=L.Draw.Feature.extend({statics:{TYPE:"polyline"},Poly:L.Polyline,options:{allowIntersection:!0,repeatMode:!1,drawError:{color:"#b00b00",timeout:2500},icon:new L.DivIcon({iconSize:new L.Point(8,8),className:"leaflet-div-icon leaflet-editing-icon"}),guidelineDistance:20,maxGuideLineLength:4e3,shapeOptions:{stroke:!0,color:"#f06eaa",weight:4,opacity:.5,fill:!1,clickable:!0},metric:!0,showLength:!0,zIndexOffset:2e3},initialize:function(t,e){this.options.drawError.message=L.drawLocal.draw.handlers.polyline.error,e&&e.drawError&&(e.drawError=L.Util.extend({},this.options.drawError,e.drawError)),this.type=L.Draw.Polyline.TYPE,L.Draw.Feature.prototype.initialize.call(this,t,e)},addHooks:function(){L.Draw.Feature.prototype.addHooks.call(this),this._map&&(this._markers=[],this._markerGroup=new L.LayerGroup,this._map.addLayer(this._markerGroup),this._poly=new L.Polyline([],this.options.shapeOptions),this._tooltip.updateContent(this._getTooltipText()),this._mouseMarker||(this._mouseMarker=L.marker(this._map.getCenter(),{icon:L.divIcon({className:"leaflet-mouse-marker",iconAnchor:[20,20],iconSize:[40,40]}),opacity:0,zIndexOffset:this.options.zIndexOffset})),this._mouseMarker.on("mousedown",this._onMouseDown,this).addTo(this._map),this._map.on("mousemove",this._onMouseMove,this).on("mouseup",this._onMouseUp,this).on("zoomend",this._onZoomEnd,this))},removeHooks:function(){L.Draw.Feature.prototype.removeHooks.call(this),this._clearHideErrorTimeout(),this._cleanUpShape(),this._map.removeLayer(this._markerGroup),delete this._markerGroup,delete this._markers,this._map.removeLayer(this._poly),delete this._poly,this._mouseMarker.off("mousedown",this._onMouseDown,this).off("mouseup",this._onMouseUp,this),this._map.removeLayer(this._mouseMarker),delete this._mouseMarker,this._clearGuides(),this._map.off("mousemove",this._onMouseMove,this).off("zoomend",this._onZoomEnd,this)},deleteLastVertex:function(){if(!(this._markers.length<=1)){var t=this._markers.pop(),e=this._poly,i=this._poly.spliceLatLngs(e.getLatLngs().length-1,1)[0];this._markerGroup.removeLayer(t),e.getLatLngs().length<2&&this._map.removeLayer(e),this._vertexChanged(i,!1)}},addVertex:function(t){var e=this._markers.length;return e>0&&!this.options.allowIntersection&&this._poly.newLatLngIntersects(t)?(this._showErrorTooltip(),void 0):(this._errorShown&&this._hideErrorTooltip(),this._markers.push(this._createMarker(t)),this._poly.addLatLng(t),2===this._poly.getLatLngs().length&&this._map.addLayer(this._poly),this._vertexChanged(t,!0),void 0)},_finishShape:function(){var t=this._poly.newLatLngIntersects(this._poly.getLatLngs()[0],!0);return!this.options.allowIntersection&&t||!this._shapeIsValid()?(this._showErrorTooltip(),void 0):(this._fireCreatedEvent(),this.disable(),this.options.repeatMode&&this.enable(),void 0)},_shapeIsValid:function(){return!0},_onZoomEnd:function(){this._updateGuide()},_onMouseMove:function(t){var e=t.layerPoint,i=t.latlng;this._currentLatLng=i,this._updateTooltip(i),this._updateGuide(e),this._mouseMarker.setLatLng(i),L.DomEvent.preventDefault(t.originalEvent)},_vertexChanged:function(t,e){this._updateFinishHandler(),this._updateRunningMeasure(t,e),this._clearGuides(),this._updateTooltip()},_onMouseDown:function(t){var e=t.originalEvent;this._mouseDownOrigin=L.point(e.clientX,e.clientY)},_onMouseUp:function(e){if(this._mouseDownOrigin){var i=L.point(e.originalEvent.clientX,e.originalEvent.clientY).distanceTo(this._mouseDownOrigin);Math.abs(i)<9*(t.devicePixelRatio||1)&&this.addVertex(e.latlng)}this._mouseDownOrigin=null},_updateFinishHandler:function(){var t=this._markers.length;t>1&&this._markers[t-1].on("click",this._finishShape,this),t>2&&this._markers[t-2].off("click",this._finishShape,this)},_createMarker:function(t){var e=new L.Marker(t,{icon:this.options.icon,zIndexOffset:2*this.options.zIndexOffset});return this._markerGroup.addLayer(e),e},_updateGuide:function(t){var e=this._markers.length;e>0&&(t=t||this._map.latLngToLayerPoint(this._currentLatLng),this._clearGuides(),this._drawGuide(this._map.latLngToLayerPoint(this._markers[e-1].getLatLng()),t))},_updateTooltip:function(t){var e=this._getTooltipText();t&&this._tooltip.updatePosition(t),this._errorShown||this._tooltip.updateContent(e)},_drawGuide:function(t,e){var i,o,a,s=Math.floor(Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))),r=this.options.guidelineDistance,n=this.options.maxGuideLineLength,l=s>n?s-n:r;for(this._guidesContainer||(this._guidesContainer=L.DomUtil.create("div","leaflet-draw-guides",this._overlayPane));s>l;l+=this.options.guidelineDistance)i=l/s,o={x:Math.floor(t.x*(1-i)+i*e.x),y:Math.floor(t.y*(1-i)+i*e.y)},a=L.DomUtil.create("div","leaflet-draw-guide-dash",this._guidesContainer),a.style.backgroundColor=this._errorShown?this.options.drawError.color:this.options.shapeOptions.color,L.DomUtil.setPosition(a,o)},_updateGuideColor:function(t){if(this._guidesContainer)for(var e=0,i=this._guidesContainer.childNodes.length;i>e;e++)this._guidesContainer.childNodes[e].style.backgroundColor=t},_clearGuides:function(){if(this._guidesContainer)for(;this._guidesContainer.firstChild;)this._guidesContainer.removeChild(this._guidesContainer.firstChild)},_getTooltipText:function(){var t,e,i=this.options.showLength;return 0===this._markers.length?t={text:L.drawLocal.draw.handlers.polyline.tooltip.start}:(e=i?this._getMeasurementString():"",t=1===this._markers.length?{text:L.drawLocal.draw.handlers.polyline.tooltip.cont,subtext:e}:{text:L.drawLocal.draw.handlers.polyline.tooltip.end,subtext:e}),t},_updateRunningMeasure:function(t,e){var i,o,a=this._markers.length;1===this._markers.length?this._measurementRunningTotal=0:(i=a-(e?2:1),o=t.distanceTo(this._markers[i].getLatLng()),this._measurementRunningTotal+=o*(e?1:-1))},_getMeasurementString:function(){var t,e=this._currentLatLng,i=this._markers[this._markers.length-1].getLatLng();return t=this._measurementRunningTotal+e.distanceTo(i),L.GeometryUtil.readableDistance(t,this.options.metric)},_showErrorTooltip:function(){this._errorShown=!0,this._tooltip.showAsError().updateContent({text:this.options.drawError.message}),this._updateGuideColor(this.options.drawError.color),this._poly.setStyle({color:this.options.drawError.color}),this._clearHideErrorTimeout(),this._hideErrorTimeout=setTimeout(L.Util.bind(this._hideErrorTooltip,this),this.options.drawError.timeout)},_hideErrorTooltip:function(){this._errorShown=!1,this._clearHideErrorTimeout(),this._tooltip.removeError().updateContent(this._getTooltipText()),this._updateGuideColor(this.options.shapeOptions.color),this._poly.setStyle({color:this.options.shapeOptions.color})},_clearHideErrorTimeout:function(){this._hideErrorTimeout&&(clearTimeout(this._hideErrorTimeout),this._hideErrorTimeout=null)},_cleanUpShape:function(){this._markers.length>1&&this._markers[this._markers.length-1].off("click",this._finishShape,this)},_fireCreatedEvent:function(){var t=new this.Poly(this._poly.getLatLngs(),this.options.shapeOptions);L.Draw.Feature.prototype._fireCreatedEvent.call(this,t)}}),L.Draw.Polygon=L.Draw.Polyline.extend({statics:{TYPE:"polygon"},Poly:L.Polygon,options:{showArea:!1,shapeOptions:{stroke:!0,color:"#f06eaa",weight:4,opacity:.5,fill:!0,fillColor:null,fillOpacity:.2,clickable:!0}},initialize:function(t,e){L.Draw.Polyline.prototype.initialize.call(this,t,e),this.type=L.Draw.Polygon.TYPE},_updateFinishHandler:function(){var t=this._markers.length;1===t&&this._markers[0].on("click",this._finishShape,this),t>2&&(this._markers[t-1].on("dblclick",this._finishShape,this),t>3&&this._markers[t-2].off("dblclick",this._finishShape,this))},_getTooltipText:function(){var t,e;return 0===this._markers.length?t=L.drawLocal.draw.handlers.polygon.tooltip.start:this._markers.length<3?t=L.drawLocal.draw.handlers.polygon.tooltip.cont:(t=L.drawLocal.draw.handlers.polygon.tooltip.end,e=this._getMeasurementString()),{text:t,subtext:e}},_getMeasurementString:function(){var t=this._area;return t?L.GeometryUtil.readableArea(t,this.options.metric):null},_shapeIsValid:function(){return this._markers.length>=3},_vertexChanged:function(t,e){var i;!this.options.allowIntersection&&this.options.showArea&&(i=this._poly.getLatLngs(),this._area=L.GeometryUtil.geodesicArea(i)),L.Draw.Polyline.prototype._vertexChanged.call(this,t,e)},_cleanUpShape:function(){var t=this._markers.length;t>0&&(this._markers[0].off("click",this._finishShape,this),t>2&&this._markers[t-1].off("dblclick",this._finishShape,this))}}),L.SimpleShape={},L.Draw.SimpleShape=L.Draw.Feature.extend({options:{repeatMode:!1},initialize:function(t,e){this._endLabelText=L.drawLocal.draw.handlers.simpleshape.tooltip.end,L.Draw.Feature.prototype.initialize.call(this,t,e)},addHooks:function(){L.Draw.Feature.prototype.addHooks.call(this),this._map&&(this._mapDraggable=this._map.dragging.enabled(),this._mapDraggable&&this._map.dragging.disable(),this._container.style.cursor="crosshair",this._tooltip.updateContent({text:this._initialLabelText}),this._map.on("mousedown",this._onMouseDown,this).on("mousemove",this._onMouseMove,this))},removeHooks:function(){L.Draw.Feature.prototype.removeHooks.call(this),this._map&&(this._mapDraggable&&this._map.dragging.enable(),this._container.style.cursor="",this._map.off("mousedown",this._onMouseDown,this).off("mousemove",this._onMouseMove,this),L.DomEvent.off(e,"mouseup",this._onMouseUp,this),this._shape&&(this._map.removeLayer(this._shape),delete this._shape)),this._isDrawing=!1},_getTooltipText:function(){return{text:this._endLabelText}},_onMouseDown:function(t){this._isDrawing=!0,this._startLatLng=t.latlng,L.DomEvent.on(e,"mouseup",this._onMouseUp,this).preventDefault(t.originalEvent)},_onMouseMove:function(t){var e=t.latlng;this._tooltip.updatePosition(e),this._isDrawing&&(this._tooltip.updateContent(this._getTooltipText()),this._drawShape(e))},_onMouseUp:function(){this._shape&&this._fireCreatedEvent(),this.disable(),this.options.repeatMode&&this.enable()}}),L.Draw.Rectangle=L.Draw.SimpleShape.extend({statics:{TYPE:"rectangle"},options:{shapeOptions:{stroke:!0,color:"#f06eaa",weight:4,opacity:.5,fill:!0,fillColor:null,fillOpacity:.2,clickable:!0},metric:!0},initialize:function(t,e){this.type=L.Draw.Rectangle.TYPE,this._initialLabelText=L.drawLocal.draw.handlers.rectangle.tooltip.start,L.Draw.SimpleShape.prototype.initialize.call(this,t,e)},_drawShape:function(t){this._shape?this._shape.setBounds(new L.LatLngBounds(this._startLatLng,t)):(this._shape=new L.Rectangle(new L.LatLngBounds(this._startLatLng,t),this.options.shapeOptions),this._map.addLayer(this._shape))},_fireCreatedEvent:function(){var t=new L.Rectangle(this._shape.getBounds(),this.options.shapeOptions);L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this,t)},_getTooltipText:function(){var t,e,i,o=L.Draw.SimpleShape.prototype._getTooltipText.call(this),a=this._shape;return a&&(t=this._shape.getLatLngs(),e=L.GeometryUtil.geodesicArea(t),i=L.GeometryUtil.readableArea(e,this.options.metric)),{text:o.text,subtext:i}}}),L.Draw.Circle=L.Draw.SimpleShape.extend({statics:{TYPE:"circle"},options:{shapeOptions:{stroke:!0,color:"#f06eaa",weight:4,opacity:.5,fill:!0,fillColor:null,fillOpacity:.2,clickable:!0},showRadius:!0,metric:!0},initialize:function(t,e){this.type=L.Draw.Circle.TYPE,this._initialLabelText=L.drawLocal.draw.handlers.circle.tooltip.start,L.Draw.SimpleShape.prototype.initialize.call(this,t,e)},_drawShape:function(t){this._shape?this._shape.setRadius(this._startLatLng.distanceTo(t)):(this._shape=new L.Circle(this._startLatLng,this._startLatLng.distanceTo(t),this.options.shapeOptions),this._map.addLayer(this._shape))},_fireCreatedEvent:function(){var t=new L.Circle(this._startLatLng,this._shape.getRadius(),this.options.shapeOptions);L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this,t)},_onMouseMove:function(t){var e,i=t.latlng,o=this.options.showRadius,a=this.options.metric;this._tooltip.updatePosition(i),this._isDrawing&&(this._drawShape(i),e=this._shape.getRadius().toFixed(1),this._tooltip.updateContent({text:this._endLabelText,subtext:o?L.drawLocal.draw.handlers.circle.radius+": "+L.GeometryUtil.readableDistance(e,a):""}))}}),L.Draw.Marker=L.Draw.Feature.extend({statics:{TYPE:"marker"},options:{icon:new L.Icon.Default,repeatMode:!1,zIndexOffset:2e3},initialize:function(t,e){this.type=L.Draw.Marker.TYPE,L.Draw.Feature.prototype.initialize.call(this,t,e)},addHooks:function(){L.Draw.Feature.prototype.addHooks.call(this),this._map&&(this._tooltip.updateContent({text:L.drawLocal.draw.handlers.marker.tooltip.start}),this._mouseMarker||(this._mouseMarker=L.marker(this._map.getCenter(),{icon:L.divIcon({className:"leaflet-mouse-marker",iconAnchor:[20,20],iconSize:[40,40]}),opacity:0,zIndexOffset:this.options.zIndexOffset})),this._mouseMarker.on("click",this._onClick,this).addTo(this._map),this._map.on("mousemove",this._onMouseMove,this))},removeHooks:function(){L.Draw.Feature.prototype.removeHooks.call(this),this._map&&(this._marker&&(this._marker.off("click",this._onClick,this),this._map.off("click",this._onClick,this).removeLayer(this._marker),delete this._marker),this._mouseMarker.off("click",this._onClick,this),this._map.removeLayer(this._mouseMarker),delete this._mouseMarker,this._map.off("mousemove",this._onMouseMove,this))},_onMouseMove:function(t){var e=t.latlng;this._tooltip.updatePosition(e),this._mouseMarker.setLatLng(e),this._marker?(e=this._mouseMarker.getLatLng(),this._marker.setLatLng(e)):(this._marker=new L.Marker(e,{icon:this.options.icon,zIndexOffset:this.options.zIndexOffset}),this._marker.on("click",this._onClick,this),this._map.on("click",this._onClick,this).addLayer(this._marker))},_onClick:function(){this._fireCreatedEvent(),this.disable(),this.options.repeatMode&&this.enable()},_fireCreatedEvent:function(){var t=new L.Marker(this._marker.getLatLng(),{icon:this.options.icon});L.Draw.Feature.prototype._fireCreatedEvent.call(this,t)}}),L.Edit=L.Edit||{},L.Edit.Marker=L.Handler.extend({initialize:function(t,e){this._marker=t,L.setOptions(this,e)},addHooks:function(){var t=this._marker;t.dragging.enable(),t.on("dragend",this._onDragEnd,t),this._toggleMarkerHighlight()},removeHooks:function(){var t=this._marker;t.dragging.disable(),t.off("dragend",this._onDragEnd,t),this._toggleMarkerHighlight()},_onDragEnd:function(t){var e=t.target;e.edited=!0},_toggleMarkerHighlight:function(){if(this._icon){var t=this._icon;t.style.display="none",L.DomUtil.hasClass(t,"leaflet-edit-marker-selected")?(L.DomUtil.removeClass(t,"leaflet-edit-marker-selected"),this._offsetMarker(t,-4)):(L.DomUtil.addClass(t,"leaflet-edit-marker-selected"),this._offsetMarker(t,4)),t.style.display=""}},_offsetMarker:function(t,e){var i=parseInt(t.style.marginTop,10)-e,o=parseInt(t.style.marginLeft,10)-e;t.style.marginTop=i+"px",t.style.marginLeft=o+"px"}}),L.Marker.addInitHook(function(){L.Edit.Marker&&(this.editing=new L.Edit.Marker(this),this.options.editable&&this.editing.enable())}),L.Edit=L.Edit||{},L.Edit.Poly=L.Handler.extend({options:{icon:new L.DivIcon({iconSize:new L.Point(8,8),className:"leaflet-div-icon leaflet-editing-icon"})},initialize:function(t,e){this._poly=t,L.setOptions(this,e)},addHooks:function(){var t=this._poly;t instanceof L.Polygon||(t.options.editing.fill=!1),t.setStyle(t.options.editing),this._poly._map&&(this._markerGroup||this._initMarkers(),this._poly._map.addLayer(this._markerGroup))},removeHooks:function(){var t=this._poly;t.setStyle(t.options.original),t._map&&(t._map.removeLayer(this._markerGroup),delete this._markerGroup,delete this._markers)},updateMarkers:function(){this._markerGroup.clearLayers(),this._initMarkers()},_initMarkers:function(){this._markerGroup||(this._markerGroup=new L.LayerGroup),this._markers=[];var t,e,i,o,a=this._poly._latlngs;for(t=0,i=a.length;i>t;t++)o=this._createMarker(a[t],t),o.on("click",this._onMarkerClick,this),this._markers.push(o);var s,r;for(t=0,e=i-1;i>t;e=t++)(0!==t||L.Polygon&&this._poly instanceof L.Polygon)&&(s=this._markers[e],r=this._markers[t],this._createMiddleMarker(s,r),this._updatePrevNext(s,r))},_createMarker:function(t,e){var i=new L.Marker(t,{draggable:!0,icon:this.options.icon});return i._origLatLng=t,i._index=e,i.on("drag",this._onMarkerDrag,this),i.on("dragend",this._fireEdit,this),this._markerGroup.addLayer(i),i},_removeMarker:function(t){var e=t._index;this._markerGroup.removeLayer(t),this._markers.splice(e,1),this._poly.spliceLatLngs(e,1),this._updateIndexes(e,-1),t.off("drag",this._onMarkerDrag,this).off("dragend",this._fireEdit,this).off("click",this._onMarkerClick,this)},_fireEdit:function(){this._poly.edited=!0,this._poly.fire("edit")},_onMarkerDrag:function(t){var e=t.target;L.extend(e._origLatLng,e._latlng),e._middleLeft&&e._middleLeft.setLatLng(this._getMiddleLatLng(e._prev,e)),e._middleRight&&e._middleRight.setLatLng(this._getMiddleLatLng(e,e._next)),this._poly.redraw()},_onMarkerClick:function(t){var e=L.Polygon&&this._poly instanceof L.Polygon?4:3,i=t.target;this._poly._latlngs.length<e||(this._removeMarker(i),this._updatePrevNext(i._prev,i._next),i._middleLeft&&this._markerGroup.removeLayer(i._middleLeft),i._middleRight&&this._markerGroup.removeLayer(i._middleRight),i._prev&&i._next?this._createMiddleMarker(i._prev,i._next):i._prev?i._next||(i._prev._middleRight=null):i._next._middleLeft=null,this._fireEdit())},_updateIndexes:function(t,e){this._markerGroup.eachLayer(function(i){i._index>t&&(i._index+=e)})},_createMiddleMarker:function(t,e){var i,o,a,s=this._getMiddleLatLng(t,e),r=this._createMarker(s);r.setOpacity(.6),t._middleRight=e._middleLeft=r,o=function(){var o=e._index;r._index=o,r.off("click",i,this).on("click",this._onMarkerClick,this),s.lat=r.getLatLng().lat,s.lng=r.getLatLng().lng,this._poly.spliceLatLngs(o,0,s),this._markers.splice(o,0,r),r.setOpacity(1),this._updateIndexes(o,1),e._index++,this._updatePrevNext(t,r),this._updatePrevNext(r,e),this._poly.fire("editstart")},a=function(){r.off("dragstart",o,this),r.off("dragend",a,this),this._createMiddleMarker(t,r),this._createMiddleMarker(r,e)},i=function(){o.call(this),a.call(this),this._fireEdit()},r.on("click",i,this).on("dragstart",o,this).on("dragend",a,this),this._markerGroup.addLayer(r)},_updatePrevNext:function(t,e){t&&(t._next=e),e&&(e._prev=t)},_getMiddleLatLng:function(t,e){var i=this._poly._map,o=i.project(t.getLatLng()),a=i.project(e.getLatLng());return i.unproject(o._add(a)._divideBy(2))}}),L.Polyline.addInitHook(function(){this.editing||(L.Edit.Poly&&(this.editing=new L.Edit.Poly(this),this.options.editable&&this.editing.enable()),this.on("add",function(){this.editing&&this.editing.enabled()&&this.editing.addHooks()}),this.on("remove",function(){this.editing&&this.editing.enabled()&&this.editing.removeHooks()}))}),L.Edit=L.Edit||{},L.Edit.SimpleShape=L.Handler.extend({options:{moveIcon:new L.DivIcon({iconSize:new L.Point(8,8),className:"leaflet-div-icon leaflet-editing-icon leaflet-edit-move"}),resizeIcon:new L.DivIcon({iconSize:new L.Point(8,8),className:"leaflet-div-icon leaflet-editing-icon leaflet-edit-resize"})},initialize:function(t,e){this._shape=t,L.Util.setOptions(this,e)},addHooks:function(){var t=this._shape;t.setStyle(t.options.editing),t._map&&(this._map=t._map,this._markerGroup||this._initMarkers(),this._map.addLayer(this._markerGroup))},removeHooks:function(){var t=this._shape;if(t.setStyle(t.options.original),t._map){this._unbindMarker(this._moveMarker);for(var e=0,i=this._resizeMarkers.length;i>e;e++)this._unbindMarker(this._resizeMarkers[e]);this._resizeMarkers=null,this._map.removeLayer(this._markerGroup),delete this._markerGroup}this._map=null},updateMarkers:function(){this._markerGroup.clearLayers(),this._initMarkers()},_initMarkers:function(){this._markerGroup||(this._markerGroup=new L.LayerGroup),this._createMoveMarker(),this._createResizeMarker()},_createMoveMarker:function(){},_createResizeMarker:function(){},_createMarker:function(t,e){var i=new L.Marker(t,{draggable:!0,icon:e,zIndexOffset:10});return this._bindMarker(i),this._markerGroup.addLayer(i),i},_bindMarker:function(t){t.on("dragstart",this._onMarkerDragStart,this).on("drag",this._onMarkerDrag,this).on("dragend",this._onMarkerDragEnd,this)},_unbindMarker:function(t){t.off("dragstart",this._onMarkerDragStart,this).off("drag",this._onMarkerDrag,this).off("dragend",this._onMarkerDragEnd,this)},_onMarkerDragStart:function(t){var e=t.target;e.setOpacity(0),this._shape.fire("editstart")},_fireEdit:function(){this._shape.edited=!0,this._shape.fire("edit")},_onMarkerDrag:function(t){var e=t.target,i=e.getLatLng();e===this._moveMarker?this._move(i):this._resize(i),this._shape.redraw()},_onMarkerDragEnd:function(t){var e=t.target;e.setOpacity(1),this._fireEdit()},_move:function(){},_resize:function(){}}),L.Edit=L.Edit||{},L.Edit.Rectangle=L.Edit.SimpleShape.extend({_createMoveMarker:function(){var t=this._shape.getBounds(),e=t.getCenter();this._moveMarker=this._createMarker(e,this.options.moveIcon)},_createResizeMarker:function(){var t=this._getCorners();this._resizeMarkers=[];for(var e=0,i=t.length;i>e;e++)this._resizeMarkers.push(this._createMarker(t[e],this.options.resizeIcon)),this._resizeMarkers[e]._cornerIndex=e},_onMarkerDragStart:function(t){L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this,t);var e=this._getCorners(),i=t.target,o=i._cornerIndex;this._oppositeCorner=e[(o+2)%4],this._toggleCornerMarkers(0,o)},_onMarkerDragEnd:function(t){var e,i,o=t.target;o===this._moveMarker&&(e=this._shape.getBounds(),i=e.getCenter(),o.setLatLng(i)),this._toggleCornerMarkers(1),this._repositionCornerMarkers(),L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this,t)},_move:function(t){for(var e,i=this._shape.getLatLngs(),o=this._shape.getBounds(),a=o.getCenter(),s=[],r=0,n=i.length;n>r;r++)e=[i[r].lat-a.lat,i[r].lng-a.lng],s.push([t.lat+e[0],t.lng+e[1]]);this._shape.setLatLngs(s),this._repositionCornerMarkers()},_resize:function(t){var e;this._shape.setBounds(L.latLngBounds(t,this._oppositeCorner)),e=this._shape.getBounds(),this._moveMarker.setLatLng(e.getCenter())},_getCorners:function(){var t=this._shape.getBounds(),e=t.getNorthWest(),i=t.getNorthEast(),o=t.getSouthEast(),a=t.getSouthWest();return[e,i,o,a]},_toggleCornerMarkers:function(t){for(var e=0,i=this._resizeMarkers.length;i>e;e++)this._resizeMarkers[e].setOpacity(t)},_repositionCornerMarkers:function(){for(var t=this._getCorners(),e=0,i=this._resizeMarkers.length;i>e;e++)this._resizeMarkers[e].setLatLng(t[e])}}),L.Rectangle.addInitHook(function(){L.Edit.Rectangle&&(this.editing=new L.Edit.Rectangle(this),this.options.editable&&this.editing.enable())}),L.Edit=L.Edit||{},L.Edit.Circle=L.Edit.SimpleShape.extend({_createMoveMarker:function(){var t=this._shape.getLatLng();this._moveMarker=this._createMarker(t,this.options.moveIcon)},_createResizeMarker:function(){var t=this._shape.getLatLng(),e=this._getResizeMarkerPoint(t);this._resizeMarkers=[],this._resizeMarkers.push(this._createMarker(e,this.options.resizeIcon))},_getResizeMarkerPoint:function(t){var e=this._shape._radius*Math.cos(Math.PI/4),i=this._map.project(t);return this._map.unproject([i.x+e,i.y-e])},_move:function(t){var e=this._getResizeMarkerPoint(t);this._resizeMarkers[0].setLatLng(e),this._shape.setLatLng(t)},_resize:function(t){var e=this._moveMarker.getLatLng(),i=e.distanceTo(t);this._shape.setRadius(i)}}),L.Circle.addInitHook(function(){L.Edit.Circle&&(this.editing=new L.Edit.Circle(this),this.options.editable&&this.editing.enable()),this.on("add",function(){this.editing&&this.editing.enabled()&&this.editing.addHooks()}),this.on("remove",function(){this.editing&&this.editing.enabled()&&this.editing.removeHooks()})}),L.LatLngUtil={cloneLatLngs:function(t){for(var e=[],i=0,o=t.length;o>i;i++)e.push(this.cloneLatLng(t[i]));return e},cloneLatLng:function(t){return L.latLng(t.lat,t.lng)}},L.GeometryUtil=L.extend(L.GeometryUtil||{},{geodesicArea:function(t){var e,i,o=t.length,a=0,s=L.LatLng.DEG_TO_RAD;if(o>2){for(var r=0;o>r;r++)e=t[r],i=t[(r+1)%o],a+=(i.lng-e.lng)*s*(2+Math.sin(e.lat*s)+Math.sin(i.lat*s));a=6378137*a*6378137/2}return Math.abs(a)},readableArea:function(t,e){var i;return e?i=t>=1e4?(1e-4*t).toFixed(2)+" ha":t.toFixed(2)+" m²":(t/=.836127,i=t>=3097600?(t/3097600).toFixed(2)+" mi²":t>=4840?(t/4840).toFixed(2)+" acres":Math.ceil(t)+" yd²"),i},readableDistance:function(t,e){var i;return e?i=t>1e3?(t/1e3).toFixed(2)+" km":Math.ceil(t)+" m":(t*=1.09361,i=t>1760?(t/1760).toFixed(2)+" miles":Math.ceil(t)+" yd"),i}}),L.Util.extend(L.LineUtil,{segmentsIntersect:function(t,e,i,o){return this._checkCounterclockwise(t,i,o)!==this._checkCounterclockwise(e,i,o)&&this._checkCounterclockwise(t,e,i)!==this._checkCounterclockwise(t,e,o)},_checkCounterclockwise:function(t,e,i){return(i.y-t.y)*(e.x-t.x)>(e.y-t.y)*(i.x-t.x)}}),L.Polyline.include({intersects:function(){var t,e,i,o=this._originalPoints,a=o?o.length:0;if(this._tooFewPointsForIntersection())return!1;for(t=a-1;t>=3;t--)if(e=o[t-1],i=o[t],this._lineSegmentsIntersectsRange(e,i,t-2))return!0;return!1},newLatLngIntersects:function(t,e){return this._map?this.newPointIntersects(this._map.latLngToLayerPoint(t),e):!1},newPointIntersects:function(t,e){var i=this._originalPoints,o=i?i.length:0,a=i?i[o-1]:null,s=o-2;return this._tooFewPointsForIntersection(1)?!1:this._lineSegmentsIntersectsRange(a,t,s,e?1:0)},_tooFewPointsForIntersection:function(t){var e=this._originalPoints,i=e?e.length:0;return i+=t||0,!this._originalPoints||3>=i},_lineSegmentsIntersectsRange:function(t,e,i,o){var a,s,r=this._originalPoints;o=o||0;for(var n=i;n>o;n--)if(a=r[n-1],s=r[n],L.LineUtil.segmentsIntersect(t,e,a,s))return!0;return!1}}),L.Polygon.include({intersects:function(){var t,e,i,o,a,s=this._originalPoints;return this._tooFewPointsForIntersection()?!1:(t=L.Polyline.prototype.intersects.call(this))?!0:(e=s.length,i=s[0],o=s[e-1],a=e-2,this._lineSegmentsIntersectsRange(o,i,a,1))}}),L.Control.Draw=L.Control.extend({options:{position:"topleft",draw:{},edit:!1},initialize:function(t){if(L.version<"0.7")throw new Error("Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/");L.Control.prototype.initialize.call(this,t);var e;this._toolbars={},L.DrawToolbar&&this.options.draw&&(e=new L.DrawToolbar(this.options.draw),this._toolbars[L.DrawToolbar.TYPE]=e,this._toolbars[L.DrawToolbar.TYPE].on("enable",this._toolbarEnabled,this)),L.EditToolbar&&this.options.edit&&(e=new L.EditToolbar(this.options.edit),this._toolbars[L.EditToolbar.TYPE]=e,this._toolbars[L.EditToolbar.TYPE].on("enable",this._toolbarEnabled,this))},onAdd:function(t){var e,i=L.DomUtil.create("div","leaflet-draw"),o=!1,a="leaflet-draw-toolbar-top";for(var s in this._toolbars)this._toolbars.hasOwnProperty(s)&&(e=this._toolbars[s].addToolbar(t),e&&(o||(L.DomUtil.hasClass(e,a)||L.DomUtil.addClass(e.childNodes[0],a),o=!0),i.appendChild(e)));return i},onRemove:function(){for(var t in this._toolbars)this._toolbars.hasOwnProperty(t)&&this._toolbars[t].removeToolbar()},setDrawingOptions:function(t){for(var e in this._toolbars)this._toolbars[e]instanceof L.DrawToolbar&&this._toolbars[e].setOptions(t)},_toolbarEnabled:function(t){var e=t.target;for(var i in this._toolbars)this._toolbars[i]!==e&&this._toolbars[i].disable()}}),L.Map.mergeOptions({drawControlTooltips:!0,drawControl:!1}),L.Map.addInitHook(function(){this.options.drawControl&&(this.drawControl=new L.Control.Draw,this.addControl(this.drawControl))}),L.Toolbar=L.Class.extend({includes:[L.Mixin.Events],initialize:function(t){L.setOptions(this,t),this._modes={},this._actionButtons=[],this._activeMode=null},enabled:function(){return null!==this._activeMode},disable:function(){this.enabled()&&this._activeMode.handler.disable()},addToolbar:function(t){var e,i=L.DomUtil.create("div","leaflet-draw-section"),o=0,a=this._toolbarClass||"",s=this.getModeHandlers(t);for(this._toolbarContainer=L.DomUtil.create("div","leaflet-draw-toolbar leaflet-bar"),this._map=t,e=0;e<s.length;e++)s[e].enabled&&this._initModeHandler(s[e].handler,this._toolbarContainer,o++,a,s[e].title);return o?(this._lastButtonIndex=--o,this._actionsContainer=L.DomUtil.create("ul","leaflet-draw-actions"),i.appendChild(this._toolbarContainer),i.appendChild(this._actionsContainer),i):void 0},removeToolbar:function(){for(var t in this._modes)this._modes.hasOwnProperty(t)&&(this._disposeButton(this._modes[t].button,this._modes[t].handler.enable,this._modes[t].handler),this._modes[t].handler.disable(),this._modes[t].handler.off("enabled",this._handlerActivated,this).off("disabled",this._handlerDeactivated,this));this._modes={};for(var e=0,i=this._actionButtons.length;i>e;e++)this._disposeButton(this._actionButtons[e].button,this._actionButtons[e].callback,this);this._actionButtons=[],this._actionsContainer=null},_initModeHandler:function(t,e,i,o,a){var s=t.type;this._modes[s]={},this._modes[s].handler=t,this._modes[s].button=this._createButton({title:a,className:o+"-"+s,container:e,callback:this._modes[s].handler.enable,context:this._modes[s].handler}),this._modes[s].buttonIndex=i,this._modes[s].handler.on("enabled",this._handlerActivated,this).on("disabled",this._handlerDeactivated,this)},_createButton:function(t){var e=L.DomUtil.create("a",t.className||"",t.container);return e.href="#",t.text&&(e.innerHTML=t.text),t.title&&(e.title=t.title),L.DomEvent.on(e,"click",L.DomEvent.stopPropagation).on(e,"mousedown",L.DomEvent.stopPropagation).on(e,"dblclick",L.DomEvent.stopPropagation).on(e,"click",L.DomEvent.preventDefault).on(e,"click",t.callback,t.context),e | |
},_disposeButton:function(t,e){L.DomEvent.off(t,"click",L.DomEvent.stopPropagation).off(t,"mousedown",L.DomEvent.stopPropagation).off(t,"dblclick",L.DomEvent.stopPropagation).off(t,"click",L.DomEvent.preventDefault).off(t,"click",e)},_handlerActivated:function(t){this.disable(),this._activeMode=this._modes[t.handler],L.DomUtil.addClass(this._activeMode.button,"leaflet-draw-toolbar-button-enabled"),this._showActionsToolbar(),this.fire("enable")},_handlerDeactivated:function(){this._hideActionsToolbar(),L.DomUtil.removeClass(this._activeMode.button,"leaflet-draw-toolbar-button-enabled"),this._activeMode=null,this.fire("disable")},_createActions:function(t){var e,i,o,a,s=this._actionsContainer,r=this.getActions(t),n=r.length;for(i=0,o=this._actionButtons.length;o>i;i++)this._disposeButton(this._actionButtons[i].button,this._actionButtons[i].callback);for(this._actionButtons=[];s.firstChild;)s.removeChild(s.firstChild);for(var l=0;n>l;l++)"enabled"in r[l]&&!r[l].enabled||(e=L.DomUtil.create("li","",s),a=this._createButton({title:r[l].title,text:r[l].text,container:e,callback:r[l].callback,context:r[l].context}),this._actionButtons.push({button:a,callback:r[l].callback}))},_showActionsToolbar:function(){var t=this._activeMode.buttonIndex,e=this._lastButtonIndex,i=this._activeMode.button.offsetTop-1;this._createActions(this._activeMode.handler),this._actionsContainer.style.top=i+"px",0===t&&(L.DomUtil.addClass(this._toolbarContainer,"leaflet-draw-toolbar-notop"),L.DomUtil.addClass(this._actionsContainer,"leaflet-draw-actions-top")),t===e&&(L.DomUtil.addClass(this._toolbarContainer,"leaflet-draw-toolbar-nobottom"),L.DomUtil.addClass(this._actionsContainer,"leaflet-draw-actions-bottom")),this._actionsContainer.style.display="block"},_hideActionsToolbar:function(){this._actionsContainer.style.display="none",L.DomUtil.removeClass(this._toolbarContainer,"leaflet-draw-toolbar-notop"),L.DomUtil.removeClass(this._toolbarContainer,"leaflet-draw-toolbar-nobottom"),L.DomUtil.removeClass(this._actionsContainer,"leaflet-draw-actions-top"),L.DomUtil.removeClass(this._actionsContainer,"leaflet-draw-actions-bottom")}}),L.Tooltip=L.Class.extend({initialize:function(t){this._map=t,this._popupPane=t._panes.popupPane,this._container=t.options.drawControlTooltips?L.DomUtil.create("div","leaflet-draw-tooltip",this._popupPane):null,this._singleLineLabel=!1},dispose:function(){this._container&&(this._popupPane.removeChild(this._container),this._container=null)},updateContent:function(t){return this._container?(t.subtext=t.subtext||"",0!==t.subtext.length||this._singleLineLabel?t.subtext.length>0&&this._singleLineLabel&&(L.DomUtil.removeClass(this._container,"leaflet-draw-tooltip-single"),this._singleLineLabel=!1):(L.DomUtil.addClass(this._container,"leaflet-draw-tooltip-single"),this._singleLineLabel=!0),this._container.innerHTML=(t.subtext.length>0?'<span class="leaflet-draw-tooltip-subtext">'+t.subtext+"</span><br />":"")+"<span>"+t.text+"</span>",this):this},updatePosition:function(t){var e=this._map.latLngToLayerPoint(t),i=this._container;return this._container&&(i.style.visibility="inherit",L.DomUtil.setPosition(i,e)),this},showAsError:function(){return this._container&&L.DomUtil.addClass(this._container,"leaflet-error-draw-tooltip"),this},removeError:function(){return this._container&&L.DomUtil.removeClass(this._container,"leaflet-error-draw-tooltip"),this}}),L.DrawToolbar=L.Toolbar.extend({statics:{TYPE:"draw"},options:{polyline:{},polygon:{},rectangle:{},circle:{},marker:{}},initialize:function(t){for(var e in this.options)this.options.hasOwnProperty(e)&&t[e]&&(t[e]=L.extend({},this.options[e],t[e]));this._toolbarClass="leaflet-draw-draw",L.Toolbar.prototype.initialize.call(this,t)},getModeHandlers:function(t){return[{enabled:this.options.polyline,handler:new L.Draw.Polyline(t,this.options.polyline),title:L.drawLocal.draw.toolbar.buttons.polyline},{enabled:this.options.polygon,handler:new L.Draw.Polygon(t,this.options.polygon),title:L.drawLocal.draw.toolbar.buttons.polygon},{enabled:this.options.rectangle,handler:new L.Draw.Rectangle(t,this.options.rectangle),title:L.drawLocal.draw.toolbar.buttons.rectangle},{enabled:this.options.circle,handler:new L.Draw.Circle(t,this.options.circle),title:L.drawLocal.draw.toolbar.buttons.circle},{enabled:this.options.marker,handler:new L.Draw.Marker(t,this.options.marker),title:L.drawLocal.draw.toolbar.buttons.marker}]},getActions:function(t){return[{enabled:t.deleteLastVertex,title:L.drawLocal.draw.toolbar.undo.title,text:L.drawLocal.draw.toolbar.undo.text,callback:t.deleteLastVertex,context:t},{title:L.drawLocal.draw.toolbar.actions.title,text:L.drawLocal.draw.toolbar.actions.text,callback:this.disable,context:this}]},setOptions:function(t){L.setOptions(this,t);for(var e in this._modes)this._modes.hasOwnProperty(e)&&t.hasOwnProperty(e)&&this._modes[e].handler.setOptions(t[e])}}),L.EditToolbar=L.Toolbar.extend({statics:{TYPE:"edit"},options:{edit:{selectedPathOptions:{color:"#fe57a1",opacity:.6,dashArray:"10, 10",fill:!0,fillColor:"#fe57a1",fillOpacity:.1,maintainColor:!1}},remove:{},featureGroup:null},initialize:function(t){t.edit&&("undefined"==typeof t.edit.selectedPathOptions&&(t.edit.selectedPathOptions=this.options.edit.selectedPathOptions),t.edit.selectedPathOptions=L.extend({},this.options.edit.selectedPathOptions,t.edit.selectedPathOptions)),t.remove&&(t.remove=L.extend({},this.options.remove,t.remove)),this._toolbarClass="leaflet-draw-edit",L.Toolbar.prototype.initialize.call(this,t),this._selectedFeatureCount=0},getModeHandlers:function(t){var e=this.options.featureGroup;return[{enabled:this.options.edit,handler:new L.EditToolbar.Edit(t,{featureGroup:e,selectedPathOptions:this.options.edit.selectedPathOptions}),title:L.drawLocal.edit.toolbar.buttons.edit},{enabled:this.options.remove,handler:new L.EditToolbar.Delete(t,{featureGroup:e}),title:L.drawLocal.edit.toolbar.buttons.remove}]},getActions:function(){return[{title:L.drawLocal.edit.toolbar.actions.save.title,text:L.drawLocal.edit.toolbar.actions.save.text,callback:this._save,context:this},{title:L.drawLocal.edit.toolbar.actions.cancel.title,text:L.drawLocal.edit.toolbar.actions.cancel.text,callback:this.disable,context:this}]},addToolbar:function(t){var e=L.Toolbar.prototype.addToolbar.call(this,t);return this._checkDisabled(),this.options.featureGroup.on("layeradd layerremove",this._checkDisabled,this),e},removeToolbar:function(){this.options.featureGroup.off("layeradd layerremove",this._checkDisabled,this),L.Toolbar.prototype.removeToolbar.call(this)},disable:function(){this.enabled()&&(this._activeMode.handler.revertLayers(),L.Toolbar.prototype.disable.call(this))},_save:function(){this._activeMode.handler.save(),this._activeMode.handler.disable()},_checkDisabled:function(){var t,e=this.options.featureGroup,i=0!==e.getLayers().length;this.options.edit&&(t=this._modes[L.EditToolbar.Edit.TYPE].button,i?L.DomUtil.removeClass(t,"leaflet-disabled"):L.DomUtil.addClass(t,"leaflet-disabled"),t.setAttribute("title",i?L.drawLocal.edit.toolbar.buttons.edit:L.drawLocal.edit.toolbar.buttons.editDisabled)),this.options.remove&&(t=this._modes[L.EditToolbar.Delete.TYPE].button,i?L.DomUtil.removeClass(t,"leaflet-disabled"):L.DomUtil.addClass(t,"leaflet-disabled"),t.setAttribute("title",i?L.drawLocal.edit.toolbar.buttons.remove:L.drawLocal.edit.toolbar.buttons.removeDisabled))}}),L.EditToolbar.Edit=L.Handler.extend({statics:{TYPE:"edit"},includes:L.Mixin.Events,initialize:function(t,e){if(L.Handler.prototype.initialize.call(this,t),L.setOptions(this,e),this._featureGroup=e.featureGroup,!(this._featureGroup instanceof L.FeatureGroup))throw new Error("options.featureGroup must be a L.FeatureGroup");this._uneditedLayerProps={},this.type=L.EditToolbar.Edit.TYPE},enable:function(){!this._enabled&&this._hasAvailableLayers()&&(this.fire("enabled",{handler:this.type}),this._map.fire("draw:editstart",{handler:this.type}),L.Handler.prototype.enable.call(this),this._featureGroup.on("layeradd",this._enableLayerEdit,this).on("layerremove",this._disableLayerEdit,this))},disable:function(){this._enabled&&(this._featureGroup.off("layeradd",this._enableLayerEdit,this).off("layerremove",this._disableLayerEdit,this),L.Handler.prototype.disable.call(this),this._map.fire("draw:editstop",{handler:this.type}),this.fire("disabled",{handler:this.type}))},addHooks:function(){var t=this._map;t&&(t.getContainer().focus(),this._featureGroup.eachLayer(this._enableLayerEdit,this),this._tooltip=new L.Tooltip(this._map),this._tooltip.updateContent({text:L.drawLocal.edit.handlers.edit.tooltip.text,subtext:L.drawLocal.edit.handlers.edit.tooltip.subtext}),this._map.on("mousemove",this._onMouseMove,this))},removeHooks:function(){this._map&&(this._featureGroup.eachLayer(this._disableLayerEdit,this),this._uneditedLayerProps={},this._tooltip.dispose(),this._tooltip=null,this._map.off("mousemove",this._onMouseMove,this))},revertLayers:function(){this._featureGroup.eachLayer(function(t){this._revertLayer(t)},this)},save:function(){var t=new L.LayerGroup;this._featureGroup.eachLayer(function(e){e.edited&&(t.addLayer(e),e.edited=!1)}),this._map.fire("draw:edited",{layers:t})},_backupLayer:function(t){var e=L.Util.stamp(t);this._uneditedLayerProps[e]||(t instanceof L.Polyline||t instanceof L.Polygon||t instanceof L.Rectangle?this._uneditedLayerProps[e]={latlngs:L.LatLngUtil.cloneLatLngs(t.getLatLngs())}:t instanceof L.Circle?this._uneditedLayerProps[e]={latlng:L.LatLngUtil.cloneLatLng(t.getLatLng()),radius:t.getRadius()}:t instanceof L.Marker&&(this._uneditedLayerProps[e]={latlng:L.LatLngUtil.cloneLatLng(t.getLatLng())}))},_revertLayer:function(t){var e=L.Util.stamp(t);t.edited=!1,this._uneditedLayerProps.hasOwnProperty(e)&&(t instanceof L.Polyline||t instanceof L.Polygon||t instanceof L.Rectangle?t.setLatLngs(this._uneditedLayerProps[e].latlngs):t instanceof L.Circle?(t.setLatLng(this._uneditedLayerProps[e].latlng),t.setRadius(this._uneditedLayerProps[e].radius)):t instanceof L.Marker&&t.setLatLng(this._uneditedLayerProps[e].latlng),t.fire("revert-edited",{layer:t}))},_enableLayerEdit:function(t){var e,i=t.layer||t.target||t;this._backupLayer(i),this.options.selectedPathOptions&&(e=L.Util.extend({},this.options.selectedPathOptions),e.maintainColor&&(e.color=i.options.color,e.fillColor=i.options.fillColor),i.options.original=L.extend({},i.options),i.options.editing=e),i.editing.enable()},_disableLayerEdit:function(t){var e=t.layer||t.target||t;e.edited=!1,e.editing.disable(),delete e.options.editing,delete e.options.original},_onMouseMove:function(t){this._tooltip.updatePosition(t.latlng)},_hasAvailableLayers:function(){return 0!==this._featureGroup.getLayers().length}}),L.EditToolbar.Delete=L.Handler.extend({statics:{TYPE:"remove"},includes:L.Mixin.Events,initialize:function(t,e){if(L.Handler.prototype.initialize.call(this,t),L.Util.setOptions(this,e),this._deletableLayers=this.options.featureGroup,!(this._deletableLayers instanceof L.FeatureGroup))throw new Error("options.featureGroup must be a L.FeatureGroup");this.type=L.EditToolbar.Delete.TYPE},enable:function(){!this._enabled&&this._hasAvailableLayers()&&(this.fire("enabled",{handler:this.type}),this._map.fire("draw:deletestart",{handler:this.type}),L.Handler.prototype.enable.call(this),this._deletableLayers.on("layeradd",this._enableLayerDelete,this).on("layerremove",this._disableLayerDelete,this))},disable:function(){this._enabled&&(this._deletableLayers.off("layeradd",this._enableLayerDelete,this).off("layerremove",this._disableLayerDelete,this),L.Handler.prototype.disable.call(this),this._map.fire("draw:deletestop",{handler:this.type}),this.fire("disabled",{handler:this.type}))},addHooks:function(){var t=this._map;t&&(t.getContainer().focus(),this._deletableLayers.eachLayer(this._enableLayerDelete,this),this._deletedLayers=new L.LayerGroup,this._tooltip=new L.Tooltip(this._map),this._tooltip.updateContent({text:L.drawLocal.edit.handlers.remove.tooltip.text}),this._map.on("mousemove",this._onMouseMove,this))},removeHooks:function(){this._map&&(this._deletableLayers.eachLayer(this._disableLayerDelete,this),this._deletedLayers=null,this._tooltip.dispose(),this._tooltip=null,this._map.off("mousemove",this._onMouseMove,this))},revertLayers:function(){this._deletedLayers.eachLayer(function(t){this._deletableLayers.addLayer(t),t.fire("revert-deleted",{layer:t})},this)},save:function(){this._map.fire("draw:deleted",{layers:this._deletedLayers})},_enableLayerDelete:function(t){var e=t.layer||t.target||t;e.on("click",this._removeLayer,this)},_disableLayerDelete:function(t){var e=t.layer||t.target||t;e.off("click",this._removeLayer,this),this._deletedLayers.removeLayer(e)},_removeLayer:function(t){var e=t.layer||t.target||t;this._deletableLayers.removeLayer(e),this._deletedLayers.addLayer(e),e.fire("deleted")},_onMouseMove:function(t){this._tooltip.updatePosition(t.latlng)},_hasAvailableLayers:function(){return 0!==this._deletableLayers.getLayers().length}})}(window,document); | |
/***/ }, | |
/* 422 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(415); | |
__webpack_require__(423); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ScaledCircleMarkerFactory(Private) { | |
var _ = __webpack_require__(194); | |
var L = __webpack_require__(415); | |
var BaseMarker = Private(__webpack_require__(423)); | |
/** | |
* Map overlay: circle markers that are scaled to illustrate values | |
* | |
* @param map {Leaflet Object} | |
* @param mapData {geoJson Object} | |
* @param params {Object} | |
*/ | |
_['class'](ScaledCircleMarker).inherits(BaseMarker); | |
function ScaledCircleMarker(map, geoJson, params) { | |
var self = this; | |
ScaledCircleMarker.Super.apply(this, arguments); | |
// multiplier to reduce size of all circles | |
var scaleFactor = 0.6; | |
this._createMarkerGroup({ | |
pointToLayer: function pointToLayer(feature, latlng) { | |
var value = feature.properties.value; | |
var scaledRadius = self._radiusScale(value) * scaleFactor; | |
return L.circleMarker(latlng).setRadius(scaledRadius); | |
} | |
}); | |
} | |
/** | |
* radiusScale returns a number for scaled circle markers | |
* for relative sizing of markers | |
* | |
* @method _radiusScale | |
* @param value {Number} | |
* @return {Number} | |
*/ | |
ScaledCircleMarker.prototype._radiusScale = function (value) { | |
var precisionBiasBase = 5; | |
var precisionBiasNumerator = 200; | |
var zoom = this.map.getZoom(); | |
var maxValue = this.geoJson.properties.allmax; | |
var precision = _.max(this.geoJson.features.map(function (feature) { | |
return String(feature.properties.geohash).length; | |
})); | |
var pct = Math.abs(value) / Math.abs(maxValue); | |
var zoomRadius = 0.5 * Math.pow(2, zoom); | |
var precisionScale = precisionBiasNumerator / Math.pow(precisionBiasBase, precision); | |
// square root value percentage | |
return Math.pow(pct, 0.5) * zoomRadius * precisionScale; | |
}; | |
return ScaledCircleMarker; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 423 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(415); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function MarkerFactory() { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var L = __webpack_require__(415); | |
/** | |
* Base map marker overlay, all other markers inherit from this class | |
* | |
* @param map {Leaflet Object} | |
* @param geoJson {geoJson Object} | |
* @param params {Object} | |
*/ | |
function BaseMarker(map, geoJson, params) { | |
this.map = map; | |
this.geoJson = geoJson; | |
this.popups = []; | |
this._tooltipFormatter = params.tooltipFormatter || _.identity; | |
this._valueFormatter = params.valueFormatter || _.identity; | |
this._attr = params.attr || {}; | |
// set up the default legend colors | |
this.quantizeLegendColors(); | |
} | |
/** | |
* Adds legend div to each map when data is split | |
* uses d3 scale from BaseMarker.prototype.quantizeLegendColors | |
* | |
* @method addLegend | |
* @return {undefined} | |
*/ | |
BaseMarker.prototype.addLegend = function () { | |
// ensure we only ever create 1 legend | |
if (this._legend) return; | |
var self = this; | |
// create the legend control, keep a reference | |
self._legend = L.control({ position: 'bottomright' }); | |
self._legend.onAdd = function () { | |
// creates all the neccessary DOM elements for the control, adds listeners | |
// on relevant map events, and returns the element containing the control | |
var $div = $('<div>').addClass('tilemap-legend'); | |
_.each(self._legendColors, function (color, i) { | |
var labelText = self._legendQuantizer.invertExtent(color).map(self._valueFormatter).join(' – '); | |
var label = $('<div>').text(labelText); | |
var icon = $('<i>').css({ | |
background: color, | |
'border-color': self.darkerColor(color) | |
}); | |
label.append(icon); | |
$div.append(label); | |
}); | |
return $div.get(0); | |
}; | |
self._legend.addTo(self.map); | |
}; | |
/** | |
* Apply style with shading to feature | |
* | |
* @method applyShadingStyle | |
* @param value {Object} | |
* @return {Object} | |
*/ | |
BaseMarker.prototype.applyShadingStyle = function (value) { | |
var color = this._legendQuantizer(value); | |
return { | |
fillColor: color, | |
color: this.darkerColor(color), | |
weight: 1.5, | |
opacity: 1, | |
fillOpacity: 0.75 | |
}; | |
}; | |
/** | |
* Binds popup and events to each feature on map | |
* | |
* @method bindPopup | |
* @param feature {Object} | |
* @param layer {Object} | |
* return {undefined} | |
*/ | |
BaseMarker.prototype.bindPopup = function (feature, layer) { | |
var self = this; | |
var popup = layer.on({ | |
mouseover: function mouseover(e) { | |
var layer = e.target; | |
// bring layer to front if not older browser | |
if (!L.Browser.ie && !L.Browser.opera) { | |
layer.bringToFront(); | |
} | |
self._showTooltip(feature); | |
}, | |
mouseout: function mouseout(e) { | |
self._hidePopup(); | |
} | |
}); | |
self.popups.push(popup); | |
}; | |
/** | |
* d3 method returns a darker hex color, | |
* used for marker stroke color | |
* | |
* @method darkerColor | |
* @param color {String} hex color | |
* @param amount? {Number} amount to darken by | |
* @return {String} hex color | |
*/ | |
BaseMarker.prototype.darkerColor = function (color, amount) { | |
amount = amount || 1.3; | |
return d3.hcl(color).darker(amount).toString(); | |
}; | |
BaseMarker.prototype.destroy = function () { | |
var self = this; | |
// remove popups | |
self.popups = self.popups.filter(function (popup) { | |
popup.off('mouseover').off('mouseout'); | |
}); | |
if (self._legend) { | |
self.map.removeControl(self._legend); | |
self._legend = undefined; | |
} | |
// remove marker layer from map | |
if (self._markerGroup) { | |
self.map.removeLayer(self._markerGroup); | |
self._markerGroup = undefined; | |
} | |
}; | |
BaseMarker.prototype._addToMap = function () { | |
this.map.addLayer(this._markerGroup); | |
}; | |
/** | |
* Creates leaflet marker group, passing options to L.geoJson | |
* | |
* @method _createMarkerGroup | |
* @param options {Object} Options to pass to L.geoJson | |
*/ | |
BaseMarker.prototype._createMarkerGroup = function (options) { | |
var self = this; | |
var defaultOptions = { | |
onEachFeature: function onEachFeature(feature, layer) { | |
self.bindPopup(feature, layer); | |
}, | |
style: function style(feature) { | |
var value = _.get(feature, 'properties.value'); | |
return self.applyShadingStyle(value); | |
}, | |
filter: self._filterToMapBounds() | |
}; | |
this._markerGroup = L.geoJson(this.geoJson, _.defaults(defaultOptions, options)); | |
this._addToMap(); | |
}; | |
/** | |
* return whether feature is within map bounds | |
* | |
* @method _filterToMapBounds | |
* @param map {Leaflet Object} | |
* @return {boolean} | |
*/ | |
BaseMarker.prototype._filterToMapBounds = function () { | |
var self = this; | |
return function (feature) { | |
var mapBounds = self.map.getBounds(); | |
var bucketRectBounds = _.get(feature, 'properties.rectangle'); | |
return mapBounds.intersects(bucketRectBounds); | |
}; | |
}; | |
/** | |
* Checks if event latlng is within bounds of mapData | |
* features and shows tooltip for that feature | |
* | |
* @method _showTooltip | |
* @param feature {LeafletFeature} | |
* @param latLng? {Leaflet latLng} | |
* @return undefined | |
*/ | |
BaseMarker.prototype._showTooltip = function (feature, latLng) { | |
if (!this.map) return; | |
var lat = _.get(feature, 'geometry.coordinates.1'); | |
var lng = _.get(feature, 'geometry.coordinates.0'); | |
latLng = latLng || L.latLng(lat, lng); | |
var content = this._tooltipFormatter(feature); | |
if (!content) return; | |
this._createTooltip(content, latLng); | |
}; | |
BaseMarker.prototype._createTooltip = function (content, latLng) { | |
L.popup({ autoPan: false }).setLatLng(latLng).setContent(content).openOn(this.map); | |
}; | |
/** | |
* Closes the tooltip on the map | |
* | |
* @method _hidePopup | |
* @return undefined | |
*/ | |
BaseMarker.prototype._hidePopup = function () { | |
if (!this.map) return; | |
this.map.closePopup(); | |
}; | |
/** | |
* d3 quantize scale returns a hex color, used for marker fill color | |
* | |
* @method quantizeLegendColors | |
* return {undefined} | |
*/ | |
BaseMarker.prototype.quantizeLegendColors = function () { | |
var min = _.get(this.geoJson, 'properties.allmin', 0); | |
var max = _.get(this.geoJson, 'properties.allmax', 1); | |
var quantizeDomain = min !== max ? [min, max] : d3.scale.quantize().domain(); | |
var reds1 = ['#ff6128']; | |
var reds3 = ['#fecc5c', '#fd8d3c', '#e31a1c']; | |
var reds5 = ['#fed976', '#feb24c', '#fd8d3c', '#f03b20', '#bd0026']; | |
var bottomCutoff = 2; | |
var middleCutoff = 24; | |
if (max - min <= bottomCutoff) { | |
this._legendColors = reds1; | |
} else if (max - min <= middleCutoff) { | |
this._legendColors = reds3; | |
} else { | |
this._legendColors = reds5; | |
} | |
this._legendQuantizer = d3.scale.quantize().domain(quantizeDomain).range(this._legendColors); | |
}; | |
return BaseMarker; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 424 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(415); | |
__webpack_require__(423); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ShadedCircleMarkerFactory(Private) { | |
var _ = __webpack_require__(194); | |
var L = __webpack_require__(415); | |
var BaseMarker = Private(__webpack_require__(423)); | |
/** | |
* Map overlay: circle markers that are shaded to illustrate values | |
* | |
* @param map {Leaflet Object} | |
* @param mapData {geoJson Object} | |
* @return {Leaflet object} featureLayer | |
*/ | |
_['class'](ShadedCircleMarker).inherits(BaseMarker); | |
function ShadedCircleMarker(map, geoJson, params) { | |
var self = this; | |
ShadedCircleMarker.Super.apply(this, arguments); | |
// super min and max from all chart data | |
var min = this.geoJson.properties.allmin; | |
var max = this.geoJson.properties.allmax; | |
// multiplier to reduce size of all circles | |
var scaleFactor = 0.8; | |
this._createMarkerGroup({ | |
pointToLayer: function pointToLayer(feature, latlng) { | |
var radius = self._geohashMinDistance(feature) * scaleFactor; | |
return L.circle(latlng, radius); | |
} | |
}); | |
} | |
/** | |
* _geohashMinDistance returns a min distance in meters for sizing | |
* circle markers to fit within geohash grid rectangle | |
* | |
* @method _geohashMinDistance | |
* @param feature {Object} | |
* @return {Number} | |
*/ | |
ShadedCircleMarker.prototype._geohashMinDistance = function (feature) { | |
var centerPoint = _.get(feature, 'properties.center'); | |
var geohashRect = _.get(feature, 'properties.rectangle'); | |
// centerPoint is an array of [lat, lng] | |
// geohashRect is the 4 corners of the geoHash rectangle | |
// an array that starts at the southwest corner and proceeds | |
// clockwise, each value being an array of [lat, lng] | |
// center lat and southeast lng | |
var east = L.latLng([centerPoint[0], geohashRect[2][1]]); | |
// southwest lat and center lng | |
var north = L.latLng([geohashRect[3][0], centerPoint[1]]); | |
// get latLng of geohash center point | |
var center = L.latLng([centerPoint[0], centerPoint[1]]); | |
// get smallest radius at center of geohash grid rectangle | |
var eastRadius = Math.floor(center.distanceTo(east)); | |
var northRadius = Math.floor(center.distanceTo(north)); | |
return _.min([eastRadius, northRadius]); | |
}; | |
return ShadedCircleMarker; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 425 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(415); | |
__webpack_require__(423); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function GeohashGridMarkerFactory(Private) { | |
var _ = __webpack_require__(194); | |
var L = __webpack_require__(415); | |
var BaseMarker = Private(__webpack_require__(423)); | |
/** | |
* Map overlay: rectangles that show the geohash grid bounds | |
* | |
* @param map {Leaflet Object} | |
* @param geoJson {geoJson Object} | |
* @param params {Object} | |
*/ | |
_['class'](GeohashGridMarker).inherits(BaseMarker); | |
function GeohashGridMarker(map, geoJson, params) { | |
var self = this; | |
GeohashGridMarker.Super.apply(this, arguments); | |
// super min and max from all chart data | |
var min = this.geoJson.properties.allmin; | |
var max = this.geoJson.properties.allmax; | |
this._createMarkerGroup({ | |
pointToLayer: function pointToLayer(feature, latlng) { | |
var geohashRect = feature.properties.rectangle; | |
// get bounds from northEast[3] and southWest[1] | |
// corners in geohash rectangle | |
var corners = [[geohashRect[3][0], geohashRect[3][1]], [geohashRect[1][0], geohashRect[1][1]]]; | |
return L.rectangle(corners); | |
} | |
}); | |
} | |
return GeohashGridMarker; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 426 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(415); | |
__webpack_require__(423); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function HeatmapMarkerFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var L = __webpack_require__(415); | |
var BaseMarker = Private(__webpack_require__(423)); | |
/** | |
* Map overlay: canvas layer with leaflet.heat plugin | |
* | |
* @param map {Leaflet Object} | |
* @param geoJson {geoJson Object} | |
* @param params {Object} | |
*/ | |
_['class'](HeatmapMarker).inherits(BaseMarker); | |
function HeatmapMarker(map, geoJson, params) { | |
var self = this; | |
this._disableTooltips = false; | |
HeatmapMarker.Super.apply(this, arguments); | |
this._createMarkerGroup({ | |
radius: +this._attr.heatRadius, | |
blur: +this._attr.heatBlur, | |
maxZoom: +this._attr.heatMaxZoom, | |
minOpacity: +this._attr.heatMinOpacity | |
}); | |
} | |
/** | |
* Does nothing, heatmaps don't have a legend | |
* | |
* @method addLegend | |
* @return {undefined} | |
*/ | |
HeatmapMarker.prototype.addLegend = _.noop; | |
HeatmapMarker.prototype._createMarkerGroup = function (options) { | |
var max = _.get(this.geoJson, 'properties.allmax'); | |
var points = this._dataToHeatArray(max); | |
this._markerGroup = L.heatLayer(points, options); | |
this._fixTooltips(); | |
this._addToMap(); | |
}; | |
HeatmapMarker.prototype._fixTooltips = function () { | |
var self = this; | |
var debouncedMouseMoveLocation = _.debounce(mouseMoveLocation.bind(this), 15, { | |
'leading': true, | |
'trailing': false | |
}); | |
if (!this._disableTooltips && this._attr.addTooltip) { | |
this.map.on('mousemove', debouncedMouseMoveLocation); | |
this.map.on('mouseout', function () { | |
self.map.closePopup(); | |
}); | |
this.map.on('mousedown', function () { | |
self._disableTooltips = true; | |
self.map.closePopup(); | |
}); | |
this.map.on('mouseup', function () { | |
self._disableTooltips = false; | |
}); | |
} | |
function mouseMoveLocation(e) { | |
var latlng = e.latlng; | |
this.map.closePopup(); | |
// unhighlight all svgs | |
d3.selectAll('path.geohash', this.chartEl).classed('geohash-hover', false); | |
if (!this.geoJson.features.length || this._disableTooltips) { | |
return; | |
} | |
// find nearest feature to event latlng | |
var feature = this._nearestFeature(latlng); | |
// show tooltip if close enough to event latlng | |
if (this._tooltipProximity(latlng, feature)) { | |
this._showTooltip(feature, latlng); | |
} | |
} | |
}; | |
/** | |
* returns a memoized Leaflet latLng for given geoJson feature | |
* | |
* @method addLatLng | |
* @param feature {geoJson Object} | |
* @return {Leaflet latLng Object} | |
*/ | |
HeatmapMarker.prototype._getLatLng = _.memoize(function (feature) { | |
return L.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]); | |
}, function (feature) { | |
// turn coords into a string for the memoize cache | |
return [feature.geometry.coordinates[1], feature.geometry.coordinates[0]].join(','); | |
}); | |
/** | |
* Finds nearest feature in mapData to event latlng | |
* | |
* @method _nearestFeature | |
* @param latLng {Leaflet latLng} | |
* @return nearestPoint {Leaflet latLng} | |
*/ | |
HeatmapMarker.prototype._nearestFeature = function (latLng) { | |
var self = this; | |
var nearest; | |
if (latLng.lng < -180 || latLng.lng > 180) { | |
return; | |
} | |
_.reduce(this.geoJson.features, function (distance, feature) { | |
var featureLatLng = self._getLatLng(feature); | |
var dist = latLng.distanceTo(featureLatLng); | |
if (dist < distance) { | |
nearest = feature; | |
return dist; | |
} | |
return distance; | |
}, Infinity); | |
return nearest; | |
}; | |
/** | |
* display tooltip if feature is close enough to event latlng | |
* | |
* @method _tooltipProximity | |
* @param latlng {Leaflet latLng Object} | |
* @param feature {geoJson Object} | |
* @return {Boolean} | |
*/ | |
HeatmapMarker.prototype._tooltipProximity = function (latlng, feature) { | |
if (!feature) return; | |
var showTip = false; | |
var featureLatLng = this._getLatLng(feature); | |
// zoomScale takes map zoom and returns proximity value for tooltip display | |
// domain (input values) is map zoom (min 1 and max 18) | |
// range (output values) is distance in meters | |
// used to compare proximity of event latlng to feature latlng | |
var zoomScale = d3.scale.linear().domain([1, 4, 7, 10, 13, 16, 18]).range([1000000, 300000, 100000, 15000, 2000, 150, 50]); | |
var proximity = zoomScale(this.map.getZoom()); | |
var distance = latlng.distanceTo(featureLatLng); | |
// maxLngDif is max difference in longitudes | |
// to prevent feature tooltip from appearing 360° | |
// away from event latlng | |
var maxLngDif = 40; | |
var lngDif = Math.abs(latlng.lng - featureLatLng.lng); | |
if (distance < proximity && lngDif < maxLngDif) { | |
showTip = true; | |
} | |
var testScale = d3.scale.pow().exponent(0.2).domain([1, 18]).range([1500000, 50]); | |
return showTip; | |
}; | |
/** | |
* returns data for data for heat map intensity | |
* if heatNormalizeData attribute is checked/true | |
• normalizes data for heat map intensity | |
* | |
* @method _dataToHeatArray | |
* @param max {Number} | |
* @return {Array} | |
*/ | |
HeatmapMarker.prototype._dataToHeatArray = function (max) { | |
var self = this; | |
var mapData = this.geoJson; | |
return this.geoJson.features.map(function (feature) { | |
var lat = feature.properties.center[0]; | |
var lng = feature.properties.center[1]; | |
var heatIntensity; | |
if (!self._attr.heatNormalizeData) { | |
// show bucket value on heatmap | |
heatIntensity = feature.properties.value; | |
} else { | |
// show bucket value normalized to max value | |
heatIntensity = parseInt(feature.properties.value / max * 100); | |
} | |
return [lat, lng, heatIntensity]; | |
}); | |
}; | |
return HeatmapMarker; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 427 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(428); | |
__webpack_require__(433); | |
__webpack_require__(434); | |
__webpack_require__(435); | |
__webpack_require__(436); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function VisTypeFactory(Private) { | |
/** | |
* Provides the visualizations for the vislib | |
* | |
* @module vislib | |
* @submodule VisTypeFactory | |
* @param Private {Object} Loads any function as an angular module | |
* @return {Function} Returns an Object of Visualization classes | |
*/ | |
return { | |
histogram: Private(__webpack_require__(428)), | |
pie: Private(__webpack_require__(433)), | |
line: Private(__webpack_require__(434)), | |
area: Private(__webpack_require__(435)), | |
tile_map: Private(__webpack_require__(436)) | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 428 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(228); | |
__webpack_require__(361); | |
__webpack_require__(429); | |
__webpack_require__(432); | |
__webpack_require__(222); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ColumnChartFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var moment = __webpack_require__(228); | |
var DataClass = Private(__webpack_require__(361)); | |
var PointSeriesChart = Private(__webpack_require__(429)); | |
var TimeMarker = Private(__webpack_require__(432)); | |
var errors = __webpack_require__(222); | |
/** | |
* Vertical Bar Chart Visualization: renders vertical and/or stacked bars | |
* | |
* @class ColumnChart | |
* @constructor | |
* @extends Chart | |
* @param handler {Object} Reference to the Handler Class Constructor | |
* @param el {HTMLElement} HTML element to which the chart will be appended | |
* @param chartData {Object} Elasticsearch query results for this specific chart | |
*/ | |
_['class'](ColumnChart).inherits(PointSeriesChart); | |
function ColumnChart(handler, chartEl, chartData) { | |
if (!(this instanceof ColumnChart)) { | |
return new ColumnChart(handler, chartEl, chartData); | |
} | |
ColumnChart.Super.apply(this, arguments); | |
// Column chart specific attributes | |
this._attr = _.defaults(handler._attr || {}, { | |
xValue: function xValue(d) { | |
return d.x; | |
}, | |
yValue: function yValue(d) { | |
return d.y; | |
} | |
}); | |
} | |
/** | |
* Adds SVG rect to Vertical Bar Chart | |
* | |
* @method addBars | |
* @param svg {HTMLElement} SVG to which rect are appended | |
* @param layers {Array} Chart data array | |
* @returns {D3.UpdateSelection} SVG with rect added | |
*/ | |
ColumnChart.prototype.addBars = function (svg, layers) { | |
var self = this; | |
var color = this.handler.data.getColorFunc(); | |
var tooltip = this.tooltip; | |
var isTooltip = this._attr.addTooltip; | |
var layer; | |
var bars; | |
layer = svg.selectAll('.layer').data(layers).enter().append('g').attr('class', function (d, i) { | |
return 'series ' + i; | |
}); | |
bars = layer.selectAll('rect').data(function (d) { | |
return d; | |
}); | |
bars.exit().remove(); | |
bars.enter().append('rect').call(this._addIdentifier).attr('fill', function (d) { | |
return color(d.label); | |
}); | |
self.updateBars(bars); | |
// Add tooltip | |
if (isTooltip) { | |
bars.call(tooltip.render()); | |
} | |
return bars; | |
}; | |
/** | |
* Determines whether bars are grouped or stacked and updates the D3 | |
* selection | |
* | |
* @method updateBars | |
* @param bars {D3.UpdateSelection} SVG with rect added | |
* @returns {D3.UpdateSelection} | |
*/ | |
ColumnChart.prototype.updateBars = function (bars) { | |
var offset = this._attr.mode; | |
if (offset === 'grouped') { | |
return this.addGroupedBars(bars); | |
} | |
return this.addStackedBars(bars); | |
}; | |
/** | |
* Adds stacked bars to column chart visualization | |
* | |
* @method addStackedBars | |
* @param bars {D3.UpdateSelection} SVG with rect added | |
* @returns {D3.UpdateSelection} | |
*/ | |
ColumnChart.prototype.addStackedBars = function (bars) { | |
var data = this.chartData; | |
var xScale = this.handler.xAxis.xScale; | |
var yScale = this.handler.yAxis.yScale; | |
var height = yScale.range()[0]; | |
var yMin = this.handler.yAxis.yScale.domain()[0]; | |
var self = this; | |
var barWidth; | |
if (data.ordered && data.ordered.date) { | |
var start = data.ordered.min; | |
var end = moment(data.ordered.min).add(data.ordered.interval).valueOf(); | |
barWidth = xScale(end) - xScale(start); | |
barWidth = barWidth - Math.min(barWidth * 0.25, 15); | |
} | |
// update | |
bars.attr('x', function (d) { | |
return xScale(d.x); | |
}).attr('width', function () { | |
return barWidth || xScale.rangeBand(); | |
}).attr('y', function (d) { | |
if (d.y < 0) { | |
return yScale(d.y0); | |
} | |
return yScale(d.y0 + d.y); | |
}).attr('height', function (d) { | |
if (d.y < 0) { | |
return Math.abs(yScale(d.y0 + d.y) - yScale(d.y0)); | |
} | |
// Due to an issue with D3 not returning zeros correctly when using | |
// an offset='expand', need to add conditional statement to handle zeros | |
// appropriately | |
if (d._input.y === 0) { | |
return 0; | |
} | |
// for split bars or for one series, | |
// last series will have d.y0 = 0 | |
if (d.y0 === 0 && yMin > 0) { | |
return yScale(yMin) - yScale(d.y); | |
} | |
return yScale(d.y0) - yScale(d.y0 + d.y); | |
}); | |
return bars; | |
}; | |
/** | |
* Adds grouped bars to column chart visualization | |
* | |
* @method addGroupedBars | |
* @param bars {D3.UpdateSelection} SVG with rect added | |
* @returns {D3.UpdateSelection} | |
*/ | |
ColumnChart.prototype.addGroupedBars = function (bars) { | |
var xScale = this.handler.xAxis.xScale; | |
var yScale = this.handler.yAxis.yScale; | |
var yMin = this.handler.yAxis.yMin; | |
var data = this.chartData; | |
var n = data.series.length; | |
var height = yScale.range()[0]; | |
var groupSpacingPercentage = 0.15; | |
var isTimeScale = data.ordered && data.ordered.date; | |
var minWidth = 1; | |
var barWidth; | |
// update | |
bars.attr('x', function (d, i, j) { | |
if (isTimeScale) { | |
var groupWidth = xScale(data.ordered.min + data.ordered.interval) - xScale(data.ordered.min); | |
var groupSpacing = groupWidth * groupSpacingPercentage; | |
barWidth = (groupWidth - groupSpacing) / n; | |
return xScale(d.x) + barWidth * j; | |
} | |
return xScale(d.x) + xScale.rangeBand() / n * j; | |
}).attr('width', function () { | |
if (barWidth < minWidth) { | |
throw new errors.ContainerTooSmall(); | |
} | |
if (isTimeScale) { | |
return barWidth; | |
} | |
return xScale.rangeBand() / n; | |
}).attr('y', function (d) { | |
if (d.y < 0) { | |
return yScale(0); | |
} | |
return yScale(d.y); | |
}).attr('height', function (d) { | |
return Math.abs(yScale(0) - yScale(d.y)); | |
}); | |
return bars; | |
}; | |
/** | |
* Adds Events to SVG rect | |
* Visualization is only brushable when a brush event is added | |
* If a brush event is added, then a function should be returned. | |
* | |
* @method addBarEvents | |
* @param element {D3.UpdateSelection} target | |
* @param svg {D3.UpdateSelection} chart SVG | |
* @returns {D3.Selection} rect with event listeners attached | |
*/ | |
ColumnChart.prototype.addBarEvents = function (element, svg) { | |
var events = this.events; | |
var isBrushable = events.isBrushable(); | |
var brush = isBrushable ? events.addBrushEvent(svg) : undefined; | |
var hover = events.addHoverEvent(); | |
var mouseout = events.addMouseoutEvent(); | |
var click = events.addClickEvent(); | |
var attachedEvents = element.call(hover).call(mouseout).call(click); | |
if (isBrushable) { | |
attachedEvents.call(brush); | |
} | |
return attachedEvents; | |
}; | |
/** | |
* Renders d3 visualization | |
* | |
* @method draw | |
* @returns {Function} Creates the vertical bar chart | |
*/ | |
ColumnChart.prototype.draw = function () { | |
var self = this; | |
var $elem = $(this.chartEl); | |
var margin = this._attr.margin; | |
var elWidth = this._attr.width = $elem.width(); | |
var elHeight = this._attr.height = $elem.height(); | |
var yMin = this.handler.yAxis.yMin; | |
var yScale = this.handler.yAxis.yScale; | |
var xScale = this.handler.xAxis.xScale; | |
var minWidth = 20; | |
var minHeight = 20; | |
var addTimeMarker = this._attr.addTimeMarker; | |
var times = this._attr.times || []; | |
var timeMarker; | |
var div; | |
var svg; | |
var width; | |
var height; | |
var layers; | |
var bars; | |
return function (selection) { | |
selection.each(function (data) { | |
layers = self.stackData(data); | |
width = elWidth; | |
height = elHeight - margin.top - margin.bottom; | |
if (addTimeMarker) { | |
timeMarker = new TimeMarker(times, xScale, height); | |
} | |
if (width < minWidth || height < minHeight) { | |
throw new errors.ContainerTooSmall(); | |
} | |
div = d3.select(this); | |
svg = div.append('svg').attr('width', width).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(0,' + margin.top + ')'); | |
bars = self.addBars(svg, layers); | |
self.createEndZones(svg); | |
// Adds event listeners | |
self.addBarEvents(bars, svg); | |
var line = svg.append('line').attr('class', 'base-line').attr('x1', 0).attr('y1', yScale(0)).attr('x2', width).attr('y2', yScale(0)).style('stroke', '#ddd').style('stroke-width', 1); | |
if (addTimeMarker) { | |
timeMarker.render(svg); | |
} | |
return svg; | |
}); | |
}; | |
}; | |
return ColumnChart; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 429 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(430); | |
__webpack_require__(401); | |
__webpack_require__(431); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function PointSeriesChartProvider(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var Chart = Private(__webpack_require__(430)); | |
var Tooltip = Private(__webpack_require__(401)); | |
var touchdownTmpl = _.template(__webpack_require__(431)); | |
_['class'](PointSeriesChart).inherits(Chart); | |
function PointSeriesChart(handler, chartEl, chartData) { | |
if (!(this instanceof PointSeriesChart)) { | |
return new PointSeriesChart(handler, chartEl, chartData); | |
} | |
PointSeriesChart.Super.apply(this, arguments); | |
} | |
PointSeriesChart.prototype._stackMixedValues = function (stackCount) { | |
var currentStackOffsets = [0, 0]; | |
var currentStackIndex = 0; | |
return function (d, y0, y) { | |
var firstStack = currentStackIndex % stackCount === 0; | |
var lastStack = ++currentStackIndex === stackCount; | |
if (firstStack) { | |
currentStackOffsets = [0, 0]; | |
} | |
if (lastStack) currentStackIndex = 0; | |
if (y >= 0) { | |
d.y0 = currentStackOffsets[1]; | |
currentStackOffsets[1] += y; | |
} else { | |
d.y0 = currentStackOffsets[0]; | |
currentStackOffsets[0] += y; | |
} | |
}; | |
}; | |
/** | |
* Stacks chart data values | |
* | |
* @method stackData | |
* @param data {Object} Elasticsearch query result for this chart | |
* @returns {Array} Stacked data objects with x, y, and y0 values | |
*/ | |
PointSeriesChart.prototype.stackData = function (data) { | |
var self = this; | |
var isHistogram = this._attr.type === 'histogram' && this._attr.mode === 'stacked'; | |
var stack = this._attr.stack; | |
if (isHistogram) stack.out(self._stackMixedValues(data.series.length)); | |
return stack(data.series.map(function (d) { | |
var label = d.label; | |
return d.values.map(function (e, i) { | |
return { | |
_input: e, | |
label: label, | |
x: self._attr.xValue.call(d.values, e, i), | |
y: self._attr.yValue.call(d.values, e, i) | |
}; | |
}); | |
})); | |
}; | |
PointSeriesChart.prototype._invalidLogScaleValues = function (data) { | |
return data.series && data.series.some(function (d) { | |
return d.values && d.values.some(function (e) { | |
return e.y < 1; | |
}); | |
}); | |
}; | |
/** | |
* Creates rects to show buckets outside of the ordered.min and max, returns rects | |
* | |
* @param xScale {Function} D3 xScale function | |
* @param svg {HTMLElement} Reference to SVG | |
* @method createEndZones | |
* @returns {D3.Selection} | |
*/ | |
PointSeriesChart.prototype.createEndZones = function (svg) { | |
var self = this; | |
var xAxis = this.handler.xAxis; | |
var xScale = xAxis.xScale; | |
var ordered = xAxis.ordered; | |
var missingMinMax = !ordered || _.isUndefined(ordered.min) || _.isUndefined(ordered.max); | |
if (missingMinMax || ordered.endzones === false) return; | |
var attr = this.handler._attr; | |
var height = attr.height; | |
var width = attr.width; | |
var margin = attr.margin; | |
var color = '#004c99'; | |
// we don't want to draw endzones over our min and max values, they | |
// are still a part of the dataset. We want to start the endzones just | |
// outside of them so we will use these values rather than ordered.min/max | |
var oneUnit = (ordered.units || _.identity)(1); | |
var beyondMin = ordered.min - oneUnit; | |
var beyondMax = ordered.max + oneUnit; | |
// points on this axis represent the amount of time they cover, | |
// so draw the endzones at the actual time bounds | |
var leftEndzone = { | |
x: 0, | |
w: Math.max(xScale(ordered.min), 0) | |
}; | |
var rightLastVal = xAxis.expandLastBucket ? ordered.max : Math.min(ordered.max, _.last(xAxis.xValues)); | |
var rightStart = rightLastVal + oneUnit; | |
var rightEndzone = { | |
x: xScale(rightStart), | |
w: Math.max(width - xScale(rightStart), 0) | |
}; | |
this.endzones = svg.selectAll('.layer').data([leftEndzone, rightEndzone]).enter().insert('g', '.brush').attr('class', 'endzone').append('rect').attr('class', 'zone').attr('x', function (d) { | |
return d.x; | |
}).attr('y', 0).attr('height', height - margin.top - margin.bottom).attr('width', function (d) { | |
return d.w; | |
}); | |
function callPlay(event) { | |
var boundData = event.target.__data__; | |
var mouseChartXCoord = event.clientX - self.chartEl.getBoundingClientRect().left; | |
var wholeBucket = boundData && boundData.x != null; | |
// the min and max that the endzones start in | |
var min = leftEndzone.w; | |
var max = rightEndzone.x; | |
// bounds of the cursor to consider | |
var xLeft = mouseChartXCoord; | |
var xRight = mouseChartXCoord; | |
if (wholeBucket) { | |
xLeft = xScale(boundData.x); | |
xRight = xScale(xAxis.addInterval(boundData.x)); | |
} | |
return { | |
wholeBucket: wholeBucket, | |
touchdown: min > xLeft || max < xRight | |
}; | |
} | |
function textFormatter() { | |
return touchdownTmpl(callPlay(d3.event)); | |
} | |
var endzoneTT = new Tooltip('endzones', this.handler.el, textFormatter, null); | |
this.tooltips.push(endzoneTT); | |
endzoneTT.order = 0; | |
endzoneTT.showCondition = function inEndzone() { | |
return callPlay(d3.event).touchdown; | |
}; | |
endzoneTT.render()(svg); | |
}; | |
return PointSeriesChart; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 430 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(222); | |
__webpack_require__(400); | |
__webpack_require__(401); | |
__webpack_require__(404); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ChartBaseClass(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var errors = __webpack_require__(222); | |
var Dispatch = Private(__webpack_require__(400)); | |
var Tooltip = Private(__webpack_require__(401)); | |
var dataLabel = __webpack_require__(404); | |
/** | |
* The Base Class for all visualizations. | |
* | |
* @class Chart | |
* @constructor | |
* @param handler {Object} Reference to the Handler Class Constructor | |
* @param el {HTMLElement} HTML element to which the chart will be appended | |
* @param chartData {Object} Elasticsearch query results for this specific chart | |
*/ | |
function Chart(handler, el, chartData) { | |
if (!(this instanceof Chart)) { | |
return new Chart(handler, el, chartData); | |
} | |
this.handler = handler; | |
this.chartEl = el; | |
this.chartData = chartData; | |
this.tooltips = []; | |
var events = this.events = new Dispatch(handler); | |
if (_.get(this.handler, '_attr.addTooltip')) { | |
var $el = this.handler.el; | |
var formatter = this.handler.data.get('tooltipFormatter'); | |
// Add tooltip | |
this.tooltip = new Tooltip('chart', $el, formatter, events); | |
this.tooltips.push(this.tooltip); | |
} | |
this._attr = _.defaults(this.handler._attr || {}, {}); | |
this._addIdentifier = _.bind(this._addIdentifier, this); | |
} | |
/** | |
* Renders the chart(s) | |
* | |
* @method render | |
* @returns {HTMLElement} Contains the D3 chart | |
*/ | |
Chart.prototype.render = function () { | |
var selection = d3.select(this.chartEl); | |
selection.selectAll('*').remove(); | |
selection.call(this.draw()); | |
}; | |
/** | |
* Append the data label to the element | |
* | |
* @method _addIdentifier | |
* @param selection {Object} d3 select object | |
*/ | |
Chart.prototype._addIdentifier = function (selection, labelProp) { | |
labelProp = labelProp || 'label'; | |
var labels = this.handler.data.labels; | |
function resolveLabel(datum) { | |
if (labels.length === 1) return labels[0]; | |
if (datum[0]) return datum[0][labelProp]; | |
return datum[labelProp]; | |
} | |
selection.each(function (datum) { | |
var label = resolveLabel(datum); | |
if (label != null) dataLabel(this, label); | |
}); | |
}; | |
/** | |
* Removes all DOM elements from the root element | |
* | |
* @method destroy | |
*/ | |
Chart.prototype.destroy = function () { | |
var selection = d3.select(this.chartEl); | |
this.events.removeAllListeners(); | |
this.tooltips.forEach(function (tooltip) { | |
tooltip.destroy(); | |
}); | |
selection.remove(); | |
selection = null; | |
}; | |
return Chart; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 431 */ | |
/***/ function(module, exports) { | |
module.exports = "<p class=\"vis-tooltip-header bg-info\">\n <i class=\"fa fa-info-circle vis-tooltip-header-icon\"></i>\n <span class=\"vis-tooltip-header-text\">\n <%= wholeBucket ? 'Part of this bucket' : 'This area' %>\n may contain partial data. <br> The selected time range does not fully cover it.\n </span>\n</p>" | |
/***/ }, | |
/* 432 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(230); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function TimeMarkerFactory() { | |
var d3 = __webpack_require__(359); | |
var dateMath = __webpack_require__(230); | |
function TimeMarker(times, xScale, height) { | |
if (!(this instanceof TimeMarker)) { | |
return new TimeMarker(times, xScale, height); | |
} | |
var currentTimeArr = [{ | |
'time': new Date().getTime(), | |
'class': 'time-marker', | |
'color': '#c80000', | |
'opacity': 0.3, | |
'width': 2 | |
}]; | |
this.xScale = xScale; | |
this.height = height; | |
this.times = times.length ? times.map(function (d) { | |
return { | |
'time': dateMath.parse(d.time), | |
'class': d['class'] || 'time-marker', | |
'color': d.color || '#c80000', | |
'opacity': d.opacity || 0.3, | |
'width': d.width || 2 | |
}; | |
}) : currentTimeArr; | |
} | |
TimeMarker.prototype._isTimeBasedChart = function (selection) { | |
var data = selection.data(); | |
return data.every(function (datum) { | |
return datum.ordered && datum.ordered.date; | |
}); | |
}; | |
TimeMarker.prototype.render = function (selection) { | |
var self = this; | |
// return if not time based chart | |
if (!self._isTimeBasedChart(selection)) return; | |
selection.each(function () { | |
d3.select(this).selectAll('time-marker').data(self.times).enter().append('line').attr('class', function (d) { | |
return d['class']; | |
}).attr('pointer-events', 'none').attr('stroke', function (d) { | |
return d.color; | |
}).attr('stroke-width', function (d) { | |
return d.width; | |
}).attr('stroke-opacity', function (d) { | |
return d.opacity; | |
}).attr('x1', function (d) { | |
return self.xScale(d.time); | |
}).attr('x2', function (d) { | |
return self.xScale(d.time); | |
}).attr('y1', self.height).attr('y2', self.xScale.range()[0]); | |
}); | |
}; | |
return TimeMarker; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 433 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(430); | |
__webpack_require__(222); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function PieChartFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var Chart = Private(__webpack_require__(430)); | |
var errors = __webpack_require__(222); | |
/** | |
* Pie Chart Visualization | |
* | |
* @class PieChart | |
* @constructor | |
* @extends Chart | |
* @param handler {Object} Reference to the Handler Class Constructor | |
* @param el {HTMLElement} HTML element to which the chart will be appended | |
* @param chartData {Object} Elasticsearch query results for this specific chart | |
*/ | |
_['class'](PieChart).inherits(Chart); | |
function PieChart(handler, chartEl, chartData) { | |
if (!(this instanceof PieChart)) { | |
return new PieChart(handler, chartEl, chartData); | |
} | |
PieChart.Super.apply(this, arguments); | |
var charts = this.handler.data.getVisData(); | |
this._validatePieData(charts); | |
this._attr = _.defaults(handler._attr || {}, { | |
isDonut: handler._attr.isDonut || false | |
}); | |
} | |
/** | |
* Checks whether pie slices have all zero values. | |
* If so, an error is thrown. | |
*/ | |
PieChart.prototype._validatePieData = function (charts) { | |
var isAllZeros = charts.every(function (chart) { | |
return chart.slices.children.length === 0; | |
}); | |
if (isAllZeros) { | |
throw new errors.PieContainsAllZeros(); | |
} | |
}; | |
/** | |
* Adds Events to SVG paths | |
* | |
* @method addPathEvents | |
* @param element {D3.Selection} Reference to SVG path | |
* @returns {D3.Selection} SVG path with event listeners attached | |
*/ | |
PieChart.prototype.addPathEvents = function (element) { | |
var events = this.events; | |
return element.call(events.addHoverEvent()).call(events.addMouseoutEvent()).call(events.addClickEvent()); | |
}; | |
PieChart.prototype.convertToPercentage = function (slices) { | |
(function assignPercentages(slices) { | |
if (slices.sumOfChildren != null) return; | |
var parent = slices; | |
var children = parent.children; | |
var parentPercent = parent.percentOfParent; | |
var sum = parent.sumOfChildren = Math.abs(children.reduce(function (sum, child) { | |
return sum + Math.abs(child.size); | |
}, 0)); | |
children.forEach(function (child) { | |
child.percentOfGroup = Math.abs(child.size) / sum; | |
child.percentOfParent = child.percentOfGroup; | |
if (parentPercent != null) { | |
child.percentOfParent *= parentPercent; | |
} | |
if (child.children) { | |
assignPercentages(child); | |
} | |
}); | |
})(slices); | |
}; | |
/** | |
* Adds pie paths to SVG | |
* | |
* @method addPath | |
* @param width {Number} Width of SVG | |
* @param height {Number} Height of SVG | |
* @param svg {HTMLElement} Chart SVG | |
* @param slices {Object} Chart data | |
* @returns {D3.Selection} SVG with paths attached | |
*/ | |
PieChart.prototype.addPath = function (width, height, svg, slices) { | |
var self = this; | |
var marginFactor = 0.95; | |
var isDonut = self._attr.isDonut; | |
var radius = Math.min(width, height) / 2 * marginFactor; | |
var color = self.handler.data.getPieColorFunc(); | |
var tooltip = self.tooltip; | |
var isTooltip = self._attr.addTooltip; | |
var partition = d3.layout.partition().sort(null).value(function (d) { | |
return d.percentOfParent * 100; | |
}); | |
var x = d3.scale.linear().range([0, 2 * Math.PI]); | |
var y = d3.scale.sqrt().range([0, radius]); | |
var arc = d3.svg.arc().startAngle(function (d) { | |
return Math.max(0, Math.min(2 * Math.PI, x(d.x))); | |
}).endAngle(function (d) { | |
return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); | |
}).innerRadius(function (d) { | |
// option for a single layer, i.e pie chart | |
if (d.depth === 1 && !isDonut) { | |
// return no inner radius | |
return 0; | |
} | |
return Math.max(0, y(d.y)); | |
}).outerRadius(function (d) { | |
return Math.max(0, y(d.y + d.dy)); | |
}); | |
var path = svg.datum(slices).selectAll('path').data(partition.nodes).enter().append('path').attr('d', arc).attr('class', function (d) { | |
if (d.depth === 0) { | |
return; | |
} | |
return 'slice'; | |
}).call(self._addIdentifier, 'name').style('stroke', '#fff').style('fill', function (d) { | |
if (d.depth === 0) { | |
return 'none'; | |
} | |
return color(d.name); | |
}); | |
if (isTooltip) { | |
path.call(tooltip.render()); | |
} | |
return path; | |
}; | |
PieChart.prototype._validateContainerSize = function (width, height) { | |
var minWidth = 20; | |
var minHeight = 20; | |
if (width <= minWidth || height <= minHeight) { | |
throw new errors.ContainerTooSmall(); | |
} | |
}; | |
/** | |
* Renders d3 visualization | |
* | |
* @method draw | |
* @returns {Function} Creates the pie chart | |
*/ | |
PieChart.prototype.draw = function () { | |
var self = this; | |
return function (selection) { | |
selection.each(function (data) { | |
var slices = data.slices; | |
var div = d3.select(this); | |
var width = $(this).width(); | |
var height = $(this).height(); | |
var path; | |
if (!slices.children.length) return; | |
self.convertToPercentage(slices); | |
self._validateContainerSize(width, height); | |
var svg = div.append('svg').attr('width', width).attr('height', height).append('g').attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')'); | |
path = self.addPath(width, height, svg, slices); | |
self.addPathEvents(path); | |
return svg; | |
}); | |
}; | |
}; | |
return PieChart; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 434 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(222); | |
__webpack_require__(429); | |
__webpack_require__(432); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function LineChartFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var errors = __webpack_require__(222); | |
var PointSeriesChart = Private(__webpack_require__(429)); | |
var TimeMarker = Private(__webpack_require__(432)); | |
/** | |
* Line Chart Visualization | |
* | |
* @class LineChart | |
* @constructor | |
* @extends Chart | |
* @param handler {Object} Reference to the Handler Class Constructor | |
* @param el {HTMLElement} HTML element to which the chart will be appended | |
* @param chartData {Object} Elasticsearch query results for this specific chart | |
*/ | |
_['class'](LineChart).inherits(PointSeriesChart); | |
function LineChart(handler, chartEl, chartData) { | |
if (!(this instanceof LineChart)) { | |
return new LineChart(handler, chartEl, chartData); | |
} | |
LineChart.Super.apply(this, arguments); | |
// Line chart specific attributes | |
this._attr = _.defaults(handler._attr || {}, { | |
interpolate: 'linear', | |
xValue: function xValue(d) { | |
return d.x; | |
}, | |
yValue: function yValue(d) { | |
return d.y; | |
} | |
}); | |
} | |
/** | |
* Adds Events to SVG circle | |
* | |
* @method addCircleEvents | |
* @param element{D3.UpdateSelection} Reference to SVG circle | |
* @returns {D3.Selection} SVG circles with event listeners attached | |
*/ | |
LineChart.prototype.addCircleEvents = function (element, svg) { | |
var events = this.events; | |
var isBrushable = events.isBrushable(); | |
var brush = isBrushable ? events.addBrushEvent(svg) : undefined; | |
var hover = events.addHoverEvent(); | |
var mouseout = events.addMouseoutEvent(); | |
var click = events.addClickEvent(); | |
var attachedEvents = element.call(hover).call(mouseout).call(click); | |
if (isBrushable) { | |
attachedEvents.call(brush); | |
} | |
return attachedEvents; | |
}; | |
/** | |
* Adds circles to SVG | |
* | |
* @method addCircles | |
* @param svg {HTMLElement} SVG to which rect are appended | |
* @param data {Array} Array of object data points | |
* @returns {D3.UpdateSelection} SVG with circles added | |
*/ | |
LineChart.prototype.addCircles = function (svg, data) { | |
var self = this; | |
var showCircles = this._attr.showCircles; | |
var color = this.handler.data.getColorFunc(); | |
var xScale = this.handler.xAxis.xScale; | |
var yScale = this.handler.yAxis.yScale; | |
var ordered = this.handler.data.get('ordered'); | |
var tooltip = this.tooltip; | |
var isTooltip = this._attr.addTooltip; | |
var radii = _(data).map(function (series) { | |
return _.pluck(series, '_input.z'); | |
}).flattenDeep().reduce(function (result, val) { | |
if (result.min > val) result.min = val; | |
if (result.max < val) result.max = val; | |
return result; | |
}, { | |
min: Infinity, | |
max: -Infinity | |
}); | |
var radiusStep = (radii.max - radii.min || radii.max * 100) / Math.pow(this._attr.radiusRatio, 2); | |
var layer = svg.selectAll('.points').data(data).enter().append('g').attr('class', 'points line'); | |
var circles = layer.selectAll('circle').data(function appendData(data) { | |
return data.filter(function (d) { | |
return !_.isNull(d.y); | |
}); | |
}); | |
circles.exit().remove(); | |
function cx(d) { | |
if (ordered && ordered.date) { | |
return xScale(d.x); | |
} | |
return xScale(d.x) + xScale.rangeBand() / 2; | |
} | |
function cy(d) { | |
return yScale(d.y); | |
} | |
function cColor(d) { | |
return color(d.label); | |
} | |
function colorCircle(d) { | |
var parent = d3.select(this).node().parentNode; | |
var lengthOfParent = d3.select(parent).data()[0].length; | |
var isVisible = lengthOfParent === 1; | |
// If only 1 point exists, show circle | |
if (!showCircles && !isVisible) return 'none'; | |
return cColor(d); | |
} | |
function getCircleRadiusFn(modifier) { | |
return function getCircleRadius(d) { | |
var margin = self._attr.margin; | |
var width = self._attr.width - margin.left - margin.right; | |
var height = self._attr.height - margin.top - margin.bottom; | |
var circleRadius = (d._input.z - radii.min) / radiusStep; | |
return _.min([Math.sqrt((circleRadius || 2) + 2), width, height]) + (modifier || 0); | |
}; | |
} | |
circles.enter().append('circle').attr('r', getCircleRadiusFn()).attr('fill-opacity', this._attr.drawLinesBetweenPoints ? 1 : 0.7).attr('cx', cx).attr('cy', cy).attr('class', 'circle-decoration').call(this._addIdentifier).attr('fill', colorCircle); | |
circles.enter().append('circle').attr('r', getCircleRadiusFn(10)).attr('cx', cx).attr('cy', cy).attr('fill', 'transparent').attr('class', 'circle').call(this._addIdentifier).attr('stroke', cColor).attr('stroke-width', 0); | |
if (isTooltip) { | |
circles.call(tooltip.render()); | |
} | |
return circles; | |
}; | |
/** | |
* Adds path to SVG | |
* | |
* @method addLines | |
* @param svg {HTMLElement} SVG to which path are appended | |
* @param data {Array} Array of object data points | |
* @returns {D3.UpdateSelection} SVG with paths added | |
*/ | |
LineChart.prototype.addLines = function (svg, data) { | |
var self = this; | |
var xScale = this.handler.xAxis.xScale; | |
var yScale = this.handler.yAxis.yScale; | |
var xAxisFormatter = this.handler.data.get('xAxisFormatter'); | |
var color = this.handler.data.getColorFunc(); | |
var ordered = this.handler.data.get('ordered'); | |
var interpolate = this._attr.smoothLines ? 'cardinal' : this._attr.interpolate; | |
var line = d3.svg.line().defined(function (d) { | |
return !_.isNull(d.y); | |
}).interpolate(interpolate).x(function x(d) { | |
if (ordered && ordered.date) { | |
return xScale(d.x); | |
} | |
return xScale(d.x) + xScale.rangeBand() / 2; | |
}).y(function y(d) { | |
return yScale(d.y); | |
}); | |
var lines; | |
lines = svg.selectAll('.lines').data(data).enter().append('g').attr('class', 'pathgroup lines'); | |
lines.append('path').call(this._addIdentifier).attr('d', function lineD(d) { | |
return line(d.values); | |
}).attr('fill', 'none').attr('stroke', function lineStroke(d) { | |
return color(d.label); | |
}).attr('stroke-width', 2); | |
return lines; | |
}; | |
/** | |
* Adds SVG clipPath | |
* | |
* @method addClipPath | |
* @param svg {HTMLElement} SVG to which clipPath is appended | |
* @param width {Number} SVG width | |
* @param height {Number} SVG height | |
* @returns {D3.UpdateSelection} SVG with clipPath added | |
*/ | |
LineChart.prototype.addClipPath = function (svg, width, height) { | |
var clipPathBuffer = 5; | |
var startX = 0; | |
var startY = 0 - clipPathBuffer; | |
var id = 'chart-area' + _.uniqueId(); | |
return svg.attr('clip-path', 'url(#' + id + ')').append('clipPath').attr('id', id).append('rect').attr('x', startX).attr('y', startY).attr('width', width) | |
// Adding clipPathBuffer to height so it doesn't | |
// cutoff the lower part of the chart | |
.attr('height', height + clipPathBuffer); | |
}; | |
/** | |
* Renders d3 visualization | |
* | |
* @method draw | |
* @returns {Function} Creates the line chart | |
*/ | |
LineChart.prototype.draw = function () { | |
var self = this; | |
var $elem = $(this.chartEl); | |
var margin = this._attr.margin; | |
var elWidth = this._attr.width = $elem.width(); | |
var elHeight = this._attr.height = $elem.height(); | |
var scaleType = this.handler.yAxis.getScaleType(); | |
var yMin = this.handler.yAxis.yMin; | |
var yScale = this.handler.yAxis.yScale; | |
var xScale = this.handler.xAxis.xScale; | |
var minWidth = 20; | |
var minHeight = 20; | |
var startLineX = 0; | |
var lineStrokeWidth = 1; | |
var addTimeMarker = this._attr.addTimeMarker; | |
var times = this._attr.times || []; | |
var timeMarker; | |
var div; | |
var svg; | |
var width; | |
var height; | |
var lines; | |
var circles; | |
return function (selection) { | |
selection.each(function (data) { | |
var el = this; | |
var layers = data.series.map(function mapSeries(d) { | |
var label = d.label; | |
return d.values.map(function mapValues(e, i) { | |
return { | |
_input: e, | |
label: label, | |
x: self._attr.xValue.call(d.values, e, i), | |
y: self._attr.yValue.call(d.values, e, i) | |
}; | |
}); | |
}); | |
width = elWidth - margin.left - margin.right; | |
height = elHeight - margin.top - margin.bottom; | |
if (addTimeMarker) { | |
timeMarker = new TimeMarker(times, xScale, height); | |
} | |
if (self._attr.scale === 'log' && self._invalidLogScaleValues(data)) { | |
throw new errors.InvalidLogScaleValues(); | |
} | |
if (width < minWidth || height < minHeight) { | |
throw new errors.ContainerTooSmall(); | |
} | |
div = d3.select(el); | |
svg = div.append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); | |
self.addClipPath(svg, width, height); | |
if (self._attr.drawLinesBetweenPoints) { | |
lines = self.addLines(svg, data.series); | |
} | |
circles = self.addCircles(svg, layers); | |
self.addCircleEvents(circles, svg); | |
self.createEndZones(svg); | |
var scale = scaleType === 'log' ? yScale(1) : yScale(0); | |
if (scale) { | |
svg.append('line').attr('class', 'base-line').attr('x1', startLineX).attr('y1', scale).attr('x2', width).attr('y2', scale).style('stroke', '#ddd').style('stroke-width', lineStrokeWidth); | |
} | |
if (addTimeMarker) { | |
timeMarker.render(svg); | |
} | |
return svg; | |
}); | |
}; | |
}; | |
return LineChart; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 435 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(429); | |
__webpack_require__(432); | |
__webpack_require__(222); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function AreaChartFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var PointSeriesChart = Private(__webpack_require__(429)); | |
var TimeMarker = Private(__webpack_require__(432)); | |
var errors = __webpack_require__(222); | |
/** | |
* Area chart visualization | |
* | |
* @class AreaChart | |
* @constructor | |
* @extends Chart | |
* @param handler {Object} Reference to the Handler Class Constructor | |
* @param el {HTMLElement} HTML element to which the chart will be appended | |
* @param chartData {Object} Elasticsearch query results for this specific | |
* chart | |
*/ | |
_['class'](AreaChart).inherits(PointSeriesChart); | |
function AreaChart(handler, chartEl, chartData) { | |
if (!(this instanceof AreaChart)) { | |
return new AreaChart(handler, chartEl, chartData); | |
} | |
AreaChart.Super.apply(this, arguments); | |
this.isOverlapping = handler._attr.mode === 'overlap'; | |
if (this.isOverlapping) { | |
// Default opacity should return to 0.6 on mouseout | |
handler._attr.defaultOpacity = 0.6; | |
} | |
this.checkIfEnoughData(); | |
this._attr = _.defaults(handler._attr || {}, { | |
xValue: function xValue(d) { | |
return d.x; | |
}, | |
yValue: function yValue(d) { | |
return d.y; | |
} | |
}); | |
} | |
/** | |
* Adds SVG path to area chart | |
* | |
* @method addPath | |
* @param svg {HTMLElement} SVG to which rect are appended | |
* @param layers {Array} Chart data array | |
* @returns {D3.UpdateSelection} SVG with path added | |
*/ | |
AreaChart.prototype.addPath = function (svg, layers) { | |
var self = this; | |
var ordered = this.handler.data.get('ordered'); | |
var isTimeSeries = ordered && ordered.date; | |
var isOverlapping = this.isOverlapping; | |
var color = this.handler.data.getColorFunc(); | |
var xScale = this.handler.xAxis.xScale; | |
var yScale = this.handler.yAxis.yScale; | |
var interpolate = this._attr.smoothLines ? 'cardinal' : this._attr.interpolate; | |
var area = d3.svg.area().x(function (d) { | |
if (isTimeSeries) { | |
return xScale(d.x); | |
} | |
return xScale(d.x) + xScale.rangeBand() / 2; | |
}).y0(function (d) { | |
if (isOverlapping) { | |
return yScale(0); | |
} | |
return yScale(d.y0); | |
}).y1(function (d) { | |
if (isOverlapping) { | |
return yScale(d.y); | |
} | |
return yScale(d.y0 + d.y); | |
}).defined(function (d) { | |
return !_.isNull(d.y); | |
}).interpolate(interpolate); | |
// Data layers | |
var layer = svg.selectAll('.layer').data(layers).enter().append('g').attr('class', function (d, i) { | |
return 'pathgroup ' + i; | |
}); | |
// Append path | |
var path = layer.append('path').call(this._addIdentifier).style('fill', function (d) { | |
return color(d[0].label); | |
}).classed('overlap_area', function () { | |
return isOverlapping; | |
}); | |
// update | |
path.attr('d', function (d) { | |
return area(d); | |
}); | |
return path; | |
}; | |
/** | |
* Adds Events to SVG circles | |
* | |
* @method addCircleEvents | |
* @param element {D3.UpdateSelection} SVG circles | |
* @returns {D3.Selection} circles with event listeners attached | |
*/ | |
AreaChart.prototype.addCircleEvents = function (element, svg) { | |
var events = this.events; | |
var isBrushable = events.isBrushable(); | |
var brush = isBrushable ? events.addBrushEvent(svg) : undefined; | |
var hover = events.addHoverEvent(); | |
var mouseout = events.addMouseoutEvent(); | |
var click = events.addClickEvent(); | |
var attachedEvents = element.call(hover).call(mouseout).call(click); | |
if (isBrushable) { | |
attachedEvents.call(brush); | |
} | |
return attachedEvents; | |
}; | |
/** | |
* Adds SVG circles to area chart | |
* | |
* @method addCircles | |
* @param svg {HTMLElement} SVG to which circles are appended | |
* @param data {Array} Chart data array | |
* @returns {D3.UpdateSelection} SVG with circles added | |
*/ | |
AreaChart.prototype.addCircles = function (svg, data) { | |
var self = this; | |
var color = this.handler.data.getColorFunc(); | |
var xScale = this.handler.xAxis.xScale; | |
var yScale = this.handler.yAxis.yScale; | |
var ordered = this.handler.data.get('ordered'); | |
var circleRadius = 12; | |
var circleStrokeWidth = 0; | |
var tooltip = this.tooltip; | |
var isTooltip = this._attr.addTooltip; | |
var isOverlapping = this.isOverlapping; | |
var layer; | |
var circles; | |
layer = svg.selectAll('.points').data(data).enter().append('g').attr('class', 'points area'); | |
// append the circles | |
circles = layer.selectAll('circles').data(function appendData(data) { | |
return data.filter(function isZeroOrNull(d) { | |
return d.y !== 0 && !_.isNull(d.y); | |
}); | |
}); | |
// exit | |
circles.exit().remove(); | |
// enter | |
circles.enter().append('circle').call(this._addIdentifier).attr('stroke', function strokeColor(d) { | |
return color(d.label); | |
}).attr('fill', 'transparent').attr('stroke-width', circleStrokeWidth); | |
// update | |
circles.attr('cx', function cx(d) { | |
if (ordered && ordered.date) { | |
return xScale(d.x); | |
} | |
return xScale(d.x) + xScale.rangeBand() / 2; | |
}).attr('cy', function cy(d) { | |
if (isOverlapping) { | |
return yScale(d.y); | |
} | |
return yScale(d.y0 + d.y); | |
}).attr('r', circleRadius); | |
// Add tooltip | |
if (isTooltip) { | |
circles.call(tooltip.render()); | |
} | |
return circles; | |
}; | |
/** | |
* Adds SVG clipPath | |
* | |
* @method addClipPath | |
* @param svg {HTMLElement} SVG to which clipPath is appended | |
* @param width {Number} SVG width | |
* @param height {Number} SVG height | |
* @returns {D3.UpdateSelection} SVG with clipPath added | |
*/ | |
AreaChart.prototype.addClipPath = function (svg, width, height) { | |
// Prevents circles from being clipped at the top of the chart | |
var startX = 0; | |
var startY = 0; | |
var id = 'chart-area' + _.uniqueId(); | |
// Creating clipPath | |
return svg.attr('clip-path', 'url(#' + id + ')').append('clipPath').attr('id', id).append('rect').attr('x', startX).attr('y', startY).attr('width', width).attr('height', height); | |
}; | |
AreaChart.prototype.checkIfEnoughData = function () { | |
var series = this.chartData.series; | |
var message = 'Area charts require more than one data point. Try adding ' + 'an X-Axis Aggregation'; | |
var notEnoughData = series.some(function (obj) { | |
return obj.values.length < 2; | |
}); | |
if (notEnoughData) { | |
throw new errors.NotEnoughData(message); | |
} | |
}; | |
AreaChart.prototype.validateWiggleSelection = function () { | |
var isWiggle = this._attr.mode === 'wiggle'; | |
var ordered = this.handler.data.get('ordered'); | |
if (isWiggle && !ordered) throw new errors.InvalidWiggleSelection(); | |
}; | |
/** | |
* Renders d3 visualization | |
* | |
* @method draw | |
* @returns {Function} Creates the area chart | |
*/ | |
AreaChart.prototype.draw = function () { | |
// Attributes | |
var self = this; | |
var xScale = this.handler.xAxis.xScale; | |
var $elem = $(this.chartEl); | |
var margin = this._attr.margin; | |
var elWidth = this._attr.width = $elem.width(); | |
var elHeight = this._attr.height = $elem.height(); | |
var yMin = this.handler.yAxis.yMin; | |
var yScale = this.handler.yAxis.yScale; | |
var minWidth = 20; | |
var minHeight = 20; | |
var addTimeMarker = this._attr.addTimeMarker; | |
var times = this._attr.times || []; | |
var timeMarker; | |
var div; | |
var svg; | |
var width; | |
var height; | |
var layers; | |
var circles; | |
var path; | |
return function (selection) { | |
selection.each(function (data) { | |
// Stack data | |
layers = self.stackData(data); | |
// Get the width and height | |
width = elWidth; | |
height = elHeight - margin.top - margin.bottom; | |
if (addTimeMarker) { | |
timeMarker = new TimeMarker(times, xScale, height); | |
} | |
if (width < minWidth || height < minHeight) { | |
throw new errors.ContainerTooSmall(); | |
} | |
self.validateWiggleSelection(); | |
// Select the current DOM element | |
div = d3.select(this); | |
// Create the canvas for the visualization | |
svg = div.append('svg').attr('width', width).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(0,' + margin.top + ')'); | |
// add clipPath to hide circles when they go out of bounds | |
self.addClipPath(svg, width, height); | |
self.createEndZones(svg); | |
// add path | |
path = self.addPath(svg, layers); | |
if (yMin < 0 && self._attr.mode !== 'wiggle' && self._attr.mode !== 'silhouette') { | |
// Draw line at yScale 0 value | |
svg.append('line').attr('class', 'zero-line').attr('x1', 0).attr('y1', yScale(0)).attr('x2', width).attr('y2', yScale(0)).style('stroke', '#ddd').style('stroke-width', 1); | |
} | |
// add circles | |
circles = self.addCircles(svg, layers); | |
// add click and hover events to circles | |
self.addCircleEvents(circles, svg); | |
// chart base line | |
var line = svg.append('line').attr('class', 'base-line').attr('x1', 0).attr('y1', yScale(0)).attr('x2', width).attr('y2', yScale(0)).style('stroke', '#ddd').style('stroke-width', 1); | |
if (addTimeMarker) { | |
timeMarker.render(svg); | |
} | |
return svg; | |
}); | |
}; | |
}; | |
return AreaChart; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 436 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(359); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(430); | |
__webpack_require__(414); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function TileMapFactory(Private) { | |
var d3 = __webpack_require__(359); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var Chart = Private(__webpack_require__(430)); | |
var TileMapMap = Private(__webpack_require__(414)); | |
/** | |
* Tile Map Visualization: renders maps | |
* | |
* @class TileMap | |
* @constructor | |
* @extends Chart | |
* @param handler {Object} Reference to the Handler Class Constructor | |
* @param chartEl {HTMLElement} HTML element to which the map will be appended | |
* @param chartData {Object} Elasticsearch query results for this map | |
*/ | |
_['class'](TileMap).inherits(Chart); | |
function TileMap(handler, chartEl, chartData) { | |
if (!(this instanceof TileMap)) { | |
return new TileMap(handler, chartEl, chartData); | |
} | |
TileMap.Super.apply(this, arguments); | |
// track the map objects | |
this.maps = []; | |
this._chartData = chartData || {}; | |
_.assign(this, this._chartData); | |
this._appendGeoExtents(); | |
} | |
/** | |
* Draws tile map, called on chart render | |
* | |
* @method draw | |
* @return {Function} - function to add a map to a selection | |
*/ | |
TileMap.prototype.draw = function () { | |
var self = this; | |
// clean up old maps | |
self.destroy(); | |
return function (selection) { | |
selection.each(function () { | |
self._appendMap(this); | |
}); | |
}; | |
}; | |
/** | |
* Invalidate the size of the map, so that leaflet will resize to fit. | |
* then moves to center | |
* | |
* @method resizeArea | |
* @return {undefined} | |
*/ | |
TileMap.prototype.resizeArea = function () { | |
this.maps.forEach(function (map) { | |
map.updateSize(); | |
}); | |
}; | |
/** | |
* clean up the maps | |
* | |
* @method destroy | |
* @return {undefined} | |
*/ | |
TileMap.prototype.destroy = function () { | |
this.maps = this.maps.filter(function (map) { | |
map.destroy(); | |
}); | |
}; | |
/** | |
* Adds allmin and allmax properties to geoJson data | |
* | |
* @method _appendMap | |
* @param selection {Object} d3 selection | |
*/ | |
TileMap.prototype._appendGeoExtents = function () { | |
// add allmin and allmax to geoJson | |
var geoMinMax = this.handler.data.getGeoExtents(); | |
this.geoJson.properties.allmin = geoMinMax.min; | |
this.geoJson.properties.allmax = geoMinMax.max; | |
}; | |
/** | |
* Renders map | |
* | |
* @method _appendMap | |
* @param selection {Object} d3 selection | |
*/ | |
TileMap.prototype._appendMap = function (selection) { | |
var container = $(selection).addClass('tilemap'); | |
var map = new TileMapMap(container, this._chartData, { | |
// center: this._attr.mapCenter, | |
// zoom: this._attr.mapZoom, | |
events: this.events, | |
markerType: this._attr.mapType, | |
tooltipFormatter: this.tooltipFormatter, | |
valueFormatter: this.valueFormatter, | |
attr: this._attr | |
}); | |
// add title for splits | |
if (this.title) { | |
map.addTitle(this.title); | |
} | |
// add fit to bounds control | |
if (_.get(this.geoJson, 'features.length') > 0) { | |
map.addFitControl(); | |
map.addBoundingControl(); | |
} | |
this.maps.push(map); | |
}; | |
return TileMap; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 437 */ | |
/***/ function(module, exports) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 438 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(359); | |
__webpack_require__(360); | |
__webpack_require__(439); | |
__webpack_require__(242); | |
__webpack_require__(413); | |
__webpack_require__(427); | |
__webpack_require__(222); | |
__webpack_require__(437); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function VisFactory(Private) { | |
var _ = __webpack_require__(194); | |
var d3 = __webpack_require__(359); | |
var Binder = __webpack_require__(360); | |
var ResizeChecker = Private(__webpack_require__(439)); | |
var Events = Private(__webpack_require__(242)); | |
var handlerTypes = Private(__webpack_require__(413)); | |
var chartTypes = Private(__webpack_require__(427)); | |
var errors = __webpack_require__(222); | |
__webpack_require__(437); | |
/** | |
* Creates the visualizations. | |
* | |
* @class Vis | |
* @constructor | |
* @param $el {HTMLElement} jQuery selected HTML element | |
* @param config {Object} Parameters that define the chart type and chart options | |
*/ | |
_['class'](Vis).inherits(Events); | |
function Vis($el, config) { | |
if (!(this instanceof Vis)) { | |
return new Vis($el, config); | |
} | |
Vis.Super.apply(this, arguments); | |
this.el = $el.get ? $el.get(0) : $el; | |
this.binder = new Binder(); | |
this.ChartClass = chartTypes[config.type]; | |
this._attr = _.defaults({}, config || {}, { | |
legendOpen: true | |
}); | |
// bind the resize function so it can be used as an event handler | |
this.resize = _.bind(this.resize, this); | |
this.resizeChecker = new ResizeChecker(this.el); | |
this.binder.on(this.resizeChecker, 'resize', this.resize); | |
} | |
/** | |
* Renders the visualization | |
* | |
* @method render | |
* @param data {Object} Elasticsearch query results | |
*/ | |
Vis.prototype.render = function (data) { | |
var chartType = this._attr.type; | |
if (!data) { | |
throw new Error('No valid data!'); | |
} | |
if (this.handler) { | |
this.data = null; | |
this._runOnHandler('destroy'); | |
} | |
this.data = data; | |
this.handler = handlerTypes[chartType](this) || handlerTypes.column(this); | |
this._runOnHandler('render'); | |
}; | |
/** | |
* Resizes the visualization | |
* | |
* @method resize | |
*/ | |
Vis.prototype.resize = function () { | |
if (!this.data) { | |
// TODO: need to come up with a solution for resizing when no data is available | |
return; | |
} | |
if (this.handler && _.isFunction(this.handler.resize)) { | |
this._runOnHandler('resize'); | |
} else { | |
this.render(this.data); | |
} | |
}; | |
Vis.prototype._runOnHandler = function (method) { | |
try { | |
this.handler[method](); | |
} catch (error) { | |
// If involving height and width of the container, log error to screen. | |
// Because we have to wait for the DOM element to initialize, we do not | |
// want to throw an error when the DOM `el` is zero | |
if (error instanceof errors.ContainerTooSmall || error instanceof errors.InvalidWiggleSelection || error instanceof errors.InvalidLogScaleValues || error instanceof errors.PieContainsAllZeros || error instanceof errors.NotEnoughData || error instanceof errors.NoResults) { | |
this.handler.error(error.message); | |
} else { | |
throw error; | |
} | |
} | |
}; | |
/** | |
* Destroys the visualization | |
* Removes chart and all elements associated with it. | |
* Removes chart and all elements associated with it. | |
* Remove event listeners and pass destroy call down to owned objects. | |
* | |
* @method destroy | |
*/ | |
Vis.prototype.destroy = function () { | |
var selection = d3.select(this.el).select('.vis-wrapper'); | |
this.binder.destroy(); | |
this.resizeChecker.destroy(); | |
if (this.handler) this._runOnHandler('destroy'); | |
selection.remove(); | |
selection = null; | |
}; | |
/** | |
* Sets attributes on the visualization | |
* | |
* @method set | |
* @param name {String} An attribute name | |
* @param val {*} Value to which the attribute name is set | |
*/ | |
Vis.prototype.set = function (name, val) { | |
this._attr[name] = val; | |
this.render(this.data); | |
}; | |
/** | |
* Gets attributes from the visualization | |
* | |
* @method get | |
* @param name {String} An attribute name | |
* @returns {*} The value of the attribute name | |
*/ | |
Vis.prototype.get = function (name) { | |
return this._attr[name]; | |
}; | |
/** | |
* Turns on event listeners. | |
* | |
* @param event {String} | |
* @param listener{Function} | |
* @returns {*} | |
*/ | |
Vis.prototype.on = function (event, listener) { | |
var first = this.listenerCount(event) === 0; | |
var ret = Events.prototype.on.call(this, event, listener); | |
var added = this.listenerCount(event) > 0; | |
// if this is the first listener added for the event | |
// enable the event in the handler | |
if (first && added && this.handler) this.handler.enable(event); | |
return ret; | |
}; | |
/** | |
* Turns off event listeners. | |
* | |
* @param event {String} | |
* @param listener{Function} | |
* @returns {*} | |
*/ | |
Vis.prototype.off = function (event, listener) { | |
var last = this.listenerCount(event) === 1; | |
var ret = Events.prototype.off.call(this, event, listener); | |
var removed = this.listenerCount(event) === 0; | |
// Once all listeners are removed, disable the events in the handler | |
if (last && removed && this.handler) this.handler.disable(event); | |
return ret; | |
}; | |
return Vis; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 439 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(208); | |
__webpack_require__(194); | |
__webpack_require__(242); | |
__webpack_require__(440); | |
__webpack_require__(441); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ResizeCheckerFactory(Private, Notifier, $rootScope) { | |
var $ = __webpack_require__(208); | |
var _ = __webpack_require__(194); | |
var EventEmitter = Private(__webpack_require__(242)); | |
var reflowWatcher = Private(__webpack_require__(440)); | |
var sequencer = __webpack_require__(441); | |
var SCHEDULE = ResizeChecker.SCHEDULE = sequencer.createEaseIn(100, // shortest delay | |
10000, // longest delay | |
50 // tick count | |
); | |
// maximum ms that we can delay emitting 'resize'. This is only used | |
// to debounce resizes when the size of the element is constantly changing | |
var MS_MAX_RESIZE_DELAY = ResizeChecker.MS_MAX_RESIZE_DELAY = 500; | |
/** | |
* Checks the size of an element on a regular basis. Provides | |
* an event that is emited when the element has changed size. | |
* | |
* @class ResizeChecker | |
* @param {HtmlElement} el - the element to track the size of | |
*/ | |
_['class'](ResizeChecker).inherits(EventEmitter); | |
function ResizeChecker(el) { | |
ResizeChecker.Super.call(this); | |
this.$el = $(el); | |
this.notify = new Notifier({ location: 'Vislib ResizeChecker ' + _.uniqueId() }); | |
this.saveSize(); | |
this.check = _.bind(this.check, this); | |
this.check(); | |
this.onReflow = _.bind(this.onReflow, this); | |
reflowWatcher.on('reflow', this.onReflow); | |
} | |
ResizeChecker.prototype.onReflow = function () { | |
this.startSchedule(SCHEDULE); | |
}; | |
/** | |
* Read the size of the element | |
* | |
* @method read | |
* @return {object} - an object with keys `w` (width) and `h` (height) | |
*/ | |
ResizeChecker.prototype.read = function () { | |
return { | |
w: this.$el[0].clientWidth, | |
h: this.$el[0].clientHeight | |
}; | |
}; | |
/** | |
* Save the element size, preventing it from being considered as an | |
* update. | |
* | |
* @method save | |
* @param {object} [size] - optional size to save, otherwise #read() is called | |
* @return {boolean} - true if their was a change in the new | |
*/ | |
ResizeChecker.prototype.saveSize = function (size) { | |
if (!size) size = this.read(); | |
if (this._equalsSavedSize(size)) { | |
return false; | |
} | |
this._savedSize = size; | |
return true; | |
}; | |
/** | |
* Determine if a given size matches the currently saved size. | |
* | |
* @private | |
* @method _equalsSavedSize | |
* @param {object} a - an object that matches the return value of #read() | |
* @return {boolean} - true if the passed in value matches the saved size | |
*/ | |
ResizeChecker.prototype._equalsSavedSize = function (a) { | |
var b = this._savedSize || {}; | |
return a.w === b.w && a.h === b.h; | |
}; | |
/** | |
* Read the time that the dirty state last changed. | |
* | |
* @method lastDirtyChange | |
* @return {timestamp} - the unix timestamp (in ms) of the last update | |
* to the dirty state | |
*/ | |
ResizeChecker.prototype.lastDirtyChange = function () { | |
return this._dirtyChangeStamp; | |
}; | |
/** | |
* Record the dirty state | |
* | |
* @method saveDirty | |
* @param {boolean} val | |
* @return {boolean} - true if the dirty state changed by this save | |
*/ | |
ResizeChecker.prototype.saveDirty = function (val) { | |
val = !!val; | |
if (val === this._isDirty) return false; | |
this._isDirty = val; | |
this._dirtyChangeStamp = Date.now(); | |
return true; | |
}; | |
/** | |
* The check routine that executes regularly and will reschedule itself | |
* to run again in the future. It determines the state of the elements | |
* size and decides when to emit the "update" event. | |
* | |
* @method check | |
* @return {void} | |
*/ | |
ResizeChecker.prototype.check = function () { | |
var newSize = this.read(); | |
var dirty = this.saveSize(newSize); | |
var dirtyChanged = this.saveDirty(dirty); | |
var doneDirty = !dirty && dirtyChanged; | |
var muchDirty = dirty && this.lastDirtyChange() - Date.now() > MS_MAX_RESIZE_DELAY; | |
if (doneDirty || muchDirty) { | |
this.emit('resize', newSize); | |
} | |
// if the dirty state is unchanged, continue using the previous schedule | |
if (!dirtyChanged) { | |
return this.continueSchedule(); | |
} | |
return this.startSchedule(SCHEDULE); | |
}; | |
/** | |
* Start running a new schedule, using one of the SCHEDULE_* constants. | |
* | |
* @method startSchedule | |
* @param {integer[]} schedule - an array of millisecond times that should | |
* be used to schedule calls to #check(); | |
* @return {integer} - the id of the next timer | |
*/ | |
ResizeChecker.prototype.startSchedule = function (schedule) { | |
this._tick = -1; | |
this._currentSchedule = schedule; | |
return this.continueSchedule(); | |
}; | |
/** | |
* Continue running the current schedule. MUST BE CALLED AFTER #startSchedule() | |
* | |
* @method continueSchedule | |
* @return {integer} - the id of the next timer | |
*/ | |
ResizeChecker.prototype.continueSchedule = function () { | |
clearTimeout(this._timerId); | |
if (this._tick < this._currentSchedule.length - 1) { | |
// at the end of the schedule, don't progress any further but repeat the last value | |
this._tick += 1; | |
} | |
var check = this.check; // already bound | |
var tick = this._tick; | |
var notify = this.notify; | |
var ms = this._currentSchedule[this._tick]; | |
return this._timerId = setTimeout(function () { | |
check(); | |
}, ms); | |
}; | |
/** | |
* Signal that the ResizeChecker should shutdown. | |
* | |
* Cleans up it's listeners and timers. | |
* | |
* @method destroy | |
* @return {void} | |
*/ | |
ResizeChecker.prototype.destroy = function () { | |
reflowWatcher.off('reflow', this.onReflow); | |
clearTimeout(this._timerId); | |
}; | |
return ResizeChecker; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 440 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(212); | |
__webpack_require__(208); | |
__webpack_require__(194); | |
__webpack_require__(242); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function ReflowWatcherService(Private, $rootScope, $http) { | |
var angular = __webpack_require__(212); | |
var $ = __webpack_require__(208); | |
var _ = __webpack_require__(194); | |
var EventEmitter = Private(__webpack_require__(242)); | |
var $body = $(document.body); | |
var $window = $(window); | |
var MOUSE_EVENTS = 'mouseup'; | |
var WINDOW_EVENTS = 'resize'; | |
_['class'](ReflowWatcher).inherits(EventEmitter); | |
/** | |
* Watches global activity which might hint at a change in the content, which | |
* in turn provides a hint to resizers that they should check their size | |
*/ | |
function ReflowWatcher() { | |
ReflowWatcher.Super.call(this); | |
// bound version of trigger that can be used as a handler | |
this.trigger = _.bind(this.trigger, this); | |
this._emitReflow = _.bind(this._emitReflow, this); | |
// list of functions to call that will unbind our watchers | |
this._unwatchers = [$rootScope.$watchCollection(function () { | |
return $http.pendingRequests; | |
}, this.trigger)]; | |
$body.on(MOUSE_EVENTS, this.trigger); | |
$window.on(WINDOW_EVENTS, this.trigger); | |
} | |
/** | |
* Simply emit reflow, but in a way that can be bound and passed to | |
* other functions. Using _.bind caused extra arguments to be added, and | |
* then emitted to other places. No Bueno | |
* | |
* @return {void} | |
*/ | |
ReflowWatcher.prototype._emitReflow = function () { | |
this.emit('reflow'); | |
}; | |
/** | |
* Emit the "reflow" event in the next tick of the digest cycle | |
* @return {void} | |
*/ | |
ReflowWatcher.prototype.trigger = function () { | |
$rootScope.$evalAsync(this._emitReflow); | |
}; | |
/** | |
* Signal to the ReflowWatcher that it should clean up it's listeners | |
* @return {void} | |
*/ | |
ReflowWatcher.prototype.destroy = function () { | |
$body.off(MOUSE_EVENTS, this.trigger); | |
$window.off(WINDOW_EVENTS, this.trigger); | |
_.callEach(this._unwatchers); | |
}; | |
return new ReflowWatcher(); | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 441 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
function create(min, max, length, mod) { | |
var seq = new Array(length); | |
var valueDist = max - min; | |
// range of values that the mod creates | |
var modRange = [mod(0, length), mod(length - 1, length)]; | |
// distance between | |
var modRangeDist = modRange[1] - modRange[0]; | |
_.times(length, function (i) { | |
var modIPercent = (mod(i, length) - modRange[0]) / modRangeDist; | |
// percent applied to distance and added to min to | |
// produce value | |
seq[i] = min + valueDist * modIPercent; | |
}); | |
seq.min = min; | |
seq.max = max; | |
return seq; | |
} | |
return { | |
/** | |
* Create an exponential sequence of numbers. | |
* | |
* Creates a curve resembling: | |
* | |
* ; | |
* / | |
* / | |
* .-' | |
* _.-" | |
* _.-'" | |
* _,.-'" | |
* _,..-'" | |
* _,..-'"" | |
* _,..-'"" | |
* ____,..--'"" | |
* | |
* @param {number} min - the min value to produce | |
* @param {number} max - the max value to produce | |
* @param {number} length - the number of values to produce | |
* @return {number[]} - an array containing the sequence | |
*/ | |
createEaseIn: _.partialRight(create, function (i, length) { | |
// generates numbers from 1 to +Infinity | |
return i * Math.pow(i, 1.1111); | |
}), | |
/** | |
* Create an sequence of numbers using sine. | |
* | |
* Create a curve resembling: | |
* | |
* ____,..--'"" | |
* _,..-'"" | |
* _,..-'"" | |
* _,..-'" | |
* _,.-'" | |
* _.-'" | |
* _.-" | |
* .-' | |
* / | |
* / | |
* ; | |
* | |
* | |
* @param {number} min - the min value to produce | |
* @param {number} max - the max value to produce | |
* @param {number} length - the number of values to produce | |
* @return {number[]} - an array containing the sequence | |
*/ | |
createEaseOut: _.partialRight(create, function (i, length) { | |
// adapted from output of http://www.timotheegroleau.com/Flash/experiments/easing_function_generator.htm | |
// generates numbers from 0 to 100 | |
var ts = (i /= length) * i; | |
var tc = ts * i; | |
return 100 * (0.5 * tc * ts + -3 * ts * ts + 6.5 * tc + -7 * ts + 4 * i); | |
}) | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 442 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(443); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(216); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
__webpack_require__(443); | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
__webpack_require__(216).get('kibana').directive('collapsibleSidebar', function () { | |
// simply a list of all of all of angulars .col-md-* classes except 12 | |
var listOfWidthClasses = _.times(11, function (i) { | |
return 'col-md-' + i; | |
}); | |
return { | |
restrict: 'C', | |
link: function link($scope, $elem) { | |
var $collapser = $('<div class="sidebar-collapser"><div class="chevron-cont"></div></div>'); | |
var $siblings = $elem.siblings(); | |
var siblingsClass = listOfWidthClasses.reduce(function (prev, className) { | |
if (prev) return prev; | |
return $siblings.hasClass(className) && className; | |
}, false); | |
$collapser.on('click', function () { | |
$elem.toggleClass('closed'); | |
// if there is are only two elements we can assume the other one will take 100% of the width | |
if ($siblings.length === 1 && siblingsClass) { | |
$siblings.toggleClass(siblingsClass + ' col-md-12'); | |
} | |
}).appendTo($elem); | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 443 */ | |
/***/ function(module, exports) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 444 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(216); | |
__webpack_require__(445); | |
__webpack_require__(446); | |
__webpack_require__(448); | |
__webpack_require__(449); | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(256); | |
__webpack_require__(452); | |
__webpack_require__(453); | |
__webpack_require__(465); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var app = __webpack_require__(216).get('apps/discover'); | |
__webpack_require__(445); | |
__webpack_require__(446); | |
__webpack_require__(448); | |
__webpack_require__(449); | |
app.directive('discFieldChooser', function ($location, globalState, config, $route, Private) { | |
var _ = __webpack_require__(194); | |
var $ = __webpack_require__(208); | |
var rison = __webpack_require__(256); | |
var fieldCalculator = __webpack_require__(452); | |
var FieldList = Private(__webpack_require__(453)); | |
return { | |
restrict: 'E', | |
scope: { | |
columns: '=', | |
hits: '=', | |
fieldCounts: '=', | |
state: '=', | |
indexPattern: '=', | |
indexPatternList: '=', | |
updateFilterInQuery: '=filter' | |
}, | |
template: __webpack_require__(465), | |
link: function link($scope) { | |
$scope.setIndexPattern = function (id) { | |
$scope.state.index = id; | |
$scope.state.save(); | |
}; | |
$scope.$watch('state.index', function (id, previousId) { | |
if (previousId == null || previousId === id) return; | |
$route.reload(); | |
}); | |
var filter = $scope.filter = { | |
props: ['type', 'indexed', 'analyzed', 'missing', 'name'], | |
defaults: { | |
missing: true | |
}, | |
boolOpts: [{ label: 'any', value: undefined }, { label: 'yes', value: true }, { label: 'no', value: false }], | |
toggleVal: function toggleVal(name, def) { | |
if (filter.vals[name] !== def) filter.vals[name] = def;else filter.vals[name] = undefined; | |
}, | |
reset: function reset() { | |
filter.vals = _.clone(filter.defaults); | |
}, | |
isFieldSelected: function isFieldSelected(field) { | |
return field.display; | |
}, | |
isFieldFiltered: function isFieldFiltered(field) { | |
var matchFilter = filter.vals.type == null || field.type === filter.vals.type; | |
var isAnalyzed = filter.vals.analyzed == null || field.analyzed === filter.vals.analyzed; | |
var isIndexed = filter.vals.indexed == null || field.indexed === filter.vals.indexed; | |
var scriptedOrMissing = !filter.vals.missing || field.scripted || field.rowCount > 0; | |
var matchName = !filter.vals.name || field.name.indexOf(filter.vals.name) !== -1; | |
return !field.display && matchFilter && isAnalyzed && isIndexed && scriptedOrMissing && matchName; | |
}, | |
popularity: function popularity(field) { | |
return field.count > 0; | |
}, | |
getActive: function getActive() { | |
return _.some(filter.props, function (prop) { | |
return filter.vals[prop] !== filter.defaults[prop]; | |
}); | |
} | |
}; | |
// set the initial values to the defaults | |
filter.reset(); | |
$scope.$watchCollection('filter.vals', function () { | |
filter.active = filter.getActive(); | |
}); | |
$scope.toggle = function (fieldName) { | |
$scope.increaseFieldCounter(fieldName); | |
_.toggleInOut($scope.columns, fieldName); | |
}; | |
$scope.$watchMulti(['[]fieldCounts', '[]columns', '[]hits'], function (cur, prev) { | |
var newHits = cur[2] !== prev[2]; | |
var fields = $scope.fields; | |
var columns = $scope.columns || []; | |
var fieldCounts = $scope.fieldCounts; | |
if (!fields || newHits) { | |
$scope.fields = fields = getFields(); | |
} | |
if (!fields) return; | |
// group the fields into popular and up-popular lists | |
_.chain(fields).each(function (field) { | |
field.displayOrder = _.indexOf(columns, field.name) + 1; | |
field.display = !!field.displayOrder; | |
field.rowCount = fieldCounts[field.name]; | |
}).sortBy(function (field) { | |
return (field.count || 0) * -1; | |
}).groupBy(function (field) { | |
if (field.display) return 'selected'; | |
return field.count > 0 ? 'popular' : 'unpopular'; | |
}).tap(function (groups) { | |
groups.selected = _.sortBy(groups.selected || [], 'displayOrder'); | |
groups.popular = groups.popular || []; | |
groups.unpopular = groups.unpopular || []; | |
// move excess popular fields to un-popular list | |
var extras = groups.popular.splice(config.get('fields:popularLimit')); | |
groups.unpopular = extras.concat(groups.unpopular); | |
}).each(function (group, name) { | |
$scope[name + 'Fields'] = _.sortBy(group, name === 'selected' ? 'display' : 'name'); | |
}).commit(); | |
// include undefined so the user can clear the filter | |
$scope.fieldTypes = _.union([undefined], _.pluck(fields, 'type')); | |
}); | |
$scope.increaseFieldCounter = function (fieldName) { | |
$scope.indexPattern.popularizeField(fieldName, 1); | |
}; | |
$scope.vizLocation = function (field) { | |
if (!$scope.state) { | |
return ''; | |
} | |
var agg = {}; | |
var isGeoPoint = field.type === 'geo_point'; | |
var type = isGeoPoint ? 'tile_map' : 'histogram'; | |
// If we're visualizing a date field, and our index is time based (and thus has a time filter), | |
// then run a date histogram | |
if (field.type === 'date' && $scope.indexPattern.timeFieldName === field.name) { | |
agg = { | |
type: 'date_histogram', | |
schema: 'segment', | |
params: { | |
field: field.name, | |
interval: 'auto' | |
} | |
}; | |
} else if (isGeoPoint) { | |
agg = { | |
type: 'geohash_grid', | |
schema: 'segment', | |
params: { | |
field: field.name, | |
precision: 3 | |
} | |
}; | |
} else { | |
agg = { | |
type: 'terms', | |
schema: 'segment', | |
params: { | |
field: field.name, | |
size: config.get('discover:aggs:terms:size', 20), | |
orderBy: '2' | |
} | |
}; | |
} | |
return '#/visualize/create?' + $.param(_.assign($location.search(), { | |
indexPattern: $scope.state.index, | |
type: type, | |
_a: rison.encode({ | |
filters: $scope.state.filters || [], | |
query: $scope.state.query || undefined, | |
vis: { | |
type: type, | |
aggs: [agg, { schema: 'metric', type: 'count', 'id': '2' }] | |
} | |
}) | |
})); | |
}; | |
$scope.details = function (field, recompute) { | |
if (_.isUndefined(field.details) || recompute) { | |
field.details = fieldCalculator.getFieldValueCounts({ | |
hits: $scope.hits, | |
field: field, | |
count: 5, | |
grouped: false | |
}); | |
_.each(field.details.buckets, function (bucket) { | |
bucket.display = field.format.convert(bucket.value); | |
}); | |
$scope.increaseFieldCounter(field, 1); | |
} else { | |
delete field.details; | |
} | |
}; | |
function getFields() { | |
var prevFields = $scope.fields; | |
var indexPattern = $scope.indexPattern; | |
var hits = $scope.hits; | |
var fieldCounts = $scope.fieldCounts; | |
if (!indexPattern || !hits || !fieldCounts) return; | |
var fieldSpecs = indexPattern.fields.slice(0); | |
var fieldNamesInDocs = _.keys(fieldCounts); | |
var fieldNamesInIndexPattern = _.keys(indexPattern.fields.byName); | |
_.difference(fieldNamesInDocs, fieldNamesInIndexPattern).forEach(function (unknownFieldName) { | |
fieldSpecs.push({ | |
name: unknownFieldName, | |
type: 'unknown' | |
}); | |
}); | |
var fields = new FieldList(indexPattern, fieldSpecs); | |
if (prevFields) { | |
fields.forEach(function (field) { | |
field.details = _.get(prevFields, ['byName', field.name, 'details']); | |
}); | |
} | |
return fields; | |
} | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 445 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(216); | |
__webpack_require__(208); | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var module = __webpack_require__(216).get('kibana'); | |
var $ = __webpack_require__(208); | |
var _ = __webpack_require__(194); | |
module.directive('cssTruncate', function ($timeout) { | |
return { | |
restrict: 'A', | |
scope: {}, | |
link: function link($scope, $elem, attrs) { | |
$elem.css({ | |
overflow: 'hidden', | |
'white-space': 'nowrap', | |
'text-overflow': 'ellipsis', | |
'word-break': 'break-all' | |
}); | |
if (attrs.cssTruncateExpandable != null) { | |
$scope.$watch(function () { | |
return $elem.html(); | |
}, function () { | |
if ($elem[0].offsetWidth < $elem[0].scrollWidth) { | |
$elem.css({ 'cursor': 'pointer' }); | |
$elem.bind('click', function () { | |
$scope.toggle(); | |
}); | |
} | |
}); | |
} | |
$scope.toggle = function () { | |
if ($elem.css('white-space') !== 'normal') { | |
$elem.css({ 'white-space': 'normal' }); | |
} else { | |
$elem.css({ 'white-space': 'nowrap' }); | |
} | |
}; | |
$scope.$on('$destroy', function () { | |
$elem.unbind('click'); | |
$elem.unbind('mouseenter'); | |
}); | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 446 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(216); | |
__webpack_require__(447); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var module = __webpack_require__(216).get('kibana'); | |
__webpack_require__(447); | |
module.directive('fieldName', function ($compile, $rootScope, $filter) { | |
return { | |
restrict: 'AE', | |
scope: { | |
'field': '=', | |
'fieldName': '=', | |
'fieldType': '=' | |
}, | |
link: function link($scope, $el) { | |
var typeIcon = function typeIcon(fieldType) { | |
switch (fieldType) { | |
case 'source': | |
return '<i class="fa fa-file-text-o "></i>'; | |
case 'string': | |
return '<i><strong>t</strong></i>'; | |
case 'murmur3': | |
return '<i><strong>h</strong></i>'; | |
case 'number': | |
return '<i><strong>#</strong></i>'; | |
case 'date': | |
return '<i class="fa fa-clock-o"></i>'; | |
case 'ip': | |
return '<i class="fa fa-laptop"></i>'; | |
case 'geo_point': | |
return '<i class="fa fa-globe"></i>'; | |
case 'boolean': | |
return '<i class="fa fa-adjust"></i>'; | |
case 'conflict': | |
return '<i class="fa fa-warning"></i>'; | |
default: | |
return '<i><strong>?</strong></i>'; | |
} | |
}; | |
$rootScope.$watchMulti.call($scope, ['field', 'fieldName', 'fieldType', 'field.rowCount'], function () { | |
var type = $scope.field ? $scope.field.type : $scope.fieldType; | |
var name = $scope.field ? $scope.field.name : $scope.fieldName; | |
var results = $scope.field ? !$scope.field.rowCount && !$scope.field.scripted : false; | |
var scripted = $scope.field ? $scope.field.scripted : false; | |
var displayName = $filter('shortDots')(name); | |
$el.text(displayName).attr('title', name).toggleClass('no-results', results).toggleClass('scripted', scripted).prepend(typeIcon(type)); | |
}); | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 447 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(216); | |
// Shorts dot notated strings | |
// eg: foo.bar.baz becomes f.b.baz | |
// 'foo.bar.baz'.replace(/(.+?\.)/g,function(v) {return v[0]+'.';}); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
__webpack_require__(216).get('kibana').filter('shortDots', function (Private) { | |
return Private(shortDotsFilterProvider); | |
}); | |
function shortDotsFilterProvider(config, $rootScope) { | |
var filter; | |
function updateFilter() { | |
filter = config.get('shortDots:enable') ? _.shortenDottedString : _.identity; | |
} | |
updateFilter(); | |
$rootScope.$on('change:config.shortDots:enable', updateFilter); | |
$rootScope.$on('init:config', updateFilter); | |
return function (str) { | |
return filter(str); | |
}; | |
} | |
return shortDotsFilterProvider; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 448 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(216); | |
// Filters out all duplicate items in an array | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
__webpack_require__(216).get('kibana').filter('unique', function () { | |
return function (arr) { | |
var list = _.unique(arr); | |
return list; | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 449 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(208); | |
__webpack_require__(216); | |
__webpack_require__(450); | |
__webpack_require__(194); | |
__webpack_require__(445); | |
__webpack_require__(446); | |
__webpack_require__(451); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var $ = __webpack_require__(208); | |
var app = __webpack_require__(216).get('apps/discover'); | |
var html = __webpack_require__(450); | |
var _ = __webpack_require__(194); | |
__webpack_require__(445); | |
__webpack_require__(446); | |
app.directive('discoverField', function ($compile) { | |
return { | |
restrict: 'E', | |
template: html, | |
replace: true, | |
link: function link($scope, $elem) { | |
var detailsElem; | |
var detailScope = $scope.$new(); | |
var detailsHtml = __webpack_require__(451); | |
var init = function init() { | |
if ($scope.field.details) { | |
$scope.toggleDetails($scope.field, true); | |
} | |
}; | |
var getWarnings = function getWarnings(field) { | |
var warnings = []; | |
if (!field.scripted) { | |
if (!field.doc_values && field.type !== 'boolean' && !(field.analyzed && field.type === 'string')) { | |
warnings.push('Doc values are not enabled on this field. This may lead to excess heap consumption when visualizing.'); | |
} | |
if (field.analyzed && field.type === 'string') { | |
warnings.push('This is an analyzed string field.' + ' Analyzed strings are highly unique and can use a lot of memory to visualize.' + ' Values such as foo-bar will be broken into foo and bar.'); | |
} | |
if (!field.indexed) { | |
warnings.push('This field is not indexed and can not be visualized.'); | |
} | |
} | |
if (field.scripted) { | |
warnings.push('Scripted fields can take a long time to execute.'); | |
} | |
if (warnings.length > 1) { | |
warnings = warnings.map(function (warning, i) { | |
return (i > 0 ? '\n' : '') + (i + 1) + ' - ' + warning; | |
}); | |
} | |
return warnings; | |
}; | |
$scope.toggleDisplay = function (field) { | |
// inheritted param to fieldChooser | |
$scope.toggle(field.name); | |
if (field.display) $scope.increaseFieldCounter(field); | |
// we are now displaying the field, kill it's details | |
if (field.details) { | |
$scope.toggleDetails(field); | |
} | |
}; | |
$scope.toggleDetails = function (field, recompute) { | |
if (_.isUndefined(field.details) || recompute) { | |
// This is inherited from fieldChooser | |
$scope.details(field, recompute); | |
detailScope.$destroy(); | |
detailScope = $scope.$new(); | |
detailScope.warnings = getWarnings(field); | |
detailsElem = $(detailsHtml); | |
$compile(detailsElem)(detailScope); | |
$elem.append(detailsElem); | |
} else { | |
delete field.details; | |
detailsElem.remove(); | |
} | |
}; | |
init(); | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 450 */ | |
/***/ function(module, exports) { | |
module.exports = "\n <li class=\"sidebar-item\" attr-field=\"{{::field.name}}\">\n <div ng-click=\"toggleDetails(field)\" class=\"sidebar-item-title\">\n <field-name field=\"field\"></field-name>\n <button\n ng-click=\"toggleDisplay(field)\"\n ng-class=\"::field.display ? 'btn-danger' : 'btn-primary'\"\n ng-bind=\"::field.display ? 'remove' : 'add'\"\n class=\"btn btn-xs btn-primary discover-field-toggle\" ></button>\n </div>\n </li>\n" | |
/***/ }, | |
/* 451 */ | |
/***/ function(module, exports) { | |
module.exports = " <div>\n <div class=\"discover-field-details\">\n <h5 ng-show=\"!field.details.error\">Quick Count <kbn-info info=\"Top 5 values based on documents in the table\" placement=\"right\"></kbn-info>\n <span ng-if=\"!field.details.error\" class=\"small discover-field-details-count\">\n (\n <a ng-show=\"field.indexed\" ng-click=\"updateFilterInQuery('_exists_', field.name, '+')\">{{::field.details.exists}}</a>\n <span ng-show=\"!field.indexed\">{{::field.details.exists}}</span>\n /{{::field.details.total}} records\n )\n </span>\n </h5>\n\n <div class=\"clearfix\"></div>\n\n <div ng-if=\"field.details.error\" class=\"discover-field-details-error\">{{field.details.error}}</div>\n\n <div ng-if=\"!field.details.error\">\n <div ng-repeat=\"bucket in ::field.details.buckets\" class=\"discover-field-details-item\">\n <div>\n <span ng-show=\"field.filterable\" class=\"pull-right\">\n <i aria-hidden=\"true\" class=\"fa fa-search-minus pull-right discover-field-details-filter\"\n ng-click=\"updateFilterInQuery(field, bucket.value, '-')\"></i>\n <i aria-hidden=\"true\" class=\"fa fa-search-plus pull-right discover-field-details-filter\"\n ng-click=\"updateFilterInQuery(field, bucket.value, '+')\"></i>\n </span>\n <div css-truncate css-truncate-expandable=\"true\" class=\"discover-field-details-value\">\n {{::bucket.display}} <i ng-show=\"bucket.display === ''\">Empty string</i>\n </div>\n </div>\n <kbn-tooltip text=\"{{::bucket.count}}\" placement=\"right\" append-to-body=\"1\">\n <progressbar value=\"bucket.percent\" max=\"100\" animate=\"false\"><span>{{bucket.percent}}%</span></progressbar>\n </kbn-tooltip>\n </div>\n </div>\n </div>\n </div>\n\n <a ng-show=\"field.indexed || field.scripted\"\n ng-href=\"{{vizLocation(field)}}\"\n class=\"sidebar-item-button primary\">\n Visualize\n <span class=\"discover-field-vis-warning\" ng-show=\"warnings.length\" tooltip=\"{{warnings.join(' ')}}\">\n ( {{::warnings.length}} <ng-pluralize count=\"warnings.length\" when=\"{'1':'warning', 'other':'warnings'}\"></ng-pluralize> <i aria-hidden=\"true\" class=\"fa fa-warning\"></i> )\n </span>\n </a>\n\n <div ng-show=\"!field.indexed && !field.scripted\"\n disabled=\"disabled\"\n tooltip=\"This field is not indexed thus unavailable for visualization and search\"\n class=\"sidebar-item-button primary\">Not Indexed</div>\n" | |
/***/ }, | |
/* 452 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
function getFieldValues(hits, field) { | |
var name = field.name; | |
var flattenHit = field.indexPattern.flattenHit; | |
return _.map(hits, function (hit) { | |
return flattenHit(hit)[name]; | |
}); | |
} | |
function getFieldValueCounts(params) { | |
params = _.defaults(params, { | |
count: 5, | |
grouped: false | |
}); | |
if (params.field.type === 'geo_point' || params.field.type === 'geo_shape' || params.field.type === 'attachment') { | |
return { error: 'Analysis is not available for geo fields.' }; | |
} | |
var allValues = getFieldValues(params.hits, params.field); | |
var counts; | |
var missing = _countMissing(allValues); | |
try { | |
var groups = _groupValues(allValues, params); | |
counts = _.map(_.sortBy(groups, 'count').reverse().slice(0, params.count), function (bucket) { | |
return { | |
value: bucket.value, | |
count: bucket.count, | |
percent: (bucket.count / (params.hits.length - missing) * 100).toFixed(1) | |
}; | |
}); | |
if (params.hits.length - missing === 0) { | |
return { | |
error: 'This field is present in your elasticsearch mapping' + ' but not in any documents in the search results.' + ' You may still be able to visualize or search on it.' | |
}; | |
} | |
return { | |
total: params.hits.length, | |
exists: params.hits.length - missing, | |
missing: missing, | |
buckets: counts | |
}; | |
} catch (e) { | |
return { error: e.message }; | |
} | |
} | |
// returns a count of fields in the array that are undefined or null | |
function _countMissing(array) { | |
return array.length - _.without(array, undefined, null).length; | |
} | |
function _groupValues(allValues, params) { | |
var groups = {}; | |
var k; | |
allValues.forEach(function (value) { | |
if (_.isObject(value) && !_.isArray(value)) { | |
throw new Error('Analysis is not available for object fields'); | |
} | |
if (_.isArray(value) && !params.grouped) { | |
k = value; | |
} else { | |
k = value == null ? undefined : [value]; | |
} | |
_.each(k, function (key) { | |
if (_.has(groups, key)) { | |
groups[key].count++; | |
} else { | |
groups[key] = { | |
value: params.grouped ? value : key, | |
count: 1 | |
}; | |
} | |
}); | |
}); | |
return groups; | |
} | |
return { | |
_groupValues: _groupValues, | |
_countMissing: _countMissing, | |
getFieldValues: getFieldValues, | |
getFieldValueCounts: getFieldValueCounts | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 453 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(454); | |
__webpack_require__(460); | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function FieldListProvider(Private) { | |
var Field = Private(__webpack_require__(454)); | |
var IndexedArray = __webpack_require__(460); | |
var _ = __webpack_require__(194); | |
_['class'](FieldList).inherits(IndexedArray); | |
function FieldList(indexPattern, specs) { | |
FieldList.Super.call(this, { | |
index: ['name'], | |
group: ['type'], | |
initialSet: specs.map(function (field) { | |
return new Field(indexPattern, field); | |
}) | |
}); | |
} | |
return FieldList; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 454 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(455); | |
__webpack_require__(459); | |
__webpack_require__(462); | |
__webpack_require__(464); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function FieldObjectProvider(Private, shortDotsFilter, $rootScope, Notifier) { | |
var notify = new Notifier({ location: 'IndexPattern Field' }); | |
var FieldFormat = Private(__webpack_require__(455)); | |
var fieldTypes = Private(__webpack_require__(459)); | |
var fieldFormats = Private(__webpack_require__(462)); | |
var ObjDefine = __webpack_require__(464); | |
function Field(indexPattern, spec) { | |
// unwrap old instances of Field | |
if (spec instanceof Field) spec = spec.$$spec; | |
// constuct this object using ObjDefine class, which | |
// extends the Field.prototype but gets it's properties | |
// defined using the logic below | |
var obj = new ObjDefine(spec, Field.prototype); | |
if (spec.name === '_source') { | |
spec.type = '_source'; | |
} | |
// find the type for this field, fallback to unknown type | |
var type = fieldTypes.byName[spec.type]; | |
if (spec.type && !type) { | |
notify.error('Unknown field type "' + spec.type + '"' + ' for field "' + spec.name + '"' + ' in indexPattern "' + indexPattern.id + '"'); | |
} | |
if (!type) type = fieldTypes.byName.unknown; | |
var format = spec.format; | |
if (!format || !(format instanceof FieldFormat)) { | |
format = indexPattern.fieldFormatMap[spec.name] || fieldFormats.getDefaultInstance(spec.type); | |
} | |
var indexed = !!spec.indexed; | |
var scripted = !!spec.scripted; | |
var sortable = spec.name === '_score' || (indexed || scripted) && type.sortable; | |
var bucketable = indexed || scripted; | |
var filterable = spec.name === '_id' || scripted || indexed && type.filterable; | |
obj.fact('name'); | |
obj.fact('type'); | |
obj.writ('count', spec.count || 0); | |
// scripted objs | |
obj.fact('scripted', scripted); | |
obj.writ('script', scripted ? spec.script : null); | |
obj.writ('lang', scripted ? spec.lang || 'expression' : null); | |
// mapping info | |
obj.fact('indexed', indexed); | |
obj.fact('analyzed', !!spec.analyzed); | |
obj.fact('doc_values', !!spec.doc_values); | |
// usage flags, read-only and won't be saved | |
obj.comp('format', format); | |
obj.comp('sortable', sortable); | |
obj.comp('bucketable', bucketable); | |
obj.comp('filterable', filterable); | |
// computed values | |
obj.comp('indexPattern', indexPattern); | |
obj.comp('displayName', shortDotsFilter(spec.name)); | |
obj.comp('$$spec', spec); | |
return obj.create(); | |
} | |
Field.prototype.routes = { | |
edit: '/settings/indices/{{indexPattern.id}}/field/{{name}}' | |
}; | |
return Field; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 455 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(456); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function FieldFormatClassProvider(config, $rootScope, Private) { | |
var _ = __webpack_require__(194); | |
var contentTypes = Private(__webpack_require__(456)); | |
function FieldFormat(params) { | |
var self = this; | |
// give the constructor a more appropriate name | |
self.type = self.constructor; | |
// keep the params and defaults seperate | |
self._params = params || {}; | |
self._paramDefaults = self.type.paramDefaults || {}; | |
// one content type, so assume text | |
if (_.isFunction(self._convert)) { | |
self._convert = { text: self._convert }; | |
} | |
contentTypes.setup(self); | |
} | |
FieldFormat.from = function (converter) { | |
_['class'](FieldFormatFromConverter).inherits(FieldFormat); | |
function FieldFormatFromConverter(params) { | |
FieldFormatFromConverter.Super.call(this, params); | |
} | |
FieldFormatFromConverter.prototype._convert = converter; | |
return FieldFormatFromConverter; | |
}; | |
/** | |
* Convert a raw value to a formated string | |
* @param {any} value | |
* @param {string} [contentType=text] - optional content type, the only two contentTypes | |
* currently supported are "html" and "text", which helps | |
* formatters adjust to different contexts | |
* @return {string} - the formatted string, which is assumed to be html, safe for | |
* injecting into the DOM or a DOM attribute | |
*/ | |
FieldFormat.prototype.convert = function (value, contentType) { | |
return this.getConverterFor(contentType)(value); | |
}; | |
/** | |
* Get a convert function that is bound to a specific contentType | |
* @param {string} [contentType=text] | |
* @return {function} - a bound converter function | |
*/ | |
FieldFormat.prototype.getConverterFor = function (contentType) { | |
return this._convert[contentType || 'text']; | |
}; | |
/** | |
* Get the value of a param. This value may be a default value. | |
* | |
* @param {string} name - the param name to fetch | |
* @return {any} | |
*/ | |
FieldFormat.prototype.param = function (name) { | |
var val = this._params[name]; | |
if (val || val === false || val === 0) { | |
// truthy, false, or 0 are fine | |
// '', NaN, null, undefined, etc are not | |
return val; | |
} | |
return this._paramDefaults[name]; | |
}; | |
/** | |
* Get all of the params in a single object | |
* @return {object} | |
*/ | |
FieldFormat.prototype.params = function () { | |
return _.cloneDeep(_.defaults({}, this._params, this._paramDefaults)); | |
}; | |
/** | |
* serialize this format to a simple POJO, with only the params | |
* that are not default | |
* | |
* @return {object} | |
*/ | |
FieldFormat.prototype.toJSON = function () { | |
var type = this.type; | |
var defaults = this._paramDefaults; | |
var params = _.transform(this._params, function (uniqParams, val, param) { | |
if (val !== defaults[param]) { | |
uniqParams[param] = val; | |
} | |
}, {}); | |
if (!_.size(params)) { | |
params = undefined; | |
} | |
return { | |
id: type.id, | |
params: params | |
}; | |
}; | |
return FieldFormat; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 456 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(212); | |
__webpack_require__(457); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function contentTypesProvider(highlightFilter) { | |
var _ = __webpack_require__(194); | |
var angular = __webpack_require__(212); | |
__webpack_require__(457); | |
var types = { | |
html: function html(format, convert) { | |
return function recurse(value, field, hit) { | |
if (!value || typeof value.map !== 'function') { | |
return convert.call(format, value, field, hit); | |
} | |
var subVals = value.map(function (v) { | |
return recurse(v, field, hit); | |
}); | |
var useMultiLine = subVals.some(function (sub) { | |
return sub.indexOf('\n') > -1; | |
}); | |
return subVals.join(',' + (useMultiLine ? '\n' : ' ')); | |
}; | |
}, | |
text: function text(format, convert) { | |
return function recurse(value) { | |
if (!value || typeof value.map !== 'function') { | |
return convert.call(format, value); | |
} | |
// format a list of values. In text contexts we just use JSON encoding | |
return angular.toJson(value.map(recurse), true); | |
}; | |
} | |
}; | |
function fallbackText(value) { | |
return _.asPrettyString(value); | |
} | |
function fallbackHtml(value, field, hit) { | |
var formatted = _.escape(this.convert(value, 'text')); | |
if (!hit || !hit.highlight || !hit.highlight[field.name]) { | |
return formatted; | |
} else { | |
return highlightFilter(formatted, hit.highlight[field.name]); | |
} | |
} | |
function setup(format) { | |
var src = format._convert || {}; | |
var converters = format._convert = {}; | |
converters.text = types.text(format, src.text || fallbackText); | |
converters.html = types.html(format, src.html || fallbackHtml); | |
return format._convert; | |
} | |
return { | |
types: types, | |
setup: setup | |
}; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 457 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(458); | |
__webpack_require__(194); | |
__webpack_require__(212); | |
__webpack_require__(216); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
__webpack_require__(458); | |
var _ = __webpack_require__(194); | |
var angular = __webpack_require__(212); | |
var module = __webpack_require__(216).get('kibana'); | |
module.filter('highlight', function (highlightTags) { | |
return function (formatted, highlight) { | |
if (typeof formatted === 'object') formatted = angular.toJson(formatted); | |
_.each(highlight, function (section) { | |
section = _.escape(section); | |
// Strip out the highlight tags to compare against the formatted string | |
var untagged = section.split(highlightTags.pre).join('').split(highlightTags.post).join(''); | |
// Replace all highlight tags with proper html tags | |
var tagged = section.split(highlightTags.pre).join('<mark>').split(highlightTags.post).join('</mark>'); | |
// Replace all instances of the untagged string with the properly tagged string | |
formatted = formatted.split(untagged).join(tagged); | |
}); | |
return formatted; | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 458 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(216); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var module = __webpack_require__(216).get('kibana'); | |
// By default, ElasticSearch surrounds matched values in <em></em>. This is not ideal because it is possible that | |
// the value could contain <em></em> in the value. We define these custom tags that we would never expect to see | |
// inside a field value. | |
module.constant('highlightTags', { | |
pre: '@kibana-highlighted-field@', | |
post: '@/kibana-highlighted-field@' | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 459 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(460); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
return function IndexPatternFieldTypes() { | |
var IndexedArray = __webpack_require__(460); | |
return new IndexedArray({ | |
index: ['name'], | |
group: ['sortable', 'filterable'], | |
immutable: true, | |
initialSet: [{ name: 'ip', sortable: true, filterable: true }, { name: 'date', sortable: true, filterable: true }, { name: 'string', sortable: true, filterable: true }, { name: 'number', sortable: true, filterable: true }, { name: 'boolean', sortable: true, filterable: true }, { name: 'conflict', sortable: false, filterable: false }, { name: 'geo_point', sortable: false, filterable: false }, { name: 'geo_shape', sortable: false, filterable: false }, { name: 'attachment', sortable: false, filterable: false }, { name: 'murmur3', sortable: false, filterable: false }, { name: 'unknown', sortable: false, filterable: false }, { name: '_source', sortable: false, filterable: false }] | |
}); | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 460 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(225); | |
__webpack_require__(194); | |
__webpack_require__(461); | |
'use strict'; | |
var _Object$defineProperty = __webpack_require__(225)['default']; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var inflector = __webpack_require__(461); | |
var pathGetter = _(_.get).rearg(1, 0).ary(2); | |
var inflectIndex = inflector('by'); | |
var inflectOrder = inflector('in', 'Order'); | |
var CLEAR_CACHE = {}; | |
var OPT_NAMES = IndexedArray.OPT_NAMES = ['index', 'group', 'order', 'initialSet', 'immutable']; | |
/** | |
* Generic extension of Array class, which will index (and reindex) the | |
* objects it contains based on their properties. | |
* | |
* @class IndexedArray | |
* @module utils | |
* @constructor | |
* @param {object} [config] - describes the properties of this registry object | |
* @param {string[]} [config.index] - a list of props/paths that should be used to index the docs. | |
* @param {string[]} [config.group] - a list of keys/paths to group docs by. | |
* @param {string[]} [config.order] - a list of keys/paths to order the keys by. | |
* @param {object[]} [config.initialSet] - the initial dataset the IndexedArray should contain. | |
* @param {boolean} [config.immutable] - a flag that hints to people reading the implementation | |
* that this IndexedArray should not be modified. It's modification | |
* methods are also removed | |
*/ | |
_['class'](IndexedArray).inherits(Array); | |
function IndexedArray(config) { | |
IndexedArray.Super.call(this); | |
// just to remind future us that this list is important | |
config = _.pick(config || {}, OPT_NAMES); | |
this.raw = []; | |
// setup indices | |
this._indexNames = _.union(this._setupIndices(config.group, inflectIndex, _.organizeBy), this._setupIndices(config.index, inflectIndex, _.indexBy), this._setupIndices(config.order, inflectOrder, _.sortBy)); | |
if (config.initialSet) { | |
this.push.apply(this, config.initialSet); | |
} | |
if (config.immutable) { | |
// just a hint, bugs caused by updates not propogating would be very | |
// very very hard to track down | |
this.push = this.splice = undefined; | |
} | |
} | |
/** | |
* Create indices for a group of object properties. getters and setters are used to | |
* read and control the indices. | |
* | |
* @param {string[]} props - the properties that should be used to index docs | |
* @param {function} inflect - a function that will be called with a property name, and | |
* creates the public property at which the index will be exposed | |
* @param {function} op - the function that will be used to create the indices, it is passed | |
* the raw representaion of the registry, and a getter for reading the | |
* right prop | |
* | |
* @returns {string[]} - the public keys of all indices created | |
*/ | |
IndexedArray.prototype._setupIndices = function (props, inflect, op) { | |
// shortcut for empty props | |
if (!props || props.length === 0) return; | |
var self = this; | |
return props.map(function (prop) { | |
var from = pathGetter.partial(prop).value(); | |
var to = inflect(prop); | |
var cache; | |
_Object$defineProperty(self, to, { | |
enumerable: false, | |
configurable: false, | |
set: function set(val) { | |
// can't set any value other than the CLEAR_CACHE constant | |
if (val === CLEAR_CACHE) { | |
cache = false; | |
} else { | |
throw new TypeError(to + ' can not be set, it is a computed index of values'); | |
} | |
}, | |
get: function get() { | |
return cache || (cache = op(self.raw, from)); | |
} | |
}); | |
return to; | |
}); | |
}; | |
/** | |
* (Re)run index/group/order procedures to create indices of | |
* sub-objects. | |
* | |
* @return {undefined} | |
*/ | |
IndexedArray.prototype._clearIndices = function () { | |
var self = this; | |
self._indexNames.forEach(function (name) { | |
self[name] = CLEAR_CACHE; | |
}); | |
}; | |
/** | |
* Copy all array methods which have side-effects, and wrap them | |
* in a function that will reindex after each call, as well | |
* as duplex the operation to the .raw version of the IndexedArray. | |
* | |
* @param {[type]} method [description] | |
* @return {[type]} [description] | |
*/ | |
'pop push shift splice unshift reverse'.split(' ').forEach(function (method) { | |
var orig = Array.prototype[method]; | |
IndexedArray.prototype[method] = function () /* args... */{ | |
// call the original method with this context | |
orig.apply(this, arguments); | |
// run the indexers | |
this._clearIndices(); | |
// call the original method on our "raw" array, and return the result(s) | |
return orig.apply(this.raw, arguments); | |
}; | |
}); | |
/** | |
* Remove items from this based on a predicate | |
* @param {function|object|string} predicate - the predicate used to decide what is removed | |
* @param {object} context - this binding for predicate | |
* @return {array} - the removed data | |
*/ | |
IndexedArray.prototype.remove = function (predicate, context) { | |
var out = _.remove(this, predicate, context); | |
_.remove(this.raw, predicate, context); | |
this._clearIndices(); | |
return out; | |
}; | |
/** | |
* provide a hook for the JSON serializer | |
* @return {array} - a plain, vanilla array with our same data | |
*/ | |
IndexedArray.prototype.toJSON = function () { | |
return this.raw; | |
}; | |
return IndexedArray; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 461 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
function upFirst(str, total) { | |
return str.charAt(0).toUpperCase() + (total ? str.substr(1).toLowerCase() : str.substr(1)); | |
} | |
function startsWith(str, test) { | |
return str.substr(0, test.length).toLowerCase() === test.toLowerCase(); | |
} | |
function endsWith(str, test) { | |
var tooShort = str.length < test.length; | |
if (tooShort) return; | |
return str.substr(str.length - test.length).toLowerCase() === test.toLowerCase(); | |
} | |
function inflector(prefix, postfix) { | |
return function inflect(key) { | |
var inflected; | |
if (key.indexOf('.') !== -1) { | |
inflected = key.split('.').map(function (step, i) { | |
return i === 0 ? step : upFirst(step, true); | |
}).join(''); | |
} else { | |
inflected = key; | |
} | |
if (prefix && !startsWith(key, prefix)) { | |
inflected = prefix + upFirst(inflected); | |
} | |
if (postfix && !endsWith(key, postfix)) { | |
inflected = inflected + postfix; | |
} | |
return inflected; | |
}; | |
} | |
return inflector; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 462 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(463); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
return __webpack_require__(463)({ | |
name: 'fieldFormats', | |
index: ['id'], | |
group: ['fieldType'], | |
constructor: function constructor(config, $rootScope) { | |
var self = this; | |
var defaultMap; | |
function init() { | |
parseDefaultTypeMap(); | |
$rootScope.$on('init:config', parseDefaultTypeMap); | |
$rootScope.$on('change:config.format:defaultTypeMap', parseDefaultTypeMap); | |
} | |
/** | |
* Get the id of the default type for this field type | |
* using the format:defaultTypeMap config map | |
* | |
* @param {String} fieldType - the field type | |
* @return {String} | |
*/ | |
self.getDefaultConfig = function (fieldType) { | |
return defaultMap[fieldType] || defaultMap._default_; | |
}; | |
/** | |
* Get a FieldFormat type (class) by it's id. | |
* | |
* @param {String} formatId - the format id | |
* @return {Function} | |
*/ | |
self.getType = function (formatId) { | |
return self.byId[formatId]; | |
}; | |
/** | |
* Get the default FieldFormat type (class) for | |
* a field type, using the format:defaultTypeMap. | |
* | |
* @param {String} fieldType | |
* @return {Function} | |
*/ | |
self.getDefaultType = function (fieldType) { | |
return self.byId[self.getDefaultConfig(fieldType).id]; | |
}; | |
/** | |
* Get the singleton instance of the FieldFormat type by it's id. | |
* | |
* @param {String} formatId | |
* @return {FieldFormat} | |
*/ | |
self.getInstance = _.memoize(function (formatId) { | |
var FieldFormat = self.byId[formatId]; | |
return new FieldFormat(); | |
}); | |
/** | |
* Get the default fieldFormat instance for a field format. | |
* | |
* @param {String} fieldType | |
* @return {FieldFormat} | |
*/ | |
self.getDefaultInstance = _.memoize(function (fieldType) { | |
var conf = self.getDefaultConfig(fieldType); | |
var FieldFormat = self.byId[conf.id]; | |
return new FieldFormat(conf.params); | |
}); | |
function parseDefaultTypeMap() { | |
defaultMap = config.get('format:defaultTypeMap'); | |
_.forOwn(self, function (fn) { | |
if (_.isFunction(fn) && fn.cache) { | |
// clear all memoize caches | |
fn.cache = new _.memoize.Cache(); | |
} | |
}); | |
} | |
init(); | |
} | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 463 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(460); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var IndexedArray = __webpack_require__(460); | |
var notPropsOptNames = IndexedArray.OPT_NAMES.concat('constructor'); | |
/** | |
* Create a registry, which is just a Private module provider. | |
* | |
* The registry allows modifying the values it will provide | |
* using the #register method. | |
* | |
* To access these modules, pass the registry to the Private | |
* module loader. | |
* | |
* # Examples | |
* | |
* + register a module | |
* ```js | |
* var registry = require('ui/registry/vis_types'); | |
* registry.add(function InjectablePrivateModule($http, Promise) { | |
* ... | |
* }) | |
* ``` | |
* | |
* + get all registered modules | |
* ```js | |
* var visTypes = Private(require('ui/registry/vis_types')); | |
* ``` | |
* | |
* | |
* @param {object} [spec] - an object describing the properties of | |
* the registry to create. Any property specified | |
* that is not listed below will be mixed into the | |
* final IndexedArray object. | |
* | |
* # init | |
* @param {Function} [spec.constructor] - an injectable function that is called when | |
* the registry is first instanciated by the app. | |
* | |
* # IndexedArray params | |
* @param {array[String]} [spec.index] - passed to the IndexedArray constructor | |
* @param {array[String]} [spec.group] - passed to the IndexedArray constructor | |
* @param {array[String]} [spec.order] - passed to the IndexedArray constructor | |
* @param {array[String]} [spec.initialSet] - passed to the IndexedArray constructor | |
* @param {array[String]} [spec.immutable] - passed to the IndexedArray constructor | |
* | |
* @return {[type]} [description] | |
*/ | |
return function createRegistry(spec) { | |
spec = spec || {}; | |
var constructor = _.has(spec, 'constructor') && spec.constructor; | |
var iaOpts = _.defaults(_.pick(spec, IndexedArray.OPT_NAMES), { index: ['name'] }); | |
var props = _.omit(spec, notPropsOptNames); | |
var providers = []; | |
/** | |
* This is the Private module that will be instanciated by | |
* | |
* @tag:PrivateModule | |
* @return {IndexedArray} - an indexed array containing the values | |
* that were registered, the registry spec | |
* defines how things will be indexed. | |
*/ | |
var registry = function registry(Private, $injector) { | |
// index all of the modules | |
iaOpts.initialSet = providers.map(Private); | |
var modules = new IndexedArray(iaOpts); | |
// mixin other props | |
_.assign(modules, props); | |
// construct | |
if (constructor) { | |
modules = $injector.invoke(constructor, modules) || modules; | |
} | |
return modules; | |
}; | |
registry.displayName = '[registry ' + props.name + ']'; | |
registry.register = function (privateModule) { | |
providers.push(privateModule); | |
return registry; | |
}; | |
return registry; | |
}; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 464 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(203); | |
__webpack_require__(225); | |
__webpack_require__(194); | |
'use strict'; | |
var _Object$create = __webpack_require__(203)['default']; | |
var _Object$defineProperty = __webpack_require__(225)['default']; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
function ObjDefine(defaults, prototype) { | |
this.obj; // created by this.create() | |
this.descs = {}; | |
this.defaults = defaults || {}; | |
this.prototype = prototype || Object.prototype; | |
} | |
ObjDefine.REDEFINE_SUPPORTED = (function () { | |
var a = _Object$create(Object.prototype, { | |
prop: { | |
configurable: true, | |
value: 1 | |
} | |
}); | |
Object.defineProperty(a, 'prop', { | |
configurable: true, | |
value: 2 | |
}); | |
return a.prop === 2; | |
})(); | |
/** | |
* normal value, writable and exported in JSON | |
* | |
* @param {any} v - value | |
* @return {object} - property descriptor | |
*/ | |
ObjDefine.prototype.writ = function (name, val) { | |
this._define(name, val, true, true); | |
}; | |
/** | |
* known value, exported in JSON, not changeable | |
* | |
* @param {any} v - value | |
* @return {object} - property descriptor | |
*/ | |
ObjDefine.prototype.fact = function (name, val) { | |
this._define(name, val, true); | |
}; | |
/** | |
* computed fact, not exported or changeable | |
* | |
* @param {any} v - value | |
* @return {object} - property descriptor | |
*/ | |
ObjDefine.prototype.comp = function (name, val) { | |
this._define(name, val); | |
}; | |
/** | |
* Creates an object, decorated by the property descriptors | |
* created by other ObjDefine methods and inheritting form the | |
* prototype | |
* | |
* # note: | |
* If a value is writable, but the value is undefined, the property will | |
* be created by not exported to JSON unless the property is written to | |
* | |
* @return {object} - created object | |
*/ | |
ObjDefine.prototype.create = function () { | |
var self = this; | |
self.obj = _Object$create(this.prototype, self.descs); | |
if (!ObjDefine.REDEFINE_SUPPORTED && !self.prototype.toJSON) { | |
// since we can't redefine properties as enumerable we will | |
// clone the object on serialization and choose which properties | |
// to include or trim manually. This is currently only in use in PhantomJS | |
// due to https://github.com/ariya/phantomjs/issues/11856 | |
self.obj.toJSON = function () { | |
return _.transform(self.obj, function (json, val, key) { | |
var desc = self.descs[key]; | |
if (desc && desc.enumerable && val == null) return; | |
json[key] = val; | |
}, {}); | |
}; | |
} | |
return self.obj; | |
}; | |
/** | |
* Private APIS | |
*/ | |
ObjDefine.prototype._define = function (name, val, exported, changeable) { | |
val = val != null ? val : this.defaults[name]; | |
this.descs[name] = this._describe(name, val, !!exported, !!changeable); | |
}; | |
ObjDefine.prototype._describe = function (name, val, exported, changeable) { | |
var self = this; | |
var exists = val != null; | |
if (exported && ObjDefine.REDEFINE_SUPPORTED) { | |
return { | |
enumerable: exists, | |
configurable: true, | |
get: _.constant(val), | |
set: function set(update) { | |
if (!changeable) return false; | |
// change the descriptor, since the value now exists. | |
self.descs[name] = self._describe(name, update, exported, changeable); | |
// apply the updated descriptor | |
_Object$defineProperty(self.obj, name, self.descs[name]); | |
} | |
}; | |
} | |
if (exported && !ObjDefine.REDEFINE_SUPPORTED) { | |
return { | |
enumerable: true, | |
configurable: true, | |
writable: changeable, | |
value: val | |
}; | |
} | |
return { | |
enumerable: false, | |
writable: changeable, | |
configurable: true, | |
value: val | |
}; | |
}; | |
return ObjDefine; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 465 */ | |
/***/ function(module, exports) { | |
module.exports = "<div class=\"sidebar-list\">\n <div ng-show=\"indexPatternList.length > 1\">\n <div class=\"index-pattern\" ng-click=\"showIndexPatternSelection = !showIndexPatternSelection\">\n <div css-truncate title=\"{{indexPattern.id}}\">{{indexPattern.id}}</div>\n <i ng-hide=\"showIndexPatternSelection\" class=\"fa fa-caret-down\"></i>\n <i ng-show=\"showIndexPatternSelection\" class=\"fa fa-caret-up\"></i>\n </div>\n <div ng-show=\"showIndexPatternSelection\">\n <ul class=\"list-unstyled sidebar-item index-pattern-selection\">\n <li css-truncate class=\"sidebar-item-title\" title=\"{{id}}\" ng-repeat=\"id in indexPatternList | orderBy\" ng-show=\"indexPattern.id != id\" ng-click=\"setIndexPattern(id)\">{{id}}</li>\n </ul>\n <div ng-click=\"showIndexPatternSelection = !showIndexPatternSelection\" class=\"discover-field-details-close\">\n <i class=\"fa fa-chevron-up\"></i>\n </div>\n </div>\n </div>\n <div ng-hide=\"indexPatternList.length > 1\">\n <div class=\"index-pattern\">\n <div css-truncate>{{ indexPattern.id }}</div>\n </div>\n </div>\n\n <div class=\"sidebar-list-header\">\n <h5>Selected Fields</h5>\n </div>\n <ul class=\"list-unstyled discover-selected-fields\" >\n <discover-field ng-repeat=\"field in fields.raw|filter:{display:true}\">\n </discover-field>\n </ul>\n\n <div class=\"sidebar-list-header sidebar-item\">\n <h5>Available Fields\n <i\n ng-class=\"{ 'fa-chevron-right': !showFields, 'fa-chevron-down': showFields }\"\n ng-click=\"showFields = !showFields\"\n aria-hidden=\"true\"\n class=\"fa visible-xs visible-sm pull-right field-collapse-toggle\" ></i>\n <button\n ng-class=\"{ 'btn-default': !filter.active, 'btn-success': filter.active, 'hidden-xs': !showFields, 'hidden-sm': !showFields }\"\n class=\"btn btn-xs btn-default pull-right discover-field-filter-toggle\"\n ng-click=\"showFilter = !showFilter\"\n aria-label=\"Field Settings\"\n aria-haspopup=\"true\"\n aria-expanded=\"{{showFilter}}\">\n <i aria-hidden=\"true\" class=\"fa fa-gear\"></i>\n </button>\n </h5>\n </div>\n\n <div class=\"sidebar-item\" ng-show=\"showFilter\">\n <div ng-click=\"showFilter = !showFilter\" class=\"discover-field-details-close\">\n <i aria-hidden=\"true\" class=\"fa fa-chevron-up\"></i>\n </div>\n <form role=\"form\" class=\"discover-field-details\">\n <div class=\"form-group\">\n <label>\n Analyzed\n </label>\n <select\n ng-options=\"opt.value as opt.label for opt in filter.boolOpts\"\n ng-model=\"filter.vals.analyzed\"\n class=\"form-control\">\n </select>\n </div>\n <div class=\"form-group\">\n <label>\n Indexed\n </label>\n <select\n ng-options=\"opt.value as opt.label for opt in filter.boolOpts\"\n ng-model=\"filter.vals.indexed\"\n class=\"form-control\">\n </select>\n </div>\n <div class=\"form-group\">\n <label>\n Type\n </label>\n <select\n ng-options=\"field as field for field in fieldTypes\"\n ng-model=\"filter.vals.type\"\n class=\"form-control\">\n </select>\n </div>\n <div class=\"form-group\">\n <label>\n Field name\n </label>\n <input type=\"text\" class=\"form-control\" ng-model=\"filter.vals.name\">\n </div>\n <div class=\"form-group\">\n <label>\n <input type=\"checkbox\" ng-model=\"filter.vals.missing\">\n Hide Missing Fields\n </label>\n </div>\n </form>\n <div\n ng-click=\"filter.reset()\"\n ng-disabled=\"!filter.active\"\n class=\"sidebar-item-button danger ng-scope\">\n Reset Filters\n </div>\n </div>\n\n <ul\n ng-show=\"(popularFields | filter:filter.isFieldFiltered).length > 0\"\n ng-class=\"{ 'hidden-sm': !showFields, 'hidden-xs': !showFields }\"\n class=\"list-unstyled sidebar-well discover-popular-fields\">\n <li class=\"sidebar-item sidebar-list-header\">\n <h6>Popular</h6>\n </li>\n <discover-field\n ng-repeat=\"field in popularFields | filter:filter.isFieldFiltered\">\n </discover-field>\n </ul>\n\n <ul\n ng-class=\"{ 'hidden-sm': !showFields, 'hidden-xs': !showFields }\"\n class=\"list-unstyled discover-unpopular-fields\">\n <discover-field\n ng-repeat=\"field in unpopularFields | filter:filter.isFieldFiltered\">\n </discover-field>\n </ul>\n\n</div>\n" | |
/***/ }, | |
/* 466 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(212); | |
__webpack_require__(228); | |
__webpack_require__(310); | |
__webpack_require__(467); | |
__webpack_require__(256); | |
__webpack_require__(230); | |
__webpack_require__(468); | |
__webpack_require__(493); | |
__webpack_require__(315); | |
__webpack_require__(500); | |
__webpack_require__(507); | |
__webpack_require__(508); | |
__webpack_require__(509); | |
__webpack_require__(510); | |
__webpack_require__(514); | |
__webpack_require__(565); | |
__webpack_require__(217); | |
__webpack_require__(458); | |
__webpack_require__(216); | |
__webpack_require__(218); | |
__webpack_require__(576); | |
__webpack_require__(577); | |
__webpack_require__(682); | |
__webpack_require__(683); | |
__webpack_require__(684); | |
__webpack_require__(685); | |
__webpack_require__(703); | |
__webpack_require__(621); | |
__webpack_require__(704); | |
__webpack_require__(705); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var angular = __webpack_require__(212); | |
var moment = __webpack_require__(228); | |
var ConfigTemplate = __webpack_require__(310); | |
var getSort = __webpack_require__(467); | |
var rison = __webpack_require__(256); | |
var dateMath = __webpack_require__(230); | |
__webpack_require__(468); | |
__webpack_require__(493); | |
__webpack_require__(315); | |
__webpack_require__(500); | |
__webpack_require__(507); | |
__webpack_require__(508); | |
__webpack_require__(509); | |
__webpack_require__(510); | |
__webpack_require__(514); | |
__webpack_require__(565); | |
__webpack_require__(217); | |
__webpack_require__(458); | |
var app = __webpack_require__(216).get('apps/discover', ['kibana/notify', 'kibana/courier', 'kibana/index_patterns']); | |
__webpack_require__(218).when('/discover/:id?', { | |
template: __webpack_require__(576), | |
reloadOnSearch: false, | |
resolve: { | |
ip: function ip(Promise, courier, config, $location) { | |
return courier.indexPatterns.getIds().then(function (list) { | |
var stateRison = $location.search()._a; | |
var state; | |
try { | |
state = rison.decode(stateRison); | |
} catch (e) { | |
state = {}; | |
} | |
var specified = !!state.index; | |
var exists = _.contains(list, state.index); | |
var id = exists ? state.index : config.get('defaultIndex'); | |
return Promise.props({ | |
list: list, | |
loaded: courier.indexPatterns.get(id), | |
stateVal: state.index, | |
stateValFound: specified && exists | |
}); | |
}); | |
}, | |
savedSearch: function savedSearch(courier, savedSearches, $route) { | |
return savedSearches.get($route.current.params.id)['catch'](courier.redirectWhenMissing({ | |
'search': '/discover', | |
'index-pattern': '/settings/objects/savedSearches/' + $route.current.params.id | |
})); | |
} | |
} | |
}); | |
app.controller('discover', function ($scope, config, courier, $route, $window, Notifier, AppState, timefilter, Promise, Private, kbnUrl, highlightTags) { | |
var Vis = Private(__webpack_require__(577)); | |
var docTitle = Private(__webpack_require__(682)); | |
var brushEvent = Private(__webpack_require__(683)); | |
var HitSortFn = Private(__webpack_require__(684)); | |
var queryFilter = Private(__webpack_require__(685)); | |
var filterManager = Private(__webpack_require__(703)); | |
var notify = new Notifier({ | |
location: 'Discover' | |
}); | |
$scope.intervalOptions = Private(__webpack_require__(621)); | |
$scope.showInterval = false; | |
$scope.intervalEnabled = function (interval) { | |
return interval.val !== 'custom'; | |
}; | |
$scope.toggleInterval = function () { | |
$scope.showInterval = !$scope.showInterval; | |
}; | |
// config panel templates | |
$scope.configTemplate = new ConfigTemplate({ | |
load: __webpack_require__(704), | |
save: __webpack_require__(705) | |
}); | |
$scope.timefilter = timefilter; | |
// the saved savedSearch | |
var savedSearch = $route.current.locals.savedSearch; | |
$scope.$on('$destroy', savedSearch.destroy); | |
// the actual courier.SearchSource | |
$scope.searchSource = savedSearch.searchSource; | |
$scope.indexPattern = resolveIndexPatternLoading(); | |
$scope.searchSource.set('index', $scope.indexPattern); | |
if (savedSearch.id) { | |
docTitle.change(savedSearch.title); | |
} | |
var $state = $scope.state = new AppState(getStateDefaults()); | |
function getStateDefaults() { | |
return { | |
query: $scope.searchSource.get('query') || '', | |
sort: getSort.array(savedSearch.sort, $scope.indexPattern), | |
columns: savedSearch.columns || ['_source'], | |
index: $scope.indexPattern.id, | |
interval: 'auto', | |
filters: _.cloneDeep($scope.searchSource.getOwn('filter')) | |
}; | |
} | |
$state.index = $scope.indexPattern.id; | |
$state.sort = getSort.array($state.sort, $scope.indexPattern); | |
$scope.$watchCollection('state.columns', function () { | |
$state.save(); | |
}); | |
$scope.opts = { | |
// number of records to fetch, then paginate through | |
sampleSize: config.get('discover:sampleSize'), | |
// Index to match | |
index: $scope.indexPattern.id, | |
timefield: $scope.indexPattern.timeFieldName, | |
savedSearch: savedSearch, | |
indexPatternList: $route.current.locals.ip.list | |
}; | |
var init = _.once(function () { | |
var showTotal = 5; | |
$scope.failuresShown = showTotal; | |
$scope.showAllFailures = function () { | |
$scope.failuresShown = $scope.failures.length; | |
}; | |
$scope.showLessFailures = function () { | |
$scope.failuresShown = showTotal; | |
}; | |
$scope.updateDataSource().then(function () { | |
$scope.$listen(timefilter, 'fetch', function () { | |
$scope.fetch(); | |
}); | |
$scope.$watchCollection('state.sort', function (sort) { | |
if (!sort) return; | |
// get the current sort from {key: val} to ["key", "val"]; | |
var currentSort = _.pairs($scope.searchSource.get('sort')).pop(); | |
// if the searchSource doesn't know, tell it so | |
if (!angular.equals(sort, currentSort)) $scope.fetch(); | |
}); | |
// update data source when filters update | |
$scope.$listen(queryFilter, 'update', function () { | |
return $scope.updateDataSource().then(function () { | |
$state.save(); | |
}); | |
}); | |
// update data source when hitting forward/back and the query changes | |
$scope.$listen($state, 'fetch_with_changes', function (diff) { | |
if (diff.indexOf('query') >= 0) $scope.fetch(); | |
}); | |
// fetch data when filters fire fetch event | |
$scope.$listen(queryFilter, 'fetch', $scope.fetch); | |
$scope.$watch('opts.timefield', function (timefield) { | |
timefilter.enabled = !!timefield; | |
}); | |
$scope.$watch('state.interval', function (interval, oldInterval) { | |
if (interval !== oldInterval && interval === 'auto') { | |
$scope.showInterval = false; | |
} | |
$scope.fetch(); | |
}); | |
$scope.$watch('vis.aggs', function () { | |
// no timefield, no vis, nothing to update | |
if (!$scope.opts.timefield) return; | |
var buckets = $scope.vis.aggs.bySchemaGroup.buckets; | |
if (buckets && buckets.length === 1) { | |
$scope.intervalName = 'by ' + buckets[0].buckets.getInterval().description; | |
} else { | |
$scope.intervalName = 'auto'; | |
} | |
}); | |
$scope.$watchMulti(['rows', 'fetchStatus'], (function updateResultState() { | |
var prev = {}; | |
var status = { | |
LOADING: 'loading', // initial data load | |
READY: 'ready', // results came back | |
NO_RESULTS: 'none' // no results came back | |
}; | |
function pick(rows, oldRows, fetchStatus) { | |
// initial state, pretend we are loading | |
if (rows == null && oldRows == null) return status.LOADING; | |
var rowsEmpty = _.isEmpty(rows); | |
// An undefined fetchStatus means the requests are still being | |
// prepared to be sent. When all requests are completed, | |
// fetchStatus is set to null, so it's important that we | |
// specifically check for undefined to determine a loading status. | |
var preparingForFetch = _.isUndefined(fetchStatus); | |
if (preparingForFetch) return status.LOADING;else if (rowsEmpty && fetchStatus) return status.LOADING;else if (!rowsEmpty) return status.READY;else return status.NO_RESULTS; | |
} | |
return function () { | |
var current = { | |
rows: $scope.rows, | |
fetchStatus: $scope.fetchStatus | |
}; | |
$scope.resultState = pick(current.rows, prev.rows, current.fetchStatus, prev.fetchStatus); | |
prev = current; | |
}; | |
})()); | |
$scope.searchSource.onError(function (err) { | |
notify.error(err); | |
})['catch'](notify.fatal); | |
function initForTime() { | |
return setupVisualization().then($scope.updateTime); | |
} | |
return Promise.resolve($scope.opts.timefield && initForTime()).then(function () { | |
init.complete = true; | |
$state.replace(); | |
$scope.$emit('application.load'); | |
}); | |
}); | |
}); | |
$scope.opts.saveDataSource = function () { | |
return $scope.updateDataSource().then(function () { | |
savedSearch.id = savedSearch.title; | |
savedSearch.columns = $scope.state.columns; | |
savedSearch.sort = $scope.state.sort; | |
return savedSearch.save().then(function (id) { | |
$scope.configTemplate.close('save'); | |
if (id) { | |
notify.info('Saved Data Source "' + savedSearch.title + '"'); | |
if (savedSearch.id !== $route.current.params.id) { | |
kbnUrl.change('/discover/{{id}}', { id: savedSearch.id }); | |
} else { | |
// Update defaults so that "reload saved query" functions correctly | |
$state.setDefaults(getStateDefaults()); | |
} | |
} | |
}); | |
})['catch'](notify.error); | |
}; | |
$scope.opts.fetch = $scope.fetch = function () { | |
// ignore requests to fetch before the app inits | |
if (!init.complete) return; | |
$scope.updateTime(); | |
$scope.updateDataSource().then(setupVisualization).then(function () { | |
$state.save(); | |
return courier.fetch(); | |
})['catch'](notify.error); | |
}; | |
$scope.searchSource.onBeginSegmentedFetch(function (segmented) { | |
function flushResponseData() { | |
$scope.hits = 0; | |
$scope.faliures = []; | |
$scope.rows = []; | |
$scope.fieldCounts = {}; | |
} | |
if (!$scope.rows) flushResponseData(); | |
var sort = $state.sort; | |
var timeField = $scope.indexPattern.timeFieldName; | |
var totalSize = $scope.size || $scope.opts.sampleSize; | |
/** | |
* Basically an emum. | |
* | |
* opts: | |
* "time" - sorted by the timefield | |
* "non-time" - explicitly sorted by a non-time field, NOT THE SAME AS `sortBy !== "time"` | |
* "implicit" - no sorting set, NOT THE SAME AS "non-time" | |
* | |
* @type {String} | |
*/ | |
var sortBy = (function () { | |
if (!_.isArray(sort)) return 'implicit';else if (sort[0] === '_score') return 'implicit';else if (sort[0] === timeField) return 'time';else return 'non-time'; | |
})(); | |
var sortFn = null; | |
if (sortBy !== 'implicit') { | |
sortFn = new HitSortFn(sort[1]); | |
} | |
$scope.updateTime(); | |
if (sort[0] === '_score') segmented.setMaxSegments(1); | |
segmented.setDirection(sortBy === 'time' ? sort[1] || 'desc' : 'desc'); | |
segmented.setSortFn(sortFn); | |
segmented.setSize($scope.opts.sampleSize); | |
// triggered when the status updated | |
segmented.on('status', function (status) { | |
$scope.fetchStatus = status; | |
}); | |
segmented.on('first', function () { | |
flushResponseData(); | |
}); | |
segmented.on('segment', notify.timed('handle each segment', function (resp) { | |
if (resp._shards.failed > 0) { | |
$scope.failures = _.union($scope.failures, resp._shards.failures); | |
$scope.failures = _.uniq($scope.failures, false, function (failure) { | |
return failure.index + failure.shard + failure.reason; | |
}); | |
} | |
})); | |
segmented.on('mergedSegment', function (merged) { | |
$scope.mergedEsResp = merged; | |
$scope.hits = merged.hits.total; | |
var indexPattern = $scope.searchSource.get('index'); | |
// the merge rows, use a new array to help watchers | |
$scope.rows = merged.hits.hits.slice(); | |
notify.event('flatten hit and count fields', function () { | |
var counts = $scope.fieldCounts; | |
// if we haven't counted yet, or need a fresh count because we are sorting, reset the counts | |
if (!counts || sortFn) counts = $scope.fieldCounts = {}; | |
$scope.rows.forEach(function (hit) { | |
// skip this work if we have already done it | |
if (hit.$$_counted) return; | |
// when we are sorting results, we need to redo the counts each time because the | |
// "top 500" may change with each response, so don't mark this as counted | |
if (!sortFn) hit.$$_counted = true; | |
var fields = _.keys(indexPattern.flattenHit(hit)); | |
var n = fields.length; | |
var field; | |
while (field = fields[--n]) { | |
if (counts[field]) counts[field] += 1;else counts[field] = 1; | |
} | |
}); | |
}); | |
}); | |
segmented.on('complete', function () { | |
if ($scope.fetchStatus.hitCount === 0) { | |
flushResponseData(); | |
} | |
$scope.fetchStatus = null; | |
}); | |
})['catch'](notify.fatal); | |
$scope.updateTime = function () { | |
$scope.timeRange = { | |
from: dateMath.parse(timefilter.time.from), | |
to: dateMath.parse(timefilter.time.to, true) | |
}; | |
}; | |
$scope.resetQuery = function () { | |
kbnUrl.change('/discover/{{id}}', { id: $route.current.params.id }); | |
}; | |
$scope.newQuery = function () { | |
kbnUrl.change('/discover'); | |
}; | |
$scope.updateDataSource = Promise.method(function () { | |
$scope.searchSource.size($scope.opts.sampleSize).sort(getSort($state.sort, $scope.indexPattern)).query(!$state.query ? null : $state.query).set('filter', queryFilter.getFilters()); | |
if (config.get('doc_table:highlight')) { | |
$scope.searchSource.highlight({ | |
pre_tags: [highlightTags.pre], | |
post_tags: [highlightTags.post], | |
fields: { '*': {} }, | |
require_field_match: false, | |
fragment_size: 2147483647 // Limit of an integer. | |
}); | |
} | |
}); | |
// TODO: On array fields, negating does not negate the combination, rather all terms | |
$scope.filterQuery = function (field, values, operation) { | |
$scope.indexPattern.popularizeField(field, 1); | |
filterManager.add(field, values, operation, $state.index); | |
}; | |
$scope.toTop = function () { | |
$window.scrollTo(0, 0); | |
}; | |
var loadingVis; | |
function setupVisualization() { | |
// If we're not setting anything up we need to return an empty promise | |
if (!$scope.opts.timefield) return Promise.resolve(); | |
if (loadingVis) return loadingVis; | |
var visStateAggs = [{ | |
type: 'count', | |
schema: 'metric' | |
}, { | |
type: 'date_histogram', | |
schema: 'segment', | |
params: { | |
field: $scope.opts.timefield, | |
interval: $state.interval, | |
min_doc_count: 0 | |
} | |
}]; | |
// we have a vis, just modify the aggs | |
if ($scope.vis) { | |
var visState = $scope.vis.getState(); | |
visState.aggs = visStateAggs; | |
$scope.vis.setState(visState); | |
return Promise.resolve($scope.vis); | |
} | |
$scope.vis = new Vis($scope.indexPattern, { | |
type: 'histogram', | |
params: { | |
addLegend: false, | |
addTimeMarker: true | |
}, | |
listeners: { | |
click: function click(e) { | |
console.log(e); | |
timefilter.time.from = moment(e.point.x); | |
timefilter.time.to = moment(e.point.x + e.data.ordered.interval); | |
timefilter.time.mode = 'absolute'; | |
}, | |
brush: brushEvent | |
}, | |
aggs: visStateAggs | |
}); | |
$scope.searchSource.aggs(function () { | |
$scope.vis.requesting(); | |
return $scope.vis.aggs.toDsl(); | |
}); | |
// stash this promise so that other calls to setupVisualization will have to wait | |
loadingVis = new Promise(function (resolve) { | |
$scope.$on('ready:vis', function () { | |
resolve($scope.vis); | |
}); | |
})['finally'](function () { | |
// clear the loading flag | |
loadingVis = null; | |
}); | |
return loadingVis; | |
} | |
function resolveIndexPatternLoading() { | |
var props = $route.current.locals.ip; | |
var loaded = props.loaded; | |
var stateVal = props.stateVal; | |
var stateValFound = props.stateValFound; | |
var own = $scope.searchSource.getOwn('index'); | |
if (own && !stateVal) return own; | |
if (stateVal && !stateValFound) { | |
var err = '"' + stateVal + '" is not a configured pattern. '; | |
if (own) { | |
notify.warning(err + ' Using the saved index pattern: "' + own.id + '"'); | |
return own; | |
} | |
notify.warning(err + ' Using the default index pattern: "' + loaded.id + '"'); | |
} | |
return loaded; | |
} | |
init(); | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 467 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
/** | |
* Take a sorting array and make it into an object | |
* @param {array} 2 item array [fieldToSort, directionToSort] | |
* @param {object} indexPattern used for determining default sort | |
* @returns {object} a sort object suitable for returning to elasticsearch | |
*/ | |
function getSort(sort, indexPattern) { | |
var sortObj = {}; | |
var field; | |
var direction; | |
function isSortable(field) { | |
return indexPattern.fields.byName[field] && indexPattern.fields.byName[field].sortable; | |
} | |
if (_.isArray(sort) && sort.length === 2 && isSortable(sort[0])) { | |
// At some point we need to refact the sorting logic, this array sucks. | |
field = sort[0]; | |
direction = sort[1]; | |
} else if (indexPattern.timeFieldName && isSortable(indexPattern.timeFieldName)) { | |
field = indexPattern.timeFieldName; | |
direction = 'desc'; | |
} | |
if (field) { | |
sortObj[field] = direction; | |
} else { | |
sortObj._score = 'desc'; | |
} | |
return sortObj; | |
} | |
getSort.array = function (sort, indexPattern) { | |
return _(getSort(sort, indexPattern)).pairs().pop(); | |
}; | |
return getSort; | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 468 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(469); | |
__webpack_require__(467); | |
__webpack_require__(470); | |
__webpack_require__(471); | |
__webpack_require__(472); | |
__webpack_require__(473); | |
__webpack_require__(475); | |
__webpack_require__(216); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var html = __webpack_require__(469); | |
var getSort = __webpack_require__(467); | |
__webpack_require__(470); | |
__webpack_require__(471); | |
__webpack_require__(472); | |
__webpack_require__(473); | |
__webpack_require__(475); | |
__webpack_require__(216).get('kibana').directive('docTable', function (config, Notifier, getAppState) { | |
return { | |
restrict: 'E', | |
template: html, | |
scope: { | |
sorting: '=', | |
columns: '=', | |
hits: '=?', // You really want either hits & indexPattern, OR searchSource | |
indexPattern: '=?', | |
searchSource: '=?', | |
infiniteScroll: '=?', | |
filter: '=?' | |
}, | |
link: function link($scope) { | |
var notify = new Notifier(); | |
$scope.limit = 50; | |
$scope.persist = { | |
sorting: $scope.sorting, | |
columns: $scope.columns | |
}; | |
var prereq = (function () { | |
var fns = []; | |
return function register(fn) { | |
fns.push(fn); | |
return function () { | |
fn.apply(this, arguments); | |
if (fns.length) { | |
_.pull(fns, fn); | |
if (!fns.length) { | |
$scope.$root.$broadcast('ready:vis'); | |
} | |
} | |
}; | |
}; | |
})(); | |
$scope.addRows = function () { | |
$scope.limit += 50; | |
}; | |
// This exists to fix the problem of an empty initial column list not playing nice with watchCollection. | |
$scope.$watch('columns', function (columns) { | |
if (columns.length !== 0) return; | |
var $state = getAppState(); | |
$scope.columns.push('_source'); | |
if ($state) $state.replace(); | |
}); | |
$scope.$watchCollection('columns', function (columns, oldColumns) { | |
if (oldColumns.length === 1 && oldColumns[0] === '_source' && $scope.columns.length > 1) { | |
_.pull($scope.columns, '_source'); | |
} | |
if ($scope.columns.length === 0) $scope.columns.push('_source'); | |
}); | |
$scope.$watch('searchSource', prereq(function (searchSource) { | |
if (!$scope.searchSource) return; | |
$scope.indexPattern = $scope.searchSource.get('index'); | |
$scope.searchSource.size(config.get('discover:sampleSize')); | |
$scope.searchSource.sort(getSort($scope.sorting, $scope.indexPattern)); | |
// Set the watcher after initialization | |
$scope.$watchCollection('sorting', function (newSort, oldSort) { | |
// Don't react if sort values didn't really change | |
if (newSort === oldSort) return; | |
$scope.searchSource.sort(getSort(newSort, $scope.indexPattern)); | |
$scope.searchSource.fetchQueued(); | |
}); | |
$scope.$on('$destroy', function () { | |
if ($scope.searchSource) $scope.searchSource.destroy(); | |
}); | |
// TODO: we need to have some way to clean up result requests | |
$scope.searchSource.onResults().then(function onResults(resp) { | |
// Reset infinite scroll limit | |
$scope.limit = 50; | |
// Abort if something changed | |
if ($scope.searchSource !== $scope.searchSource) return; | |
$scope.hits = resp.hits.hits; | |
return $scope.searchSource.onResults().then(onResults); | |
})['catch'](notify.fatal); | |
$scope.searchSource.onError(notify.error)['catch'](notify.fatal); | |
})); | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 469 */ | |
/***/ function(module, exports) { | |
module.exports = "<div\n ng-if=\"hits.length\"\n ng-class=\"{ loading: searchSource.activeFetchCount > 0 }\">\n <paginate ng-if=\"!infiniteScroll\" list=\"hits\" per-page=\"50\" top-controls=\"true\">\n <table class=\"kbn-table table\" ng-if=\"indexPattern\">\n <thead\n kbn-table-header\n columns=\"columns\"\n index-pattern=\"indexPattern\"\n sorting=\"sorting\">\n </thead>\n <tbody>\n <tr ng-repeat=\"row in page|limitTo:limit track by row._index+row._type+row._id+row._score\"\n kbn-table-row=\"row\"\n columns=\"columns\"\n sorting=\"sorting\"\n index-pattern=\"indexPattern\"\n filter=\"filter\"\n class=\"discover-table-row\"></tr>\n </tbody>\n </table>\n </paginate>\n\n <table ng-if=\"infiniteScroll\" class=\"kbn-table table\" ng-if=\"indexPattern\">\n <thead\n kbn-table-header\n columns=\"columns\"\n index-pattern=\"indexPattern\"\n sorting=\"sorting\">\n </thead>\n <tbody>\n <tr ng-repeat=\"row in hits|limitTo:limit track by row._index+row._type+row._id+row._score\"\n kbn-table-row=\"row\"\n columns=\"columns\"\n sorting=\"sorting\"\n index-pattern=\"indexPattern\"\n filter=\"filter\"\n class=\"discover-table-row\"></tr>\n </tbody>\n </table>\n <kbn-infinite-scroll ng-if=\"infiniteScroll\" more=\"addRows\"></kbn-infinite-scroll>\n</div>\n<div ng-if=\"hits != null && !hits.length\" class=\"table-vis-error\">\n <h2><i class=\"fa fa-meh-o\"></i></h2>\n <h4>No results found</h4>\n</div>" | |
/***/ }, | |
/* 470 */ | |
/***/ function(module, exports) { | |
// removed by extract-text-webpack-plugin | |
/***/ }, | |
/* 471 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(216); | |
__webpack_require__(208); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var module = __webpack_require__(216).get('kibana'); | |
var $ = __webpack_require__(208); | |
module.directive('kbnTruncated', function ($compile) { | |
return { | |
restrict: 'E', | |
scope: { | |
orig: '@', | |
length: '@' | |
}, | |
template: function template($element, attrs) { | |
var template = '<span>{{text}}</span>'; | |
template += '<span ng-if="orig.length > length"> <a ng-click="toggle()">{{action}}</a></span>'; | |
return template; | |
}, | |
link: function link($scope, $element, attrs) { | |
var fullText = $scope.orig; | |
var truncated = fullText.substring(0, $scope.length); | |
if (fullText === truncated) { | |
$scope.text = fullText; | |
return; | |
} | |
truncated += '...'; | |
$scope.expanded = false; | |
$scope.text = truncated; | |
$scope.action = 'more'; | |
$scope.toggle = function () { | |
$scope.expanded = !$scope.expanded; | |
$scope.text = $scope.expanded ? fullText : truncated; | |
$scope.action = $scope.expanded ? 'less' : 'more'; | |
}; | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 472 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(216); | |
__webpack_require__(208); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var module = __webpack_require__(216).get('kibana'); | |
var $ = __webpack_require__(208); | |
module.directive('kbnInfiniteScroll', function () { | |
return { | |
restrict: 'E', | |
scope: { | |
more: '=' | |
}, | |
link: function link($scope, $element, attrs) { | |
var $window = $(window); | |
var checkTimer; | |
function onScroll() { | |
if (!$scope.more) return; | |
var winHeight = $window.height(); | |
var winBottom = winHeight + $window.scrollTop(); | |
var elTop = $element.offset().top; | |
var remaining = elTop - winBottom; | |
if (remaining <= winHeight * 0.50) { | |
$scope[$scope.$$phase ? '$eval' : '$apply'](function () { | |
var more = $scope.more(); | |
}); | |
} | |
} | |
function scheduleCheck() { | |
if (checkTimer) return; | |
checkTimer = setTimeout(function () { | |
checkTimer = null; | |
onScroll(); | |
}, 50); | |
} | |
$window.on('scroll', scheduleCheck); | |
$scope.$on('$destroy', function () { | |
clearTimeout(checkTimer); | |
$window.off('scroll', scheduleCheck); | |
}); | |
scheduleCheck(); | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 473 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(216); | |
__webpack_require__(447); | |
__webpack_require__(474); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
var module = __webpack_require__(216).get('app/discover'); | |
__webpack_require__(447); | |
module.directive('kbnTableHeader', function (shortDotsFilter) { | |
var headerHtml = __webpack_require__(474); | |
return { | |
restrict: 'A', | |
scope: { | |
columns: '=', | |
sorting: '=', | |
indexPattern: '=' | |
}, | |
template: headerHtml, | |
controller: function controller($scope) { | |
var sortableField = function sortableField(field) { | |
if (!$scope.indexPattern) return; | |
var sortable = _.get($scope.indexPattern.fields.byName[field], 'sortable'); | |
return sortable; | |
}; | |
$scope.tooltip = function (column) { | |
if (!sortableField(column)) return ''; | |
return 'Sort by ' + shortDotsFilter(column); | |
}; | |
$scope.canRemove = function (name) { | |
return name !== '_source' || $scope.columns.length !== 1; | |
}; | |
$scope.headerClass = function (column) { | |
if (!sortableField(column)) return; | |
var sorting = $scope.sorting; | |
var defaultClass = ['fa', 'fa-sort-up', 'table-header-sortchange']; | |
if (!sorting || column !== sorting[0]) return defaultClass; | |
return ['fa', sorting[1] === 'asc' ? 'fa-sort-up' : 'fa-sort-down']; | |
}; | |
$scope.moveLeft = function (column) { | |
var index = _.indexOf($scope.columns, column); | |
if (index === 0) return; | |
_.move($scope.columns, index, --index); | |
}; | |
$scope.moveRight = function (column) { | |
var index = _.indexOf($scope.columns, column); | |
if (index === $scope.columns.length - 1) return; | |
_.move($scope.columns, index, ++index); | |
}; | |
$scope.toggleColumn = function (fieldName) { | |
_.toggleInOut($scope.columns, fieldName); | |
}; | |
$scope.sort = function (column) { | |
if (!column || !sortableField(column)) return; | |
var sorting = $scope.sorting = $scope.sorting || []; | |
var direction = sorting[1] || 'asc'; | |
if (sorting[0] !== column) { | |
direction = 'asc'; | |
} else { | |
direction = sorting[1] === 'asc' ? 'desc' : 'asc'; | |
} | |
$scope.sorting[0] = column; | |
$scope.sorting[1] = direction; | |
}; | |
} | |
}; | |
}); | |
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); | |
/***/ }, | |
/* 474 */ | |
/***/ function(module, exports) { | |
module.exports = "<tr>\n <th width=\"1%\"></th>\n <th ng-if=\"indexPattern.timeFieldName\">\n <span>Time <i ng-class=\"headerClass(indexPattern.timeFieldName)\" ng-click=\"sort(indexPattern.timeFieldName)\" tooltip=\"Sort by time\"></i></span>\n </th>\n <th ng-repeat=\"name in columns\">\n <span class=\"table-header-name\">\n {{name | shortDots}} <i ng-class=\"headerClass(name)\" ng-click=\"sort(name)\" tooltip=\"{{tooltip(name)}}\" tooltip-append-to-body=\"1\"></i>\n </span>\n <span class=\"table-header-move\">\n <i ng-click=\"toggleColumn(name)\" ng-show=\"canRemove(name)\" class=\"fa fa-remove\" tooltip=\"Remove column\" tooltip-append-to-body=\"1\"></i>\n <i ng-click=\"moveLeft(name)\" class=\"fa fa-angle-double-left\" ng-show=\"!$first\" tooltip=\"Move column to the left\" tooltip-append-to-body=\"1\"></i>\n <i ng-click=\"moveRight(name)\" class=\"fa fa-angle-double-right\" ng-show=\"!$last\" tooltip=\"Move column to the right\" tooltip-append-to-body=\"1\"></i>\n </span>\n </th>\n</tr>" | |
/***/ }, | |
/* 475 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var __WEBPACK_AMD_DEFINE_RESULT__;/*** auto-preload-rjscommon-deps-loader ***/ | |
__webpack_require__(194); | |
__webpack_require__(208); | |
__webpack_require__(476); | |
__webpack_require__(216); | |
__webpack_require__(457); | |
__webpack_require__(458); | |
__webpack_require__(477); | |
__webpack_require__(487); | |
__webpack_require__(447); | |
__webpack_require__(488); | |
__webpack_require__(489); | |
__webpack_require__(490); | |
__webpack_require__(491); | |
__webpack_require__(492); | |
'use strict'; | |
!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { | |
var _ = __webpack_require__(194); | |
v |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment