LargeSymbolDraw.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /**
  20. * AUTO-GENERATED FILE. DO NOT MODIFY.
  21. */
  22. /*
  23. * Licensed to the Apache Software Foundation (ASF) under one
  24. * or more contributor license agreements. See the NOTICE file
  25. * distributed with this work for additional information
  26. * regarding copyright ownership. The ASF licenses this file
  27. * to you under the Apache License, Version 2.0 (the
  28. * "License"); you may not use this file except in compliance
  29. * with the License. You may obtain a copy of the License at
  30. *
  31. * http://www.apache.org/licenses/LICENSE-2.0
  32. *
  33. * Unless required by applicable law or agreed to in writing,
  34. * software distributed under the License is distributed on an
  35. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  36. * KIND, either express or implied. See the License for the
  37. * specific language governing permissions and limitations
  38. * under the License.
  39. */
  40. import { __extends } from "tslib";
  41. /* global Float32Array */
  42. // TODO Batch by color
  43. import * as graphic from '../../util/graphic';
  44. import { createSymbol } from '../../util/symbol';
  45. import IncrementalDisplayable from 'zrender/lib/graphic/IncrementalDisplayable';
  46. import { getECData } from '../../util/innerStore';
  47. var BOOST_SIZE_THRESHOLD = 4;
  48. var LargeSymbolPathShape =
  49. /** @class */
  50. function () {
  51. function LargeSymbolPathShape() {}
  52. return LargeSymbolPathShape;
  53. }();
  54. var LargeSymbolPath =
  55. /** @class */
  56. function (_super) {
  57. __extends(LargeSymbolPath, _super);
  58. function LargeSymbolPath(opts) {
  59. return _super.call(this, opts) || this;
  60. }
  61. LargeSymbolPath.prototype.getDefaultShape = function () {
  62. return new LargeSymbolPathShape();
  63. };
  64. LargeSymbolPath.prototype.buildPath = function (path, shape) {
  65. var points = shape.points;
  66. var size = shape.size;
  67. var symbolProxy = this.symbolProxy;
  68. var symbolProxyShape = symbolProxy.shape;
  69. var ctx = path.getContext ? path.getContext() : path;
  70. var canBoost = ctx && size[0] < BOOST_SIZE_THRESHOLD; // Do draw in afterBrush.
  71. if (canBoost) {
  72. this._ctx = ctx;
  73. return;
  74. }
  75. this._ctx = null;
  76. for (var i = 0; i < points.length;) {
  77. var x = points[i++];
  78. var y = points[i++];
  79. if (isNaN(x) || isNaN(y)) {
  80. continue;
  81. }
  82. if (this.softClipShape && !this.softClipShape.contain(x, y)) {
  83. continue;
  84. }
  85. symbolProxyShape.x = x - size[0] / 2;
  86. symbolProxyShape.y = y - size[1] / 2;
  87. symbolProxyShape.width = size[0];
  88. symbolProxyShape.height = size[1];
  89. symbolProxy.buildPath(path, symbolProxyShape, true);
  90. }
  91. };
  92. LargeSymbolPath.prototype.afterBrush = function () {
  93. var shape = this.shape;
  94. var points = shape.points;
  95. var size = shape.size;
  96. var ctx = this._ctx;
  97. if (!ctx) {
  98. return;
  99. } // PENDING If style or other canvas status changed?
  100. for (var i = 0; i < points.length;) {
  101. var x = points[i++];
  102. var y = points[i++];
  103. if (isNaN(x) || isNaN(y)) {
  104. continue;
  105. }
  106. if (this.softClipShape && !this.softClipShape.contain(x, y)) {
  107. continue;
  108. } // fillRect is faster than building a rect path and draw.
  109. // And it support light globalCompositeOperation.
  110. ctx.fillRect(x - size[0] / 2, y - size[1] / 2, size[0], size[1]);
  111. }
  112. };
  113. LargeSymbolPath.prototype.findDataIndex = function (x, y) {
  114. // TODO ???
  115. // Consider transform
  116. var shape = this.shape;
  117. var points = shape.points;
  118. var size = shape.size;
  119. var w = Math.max(size[0], 4);
  120. var h = Math.max(size[1], 4); // Not consider transform
  121. // Treat each element as a rect
  122. // top down traverse
  123. for (var idx = points.length / 2 - 1; idx >= 0; idx--) {
  124. var i = idx * 2;
  125. var x0 = points[i] - w / 2;
  126. var y0 = points[i + 1] - h / 2;
  127. if (x >= x0 && y >= y0 && x <= x0 + w && y <= y0 + h) {
  128. return idx;
  129. }
  130. }
  131. return -1;
  132. };
  133. return LargeSymbolPath;
  134. }(graphic.Path);
  135. var LargeSymbolDraw =
  136. /** @class */
  137. function () {
  138. function LargeSymbolDraw() {
  139. this.group = new graphic.Group();
  140. }
  141. LargeSymbolDraw.prototype.isPersistent = function () {
  142. return !this._incremental;
  143. };
  144. ;
  145. /**
  146. * Update symbols draw by new data
  147. */
  148. LargeSymbolDraw.prototype.updateData = function (data, opt) {
  149. this.group.removeAll();
  150. var symbolEl = new LargeSymbolPath({
  151. rectHover: true,
  152. cursor: 'default'
  153. });
  154. symbolEl.setShape({
  155. points: data.getLayout('points')
  156. });
  157. this._setCommon(symbolEl, data, false, opt);
  158. this.group.add(symbolEl);
  159. this._incremental = null;
  160. };
  161. LargeSymbolDraw.prototype.updateLayout = function (data) {
  162. if (this._incremental) {
  163. return;
  164. }
  165. var points = data.getLayout('points');
  166. this.group.eachChild(function (child) {
  167. if (child.startIndex != null) {
  168. var len = (child.endIndex - child.startIndex) * 2;
  169. var byteOffset = child.startIndex * 4 * 2;
  170. points = new Float32Array(points.buffer, byteOffset, len);
  171. }
  172. child.setShape('points', points);
  173. });
  174. };
  175. LargeSymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
  176. this.group.removeAll();
  177. this._clearIncremental(); // Only use incremental displayables when data amount is larger than 2 million.
  178. // PENDING Incremental data?
  179. if (data.count() > 2e6) {
  180. if (!this._incremental) {
  181. this._incremental = new IncrementalDisplayable({
  182. silent: true
  183. });
  184. }
  185. this.group.add(this._incremental);
  186. } else {
  187. this._incremental = null;
  188. }
  189. };
  190. LargeSymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
  191. var symbolEl;
  192. if (this._incremental) {
  193. symbolEl = new LargeSymbolPath();
  194. this._incremental.addDisplayable(symbolEl, true);
  195. } else {
  196. symbolEl = new LargeSymbolPath({
  197. rectHover: true,
  198. cursor: 'default',
  199. startIndex: taskParams.start,
  200. endIndex: taskParams.end
  201. });
  202. symbolEl.incremental = true;
  203. this.group.add(symbolEl);
  204. }
  205. symbolEl.setShape({
  206. points: data.getLayout('points')
  207. });
  208. this._setCommon(symbolEl, data, !!this._incremental, opt);
  209. };
  210. LargeSymbolDraw.prototype._setCommon = function (symbolEl, data, isIncremental, opt) {
  211. var hostModel = data.hostModel;
  212. opt = opt || {};
  213. var size = data.getVisual('symbolSize');
  214. symbolEl.setShape('size', size instanceof Array ? size : [size, size]);
  215. symbolEl.softClipShape = opt.clipShape || null; // Create symbolProxy to build path for each data
  216. symbolEl.symbolProxy = createSymbol(data.getVisual('symbol'), 0, 0, 0, 0); // Use symbolProxy setColor method
  217. symbolEl.setColor = symbolEl.symbolProxy.setColor;
  218. var extrudeShadow = symbolEl.shape.size[0] < BOOST_SIZE_THRESHOLD;
  219. symbolEl.useStyle( // Draw shadow when doing fillRect is extremely slow.
  220. hostModel.getModel('itemStyle').getItemStyle(extrudeShadow ? ['color', 'shadowBlur', 'shadowColor'] : ['color']));
  221. var globalStyle = data.getVisual('style');
  222. var visualColor = globalStyle && globalStyle.fill;
  223. if (visualColor) {
  224. symbolEl.setColor(visualColor);
  225. }
  226. if (!isIncremental) {
  227. var ecData_1 = getECData(symbolEl); // Enable tooltip
  228. // PENDING May have performance issue when path is extremely large
  229. ecData_1.seriesIndex = hostModel.seriesIndex;
  230. symbolEl.on('mousemove', function (e) {
  231. ecData_1.dataIndex = null;
  232. var dataIndex = symbolEl.findDataIndex(e.offsetX, e.offsetY);
  233. if (dataIndex >= 0) {
  234. // Provide dataIndex for tooltip
  235. ecData_1.dataIndex = dataIndex + (symbolEl.startIndex || 0);
  236. }
  237. });
  238. }
  239. };
  240. LargeSymbolDraw.prototype.remove = function () {
  241. this._clearIncremental();
  242. this._incremental = null;
  243. this.group.removeAll();
  244. };
  245. LargeSymbolDraw.prototype._clearIncremental = function () {
  246. var incremental = this._incremental;
  247. if (incremental) {
  248. incremental.clearDisplaybles();
  249. }
  250. };
  251. return LargeSymbolDraw;
  252. }();
  253. export default LargeSymbolDraw;