| 
/* 
 | 
* 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"; 
 | 
import * as zrUtil from 'zrender/lib/core/util.js'; 
 | 
import * as graphic from '../../util/graphic.js'; 
 | 
import { toggleHoverEmphasis } from '../../util/states.js'; 
 | 
import { createSymbol, normalizeSymbolOffset } from '../../util/symbol.js'; 
 | 
import { parsePercent, isNumeric } from '../../util/number.js'; 
 | 
import ChartView from '../../view/Chart.js'; 
 | 
import { getDefaultLabel } from '../helper/labelHelper.js'; 
 | 
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle.js'; 
 | 
import ZRImage from 'zrender/lib/graphic/Image.js'; 
 | 
import { getECData } from '../../util/innerStore.js'; 
 | 
import { createClipPath } from '../helper/createClipPathFromCoordSys.js'; 
 | 
var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'borderWidth']; 
 | 
// index: +isHorizontal 
 | 
var LAYOUT_ATTRS = [{ 
 | 
  xy: 'x', 
 | 
  wh: 'width', 
 | 
  index: 0, 
 | 
  posDesc: ['left', 'right'] 
 | 
}, { 
 | 
  xy: 'y', 
 | 
  wh: 'height', 
 | 
  index: 1, 
 | 
  posDesc: ['top', 'bottom'] 
 | 
}]; 
 | 
var pathForLineWidth = new graphic.Circle(); 
 | 
var PictorialBarView = /** @class */function (_super) { 
 | 
  __extends(PictorialBarView, _super); 
 | 
  function PictorialBarView() { 
 | 
    var _this = _super !== null && _super.apply(this, arguments) || this; 
 | 
    _this.type = PictorialBarView.type; 
 | 
    return _this; 
 | 
  } 
 | 
  PictorialBarView.prototype.render = function (seriesModel, ecModel, api) { 
 | 
    var group = this.group; 
 | 
    var data = seriesModel.getData(); 
 | 
    var oldData = this._data; 
 | 
    var cartesian = seriesModel.coordinateSystem; 
 | 
    var baseAxis = cartesian.getBaseAxis(); 
 | 
    var isHorizontal = baseAxis.isHorizontal(); 
 | 
    var coordSysRect = cartesian.master.getRect(); 
 | 
    var opt = { 
 | 
      ecSize: { 
 | 
        width: api.getWidth(), 
 | 
        height: api.getHeight() 
 | 
      }, 
 | 
      seriesModel: seriesModel, 
 | 
      coordSys: cartesian, 
 | 
      coordSysExtent: [[coordSysRect.x, coordSysRect.x + coordSysRect.width], [coordSysRect.y, coordSysRect.y + coordSysRect.height]], 
 | 
      isHorizontal: isHorizontal, 
 | 
      valueDim: LAYOUT_ATTRS[+isHorizontal], 
 | 
      categoryDim: LAYOUT_ATTRS[1 - +isHorizontal] 
 | 
    }; 
 | 
    data.diff(oldData).add(function (dataIndex) { 
 | 
      if (!data.hasValue(dataIndex)) { 
 | 
        return; 
 | 
      } 
 | 
      var itemModel = getItemModel(data, dataIndex); 
 | 
      var symbolMeta = getSymbolMeta(data, dataIndex, itemModel, opt); 
 | 
      var bar = createBar(data, opt, symbolMeta); 
 | 
      data.setItemGraphicEl(dataIndex, bar); 
 | 
      group.add(bar); 
 | 
      updateCommon(bar, opt, symbolMeta); 
 | 
    }).update(function (newIndex, oldIndex) { 
 | 
      var bar = oldData.getItemGraphicEl(oldIndex); 
 | 
      if (!data.hasValue(newIndex)) { 
 | 
        group.remove(bar); 
 | 
        return; 
 | 
      } 
 | 
      var itemModel = getItemModel(data, newIndex); 
 | 
      var symbolMeta = getSymbolMeta(data, newIndex, itemModel, opt); 
 | 
      var pictorialShapeStr = getShapeStr(data, symbolMeta); 
 | 
      if (bar && pictorialShapeStr !== bar.__pictorialShapeStr) { 
 | 
        group.remove(bar); 
 | 
        data.setItemGraphicEl(newIndex, null); 
 | 
        bar = null; 
 | 
      } 
 | 
      if (bar) { 
 | 
        updateBar(bar, opt, symbolMeta); 
 | 
      } else { 
 | 
        bar = createBar(data, opt, symbolMeta, true); 
 | 
      } 
 | 
      data.setItemGraphicEl(newIndex, bar); 
 | 
      bar.__pictorialSymbolMeta = symbolMeta; 
 | 
      // Add back 
 | 
      group.add(bar); 
 | 
      updateCommon(bar, opt, symbolMeta); 
 | 
    }).remove(function (dataIndex) { 
 | 
      var bar = oldData.getItemGraphicEl(dataIndex); 
 | 
      bar && removeBar(oldData, dataIndex, bar.__pictorialSymbolMeta.animationModel, bar); 
 | 
    }).execute(); 
 | 
    // Do clipping 
 | 
    var clipPath = seriesModel.get('clip', true) ? createClipPath(seriesModel.coordinateSystem, false, seriesModel) : null; 
 | 
    if (clipPath) { 
 | 
      group.setClipPath(clipPath); 
 | 
    } else { 
 | 
      group.removeClipPath(); 
 | 
    } 
 | 
    this._data = data; 
 | 
    return this.group; 
 | 
  }; 
 | 
  PictorialBarView.prototype.remove = function (ecModel, api) { 
 | 
    var group = this.group; 
 | 
    var data = this._data; 
 | 
    if (ecModel.get('animation')) { 
 | 
      if (data) { 
 | 
        data.eachItemGraphicEl(function (bar) { 
 | 
          removeBar(data, getECData(bar).dataIndex, ecModel, bar); 
 | 
        }); 
 | 
      } 
 | 
    } else { 
 | 
      group.removeAll(); 
 | 
    } 
 | 
  }; 
 | 
  PictorialBarView.type = 'pictorialBar'; 
 | 
  return PictorialBarView; 
 | 
}(ChartView); 
 | 
