| 
/* 
 | 
* Licensed to the Apache Software Foundation (ASF) under one 
 | 
* or more contributor license agreements.  See the NOTICE file 
 | 
* distributed with this work for additional information 
 | 
* regarding copyright ownership.  The ASF licenses this file 
 | 
* to you under the Apache License, Version 2.0 (the 
 | 
* "License"); you may not use this file except in compliance 
 | 
* with the License.  You may obtain a copy of the License at 
 | 
* 
 | 
*   http://www.apache.org/licenses/LICENSE-2.0 
 | 
* 
 | 
* Unless required by applicable law or agreed to in writing, 
 | 
* software distributed under the License is distributed on an 
 | 
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 | 
* KIND, either express or implied.  See the License for the 
 | 
* specific language governing permissions and limitations 
 | 
* under the License. 
 | 
*/ 
 | 
  
 | 
  
 | 
/** 
 | 
 * AUTO-GENERATED FILE. DO NOT MODIFY. 
 | 
 */ 
 | 
  
 | 
/* 
 | 
* Licensed to the Apache Software Foundation (ASF) under one 
 | 
* or more contributor license agreements.  See the NOTICE file 
 | 
* distributed with this work for additional information 
 | 
* regarding copyright ownership.  The ASF licenses this file 
 | 
* to you under the Apache License, Version 2.0 (the 
 | 
* "License"); you may not use this file except in compliance 
 | 
* with the License.  You may obtain a copy of the License at 
 | 
* 
 | 
*   http://www.apache.org/licenses/LICENSE-2.0 
 | 
* 
 | 
* Unless required by applicable law or agreed to in writing, 
 | 
* software distributed under the License is distributed on an 
 | 
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 | 
* KIND, either express or implied.  See the License for the 
 | 
* specific language governing permissions and limitations 
 | 
* under the License. 
 | 
*/ 
 | 
import { __extends } from "tslib"; 
 | 
/* global Float32Array */ 
 | 
// TODO Batch by color 
 | 
import * as graphic from '../../util/graphic.js'; 
 | 
import { createSymbol } from '../../util/symbol.js'; 
 | 
import { getECData } from '../../util/innerStore.js'; 
 | 
var BOOST_SIZE_THRESHOLD = 4; 
 | 
var LargeSymbolPathShape = /** @class */function () { 
 | 
  function LargeSymbolPathShape() {} 
 | 
  return LargeSymbolPathShape; 
 | 
}(); 
 | 
