heatmap.min.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*
  2. * heatmap.js v2.0.0 | JavaScript Heatmap Library
  3. *
  4. * Copyright 2008-2014 Patrick Wied <heatmapjs@patrick-wied.at> - All rights reserved.
  5. * Dual licensed under MIT and Beerware license
  6. *
  7. * :: 2014-08-05 01:42
  8. */
  9. (function (a) {
  10. var b = {
  11. defaultRadius: 40,
  12. defaultRenderer: "canvas2d",
  13. defaultGradient: {
  14. .15: "rgb(133,167,109)",
  15. .55: "rgb(0,255,0)",
  16. .85: "yellow",
  17. 1: "rgb(255,0,0)"
  18. },
  19. defaultMaxOpacity: 1,
  20. defaultMinOpacity: 0,
  21. defaultBlur: .85,
  22. defaultXField: "x",
  23. defaultYField: "y",
  24. defaultValueField: "value",
  25. plugins: {}
  26. };
  27. var c = function i() {
  28. var a = function d(a) {
  29. this._coordinator = {};
  30. this._data = [];
  31. this._radi = [];
  32. this._min = 0;
  33. this._max = 1;
  34. this._xField = a["xField"] || a.defaultXField;
  35. this._yField = a["yField"] || a.defaultYField;
  36. this._valueField = a["valueField"] || a.defaultValueField;
  37. if (a["sp-radius"]) {
  38. this._cfgRadius = a["sp-radius"]
  39. }
  40. };
  41. var c = b.defaultRadius;
  42. a.prototype = {
  43. _organiseData: function (a, b) {
  44. var d = a[this._xField];
  45. var e = a[this._yField];
  46. var f = this._radi;
  47. var g = this._data;
  48. var h = this._max;
  49. var i = this._min;
  50. var j = a[this._valueField] || 1;
  51. var k = a.radius || this._cfgRadius || c;
  52. if (!g[d]) {
  53. g[d] = [];
  54. f[d] = []
  55. }
  56. if (!g[d][e]) {
  57. g[d][e] = j;
  58. f[d][e] = k
  59. } else {
  60. g[d][e] += j
  61. }
  62. if (g[d][e] > h) {
  63. if (!b) {
  64. this._max = g[d][e]
  65. } else {
  66. this.setDataMax(g[d][e])
  67. }
  68. return false
  69. } else {
  70. return {
  71. x: d,
  72. y: e,
  73. value: j,
  74. radius: k,
  75. min: i,
  76. max: h
  77. }
  78. }
  79. },
  80. _unOrganizeData: function () {
  81. var a = [];
  82. var b = this._data;
  83. var c = this._radi;
  84. for (var d in b) {
  85. for (var e in b[d]) {
  86. a.push({
  87. x: d,
  88. y: e,
  89. radius: c[d][e],
  90. value: b[d][e]
  91. })
  92. }
  93. }
  94. return {
  95. min: this._min,
  96. max: this._max,
  97. data: a
  98. }
  99. },
  100. _onExtremaChange: function () {
  101. this._coordinator.emit("extremachange", {
  102. min: this._min,
  103. max: this._max
  104. })
  105. },
  106. addData: function () {
  107. if (arguments[0].length > 0) {
  108. var a = arguments[0];
  109. var b = a.length;
  110. while (b--) {
  111. this.addData.call(this, a[b])
  112. }
  113. } else {
  114. var c = this._organiseData(arguments[0], true);
  115. if (c) {
  116. this._coordinator.emit("renderpartial", {
  117. min: this._min,
  118. max: this._max,
  119. data: [c]
  120. })
  121. }
  122. }
  123. return this
  124. },
  125. setData: function (a) {
  126. var b = a.data;
  127. var c = b.length;
  128. this._max = a.max;
  129. this._min = a.min || 0;
  130. this._data = [];
  131. this._radi = [];
  132. for (var d = 0; d < c; d++) {
  133. this._organiseData(b[d], false)
  134. }
  135. this._onExtremaChange();
  136. this._coordinator.emit("renderall", this._getInternalData());
  137. return this
  138. },
  139. removeData: function () { },
  140. setDataMax: function (a) {
  141. this._max = a;
  142. this._onExtremaChange();
  143. this._coordinator.emit("renderall", this._getInternalData());
  144. return this
  145. },
  146. setDataMin: function (a) {
  147. this._min = a;
  148. this._onExtremaChange();
  149. this._coordinator.emit("renderall", this._getInternalData());
  150. return this
  151. },
  152. setCoordinator: function (a) {
  153. this._coordinator = a
  154. },
  155. _getInternalData: function () {
  156. return {
  157. max: this._max,
  158. min: this._min,
  159. data: this._data,
  160. radi: this._radi
  161. }
  162. },
  163. getData: function () {
  164. return this._unOrganizeData()
  165. }
  166. };
  167. return a
  168. }();
  169. var d = function j() {
  170. var a = function (a) {
  171. var b = a.gradient || a.defaultGradient;
  172. var c = document.createElement("canvas");
  173. var d = c.getContext("2d");
  174. c.width = 256;
  175. c.height = 1;
  176. var e = d.createLinearGradient(0, 0, 256, 1);
  177. for (var f in b) {
  178. e.addColorStop(f, b[f])
  179. }
  180. d.fillStyle = e;
  181. d.fillRect(0, 0, 256, 1);
  182. return d.getImageData(0, 0, 256, 1).data
  183. };
  184. var b = function (a, b) {
  185. var c = document.createElement("canvas");
  186. var d = c.getContext("2d");
  187. var e = a;
  188. var f = a;
  189. c.width = c.height = a * 2;
  190. if (b == 1) {
  191. d.beginPath();
  192. d.arc(e, f, a, 0, 2 * Math.PI, false);
  193. d.fillStyle = "rgba(0,0,0,1)";
  194. d.fill()
  195. } else {
  196. var g = d.createRadialGradient(e, f, a * b, e, f, a);
  197. g.addColorStop(0, "rgba(0,0,0,1)");
  198. g.addColorStop(1, "rgba(0,0,0,0)");
  199. d.fillStyle = g;
  200. d.fillRect(0, 0, 2 * a, 2 * a)
  201. }
  202. return c
  203. };
  204. var c = function (a) {
  205. var b = [];
  206. var c = a.min;
  207. var d = a.max;
  208. var e = a.radi;
  209. var a = a.data;
  210. var f = Object.keys(a);
  211. var g = f.length;
  212. while (g--) {
  213. var h = f[g];
  214. var i = Object.keys(a[h]);
  215. var j = i.length;
  216. while (j--) {
  217. var k = i[j];
  218. var l = a[h][k];
  219. var m = e[h][k];
  220. b.push({
  221. x: h,
  222. y: k,
  223. value: l,
  224. radius: m
  225. })
  226. }
  227. }
  228. return {
  229. min: c,
  230. max: d,
  231. data: b
  232. }
  233. };
  234. function d(b) {
  235. var c = b.container;
  236. var d = this.shadowCanvas = document.createElement("canvas");
  237. var e = this.canvas = b.canvas || document.createElement("canvas");
  238. var f = this._renderBoundaries = [1e4, 1e4, 0, 0];
  239. var g = getComputedStyle(b.container) || {};
  240. e.className = "heatmap-canvas";
  241. this._width = e.width = d.width = +g.width.replace(/px/, "");
  242. this._height = e.height = d.height = +g.height.replace(/px/, "");
  243. this.shadowCtx = d.getContext("2d");
  244. this.ctx = e.getContext("2d");
  245. e.style.cssText = d.style.cssText = "position:absolute;left:0;top:0;";
  246. c.style.position = "relative";
  247. c.appendChild(e);
  248. this._palette = a(b);
  249. this._templates = {};
  250. this._setStyles(b)
  251. }
  252. d.prototype = {
  253. renderPartial: function (a) {
  254. this._drawAlpha(a);
  255. this._colorize()
  256. },
  257. renderAll: function (a) {
  258. this._clear();
  259. this._drawAlpha(c(a));
  260. this._colorize()
  261. },
  262. _updateGradient: function (b) {
  263. this._palette = a(b)
  264. },
  265. updateConfig: function (a) {
  266. if (a["gradient"]) {
  267. this._updateGradient(a)
  268. }
  269. this._setStyles(a)
  270. },
  271. setDimensions: function (a, b) {
  272. this._width = a;
  273. this._height = b;
  274. this.canvas.width = this.shadowCanvas.width = a;
  275. this.canvas.height = this.shadowCanvas.height = b
  276. },
  277. _clear: function () {
  278. this.shadowCtx.clearRect(0, 0, this._width, this._height);
  279. this.ctx.clearRect(0, 0, this._width, this._height)
  280. },
  281. _setStyles: function (a) {
  282. this._blur = a.blur == 0 ? 0 : a.blur || a.defaultBlur;
  283. if (a.backgroundColor) {
  284. this.canvas.style.backgroundColor = a.backgroundColor
  285. }
  286. this._opacity = (a.opacity || 0) * 255;
  287. this._maxOpacity = (a.maxOpacity || a.defaultMaxOpacity) * 255;
  288. this._minOpacity = (a.minOpacity || a.defaultMinOpacity) * 255
  289. },
  290. _drawAlpha: function (a) {
  291. var c = this._min = a.min;
  292. var d = this._max = a.max;
  293. var a = a.data || [];
  294. var e = a.length;
  295. var f = 1 - this._blur;
  296. while (e--) {
  297. var g = a[e];
  298. var h = g.x;
  299. var i = g.y;
  300. var j = g.radius;
  301. var k = g.value;
  302. var l = h - j;
  303. var m = i - j;
  304. var n = this.shadowCtx;
  305. var o;
  306. if (!this._templates[j]) {
  307. this._templates[j] = o = b(j, f)
  308. } else {
  309. o = this._templates[j]
  310. }
  311. n.globalAlpha = k / Math.abs(d - c);
  312. n.drawImage(o, l, m);
  313. if (l < this._renderBoundaries[0]) {
  314. this._renderBoundaries[0] = l
  315. }
  316. if (m < this._renderBoundaries[1]) {
  317. this._renderBoundaries[1] = m
  318. }
  319. if (l + 2 * j > this._renderBoundaries[2]) {
  320. this._renderBoundaries[2] = l + 2 * j
  321. }
  322. if (m + 2 * j > this._renderBoundaries[3]) {
  323. this._renderBoundaries[3] = m + 2 * j
  324. }
  325. }
  326. },
  327. _colorize: function () {
  328. var a = this._renderBoundaries[0];
  329. var b = this._renderBoundaries[1];
  330. var c = this._renderBoundaries[2] - a;
  331. var d = this._renderBoundaries[3] - b;
  332. var e = this._width;
  333. var f = this._height;
  334. var g = this._opacity;
  335. var h = this._maxOpacity;
  336. var i = this._minOpacity;
  337. if (a < 0) {
  338. a = 0
  339. }
  340. if (b < 0) {
  341. b = 0
  342. }
  343. if (a + c > e) {
  344. c = e - a
  345. }
  346. if (b + d > f) {
  347. d = f - b
  348. }
  349. var j = this.shadowCtx.getImageData(a, b, c, d);
  350. var k = j.data;
  351. var l = k.length;
  352. var m = this._palette;
  353. for (var n = 3; n < l; n += 4) {
  354. var o = k[n];
  355. var p = o * 4;
  356. if (!p) {
  357. continue
  358. }
  359. var q;
  360. if (g > 0) {
  361. q = g
  362. } else {
  363. if (o < h) {
  364. if (o < i) {
  365. q = i
  366. } else {
  367. q = o
  368. }
  369. } else {
  370. q = h
  371. }
  372. }
  373. k[n - 3] = m[p];
  374. k[n - 2] = m[p + 1];
  375. k[n - 1] = m[p + 2];
  376. k[n] = q
  377. }
  378. j.data = k;
  379. this.ctx.putImageData(j, a, b);
  380. this._renderBoundaries = [1e3, 1e3, 0, 0]
  381. },
  382. getValueAt: function (a) {
  383. var b;
  384. var c = this.shadowCtx;
  385. var d = c.getImageData(a.x, a.y, 1, 1);
  386. var e = d.data[3];
  387. var f = this._max;
  388. var g = this._min;
  389. b = Math.abs(f - g) * (e / 255) >> 0;
  390. return b
  391. },
  392. getDataURL: function () {
  393. return this.canvas.toDataURL()
  394. }
  395. };
  396. return d
  397. }();
  398. var e = function k() {
  399. var a = false;
  400. if (b["defaultRenderer"] === "canvas2d") {
  401. a = d
  402. }
  403. return a
  404. }();
  405. var f = {
  406. merge: function () {
  407. var a = {};
  408. var b = arguments.length;
  409. for (var c = 0; c < b; c++) {
  410. var d = arguments[c];
  411. for (var e in d) {
  412. a[e] = d[e]
  413. }
  414. }
  415. return a
  416. }
  417. };
  418. var g = function l() {
  419. var a = function h() {
  420. function a() {
  421. this.cStore = {}
  422. }
  423. a.prototype = {
  424. on: function (a, b, c) {
  425. var d = this.cStore;
  426. if (!d[a]) {
  427. d[a] = []
  428. }
  429. d[a].push(function (a) {
  430. return b.call(c, a)
  431. })
  432. },
  433. emit: function (a, b) {
  434. var c = this.cStore;
  435. if (c[a]) {
  436. var d = c[a].length;
  437. for (var e = 0; e < d; e++) {
  438. var f = c[a][e];
  439. f(b)
  440. }
  441. }
  442. }
  443. };
  444. return a
  445. }();
  446. var d = function (a) {
  447. var b = a._renderer;
  448. var c = a._coordinator;
  449. var d = a._store;
  450. c.on("renderpartial", b.renderPartial, b);
  451. c.on("renderall", b.renderAll, b);
  452. c.on("extremachange",
  453. function (b) {
  454. a._config.onExtremaChange && a._config.onExtremaChange({
  455. min: b.min,
  456. max: b.max,
  457. gradient: a._config["gradient"] || a._config["defaultGradient"]
  458. })
  459. });
  460. d.setCoordinator(c)
  461. };
  462. function g() {
  463. var g = this._config = f.merge(b, arguments[0] || {});
  464. this._coordinator = new a;
  465. if (g["plugin"]) {
  466. var h = g["plugin"];
  467. if (!b.plugins[h]) {
  468. throw new Error("Plugin '" + h + "' not found. Maybe it was not registered.")
  469. } else {
  470. var i = b.plugins[h];
  471. this._renderer = i.renderer;
  472. this._store = i.store
  473. }
  474. } else {
  475. this._renderer = new e(g);
  476. this._store = new c(g)
  477. }
  478. d(this)
  479. }
  480. g.prototype = {
  481. addData: function () {
  482. this._store.addData.apply(this._store, arguments);
  483. return this
  484. },
  485. removeData: function () {
  486. this._store.removeData && this._store.removeData.apply(this._store, arguments);
  487. return this
  488. },
  489. setData: function () {
  490. this._store.setData.apply(this._store, arguments);
  491. return this
  492. },
  493. setDataMax: function () {
  494. this._store.setDataMax.apply(this._store, arguments);
  495. return this
  496. },
  497. setDataMin: function () {
  498. this._store.setDataMin.apply(this._store, arguments);
  499. return this
  500. },
  501. configure: function (a) {
  502. this._config = f.merge(this._config, a);
  503. this._renderer.updateConfig(this._config);
  504. this._coordinator.emit("renderall", this._store._getInternalData());
  505. return this
  506. },
  507. repaint: function () {
  508. this._coordinator.emit("renderall", this._store._getInternalData());
  509. return this
  510. },
  511. getData: function () {
  512. return this._store.getData()
  513. },
  514. getDataURL: function () {
  515. return this._renderer.getDataURL()
  516. },
  517. getValueAt: function (a) {
  518. if (this._store.getValueAt) {
  519. return this._store.getValueAt(a)
  520. } else if (this._renderer.getValueAt) {
  521. return this._renderer.getValueAt(a)
  522. } else {
  523. return null
  524. }
  525. }
  526. };
  527. return g
  528. }();
  529. var h = {
  530. create: function (a) {
  531. return new g(a)
  532. },
  533. register: function (a, c) {
  534. b.plugins[a] = c
  535. }
  536. };
  537. a["h337"] = h
  538. })(this || window);