// Set or calculate default value about symbol, and calculate layout info. 
 | 
function getSymbolMeta(data, dataIndex, itemModel, opt) { 
 | 
  var layout = data.getItemLayout(dataIndex); 
 | 
  var symbolRepeat = itemModel.get('symbolRepeat'); 
 | 
  var symbolClip = itemModel.get('symbolClip'); 
 | 
  var symbolPosition = itemModel.get('symbolPosition') || 'start'; 
 | 
  var symbolRotate = itemModel.get('symbolRotate'); 
 | 
  var rotation = (symbolRotate || 0) * Math.PI / 180 || 0; 
 | 
  var symbolPatternSize = itemModel.get('symbolPatternSize') || 2; 
 | 
  var isAnimationEnabled = itemModel.isAnimationEnabled(); 
 | 
  var symbolMeta = { 
 | 
    dataIndex: dataIndex, 
 | 
    layout: layout, 
 | 
    itemModel: itemModel, 
 | 
    symbolType: data.getItemVisual(dataIndex, 'symbol') || 'circle', 
 | 
    style: data.getItemVisual(dataIndex, 'style'), 
 | 
    symbolClip: symbolClip, 
 | 
    symbolRepeat: symbolRepeat, 
 | 
    symbolRepeatDirection: itemModel.get('symbolRepeatDirection'), 
 | 
    symbolPatternSize: symbolPatternSize, 
 | 
    rotation: rotation, 
 | 
    animationModel: isAnimationEnabled ? itemModel : null, 
 | 
    hoverScale: isAnimationEnabled && itemModel.get(['emphasis', 'scale']), 
 | 
    z2: itemModel.getShallow('z', true) || 0 
 | 
  }; 
 | 
  prepareBarLength(itemModel, symbolRepeat, layout, opt, symbolMeta); 
 | 
  prepareSymbolSize(data, dataIndex, layout, symbolRepeat, symbolClip, symbolMeta.boundingLength, symbolMeta.pxSign, symbolPatternSize, opt, symbolMeta); 
 | 
  prepareLineWidth(itemModel, symbolMeta.symbolScale, rotation, opt, symbolMeta); 
 | 
  var symbolSize = symbolMeta.symbolSize; 
 | 
  var symbolOffset = normalizeSymbolOffset(itemModel.get('symbolOffset'), symbolSize); 
 | 
  prepareLayoutInfo(itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, symbolPosition, symbolMeta.valueLineWidth, symbolMeta.boundingLength, symbolMeta.repeatCutLength, opt, symbolMeta); 
 | 
  return symbolMeta; 
 | 
} 
 | 
// bar length can be negative. 
 | 