var LargeSymbolPath = /** @class */function (_super) { 
 | 
  __extends(LargeSymbolPath, _super); 
 | 
  function LargeSymbolPath(opts) { 
 | 
    var _this = _super.call(this, opts) || this; 
 | 
    _this._off = 0; 
 | 
    _this.hoverDataIdx = -1; 
 | 
    return _this; 
 | 
  } 
 | 
  LargeSymbolPath.prototype.getDefaultShape = function () { 
 | 
    return new LargeSymbolPathShape(); 
 | 
  }; 
 | 
  LargeSymbolPath.prototype.reset = function () { 
 | 
    this.notClear = false; 
 | 
    this._off = 0; 
 | 
  }; 
 | 
  LargeSymbolPath.prototype.buildPath = function (path, shape) { 
 | 
    var points = shape.points; 
 | 
    var size = shape.size; 
 | 
    var symbolProxy = this.symbolProxy; 
 | 
    var symbolProxyShape = symbolProxy.shape; 
 | 
    var ctx = path.getContext ? path.getContext() : path; 
 | 
    var canBoost = ctx && size[0] < BOOST_SIZE_THRESHOLD; 
 | 
    var softClipShape = this.softClipShape; 
 | 
    var i; 
 | 
    // Do draw in afterBrush. 
 | 
    if (canBoost) { 
 | 
      this._ctx = ctx; 
 | 
      return; 
 | 
    } 
 | 
    this._ctx = null; 
 | 
    for (i = this._off; i < points.length;) { 
 | 
      var x = points[i++]; 
 | 
      var y = points[i++]; 
 | 
      if (isNaN(x) || isNaN(y)) { 
 | 
        continue; 
 | 
      } 
 | 
      if (softClipShape && !softClipShape.contain(x, y)) { 
 | 
        continue; 
 | 
      } 
 | 
      symbolProxyShape.x = x - size[0] / 2; 
 | 
      symbolProxyShape.y = y - size[1] / 2; 
 | 
      symbolProxyShape.width = size[0]; 
 | 
      symbolProxyShape.height = size[1]; 
 | 
      symbolProxy.buildPath(path, symbolProxyShape, true); 
 | 
    } 
 | 
    if (this.incremental) { 
 | 
      this._off = i; 
 | 
      this.notClear = true; 
 | 
    } 
 | 
  }; 
 | 
  LargeSymbolPath.prototype.afterBrush = function () { 
 | 
    var shape = this.shape; 
 | 
    var points = shape.points; 
 | 
    var size = shape.size; 
 | 
    var ctx = this._ctx; 
 | 
    var softClipShape = this.softClipShape; 
 | 
    var i; 
 | 
    if (!ctx) { 
 | 
      return; 
 | 
    } 
 | 
    // PENDING If style or other canvas status changed? 
 | 
    for (i = this._off; i < points.length;) { 
 | 
      var x = points[i++]; 
 | 
      var y = points[i++]; 
 | 
      if (isNaN(x) || isNaN(y)) { 
 | 
        continue; 
 | 
      } 
 | 
      if (softClipShape && !softClipShape.contain(x, y)) { 
 | 
        continue; 
 | 
      } 
 | 
      // fillRect is faster than building a rect path and draw. 
 | 
      // And it support light globalCompositeOperation. 
 | 
      ctx.fillRect(x - size[0] / 2, y - size[1] / 2, size[0], size[1]); 
 | 
    } 
 | 
    if (this.incremental) { 
 | 
      this._off = i; 
 | 
      this.notClear = true; 
 | 
    } 
 | 
  }; 
 | 
  LargeSymbolPath.prototype.findDataIndex = function (x, y) { 
 | 
    // TODO ??? 
 | 
    // Consider transform 
 | 
    var shape = this.shape; 
 | 
    var points = shape.points; 
 | 
    var size = shape.size; 
 | 
    var w = Math.max(size[0], 4); 
 | 
    var h = Math.max(size[1], 4); 
 | 
    // Not consider transform 
 | 
    // Treat each element as a rect 
 | 
    // top down traverse 
 | 
    for (var idx = points.length / 2 - 1; idx >= 0; idx--) { 
 | 
      var i = idx * 2; 
 | 
      var x0 = points[i] - w / 2; 
 | 
      var y0 = points[i + 1] - h / 2; 
 | 
      if (x >= x0 && y >= y0 && x <= x0 + w && y <= y0 + h) { 
 | 
        return idx; 
 | 
      } 
 | 
    } 
 | 
    return -1; 
 | 
  }; 
 | 
  LargeSymbolPath.prototype.contain = function (x, y) { 
 | 
    var localPos = this.transformCoordToLocal(x, y); 
 | 
    var rect = this.getBoundingRect(); 
 | 
    x = localPos[0]; 
 | 
    y = localPos[1]; 
 | 
    if (rect.contain(x, y)) { 
 | 
      // Cache found data index. 
 | 
      var dataIdx = this.hoverDataIdx = this.findDataIndex(x, y); 
 | 
      return dataIdx >= 0; 
 | 
    } 
 | 
    this.hoverDataIdx = -1; 
 | 
    return false; 
 | 
  }; 
 | 
  LargeSymbolPath.prototype.getBoundingRect = function () { 
 | 
    // Ignore stroke for large symbol draw. 
 | 
    var rect = this._rect; 
 | 
    if (!rect) { 
 | 
      var shape = this.shape; 
 | 
      var points = shape.points; 
 | 
      var size = shape.size; 
 | 
      var w = size[0]; 
 | 
      var h = size[1]; 
 | 
      var minX = Infinity; 
 | 
      var minY = Infinity; 
 | 
      var maxX = -Infinity; 
 | 
      var maxY = -Infinity; 
 | 
      for (var i = 0; i < points.length;) { 
 | 
        var x = points[i++]; 
 | 
        var y = points[i++]; 
 | 
        minX = Math.min(x, minX); 
 | 
        maxX = Math.max(x, maxX); 
 | 
        minY = Math.min(y, minY); 
 | 
        maxY = Math.max(y, maxY); 
 | 
      } 
 | 
      rect = this._rect = new graphic.BoundingRect(minX - w / 2, minY - h / 2, maxX - minX + w, maxY - minY + h); 
 | 
    } 
 | 
    return rect; 
 | 
  }; 
 | 
  return LargeSymbolPath; 
 | 
}(graphic.Path); 
 | 
