heatmap.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. define('echarts/chart/heatmap', [
  2. 'require',
  3. './base',
  4. '../layer/heatmap',
  5. '../config',
  6. '../util/ecData',
  7. 'zrender/tool/util',
  8. 'zrender/tool/color',
  9. 'zrender/shape/Image',
  10. '../chart'
  11. ], function (require) {
  12. var ChartBase = require('./base');
  13. var HeatmapLayer = require('../layer/heatmap');
  14. var ecConfig = require('../config');
  15. var ecData = require('../util/ecData');
  16. var zrUtil = require('zrender/tool/util');
  17. var zrColor = require('zrender/tool/color');
  18. var zrImage = require('zrender/shape/Image');
  19. ecConfig.heatmap = {
  20. zlevel: 0,
  21. z: 2,
  22. clickable: true
  23. };
  24. function Heatmap(ecTheme, messageCenter, zr, option, myChart) {
  25. ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
  26. this.refresh(option);
  27. }
  28. Heatmap.prototype = {
  29. type: ecConfig.CHART_TYPE_HEATMAP,
  30. refresh: function (newOption) {
  31. this.clear();
  32. if (newOption) {
  33. this.option = newOption;
  34. this.series = newOption.series;
  35. }
  36. this._init();
  37. },
  38. _init: function () {
  39. var series = this.series;
  40. this.backupShapeList();
  41. var len = series.length;
  42. for (var i = 0; i < len; ++i) {
  43. if (series[i].type === ecConfig.CHART_TYPE_HEATMAP) {
  44. series[i] = this.reformOption(series[i]);
  45. var layer = new HeatmapLayer(series[i]);
  46. var canvas = layer.getCanvas(series[i].data, this.zr.getWidth(), this.zr.getHeight());
  47. var image = new zrImage({
  48. position: [
  49. 0,
  50. 0
  51. ],
  52. scale: [
  53. 1,
  54. 1
  55. ],
  56. hoverable: this.option.hoverable,
  57. style: {
  58. x: 0,
  59. y: 0,
  60. image: canvas,
  61. width: canvas.width,
  62. height: canvas.height
  63. }
  64. });
  65. this.shapeList.push(image);
  66. }
  67. }
  68. this.addShapeList();
  69. }
  70. };
  71. zrUtil.inherits(Heatmap, ChartBase);
  72. require('../chart').define('heatmap', Heatmap);
  73. return Heatmap;
  74. });define('echarts/layer/heatmap', ['require'], function (require) {
  75. var defaultOptions = {
  76. blurSize: 30,
  77. gradientColors: [
  78. 'blue',
  79. 'cyan',
  80. 'lime',
  81. 'yellow',
  82. 'red'
  83. ],
  84. minAlpha: 0.05,
  85. valueScale: 1,
  86. opacity: 1
  87. };
  88. var BRUSH_SIZE = 20;
  89. var GRADIENT_LEVELS = 256;
  90. function Heatmap(opt) {
  91. this.option = opt;
  92. if (opt) {
  93. for (var i in defaultOptions) {
  94. if (opt[i] !== undefined) {
  95. this.option[i] = opt[i];
  96. } else {
  97. this.option[i] = defaultOptions[i];
  98. }
  99. }
  100. } else {
  101. this.option = defaultOptions;
  102. }
  103. }
  104. Heatmap.prototype = {
  105. getCanvas: function (data, width, height) {
  106. var brush = this._getBrush();
  107. var gradient = this._getGradient();
  108. var r = BRUSH_SIZE + this.option.blurSize;
  109. var canvas = document.createElement('canvas');
  110. canvas.width = width;
  111. canvas.height = height;
  112. var ctx = canvas.getContext('2d');
  113. var len = data.length;
  114. for (var i = 0; i < len; ++i) {
  115. var p = data[i];
  116. var x = p[0];
  117. var y = p[1];
  118. var value = p[2];
  119. var alpha = Math.min(1, Math.max(value * this.option.valueScale || this.option.minAlpha, this.option.minAlpha));
  120. ctx.globalAlpha = alpha;
  121. ctx.drawImage(brush, x - r, y - r);
  122. }
  123. var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  124. var pixels = imageData.data;
  125. var len = pixels.length / 4;
  126. while (len--) {
  127. var id = len * 4 + 3;
  128. var alpha = pixels[id] / 256;
  129. var colorOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1));
  130. pixels[id - 3] = gradient[colorOffset * 4];
  131. pixels[id - 2] = gradient[colorOffset * 4 + 1];
  132. pixels[id - 1] = gradient[colorOffset * 4 + 2];
  133. pixels[id] *= this.option.opacity;
  134. }
  135. ctx.putImageData(imageData, 0, 0);
  136. return canvas;
  137. },
  138. _getBrush: function () {
  139. if (!this._brushCanvas) {
  140. this._brushCanvas = document.createElement('canvas');
  141. var r = BRUSH_SIZE + this.option.blurSize;
  142. var d = r * 2;
  143. this._brushCanvas.width = d;
  144. this._brushCanvas.height = d;
  145. var ctx = this._brushCanvas.getContext('2d');
  146. ctx.shadowOffsetX = d;
  147. ctx.shadowBlur = this.option.blurSize;
  148. ctx.shadowColor = 'black';
  149. ctx.beginPath();
  150. ctx.arc(-r, r, BRUSH_SIZE, 0, Math.PI * 2, true);
  151. ctx.closePath();
  152. ctx.fill();
  153. }
  154. return this._brushCanvas;
  155. },
  156. _getGradient: function () {
  157. if (!this._gradientPixels) {
  158. var levels = GRADIENT_LEVELS;
  159. var canvas = document.createElement('canvas');
  160. canvas.width = 1;
  161. canvas.height = levels;
  162. var ctx = canvas.getContext('2d');
  163. var gradient = ctx.createLinearGradient(0, 0, 0, levels);
  164. var len = this.option.gradientColors.length;
  165. for (var i = 0; i < len; ++i) {
  166. if (typeof this.option.gradientColors[i] === 'string') {
  167. gradient.addColorStop((i + 1) / len, this.option.gradientColors[i]);
  168. } else {
  169. gradient.addColorStop(this.option.gradientColors[i].offset, this.option.gradientColors[i].color);
  170. }
  171. }
  172. ctx.fillStyle = gradient;
  173. ctx.fillRect(0, 0, 1, levels);
  174. this._gradientPixels = ctx.getImageData(0, 0, 1, levels).data;
  175. }
  176. return this._gradientPixels;
  177. }
  178. };
  179. return Heatmap;
  180. });define('echarts/layer/heatmap', ['require'], function (require) {
  181. var defaultOptions = {
  182. blurSize: 30,
  183. gradientColors: [
  184. 'blue',
  185. 'cyan',
  186. 'lime',
  187. 'yellow',
  188. 'red'
  189. ],
  190. minAlpha: 0.05,
  191. valueScale: 1,
  192. opacity: 1
  193. };
  194. var BRUSH_SIZE = 20;
  195. var GRADIENT_LEVELS = 256;
  196. function Heatmap(opt) {
  197. this.option = opt;
  198. if (opt) {
  199. for (var i in defaultOptions) {
  200. if (opt[i] !== undefined) {
  201. this.option[i] = opt[i];
  202. } else {
  203. this.option[i] = defaultOptions[i];
  204. }
  205. }
  206. } else {
  207. this.option = defaultOptions;
  208. }
  209. }
  210. Heatmap.prototype = {
  211. getCanvas: function (data, width, height) {
  212. var brush = this._getBrush();
  213. var gradient = this._getGradient();
  214. var r = BRUSH_SIZE + this.option.blurSize;
  215. var canvas = document.createElement('canvas');
  216. canvas.width = width;
  217. canvas.height = height;
  218. var ctx = canvas.getContext('2d');
  219. var len = data.length;
  220. for (var i = 0; i < len; ++i) {
  221. var p = data[i];
  222. var x = p[0];
  223. var y = p[1];
  224. var value = p[2];
  225. var alpha = Math.min(1, Math.max(value * this.option.valueScale || this.option.minAlpha, this.option.minAlpha));
  226. ctx.globalAlpha = alpha;
  227. ctx.drawImage(brush, x - r, y - r);
  228. }
  229. var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  230. var pixels = imageData.data;
  231. var len = pixels.length / 4;
  232. while (len--) {
  233. var id = len * 4 + 3;
  234. var alpha = pixels[id] / 256;
  235. var colorOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1));
  236. pixels[id - 3] = gradient[colorOffset * 4];
  237. pixels[id - 2] = gradient[colorOffset * 4 + 1];
  238. pixels[id - 1] = gradient[colorOffset * 4 + 2];
  239. pixels[id] *= this.option.opacity;
  240. }
  241. ctx.putImageData(imageData, 0, 0);
  242. return canvas;
  243. },
  244. _getBrush: function () {
  245. if (!this._brushCanvas) {
  246. this._brushCanvas = document.createElement('canvas');
  247. var r = BRUSH_SIZE + this.option.blurSize;
  248. var d = r * 2;
  249. this._brushCanvas.width = d;
  250. this._brushCanvas.height = d;
  251. var ctx = this._brushCanvas.getContext('2d');
  252. ctx.shadowOffsetX = d;
  253. ctx.shadowBlur = this.option.blurSize;
  254. ctx.shadowColor = 'black';
  255. ctx.beginPath();
  256. ctx.arc(-r, r, BRUSH_SIZE, 0, Math.PI * 2, true);
  257. ctx.closePath();
  258. ctx.fill();
  259. }
  260. return this._brushCanvas;
  261. },
  262. _getGradient: function () {
  263. if (!this._gradientPixels) {
  264. var levels = GRADIENT_LEVELS;
  265. var canvas = document.createElement('canvas');
  266. canvas.width = 1;
  267. canvas.height = levels;
  268. var ctx = canvas.getContext('2d');
  269. var gradient = ctx.createLinearGradient(0, 0, 0, levels);
  270. var len = this.option.gradientColors.length;
  271. for (var i = 0; i < len; ++i) {
  272. if (typeof this.option.gradientColors[i] === 'string') {
  273. gradient.addColorStop((i + 1) / len, this.option.gradientColors[i]);
  274. } else {
  275. gradient.addColorStop(this.option.gradientColors[i].offset, this.option.gradientColors[i].color);
  276. }
  277. }
  278. ctx.fillStyle = gradient;
  279. ctx.fillRect(0, 0, 1, levels);
  280. this._gradientPixels = ctx.getImageData(0, 0, 1, levels).data;
  281. }
  282. return this._gradientPixels;
  283. }
  284. };
  285. return Heatmap;
  286. });