function prepareBarLength(itemModel, symbolRepeat, layout, opt, outputSymbolMeta) { 
 | 
  var valueDim = opt.valueDim; 
 | 
  var symbolBoundingData = itemModel.get('symbolBoundingData'); 
 | 
  var valueAxis = opt.coordSys.getOtherAxis(opt.coordSys.getBaseAxis()); 
 | 
  var zeroPx = valueAxis.toGlobalCoord(valueAxis.dataToCoord(0)); 
 | 
  var pxSignIdx = 1 - +(layout[valueDim.wh] <= 0); 
 | 
  var boundingLength; 
 | 
  if (zrUtil.isArray(symbolBoundingData)) { 
 | 
    var symbolBoundingExtent = [convertToCoordOnAxis(valueAxis, symbolBoundingData[0]) - zeroPx, convertToCoordOnAxis(valueAxis, symbolBoundingData[1]) - zeroPx]; 
 | 
    symbolBoundingExtent[1] < symbolBoundingExtent[0] && symbolBoundingExtent.reverse(); 
 | 
    boundingLength = symbolBoundingExtent[pxSignIdx]; 
 | 
  } else if (symbolBoundingData != null) { 
 | 
    boundingLength = convertToCoordOnAxis(valueAxis, symbolBoundingData) - zeroPx; 
 | 
  } else if (symbolRepeat) { 
 | 
    boundingLength = opt.coordSysExtent[valueDim.index][pxSignIdx] - zeroPx; 
 | 
  } else { 
 | 
    boundingLength = layout[valueDim.wh]; 
 | 
  } 
 | 
  outputSymbolMeta.boundingLength = boundingLength; 
 | 
  if (symbolRepeat) { 
 | 
    outputSymbolMeta.repeatCutLength = layout[valueDim.wh]; 
 | 
  } 
 | 
  // if 'pxSign' means sign of pixel,  it can't be zero, or symbolScale will be zero 
 | 
  // and when borderWidth be settled, the actual linewidth will be NaN 
 | 
  var isXAxis = valueDim.xy === 'x'; 
 | 
  var isInverse = valueAxis.inverse; 
 | 
  outputSymbolMeta.pxSign = isXAxis && !isInverse || !isXAxis && isInverse ? boundingLength >= 0 ? 1 : -1 : boundingLength > 0 ? 1 : -1; 
 | 
} 
 | 
function convertToCoordOnAxis(axis, value) { 
 | 
  return axis.toGlobalCoord(axis.dataToCoord(axis.scale.parse(value))); 
 | 
} 
 | 
// Support ['100%', '100%'] 
 | 
function prepareSymbolSize(data, dataIndex, layout, symbolRepeat, symbolClip, boundingLength, pxSign, symbolPatternSize, opt, outputSymbolMeta) { 
 | 
  var valueDim = opt.valueDim; 
 | 
  var categoryDim = opt.categoryDim; 
 | 
  var categorySize = Math.abs(layout[categoryDim.wh]); 
 | 
  var symbolSize = data.getItemVisual(dataIndex, 'symbolSize'); 
 | 
  var parsedSymbolSize; 
 | 
  if (zrUtil.isArray(symbolSize)) { 
 | 
    parsedSymbolSize = symbolSize.slice(); 
 | 
  } else { 
 | 
    if (symbolSize == null) { 
 | 
      // will parse to number below 
 | 
      parsedSymbolSize = ['100%', '100%']; 
 | 
    } else { 
 | 
      parsedSymbolSize = [symbolSize, symbolSize]; 
 | 
    } 
 | 
  } 
 | 
  // Note: percentage symbolSize (like '100%') do not consider lineWidth, because it is 
 | 
  // to complicated to calculate real percent value if considering scaled lineWidth. 
 | 
  // So the actual size will bigger than layout size if lineWidth is bigger than zero, 
 | 
  // which can be tolerated in pictorial chart. 
 | 
  parsedSymbolSize[categoryDim.index] = parsePercent(parsedSymbolSize[categoryDim.index], categorySize); 
 | 
  parsedSymbolSize[valueDim.index] = parsePercent(parsedSymbolSize[valueDim.index], symbolRepeat ? categorySize : Math.abs(boundingLength)); 
 | 
  outputSymbolMeta.symbolSize = parsedSymbolSize; 
 | 
  // If x or y is less than zero, show reversed shape. 
 | 
  var symbolScale = outputSymbolMeta.symbolScale = [parsedSymbolSize[0] / symbolPatternSize, parsedSymbolSize[1] / symbolPatternSize]; 
 | 
  // Follow convention, 'right' and 'top' is the normal scale. 
 | 
  symbolScale[valueDim.index] *= (opt.isHorizontal ? -1 : 1) * pxSign; 
 | 
} 
 | 
