LargeSymbolDraw.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. var graphic = require("../../util/graphic");
  2. var _symbol = require("../../util/symbol");
  3. var createSymbol = _symbol.createSymbol;
  4. // TODO Batch by color
  5. var LargeSymbolPath = graphic.extendShape({
  6. shape: {
  7. points: null,
  8. sizes: null
  9. },
  10. symbolProxy: null,
  11. buildPath: function (path, shape) {
  12. var points = shape.points;
  13. var sizes = shape.sizes;
  14. var symbolProxy = this.symbolProxy;
  15. var symbolProxyShape = symbolProxy.shape;
  16. for (var i = 0; i < points.length; i++) {
  17. var pt = points[i];
  18. if (isNaN(pt[0]) || isNaN(pt[1])) {
  19. continue;
  20. }
  21. var size = sizes[i];
  22. if (size[0] < 4) {
  23. // Optimize for small symbol
  24. path.rect(pt[0] - size[0] / 2, pt[1] - size[1] / 2, size[0], size[1]);
  25. } else {
  26. symbolProxyShape.x = pt[0] - size[0] / 2;
  27. symbolProxyShape.y = pt[1] - size[1] / 2;
  28. symbolProxyShape.width = size[0];
  29. symbolProxyShape.height = size[1];
  30. symbolProxy.buildPath(path, symbolProxyShape, true);
  31. }
  32. }
  33. },
  34. findDataIndex: function (x, y) {
  35. var shape = this.shape;
  36. var points = shape.points;
  37. var sizes = shape.sizes; // Not consider transform
  38. // Treat each element as a rect
  39. // top down traverse
  40. for (var i = points.length - 1; i >= 0; i--) {
  41. var pt = points[i];
  42. var size = sizes[i];
  43. var x0 = pt[0] - size[0] / 2;
  44. var y0 = pt[1] - size[1] / 2;
  45. if (x >= x0 && y >= y0 && x <= x0 + size[0] && y <= y0 + size[1]) {
  46. // i is dataIndex
  47. return i;
  48. }
  49. }
  50. return -1;
  51. }
  52. });
  53. function LargeSymbolDraw() {
  54. this.group = new graphic.Group();
  55. this._symbolEl = new LargeSymbolPath({// rectHover: true,
  56. // cursor: 'default'
  57. });
  58. }
  59. var largeSymbolProto = LargeSymbolDraw.prototype;
  60. /**
  61. * Update symbols draw by new data
  62. * @param {module:echarts/data/List} data
  63. */
  64. largeSymbolProto.updateData = function (data) {
  65. this.group.removeAll();
  66. var symbolEl = this._symbolEl;
  67. var seriesModel = data.hostModel;
  68. symbolEl.setShape({
  69. points: data.mapArray(data.getItemLayout),
  70. sizes: data.mapArray(function (idx) {
  71. var size = data.getItemVisual(idx, 'symbolSize');
  72. if (!(size instanceof Array)) {
  73. size = [size, size];
  74. }
  75. return size;
  76. })
  77. }); // Create symbolProxy to build path for each data
  78. symbolEl.symbolProxy = createSymbol(data.getVisual('symbol'), 0, 0, 0, 0); // Use symbolProxy setColor method
  79. symbolEl.setColor = symbolEl.symbolProxy.setColor;
  80. symbolEl.useStyle(seriesModel.getModel('itemStyle.normal').getItemStyle(['color']));
  81. var visualColor = data.getVisual('color');
  82. if (visualColor) {
  83. symbolEl.setColor(visualColor);
  84. } // Enable tooltip
  85. // PENDING May have performance issue when path is extremely large
  86. symbolEl.seriesIndex = seriesModel.seriesIndex;
  87. symbolEl.on('mousemove', function (e) {
  88. symbolEl.dataIndex = null;
  89. var dataIndex = symbolEl.findDataIndex(e.offsetX, e.offsetY);
  90. if (dataIndex >= 0) {
  91. // Provide dataIndex for tooltip
  92. symbolEl.dataIndex = dataIndex;
  93. }
  94. }); // Add back
  95. this.group.add(symbolEl);
  96. };
  97. largeSymbolProto.updateLayout = function (seriesModel) {
  98. var data = seriesModel.getData();
  99. this._symbolEl.setShape({
  100. points: data.mapArray(data.getItemLayout)
  101. });
  102. };
  103. largeSymbolProto.remove = function () {
  104. this.group.removeAll();
  105. };
  106. var _default = LargeSymbolDraw;
  107. module.exports = _default;