HeatmapView.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. var _config = require("../../config");
  2. var __DEV__ = _config.__DEV__;
  3. var echarts = require("../../echarts");
  4. var graphic = require("../../util/graphic");
  5. var HeatmapLayer = require("./HeatmapLayer");
  6. var zrUtil = require("zrender/lib/core/util");
  7. function getIsInPiecewiseRange(dataExtent, pieceList, selected) {
  8. var dataSpan = dataExtent[1] - dataExtent[0];
  9. pieceList = zrUtil.map(pieceList, function (piece) {
  10. return {
  11. interval: [(piece.interval[0] - dataExtent[0]) / dataSpan, (piece.interval[1] - dataExtent[0]) / dataSpan]
  12. };
  13. });
  14. var len = pieceList.length;
  15. var lastIndex = 0;
  16. return function (val) {
  17. // Try to find in the location of the last found
  18. for (var i = lastIndex; i < len; i++) {
  19. var interval = pieceList[i].interval;
  20. if (interval[0] <= val && val <= interval[1]) {
  21. lastIndex = i;
  22. break;
  23. }
  24. }
  25. if (i === len) {
  26. // Not found, back interation
  27. for (var i = lastIndex - 1; i >= 0; i--) {
  28. var interval = pieceList[i].interval;
  29. if (interval[0] <= val && val <= interval[1]) {
  30. lastIndex = i;
  31. break;
  32. }
  33. }
  34. }
  35. return i >= 0 && i < len && selected[i];
  36. };
  37. }
  38. function getIsInContinuousRange(dataExtent, range) {
  39. var dataSpan = dataExtent[1] - dataExtent[0];
  40. range = [(range[0] - dataExtent[0]) / dataSpan, (range[1] - dataExtent[0]) / dataSpan];
  41. return function (val) {
  42. return val >= range[0] && val <= range[1];
  43. };
  44. }
  45. function isGeoCoordSys(coordSys) {
  46. var dimensions = coordSys.dimensions; // Not use coorSys.type === 'geo' because coordSys maybe extended
  47. return dimensions[0] === 'lng' && dimensions[1] === 'lat';
  48. }
  49. var _default = echarts.extendChartView({
  50. type: 'heatmap',
  51. render: function (seriesModel, ecModel, api) {
  52. var visualMapOfThisSeries;
  53. ecModel.eachComponent('visualMap', function (visualMap) {
  54. visualMap.eachTargetSeries(function (targetSeries) {
  55. if (targetSeries === seriesModel) {
  56. visualMapOfThisSeries = visualMap;
  57. }
  58. });
  59. });
  60. this.group.removeAll();
  61. var coordSys = seriesModel.coordinateSystem;
  62. if (coordSys.type === 'cartesian2d' || coordSys.type === 'calendar') {
  63. this._renderOnCartesianAndCalendar(coordSys, seriesModel, api);
  64. } else if (isGeoCoordSys(coordSys)) {
  65. this._renderOnGeo(coordSys, seriesModel, visualMapOfThisSeries, api);
  66. }
  67. },
  68. dispose: function () {},
  69. _renderOnCartesianAndCalendar: function (coordSys, seriesModel, api) {
  70. if (coordSys.type === 'cartesian2d') {
  71. var xAxis = coordSys.getAxis('x');
  72. var yAxis = coordSys.getAxis('y');
  73. var width = xAxis.getBandWidth();
  74. var height = yAxis.getBandWidth();
  75. }
  76. var group = this.group;
  77. var data = seriesModel.getData();
  78. var itemStyleQuery = 'itemStyle.normal';
  79. var hoverItemStyleQuery = 'itemStyle.emphasis';
  80. var labelQuery = 'label.normal';
  81. var hoverLabelQuery = 'label.emphasis';
  82. var style = seriesModel.getModel(itemStyleQuery).getItemStyle(['color']);
  83. var hoverStl = seriesModel.getModel(hoverItemStyleQuery).getItemStyle();
  84. var labelModel = seriesModel.getModel('label.normal');
  85. var hoverLabelModel = seriesModel.getModel('label.emphasis');
  86. var coordSysType = coordSys.type;
  87. var dataDims = coordSysType === 'cartesian2d' ? [seriesModel.coordDimToDataDim('x')[0], seriesModel.coordDimToDataDim('y')[0], seriesModel.coordDimToDataDim('value')[0]] : [seriesModel.coordDimToDataDim('time')[0], seriesModel.coordDimToDataDim('value')[0]];
  88. data.each(function (idx) {
  89. var rect;
  90. if (coordSysType === 'cartesian2d') {
  91. // Ignore empty data
  92. if (isNaN(data.get(dataDims[2], idx))) {
  93. return;
  94. }
  95. var point = coordSys.dataToPoint([data.get(dataDims[0], idx), data.get(dataDims[1], idx)]);
  96. rect = new graphic.Rect({
  97. shape: {
  98. x: point[0] - width / 2,
  99. y: point[1] - height / 2,
  100. width: width,
  101. height: height
  102. },
  103. style: {
  104. fill: data.getItemVisual(idx, 'color'),
  105. opacity: data.getItemVisual(idx, 'opacity')
  106. }
  107. });
  108. } else {
  109. // Ignore empty data
  110. if (isNaN(data.get(dataDims[1], idx))) {
  111. return;
  112. }
  113. rect = new graphic.Rect({
  114. z2: 1,
  115. shape: coordSys.dataToRect([data.get(dataDims[0], idx)]).contentShape,
  116. style: {
  117. fill: data.getItemVisual(idx, 'color'),
  118. opacity: data.getItemVisual(idx, 'opacity')
  119. }
  120. });
  121. }
  122. var itemModel = data.getItemModel(idx); // Optimization for large datset
  123. if (data.hasItemOption) {
  124. style = itemModel.getModel(itemStyleQuery).getItemStyle(['color']);
  125. hoverStl = itemModel.getModel(hoverItemStyleQuery).getItemStyle();
  126. labelModel = itemModel.getModel(labelQuery);
  127. hoverLabelModel = itemModel.getModel(hoverLabelQuery);
  128. }
  129. var rawValue = seriesModel.getRawValue(idx);
  130. var defaultText = '-';
  131. if (rawValue && rawValue[2] != null) {
  132. defaultText = rawValue[2];
  133. }
  134. graphic.setLabelStyle(style, hoverStl, labelModel, hoverLabelModel, {
  135. labelFetcher: seriesModel,
  136. labelDataIndex: idx,
  137. defaultText: defaultText,
  138. isRectText: true
  139. });
  140. rect.setStyle(style);
  141. graphic.setHoverStyle(rect, data.hasItemOption ? hoverStl : zrUtil.extend({}, hoverStl));
  142. group.add(rect);
  143. data.setItemGraphicEl(idx, rect);
  144. });
  145. },
  146. _renderOnGeo: function (geo, seriesModel, visualMapModel, api) {
  147. var inRangeVisuals = visualMapModel.targetVisuals.inRange;
  148. var outOfRangeVisuals = visualMapModel.targetVisuals.outOfRange; // if (!visualMapping) {
  149. // throw new Error('Data range must have color visuals');
  150. // }
  151. var data = seriesModel.getData();
  152. var hmLayer = this._hmLayer || this._hmLayer || new HeatmapLayer();
  153. hmLayer.blurSize = seriesModel.get('blurSize');
  154. hmLayer.pointSize = seriesModel.get('pointSize');
  155. hmLayer.minOpacity = seriesModel.get('minOpacity');
  156. hmLayer.maxOpacity = seriesModel.get('maxOpacity');
  157. var rect = geo.getViewRect().clone();
  158. var roamTransform = geo.getRoamTransform().transform;
  159. rect.applyTransform(roamTransform); // Clamp on viewport
  160. var x = Math.max(rect.x, 0);
  161. var y = Math.max(rect.y, 0);
  162. var x2 = Math.min(rect.width + rect.x, api.getWidth());
  163. var y2 = Math.min(rect.height + rect.y, api.getHeight());
  164. var width = x2 - x;
  165. var height = y2 - y;
  166. var points = data.mapArray(['lng', 'lat', 'value'], function (lng, lat, value) {
  167. var pt = geo.dataToPoint([lng, lat]);
  168. pt[0] -= x;
  169. pt[1] -= y;
  170. pt.push(value);
  171. return pt;
  172. });
  173. var dataExtent = visualMapModel.getExtent();
  174. var isInRange = visualMapModel.type === 'visualMap.continuous' ? getIsInContinuousRange(dataExtent, visualMapModel.option.range) : getIsInPiecewiseRange(dataExtent, visualMapModel.getPieceList(), visualMapModel.option.selected);
  175. hmLayer.update(points, width, height, inRangeVisuals.color.getNormalizer(), {
  176. inRange: inRangeVisuals.color.getColorMapper(),
  177. outOfRange: outOfRangeVisuals.color.getColorMapper()
  178. }, isInRange);
  179. var img = new graphic.Image({
  180. style: {
  181. width: width,
  182. height: height,
  183. x: x,
  184. y: y,
  185. image: hmLayer.canvas
  186. },
  187. silent: true
  188. });
  189. this.group.add(img);
  190. }
  191. });
  192. module.exports = _default;