function prepareLineWidth(itemModel, symbolScale, rotation, opt, outputSymbolMeta) { 
 | 
  // In symbols are drawn with scale, so do not need to care about the case that width 
 | 
  // or height are too small. But symbol use strokeNoScale, where acture lineWidth should 
 | 
  // be calculated. 
 | 
  var valueLineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0; 
 | 
  if (valueLineWidth) { 
 | 
    pathForLineWidth.attr({ 
 | 
      scaleX: symbolScale[0], 
 | 
      scaleY: symbolScale[1], 
 | 
      rotation: rotation 
 | 
    }); 
 | 
    pathForLineWidth.updateTransform(); 
 | 
    valueLineWidth /= pathForLineWidth.getLineScale(); 
 | 
    valueLineWidth *= symbolScale[opt.valueDim.index]; 
 | 
  } 
 | 
  outputSymbolMeta.valueLineWidth = valueLineWidth || 0; 
 | 
} 
 | 
function prepareLayoutInfo(itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, symbolPosition, valueLineWidth, boundingLength, repeatCutLength, opt, outputSymbolMeta) { 
 | 
  var categoryDim = opt.categoryDim; 
 | 
  var valueDim = opt.valueDim; 
 | 
  var pxSign = outputSymbolMeta.pxSign; 
 | 
  var unitLength = Math.max(symbolSize[valueDim.index] + valueLineWidth, 0); 
 | 
  var pathLen = unitLength; 
 | 
  // Note: rotation will not effect the layout of symbols, because user may 
 | 
  // want symbols to rotate on its center, which should not be translated 
 | 
  // when rotating. 
 | 
  if (symbolRepeat) { 
 | 
    var absBoundingLength = Math.abs(boundingLength); 
 | 
    var symbolMargin = zrUtil.retrieve(itemModel.get('symbolMargin'), '15%') + ''; 
 | 
    var hasEndGap = false; 
 | 
    if (symbolMargin.lastIndexOf('!') === symbolMargin.length - 1) { 
 | 
      hasEndGap = true; 
 | 
      symbolMargin = symbolMargin.slice(0, symbolMargin.length - 1); 
 | 
    } 
 | 
    var symbolMarginNumeric = parsePercent(symbolMargin, symbolSize[valueDim.index]); 
 | 
    var uLenWithMargin = Math.max(unitLength + symbolMarginNumeric * 2, 0); 
 | 
    // When symbol margin is less than 0, margin at both ends will be subtracted 
 | 
    // to ensure that all of the symbols will not be overflow the given area. 
 | 
    var endFix = hasEndGap ? 0 : symbolMarginNumeric * 2; 
 | 
    // Both final repeatTimes and final symbolMarginNumeric area calculated based on 
 | 
    // boundingLength. 
 | 
    var repeatSpecified = isNumeric(symbolRepeat); 
 | 
    var repeatTimes = repeatSpecified ? symbolRepeat : toIntTimes((absBoundingLength + endFix) / uLenWithMargin); 
 | 
    // Adjust calculate margin, to ensure each symbol is displayed 
 | 
    // entirely in the given layout area. 
 | 
    var mDiff = absBoundingLength - repeatTimes * unitLength; 
 | 
    symbolMarginNumeric = mDiff / 2 / (hasEndGap ? repeatTimes : Math.max(repeatTimes - 1, 1)); 
 | 
    uLenWithMargin = unitLength + symbolMarginNumeric * 2; 
 | 
    endFix = hasEndGap ? 0 : symbolMarginNumeric * 2; 
 | 
    // Update repeatTimes when not all symbol will be shown. 
 | 
    if (!repeatSpecified && symbolRepeat !== 'fixed') { 
 | 
      repeatTimes = repeatCutLength ? toIntTimes((Math.abs(repeatCutLength) + endFix) / uLenWithMargin) : 0; 
 | 
    } 
 | 
    pathLen = repeatTimes * uLenWithMargin - endFix; 
 | 
    outputSymbolMeta.repeatTimes = repeatTimes; 
 | 
    outputSymbolMeta.symbolMargin = symbolMarginNumeric; 
 | 
  } 
 | 
  var sizeFix = pxSign * (pathLen / 2); 
 | 
  var pathPosition = outputSymbolMeta.pathPosition = []; 
 | 
  pathPosition[categoryDim.index] = layout[categoryDim.wh] / 2; 
 | 
  pathPosition[valueDim.index] = symbolPosition === 'start' ? sizeFix : symbolPosition === 'end' ? boundingLength - sizeFix : boundingLength / 2; // 'center' 
 | 
  if (symbolOffset) { 
 | 
    pathPosition[0] += symbolOffset[0]; 
 | 
    pathPosition[1] += symbolOffset[1]; 
 | 
  } 
 | 
  var bundlePosition = outputSymbolMeta.bundlePosition = []; 
 | 
  bundlePosition[categoryDim.index] = layout[categoryDim.xy]; 
 | 
  bundlePosition[valueDim.index] = layout[valueDim.xy]; 
 | 
  var barRectShape = outputSymbolMeta.barRectShape = zrUtil.extend({}, layout); 
 | 
  barRectShape[valueDim.wh] = pxSign * Math.max(Math.abs(layout[valueDim.wh]), Math.abs(pathPosition[valueDim.index] + sizeFix)); 
 | 
  barRectShape[categoryDim.wh] = layout[categoryDim.wh]; 
 | 
  var clipShape = outputSymbolMeta.clipShape = {}; 
 | 
  // Consider that symbol may be overflow layout rect. 
 | 
  clipShape[categoryDim.xy] = -layout[categoryDim.xy]; 
 | 
  clipShape[categoryDim.wh] = opt.ecSize[categoryDim.wh]; 
 | 
  clipShape[valueDim.xy] = 0; 
 | 
  clipShape[valueDim.wh] = layout[valueDim.wh]; 
 | 
} 
 | 