var LargeSymbolDraw = /** @class */function () { 
 | 
  function LargeSymbolDraw() { 
 | 
    this.group = new graphic.Group(); 
 | 
  } 
 | 
  /** 
 | 
   * Update symbols draw by new data 
 | 
   */ 
 | 
  LargeSymbolDraw.prototype.updateData = function (data, opt) { 
 | 
    this._clear(); 
 | 
    var symbolEl = this._create(); 
 | 
    symbolEl.setShape({ 
 | 
      points: data.getLayout('points') 
 | 
    }); 
 | 
    this._setCommon(symbolEl, data, opt); 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype.updateLayout = function (data) { 
 | 
    var points = data.getLayout('points'); 
 | 
    this.group.eachChild(function (child) { 
 | 
      if (child.startIndex != null) { 
 | 
        var len = (child.endIndex - child.startIndex) * 2; 
 | 
        var byteOffset = child.startIndex * 4 * 2; 
 | 
        points = new Float32Array(points.buffer, byteOffset, len); 
 | 
      } 
 | 
      child.setShape('points', points); 
 | 
      // Reset draw cursor. 
 | 
      child.reset(); 
 | 
    }); 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype.incrementalPrepareUpdate = function (data) { 
 | 
    this._clear(); 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) { 
 | 
    var lastAdded = this._newAdded[0]; 
 | 
    var points = data.getLayout('points'); 
 | 
    var oldPoints = lastAdded && lastAdded.shape.points; 
 | 
    // Merging the exists. Each element has 1e4 points. 
 | 
    // Consider the performance balance between too much elements and too much points in one shape(may affect hover optimization) 
 | 
    if (oldPoints && oldPoints.length < 2e4) { 
 | 
      var oldLen = oldPoints.length; 
 | 
      var newPoints = new Float32Array(oldLen + points.length); 
 | 
      // Concat two array 
 | 
      newPoints.set(oldPoints); 
 | 
      newPoints.set(points, oldLen); 
 | 
      // Update endIndex 
 | 
      lastAdded.endIndex = taskParams.end; 
 | 
      lastAdded.setShape({ 
 | 
        points: newPoints 
 | 
      }); 
 | 
    } else { 
 | 
      // Clear 
 | 
      this._newAdded = []; 
 | 
      var symbolEl = this._create(); 
 | 
      symbolEl.startIndex = taskParams.start; 
 | 
      symbolEl.endIndex = taskParams.end; 
 | 
      symbolEl.incremental = true; 
 | 
      symbolEl.setShape({ 
 | 
        points: points 
 | 
      }); 
 | 
      this._setCommon(symbolEl, data, opt); 
 | 
    } 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype.eachRendered = function (cb) { 
 | 
    this._newAdded[0] && cb(this._newAdded[0]); 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype._create = function () { 
 | 
    var symbolEl = new LargeSymbolPath({ 
 | 
      cursor: 'default' 
 | 
    }); 
 | 
    symbolEl.ignoreCoarsePointer = true; 
 | 
    this.group.add(symbolEl); 
 | 
    this._newAdded.push(symbolEl); 
 | 
    return symbolEl; 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype._setCommon = function (symbolEl, data, opt) { 
 | 
    var hostModel = data.hostModel; 
 | 
    opt = opt || {}; 
 | 
    var size = data.getVisual('symbolSize'); 
 | 
    symbolEl.setShape('size', size instanceof Array ? size : [size, size]); 
 | 
    symbolEl.softClipShape = opt.clipShape || null; 
 | 
    // Create symbolProxy to build path for each data 
 | 
    symbolEl.symbolProxy = createSymbol(data.getVisual('symbol'), 0, 0, 0, 0); 
 | 
    // Use symbolProxy setColor method 
 | 
    symbolEl.setColor = symbolEl.symbolProxy.setColor; 
 | 
    var extrudeShadow = symbolEl.shape.size[0] < BOOST_SIZE_THRESHOLD; 
 | 
    symbolEl.useStyle( 
 | 
    // Draw shadow when doing fillRect is extremely slow. 
 | 
    hostModel.getModel('itemStyle').getItemStyle(extrudeShadow ? ['color', 'shadowBlur', 'shadowColor'] : ['color'])); 
 | 
    var globalStyle = data.getVisual('style'); 
 | 
    var visualColor = globalStyle && globalStyle.fill; 
 | 
    if (visualColor) { 
 | 
      symbolEl.setColor(visualColor); 
 | 
    } 
 | 
    var ecData = getECData(symbolEl); 
 | 
    // Enable tooltip 
 | 
    // PENDING May have performance issue when path is extremely large 
 | 
    ecData.seriesIndex = hostModel.seriesIndex; 
 | 
    symbolEl.on('mousemove', function (e) { 
 | 
      ecData.dataIndex = null; 
 | 
      var dataIndex = symbolEl.hoverDataIdx; 
 | 
      if (dataIndex >= 0) { 
 | 
        // Provide dataIndex for tooltip 
 | 
        ecData.dataIndex = dataIndex + (symbolEl.startIndex || 0); 
 | 
      } 
 | 
    }); 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype.remove = function () { 
 | 
    this._clear(); 
 | 
  }; 
 | 
  LargeSymbolDraw.prototype._clear = function () { 
 | 
    this._newAdded = []; 
 | 
    this.group.removeAll(); 
 | 
  }; 
 | 
  return LargeSymbolDraw; 
 | 
}(); 
 | 
export default LargeSymbolDraw; 
 |