function createPath(symbolMeta) { 
 | 
  var symbolPatternSize = symbolMeta.symbolPatternSize; 
 | 
  var path = createSymbol( 
 | 
  // Consider texture img, make a big size. 
 | 
  symbolMeta.symbolType, -symbolPatternSize / 2, -symbolPatternSize / 2, symbolPatternSize, symbolPatternSize); 
 | 
  path.attr({ 
 | 
    culling: true 
 | 
  }); 
 | 
  path.type !== 'image' && path.setStyle({ 
 | 
    strokeNoScale: true 
 | 
  }); 
 | 
  return path; 
 | 
} 
 | 
function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) { 
 | 
  var bundle = bar.__pictorialBundle; 
 | 
  var symbolSize = symbolMeta.symbolSize; 
 | 
  var valueLineWidth = symbolMeta.valueLineWidth; 
 | 
  var pathPosition = symbolMeta.pathPosition; 
 | 
  var valueDim = opt.valueDim; 
 | 
  var repeatTimes = symbolMeta.repeatTimes || 0; 
 | 
  var index = 0; 
 | 
  var unit = symbolSize[opt.valueDim.index] + valueLineWidth + symbolMeta.symbolMargin * 2; 
 | 
  eachPath(bar, function (path) { 
 | 
    path.__pictorialAnimationIndex = index; 
 | 
    path.__pictorialRepeatTimes = repeatTimes; 
 | 
    if (index < repeatTimes) { 
 | 
      updateAttr(path, null, makeTarget(index), symbolMeta, isUpdate); 
 | 
    } else { 
 | 
      updateAttr(path, null, { 
 | 
        scaleX: 0, 
 | 
        scaleY: 0 
 | 
      }, symbolMeta, isUpdate, function () { 
 | 
        bundle.remove(path); 
 | 
      }); 
 | 
    } 
 | 
    // updateHoverAnimation(path, symbolMeta); 
 | 
    index++; 
 | 
  }); 
 | 
  for (; index < repeatTimes; index++) { 
 | 
    var path = createPath(symbolMeta); 
 | 
    path.__pictorialAnimationIndex = index; 
 | 
    path.__pictorialRepeatTimes = repeatTimes; 
 | 
    bundle.add(path); 
 | 
    var target = makeTarget(index); 
 | 
    updateAttr(path, { 
 | 
      x: target.x, 
 | 
      y: target.y, 
 | 
      scaleX: 0, 
 | 
      scaleY: 0 
 | 
    }, { 
 | 
      scaleX: target.scaleX, 
 | 
      scaleY: target.scaleY, 
 | 
      rotation: target.rotation 
 | 
    }, symbolMeta, isUpdate); 
 | 
  } 
 | 
  function makeTarget(index) { 
 | 
    var position = pathPosition.slice(); 
 | 
    // (start && pxSign > 0) || (end && pxSign < 0): i = repeatTimes - index 
 | 
    // Otherwise: i = index; 
 | 
    var pxSign = symbolMeta.pxSign; 
 | 
    var i = index; 
 | 
    if (symbolMeta.symbolRepeatDirection === 'start' ? pxSign > 0 : pxSign < 0) { 
 | 
      i = repeatTimes - 1 - index; 
 | 
    } 
 | 
    position[valueDim.index] = unit * (i - repeatTimes / 2 + 0.5) + pathPosition[valueDim.index]; 
 | 
    return { 
 | 
      x: position[0], 
 | 
      y: position[1], 
 | 
      scaleX: symbolMeta.symbolScale[0], 
 | 
      scaleY: symbolMeta.symbolScale[1], 
 | 
      rotation: symbolMeta.rotation 
 | 
    }; 
 | 
  } 
 | 
} 
 | 
function createOrUpdateSingleSymbol(bar, opt, symbolMeta, isUpdate) { 
 | 
  var bundle = bar.__pictorialBundle; 
 | 
  var mainPath = bar.__pictorialMainPath; 
 | 
  if (!mainPath) { 
 | 
    mainPath = bar.__pictorialMainPath = createPath(symbolMeta); 
 | 
    bundle.add(mainPath); 
 | 
    updateAttr(mainPath, { 
 | 
      x: symbolMeta.pathPosition[0], 
 | 
      y: symbolMeta.pathPosition[1], 
 | 
      scaleX: 0, 
 | 
      scaleY: 0, 
 | 
      rotation: symbolMeta.rotation 
 | 
    }, { 
 | 
      scaleX: symbolMeta.symbolScale[0], 
 | 
      scaleY: symbolMeta.symbolScale[1] 
 | 
    }, symbolMeta, isUpdate); 
 | 
  } else { 
 | 
    updateAttr(mainPath, null, { 
 | 
      x: symbolMeta.pathPosition[0], 
 | 
      y: symbolMeta.pathPosition[1], 
 | 
      scaleX: symbolMeta.symbolScale[0], 
 | 
      scaleY: symbolMeta.symbolScale[1], 
 | 
      rotation: symbolMeta.rotation 
 | 
    }, symbolMeta, isUpdate); 
 | 
  } 
 | 
} 
 | 
// bar rect is used for label. 
 | 
function createOrUpdateBarRect(bar, symbolMeta, isUpdate) { 
 | 
  var rectShape = zrUtil.extend({}, symbolMeta.barRectShape); 
 | 
  var barRect = bar.__pictorialBarRect; 
 | 
  if (!barRect) { 
 | 
    barRect = bar.__pictorialBarRect = new graphic.Rect({ 
 | 
      z2: 2, 
 | 
      shape: rectShape, 
 | 
      silent: true, 
 | 
      style: { 
 | 
        stroke: 'transparent', 
 | 
        fill: 'transparent', 
 | 
        lineWidth: 0 
 | 
      } 
 | 
    }); 
 | 
    barRect.disableMorphing = true; 
 | 
    bar.add(barRect); 
 | 
  } else { 
 | 
    updateAttr(barRect, null, { 
 | 
      shape: rectShape 
 | 
    }, symbolMeta, isUpdate); 
 | 
  } 
 | 
} 
 | 
function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) { 
 | 
  // If not clip, symbol will be remove and rebuilt. 
 | 
  if (symbolMeta.symbolClip) { 
 | 
    var clipPath = bar.__pictorialClipPath; 
 | 
    var clipShape = zrUtil.extend({}, symbolMeta.clipShape); 
 | 
    var valueDim = opt.valueDim; 
 | 
    var animationModel = symbolMeta.animationModel; 
 | 
    var dataIndex = symbolMeta.dataIndex; 
 | 
    if (clipPath) { 
 | 
      graphic.updateProps(clipPath, { 
 | 
        shape: clipShape 
 | 
      }, animationModel, dataIndex); 
 | 
    } else { 
 | 
      clipShape[valueDim.wh] = 0; 
 | 
      clipPath = new graphic.Rect({ 
 | 
        shape: clipShape 
 | 
      }); 
 | 
      bar.__pictorialBundle.setClipPath(clipPath); 
 | 
      bar.__pictorialClipPath = clipPath; 
 | 
      var target = {}; 
 | 
      target[valueDim.wh] = symbolMeta.clipShape[valueDim.wh]; 
 | 
      graphic[isUpdate ? 'updateProps' : 'initProps'](clipPath, { 
 | 
        shape: target 
 | 
      }, animationModel, dataIndex); 
 | 
    } 
 | 
  } 
 | 
} 
 | 
function getItemModel(data, dataIndex) { 
 | 
  var itemModel = data.getItemModel(dataIndex); 
 | 
  itemModel.getAnimationDelayParams = getAnimationDelayParams; 
 | 
  itemModel.isAnimationEnabled = isAnimationEnabled; 
 | 
  return itemModel; 
 | 
} 
 | 
function getAnimationDelayParams(path) { 
 | 
  // The order is the same as the z-order, see `symbolRepeatDiretion`. 
 | 
  return { 
 | 
    index: path.__pictorialAnimationIndex, 
 | 
    count: path.__pictorialRepeatTimes 
 | 
  }; 
 | 
} 
 | 
function isAnimationEnabled() { 
 | 
  // `animation` prop can be set on itemModel in pictorial bar chart. 
 | 
  return this.parentModel.isAnimationEnabled() && !!this.getShallow('animation'); 
 | 
} 
 | 
function createBar(data, opt, symbolMeta, isUpdate) { 
 | 
  // bar is the main element for each data. 
 | 
  var bar = new graphic.Group(); 
 | 
  // bundle is used for location and clip. 
 | 
  var bundle = new graphic.Group(); 
 | 
  bar.add(bundle); 
 | 
  bar.__pictorialBundle = bundle; 
 | 
  bundle.x = symbolMeta.bundlePosition[0]; 
 | 
  bundle.y = symbolMeta.bundlePosition[1]; 
 | 
  if (symbolMeta.symbolRepeat) { 
 | 
    createOrUpdateRepeatSymbols(bar, opt, symbolMeta); 
 | 
  } else { 
 | 
    createOrUpdateSingleSymbol(bar, opt, symbolMeta); 
 | 
  } 
 | 
  createOrUpdateBarRect(bar, symbolMeta, isUpdate); 
 | 
  createOrUpdateClip(bar, opt, symbolMeta, isUpdate); 
 | 
  bar.__pictorialShapeStr = getShapeStr(data, symbolMeta); 
 | 
  bar.__pictorialSymbolMeta = symbolMeta; 
 | 
  return bar; 
 | 
} 
 | 
function updateBar(bar, opt, symbolMeta) { 
 | 
  var animationModel = symbolMeta.animationModel; 
 | 
  var dataIndex = symbolMeta.dataIndex; 
 | 
  var bundle = bar.__pictorialBundle; 
 | 
  graphic.updateProps(bundle, { 
 | 
    x: symbolMeta.bundlePosition[0], 
 | 
    y: symbolMeta.bundlePosition[1] 
 | 
  }, animationModel, dataIndex); 
 | 
  if (symbolMeta.symbolRepeat) { 
 | 
    createOrUpdateRepeatSymbols(bar, opt, symbolMeta, true); 
 | 
  } else { 
 | 
    createOrUpdateSingleSymbol(bar, opt, symbolMeta, true); 
 | 
  } 
 | 
  createOrUpdateBarRect(bar, symbolMeta, true); 
 | 
  createOrUpdateClip(bar, opt, symbolMeta, true); 
 | 
} 
 | 
function removeBar(data, dataIndex, animationModel, bar) { 
 | 
  // Not show text when animating 
 | 
  var labelRect = bar.__pictorialBarRect; 
 | 
  labelRect && labelRect.removeTextContent(); 
 | 
  var paths = []; 
 | 
  eachPath(bar, function (path) { 
 | 
    paths.push(path); 
 | 
  }); 
 | 
  bar.__pictorialMainPath && paths.push(bar.__pictorialMainPath); 
 | 
  // I do not find proper remove animation for clip yet. 
 | 
  bar.__pictorialClipPath && (animationModel = null); 
 | 
  zrUtil.each(paths, function (path) { 
 | 
    graphic.removeElement(path, { 
 | 
      scaleX: 0, 
 | 
      scaleY: 0 
 | 
    }, animationModel, dataIndex, function () { 
 | 
      bar.parent && bar.parent.remove(bar); 
 | 
    }); 
 | 
  }); 
 | 
  data.setItemGraphicEl(dataIndex, null); 
 | 
} 
 | 
function getShapeStr(data, symbolMeta) { 
 | 
  return [data.getItemVisual(symbolMeta.dataIndex, 'symbol') || 'none', !!symbolMeta.symbolRepeat, !!symbolMeta.symbolClip].join(':'); 
 | 
} 
 | 
function eachPath(bar, cb, context) { 
 | 
  // Do not use Group#eachChild, because it do not support remove. 
 | 
  zrUtil.each(bar.__pictorialBundle.children(), function (el) { 
 | 
    el !== bar.__pictorialBarRect && cb.call(context, el); 
 | 
  }); 
 | 
} 
 | 
function updateAttr(el, immediateAttrs, animationAttrs, symbolMeta, isUpdate, cb) { 
 | 
  immediateAttrs && el.attr(immediateAttrs); 
 | 
  // when symbolCip used, only clip path has init animation, otherwise it would be weird effect. 
 | 
  if (symbolMeta.symbolClip && !isUpdate) { 
 | 
    animationAttrs && el.attr(animationAttrs); 
 | 
  } else { 
 | 
    animationAttrs && graphic[isUpdate ? 'updateProps' : 'initProps'](el, animationAttrs, symbolMeta.animationModel, symbolMeta.dataIndex, cb); 
 | 
  } 
 | 
} 
 | 
function updateCommon(bar, opt, symbolMeta) { 
 | 
  var dataIndex = symbolMeta.dataIndex; 
 | 
  var itemModel = symbolMeta.itemModel; 
 | 
  // Color must be excluded. 
 | 
  // Because symbol provide setColor individually to set fill and stroke 
 | 
  var emphasisModel = itemModel.getModel('emphasis'); 
 | 
  var emphasisStyle = emphasisModel.getModel('itemStyle').getItemStyle(); 
 | 
  var blurStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle(); 
 | 
  var selectStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle(); 
 | 
  var cursorStyle = itemModel.getShallow('cursor'); 
 | 
  var focus = emphasisModel.get('focus'); 
 | 
  var blurScope = emphasisModel.get('blurScope'); 
 | 
  var hoverScale = emphasisModel.get('scale'); 
 | 
  eachPath(bar, function (path) { 
 | 
    if (path instanceof ZRImage) { 
 | 
      var pathStyle = path.style; 
 | 
      path.useStyle(zrUtil.extend({ 
 | 
        // TODO other properties like dx, dy ? 
 | 
        image: pathStyle.image, 
 | 
        x: pathStyle.x, 
 | 
        y: pathStyle.y, 
 | 
        width: pathStyle.width, 
 | 
        height: pathStyle.height 
 | 
      }, symbolMeta.style)); 
 | 
    } else { 
 | 
      path.useStyle(symbolMeta.style); 
 | 
    } 
 | 
    var emphasisState = path.ensureState('emphasis'); 
 | 
    emphasisState.style = emphasisStyle; 
 | 
    if (hoverScale) { 
 | 
      // NOTE: Must after scale is set after updateAttr 
 | 
      emphasisState.scaleX = path.scaleX * 1.1; 
 | 
      emphasisState.scaleY = path.scaleY * 1.1; 
 | 
    } 
 | 
    path.ensureState('blur').style = blurStyle; 
 | 
    path.ensureState('select').style = selectStyle; 
 | 
    cursorStyle && (path.cursor = cursorStyle); 
 | 
    path.z2 = symbolMeta.z2; 
 | 
  }); 
 | 
  var barPositionOutside = opt.valueDim.posDesc[+(symbolMeta.boundingLength > 0)]; 
 | 
  var barRect = bar.__pictorialBarRect; 
 | 
  barRect.ignoreClip = true; 
 | 
  setLabelStyle(barRect, getLabelStatesModels(itemModel), { 
 | 
    labelFetcher: opt.seriesModel, 
 | 
    labelDataIndex: dataIndex, 
 | 
    defaultText: getDefaultLabel(opt.seriesModel.getData(), dataIndex), 
 | 
    inheritColor: symbolMeta.style.fill, 
 | 
    defaultOpacity: symbolMeta.style.opacity, 
 | 
    defaultOutsidePosition: barPositionOutside 
 | 
  }); 
 | 
  toggleHoverEmphasis(bar, focus, blurScope, emphasisModel.get('disabled')); 
 | 
} 
 | 
function toIntTimes(times) { 
 | 
  var roundedTimes = Math.round(times); 
 | 
  // Escapse accurate error 
 | 
  return Math.abs(times - roundedTimes) < 1e-4 ? roundedTimes : Math.ceil(times); 
 | 
} 
 | 
export default PictorialBarView; 
 |