
/*
* 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.
 */

import { __extends } from "tslib";
import { hasOwn, assert, isString, retrieve2, retrieve3, defaults, each, keys, isArrayLike, bind } from 'zrender/esm/core/util';
import * as graphicUtil from '../util/graphic';
import { setDefaultStateProxy, enableHoverEmphasis } from '../util/states';
import * as labelStyleHelper from '../label/labelStyle';
import { getDefaultLabel } from './helper/labelHelper';
import createListFromArray from './helper/createListFromArray';
import { getLayoutOnAxis } from '../layout/barGrid';
import DataDiffer from '../data/DataDiffer';
import SeriesModel from '../model/Series';
import ChartView from '../view/Chart';
import { createClipPath } from './helper/createClipPathFromCoordSys';
import prepareCartesian2d from '../coord/cartesian/prepareCustom';
import prepareGeo from '../coord/geo/prepareCustom';
import prepareSingleAxis from '../coord/single/prepareCustom';
import preparePolar from '../coord/polar/prepareCustom';
import prepareCalendar from '../coord/calendar/prepareCustom';
import ComponentModel from '../model/Component';
import { makeInner, normalizeToArray } from '../util/model';
import { convertToEC4StyleForCustomSerise, isEC4CompatibleStyle, convertFromEC4CompatibleStyle, warnDeprecated } from '../util/styleCompat';
import { cloneValue } from 'zrender/esm/animation/Animator';
var inner = makeInner();
var TRANSFORM_PROPS = {
  x: 1,
  y: 1,
  scaleX: 1,
  scaleY: 1,
  originX: 1,
  originY: 1,
  rotation: 1
};
var transformPropNamesStr = keys(TRANSFORM_PROPS).join(', ');
;
var STYLE_VISUAL_TYPE = {
  color: 'fill',
  borderColor: 'stroke'
};
var VISUAL_PROPS = {
  symbol: 1,
  symbolSize: 1,
  symbolKeepAspect: 1,
  legendSymbol: 1,
  visualMeta: 1,
  liftZ: 1
};
var EMPHASIS = 'emphasis';
var NORMAL = 'normal';
var BLUR = 'blur';
var SELECT = 'select';
var STATES = [NORMAL, EMPHASIS, BLUR, SELECT];
var PATH_ITEM_STYLE = {
  normal: ['itemStyle'],
  emphasis: [EMPHASIS, 'itemStyle'],
  blur: [BLUR, 'itemStyle'],
  select: [SELECT, 'itemStyle']
};
var PATH_LABEL = {
  normal: ['label'],
  emphasis: [EMPHASIS, 'label'],
  blur: [BLUR, 'label'],
  select: [SELECT, 'label']
};
var GROUP_DIFF_PREFIX = 'e\0\0';
var attachedTxInfoTmp = {
  normal: {},
  emphasis: {},
  blur: {},
  select: {}
};
var LEGACY_TRANSFORM_PROPS = {
  position: ['x', 'y'],
  scale: ['scaleX', 'scaleY'],
  origin: ['originX', 'originY']
};
var prepareCustoms = {
  cartesian2d: prepareCartesian2d,
  geo: prepareGeo,
  singleAxis: prepareSingleAxis,
  polar: preparePolar,
  calendar: prepareCalendar
};

var CustomSeriesModel = function (_super) {
  __extends(CustomSeriesModel, _super);

  function CustomSeriesModel() {
    var _this = _super !== null && _super.apply(this, arguments) || this;

    _this.type = CustomSeriesModel.type;
    return _this;
  }

  CustomSeriesModel.prototype.optionUpdated = function () {
    this.currentZLevel = this.get('zlevel', true);
    this.currentZ = this.get('z', true);
  };

  CustomSeriesModel.prototype.getInitialData = function (option, ecModel) {
    return createListFromArray(this.getSource(), this);
  };

  CustomSeriesModel.prototype.getDataParams = function (dataIndex, dataType, el) {
    var params = _super.prototype.getDataParams.call(this, dataIndex, dataType);

    el && (params.info = inner(el).info);
    return params;
  };

  CustomSeriesModel.type = 'series.custom';
  CustomSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];
  CustomSeriesModel.defaultOption = {
    coordinateSystem: 'cartesian2d',
    zlevel: 0,
    z: 2,
    legendHoverLink: true,
    clip: false
  };
  return CustomSeriesModel;
}(SeriesModel);

ComponentModel.registerClass(CustomSeriesModel);

var CustomSeriesView = function (_super) {
  __extends(CustomSeriesView, _super);

  function CustomSeriesView() {
    var _this = _super !== null && _super.apply(this, arguments) || this;

    _this.type = CustomSeriesView.type;
    return _this;
  }

  CustomSeriesView.prototype.render = function (customSeries, ecModel, api, payload) {
    var oldData = this._data;
    var data = customSeries.getData();
    var group = this.group;
    var renderItem = makeRenderItem(customSeries, data, ecModel, api);
    data.diff(oldData).add(function (newIdx) {
      createOrUpdateItem(null, newIdx, renderItem(newIdx, payload), customSeries, group, data);
    }).update(function (newIdx, oldIdx) {
      createOrUpdateItem(oldData.getItemGraphicEl(oldIdx), newIdx, renderItem(newIdx, payload), customSeries, group, data);
    }).remove(function (oldIdx) {
      doRemoveEl(oldData.getItemGraphicEl(oldIdx), customSeries, group);
    }).execute();
    var clipPath = customSeries.get('clip', true) ? createClipPath(customSeries.coordinateSystem, false, customSeries) : null;

    if (clipPath) {
      group.setClipPath(clipPath);
    } else {
      group.removeClipPath();
    }

    this._data = data;
  };

  CustomSeriesView.prototype.incrementalPrepareRender = function (customSeries, ecModel, api) {
    this.group.removeAll();
    this._data = null;
  };

  CustomSeriesView.prototype.incrementalRender = function (params, customSeries, ecModel, api, payload) {
    var data = customSeries.getData();
    var renderItem = makeRenderItem(customSeries, data, ecModel, api);

    function setIncrementalAndHoverLayer(el) {
      if (!el.isGroup) {
        el.incremental = true;
        el.ensureState('emphasis').hoverLayer = true;
      }
    }

    for (var idx = params.start; idx < params.end; idx++) {
      var el = createOrUpdateItem(null, idx, renderItem(idx, payload), customSeries, this.group, data);
      el.traverse(setIncrementalAndHoverLayer);
    }
  };

  CustomSeriesView.prototype.filterForExposedEvent = function (eventType, query, targetEl, packedEvent) {
    var elementName = query.element;

    if (elementName == null || targetEl.name === elementName) {
      return true;
    }

    while ((targetEl = targetEl.parent) && targetEl !== this.group) {
      if (targetEl.name === elementName) {
        return true;
      }
    }

    return false;
  };

  CustomSeriesView.type = 'custom';
  return CustomSeriesView;
}(ChartView);

ChartView.registerClass(CustomSeriesView);

function createEl(elOption) {
  var graphicType = elOption.type;
  var el;

  if (graphicType === 'path') {
    var shape = elOption.shape;
    var pathRect = shape.width != null && shape.height != null ? {
      x: shape.x || 0,
      y: shape.y || 0,
      width: shape.width,
      height: shape.height
    } : null;
    var pathData = getPathData(shape);
    el = graphicUtil.makePath(pathData, null, pathRect, shape.layout || 'center');
    inner(el).customPathData = pathData;
  } else if (graphicType === 'image') {
    el = new graphicUtil.Image({});
    inner(el).customImagePath = elOption.style.image;
  } else if (graphicType === 'text') {
    el = new graphicUtil.Text({});
  } else if (graphicType === 'group') {
    el = new graphicUtil.Group();
  } else if (graphicType === 'compoundPath') {
    throw new Error('"compoundPath" is not supported yet.');
  } else {
    var Clz = graphicUtil.getShapeClass(graphicType);

    if (process.env.NODE_ENV !== 'production') {
      assert(Clz, 'graphic type "' + graphicType + '" can not be found.');
    }

    el = new Clz();
  }

  inner(el).customGraphicType = graphicType;
  el.name = elOption.name;
  el.z2EmphasisLift = 1;
  el.z2SelectLift = 1;
  return el;
}

function updateElNormal(el, dataIndex, elOption, styleOpt, attachedTxInfo, seriesModel, isInit, isTextContent) {
  var transFromProps = {};
  var allProps = {};
  var elDisplayable = el.isGroup ? null : el;
  prepareShapeOrExtraUpdate('shape', el, elOption, allProps, transFromProps, isInit);
  prepareShapeOrExtraUpdate('extra', el, elOption, allProps, transFromProps, isInit);
  prepareTransformUpdate(el, elOption, allProps, transFromProps, isInit);
  var txCfgOpt = attachedTxInfo && attachedTxInfo.normal.cfg;

  if (txCfgOpt) {
    el.setTextConfig(txCfgOpt);
  }

  if (el.type === 'text' && styleOpt) {
    var textOptionStyle = styleOpt;
    hasOwn(textOptionStyle, 'textFill') && (textOptionStyle.fill = textOptionStyle.textFill);
    hasOwn(textOptionStyle, 'textStroke') && (textOptionStyle.stroke = textOptionStyle.textStroke);
  }

  prepareStyleUpdate(el, styleOpt, transFromProps, isInit);

  if (elDisplayable) {
    styleOpt && elDisplayable.useStyle(styleOpt);
    var animators = elDisplayable.animators;

    for (var i = 0; i < animators.length; i++) {
      var animator = animators[i];

      if (animator.targetName === 'style') {
        animator.changeTarget(elDisplayable.style);
      }
    }

    hasOwn(elOption, 'invisible') && (elDisplayable.invisible = elOption.invisible);
  }

  var userDuring = elOption.during;
  inner(el).userDuring = userDuring;
  var cfgDuringCall = userDuring ? bind(duringCall, {
    el: el,
    userDuring: userDuring
  }) : null;
  el.attr(allProps);
  var cfg = {
    dataIndex: dataIndex,
    isFrom: true,
    during: cfgDuringCall
  };
  isInit ? graphicUtil.initProps(el, transFromProps, seriesModel, cfg) : graphicUtil.updateProps(el, transFromProps, seriesModel, cfg);
  hasOwn(elOption, 'silent') && (el.silent = elOption.silent);
  hasOwn(elOption, 'ignore') && (el.ignore = elOption.ignore);

  if (!isTextContent) {
    hasOwn(elOption, 'info') && (inner(el).info = elOption.info);
  }

  styleOpt ? el.dirty() : el.markRedraw();
}

function prepareShapeOrExtraUpdate(mainAttr, el, elOption, allProps, transFromProps, isInit) {
  var attrOpt = elOption[mainAttr];

  if (!attrOpt) {
    return;
  }

  var elPropsInAttr = el[mainAttr];
  var transFromPropsInAttr;
  var enterFrom = attrOpt.enterFrom;

  if (isInit && enterFrom) {
    !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
    var enterFromKeys = keys(enterFrom);

    for (var i = 0; i < enterFromKeys.length; i++) {
      var key = enterFromKeys[i];
      transFromPropsInAttr[key] = enterFrom[key];
    }
  }

  if (!isInit && elPropsInAttr && attrOpt.transition) {
    !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
    var transitionKeys = normalizeToArray(attrOpt.transition);

    for (var i = 0; i < transitionKeys.length; i++) {
      var key = transitionKeys[i];
      var elVal = elPropsInAttr[key];

      if (process.env.NODE_ENV !== 'production') {
        checkTansitionRefer(key, attrOpt[key], elVal);
      }

      transFromPropsInAttr[key] = elVal;
    }
  }

  var allPropsInAttr = allProps[mainAttr] = {};
  var keysInAttr = keys(attrOpt);

  for (var i = 0; i < keysInAttr.length; i++) {
    var key = keysInAttr[i];
    allPropsInAttr[key] = cloneValue(attrOpt[key]);
  }

  var leaveTo = attrOpt.leaveTo;

  if (leaveTo) {
    var leaveToProps = getOrCreateLeaveToPropsFromEl(el);
    var leaveToPropsInAttr = leaveToProps[mainAttr] || (leaveToProps[mainAttr] = {});
    var leaveToKeys = keys(leaveTo);

    for (var i = 0; i < leaveToKeys.length; i++) {
      var key = leaveToKeys[i];
      leaveToPropsInAttr[key] = leaveTo[key];
    }
  }
}

function prepareTransformUpdate(el, elOption, allProps, transFromProps, isInit) {
  var enterFrom = elOption.enterFrom;

  if (isInit && enterFrom) {
    var enterFromKeys = keys(enterFrom);

    for (var i = 0; i < enterFromKeys.length; i++) {
      var key = enterFromKeys[i];

      if (process.env.NODE_ENV !== 'production') {
        checkTransformPropRefer(key, 'el.enterFrom');
      }

      transFromProps[key] = enterFrom[key];
    }
  }

  if (!isInit) {
    if (elOption.transition) {
      var transitionKeys = normalizeToArray(elOption.transition);

      for (var i = 0; i < transitionKeys.length; i++) {
        var key = transitionKeys[i];
        var elVal = el[key];

        if (process.env.NODE_ENV !== 'production') {
          checkTransformPropRefer(key, 'el.transition');
          checkTansitionRefer(key, elOption[key], elVal);
        }

        transFromProps[key] = elVal;
      }
    } else {
      setLagecyProp(elOption, transFromProps, 'position', el);
      setTransProp(elOption, transFromProps, 'x', el);
      setTransProp(elOption, transFromProps, 'y', el);
    }
  }

  setLagecyProp(elOption, allProps, 'position');
  setLagecyProp(elOption, allProps, 'scale');
  setLagecyProp(elOption, allProps, 'origin');
  setTransProp(elOption, allProps, 'x');
  setTransProp(elOption, allProps, 'y');
  setTransProp(elOption, allProps, 'scaleX');
  setTransProp(elOption, allProps, 'scaleY');
  setTransProp(elOption, allProps, 'originX');
  setTransProp(elOption, allProps, 'originY');
  setTransProp(elOption, allProps, 'rotation');
  var leaveTo = elOption.leaveTo;

  if (leaveTo) {
    var leaveToProps = getOrCreateLeaveToPropsFromEl(el);
    var leaveToKeys = keys(leaveTo);

    for (var i = 0; i < leaveToKeys.length; i++) {
      var key = leaveToKeys[i];

      if (process.env.NODE_ENV !== 'production') {
        checkTransformPropRefer(key, 'el.leaveTo');
      }

      leaveToProps[key] = leaveTo[key];
    }
  }
}

function prepareStyleUpdate(el, styleOpt, transFromProps, isInit) {
  if (!styleOpt) {
    return;
  }

  var elStyle = el.style;
  var transFromStyleProps;
  var enterFrom = styleOpt.enterFrom;

  if (isInit && enterFrom) {
    var enterFromKeys = keys(enterFrom);
    !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});

    for (var i = 0; i < enterFromKeys.length; i++) {
      var key = enterFromKeys[i];
      transFromStyleProps[key] = enterFrom[key];
    }
  }

  if (!isInit && elStyle && styleOpt.transition) {
    var transitionKeys = normalizeToArray(styleOpt.transition);
    !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});

    for (var i = 0; i < transitionKeys.length; i++) {
      var key = transitionKeys[i];
      var elVal = elStyle[key];

      if (process.env.NODE_ENV !== 'production') {
        checkTansitionRefer(key, styleOpt[key], elVal);
      }

      transFromStyleProps[key] = elVal;
    }
  }

  var leaveTo = styleOpt.leaveTo;

  if (leaveTo) {
    var leaveToKeys = keys(leaveTo);
    var leaveToProps = getOrCreateLeaveToPropsFromEl(el);
    var leaveToStyleProps = leaveToProps.style || (leaveToProps.style = {});

    for (var i = 0; i < leaveToKeys.length; i++) {
      var key = leaveToKeys[i];
      leaveToStyleProps[key] = leaveTo[key];
    }
  }
}

function checkTansitionRefer(propName, optVal, elVal) {
  var isArrLike = isArrayLike(optVal);
  assert(isArrLike || optVal != null && isFinite(optVal), 'Prop `' + propName + '` must refer to a finite number or ArrayLike for transition.');
  assert(!isArrLike || optVal !== elVal, 'Prop `' + propName + '` must use different Array object each time for transition.');
}

function checkTransformPropRefer(key, usedIn) {
  assert(hasOwn(TRANSFORM_PROPS, key), 'Prop `' + key + '` is not a permitted in `' + usedIn + '`. ' + 'Only `' + keys(TRANSFORM_PROPS).join('`, `') + '` are permitted.');
}

function getOrCreateLeaveToPropsFromEl(el) {
  var innerEl = inner(el);
  return innerEl.leaveToProps || (innerEl.leaveToProps = {});
}

var tmpDuringScope = {};
var customDuringAPI = {
  setTransform: function (key, val) {
    if (process.env.NODE_ENV !== 'production') {
      assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
    }

    tmpDuringScope.el[key] = val;
    return this;
  },
  getTransform: function (key) {
    if (process.env.NODE_ENV !== 'production') {
      assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
    }

    return tmpDuringScope.el[key];
  },
  setShape: function (key, val) {
    if (process.env.NODE_ENV !== 'production') {
      assertNotReserved(key);
    }

    var shape = tmpDuringScope.el.shape || (tmpDuringScope.el.shape = {});
    shape[key] = val;
    tmpDuringScope.isShapeDirty = true;
    return this;
  },
  getShape: function (key) {
    if (process.env.NODE_ENV !== 'production') {
      assertNotReserved(key);
    }

    var shape = tmpDuringScope.el.shape;

    if (shape) {
      return shape[key];
    }
  },
  setStyle: function (key, val) {
    if (process.env.NODE_ENV !== 'production') {
      assertNotReserved(key);
    }

    var style = tmpDuringScope.el.style;

    if (style) {
      style[key] = val;
      tmpDuringScope.isStyleDirty = true;
    }

    return this;
  },
  getStyle: function (key) {
    if (process.env.NODE_ENV !== 'production') {
      assertNotReserved(key);
    }

    var style = tmpDuringScope.el.style;

    if (style) {
      return style[key];
    }
  },
  setExtra: function (key, val) {
    if (process.env.NODE_ENV !== 'production') {
      assertNotReserved(key);
    }

    var extra = tmpDuringScope.el.extra || (tmpDuringScope.el.extra = {});
    extra[key] = val;
    return this;
  },
  getExtra: function (key) {
    if (process.env.NODE_ENV !== 'production') {
      assertNotReserved(key);
    }

    var extra = tmpDuringScope.el.extra;

    if (extra) {
      return extra[key];
    }
  }
};

function assertNotReserved(key) {
  if (process.env.NODE_ENV !== 'production') {
    if (key === 'transition' || key === 'enterFrom' || key === 'leaveTo') {
      throw new Error('key must not be "' + key + '"');
    }
  }
}

function duringCall() {
  var scope = this;
  var el = scope.el;

  if (!el) {
    return;
  }

  var newstUserDuring = inner(el).userDuring;
  var scopeUserDuring = scope.userDuring;

  if (newstUserDuring !== scopeUserDuring) {
    scope.el = scope.userDuring = null;
    return;
  }

  tmpDuringScope.el = el;
  tmpDuringScope.isShapeDirty = false;
  tmpDuringScope.isStyleDirty = false;
  scopeUserDuring(customDuringAPI);

  if (tmpDuringScope.isShapeDirty && el.dirtyShape) {
    el.dirtyShape();
  }

  if (tmpDuringScope.isStyleDirty && el.dirtyStyle) {
    el.dirtyStyle();
  }
}

function updateElOnState(state, el, elStateOpt, styleOpt, attachedTxInfo, isRoot, isTextContent) {
  var elDisplayable = el.isGroup ? null : el;
  var txCfgOpt = attachedTxInfo && attachedTxInfo[state].cfg;

  if (elDisplayable) {
    var stateObj = elDisplayable.ensureState(state);

    if (styleOpt === false) {
      var existingEmphasisState = elDisplayable.getState(state);

      if (existingEmphasisState) {
        existingEmphasisState.style = null;
      }
    } else {
      stateObj.style = styleOpt || null;
    }

    if (txCfgOpt) {
      stateObj.textConfig = txCfgOpt;
    }

    setDefaultStateProxy(elDisplayable);
  }
}

function updateZ(el, elOption, seriesModel, attachedTxInfo) {
  if (el.isGroup) {
    return;
  }

  var elDisplayable = el;
  var currentZ = seriesModel.currentZ;
  var currentZLevel = seriesModel.currentZLevel;
  elDisplayable.z = currentZ;
  elDisplayable.zlevel = currentZLevel;
  var optZ2 = elOption.z2;
  optZ2 != null && (elDisplayable.z2 = optZ2 || 0);

  for (var i = 0; i < STATES.length; i++) {
    updateZForEachState(elDisplayable, elOption, STATES[i]);
  }
}

function updateZForEachState(elDisplayable, elOption, state) {
  var isNormal = state === NORMAL;
  var elStateOpt = isNormal ? elOption : retrieveStateOption(elOption, state);
  var optZ2 = elStateOpt ? elStateOpt.z2 : null;
  var stateObj;

  if (optZ2 != null) {
    stateObj = isNormal ? elDisplayable : elDisplayable.ensureState(state);
    stateObj.z2 = optZ2 || 0;
  }
}

function setLagecyProp(elOption, targetProps, legacyName, fromEl) {
  var legacyArr = elOption[legacyName];
  var xyName = LEGACY_TRANSFORM_PROPS[legacyName];

  if (legacyArr) {
    if (fromEl) {
      targetProps[xyName[0]] = fromEl[xyName[0]];
      targetProps[xyName[1]] = fromEl[xyName[1]];
    } else {
      targetProps[xyName[0]] = legacyArr[0];
      targetProps[xyName[1]] = legacyArr[1];
    }
  }
}

function setTransProp(elOption, targetProps, name, fromEl) {
  if (elOption[name] != null) {
    targetProps[name] = fromEl ? fromEl[name] : elOption[name];
  }
}

function makeRenderItem(customSeries, data, ecModel, api) {
  var renderItem = customSeries.get('renderItem');
  var coordSys = customSeries.coordinateSystem;
  var prepareResult = {};

  if (coordSys) {
    if (process.env.NODE_ENV !== 'production') {
      assert(renderItem, 'series.render is required.');
      assert(coordSys.prepareCustoms || prepareCustoms[coordSys.type], 'This coordSys does not support custom series.');
    }

    prepareResult = coordSys.prepareCustoms ? coordSys.prepareCustoms(coordSys) : prepareCustoms[coordSys.type](coordSys);
  }

  var userAPI = defaults({
    getWidth: api.getWidth,
    getHeight: api.getHeight,
    getZr: api.getZr,
    getDevicePixelRatio: api.getDevicePixelRatio,
    value: value,
    style: style,
    styleEmphasis: styleEmphasis,
    visual: visual,
    barLayout: barLayout,
    currentSeriesIndices: currentSeriesIndices,
    font: font
  }, prepareResult.api || {});
  var userParams = {
    context: {},
    seriesId: customSeries.id,
    seriesName: customSeries.name,
    seriesIndex: customSeries.seriesIndex,
    coordSys: prepareResult.coordSys,
    dataInsideLength: data.count(),
    encode: wrapEncodeDef(customSeries.getData())
  };
  var currDataIndexInside;
  var currItemModel;
  var currItemStyleModels = {};
  var currLabelModels = {};
  var seriesItemStyleModels = {};
  var seriesLabelModels = {};

  for (var i = 0; i < STATES.length; i++) {
    var stateName = STATES[i];
    seriesItemStyleModels[stateName] = customSeries.getModel(PATH_ITEM_STYLE[stateName]);
    seriesLabelModels[stateName] = customSeries.getModel(PATH_LABEL[stateName]);
  }

  function getItemModel(dataIndexInside) {
    return dataIndexInside === currDataIndexInside ? currItemModel || (currItemModel = data.getItemModel(dataIndexInside)) : data.getItemModel(dataIndexInside);
  }

  function getItemStyleModel(dataIndexInside, state) {
    return !data.hasItemOption ? seriesItemStyleModels[state] : dataIndexInside === currDataIndexInside ? currItemStyleModels[state] || (currItemStyleModels[state] = getItemModel(dataIndexInside).getModel(PATH_ITEM_STYLE[state])) : getItemModel(dataIndexInside).getModel(PATH_ITEM_STYLE[state]);
  }

  function getLabelModel(dataIndexInside, state) {
    return !data.hasItemOption ? seriesLabelModels[state] : dataIndexInside === currDataIndexInside ? currLabelModels[state] || (currLabelModels[state] = getItemModel(dataIndexInside).getModel(PATH_LABEL[state])) : getItemModel(dataIndexInside).getModel(PATH_LABEL[state]);
  }

  return function (dataIndexInside, payload) {
    currDataIndexInside = dataIndexInside;
    currItemModel = null;
    currItemStyleModels = {};
    currLabelModels = {};
    return renderItem && renderItem(defaults({
      dataIndexInside: dataIndexInside,
      dataIndex: data.getRawIndex(dataIndexInside),
      actionType: payload ? payload.type : null
    }, userParams), userAPI);
  };

  function value(dim, dataIndexInside) {
    dataIndexInside == null && (dataIndexInside = currDataIndexInside);
    return data.get(data.getDimension(dim || 0), dataIndexInside);
  }

  function style(userProps, dataIndexInside) {
    if (process.env.NODE_ENV !== 'production') {
      warnDeprecated('api.style', 'Please write literal style directly instead.');
    }

    dataIndexInside == null && (dataIndexInside = currDataIndexInside);
    var style = data.getItemVisual(dataIndexInside, 'style');
    var visualColor = style && style.fill;
    var opacity = style && style.opacity;
    var itemStyle = getItemStyleModel(dataIndexInside, NORMAL).getItemStyle();
    visualColor != null && (itemStyle.fill = visualColor);
    opacity != null && (itemStyle.opacity = opacity);
    var opt = {
      inheritColor: isString(visualColor) ? visualColor : '#000'
    };
    var labelModel = getLabelModel(dataIndexInside, NORMAL);
    var textStyle = labelStyleHelper.createTextStyle(labelModel, null, opt, false, true);
    textStyle.text = labelModel.getShallow('show') ? retrieve2(customSeries.getFormattedLabel(dataIndexInside, NORMAL), getDefaultLabel(data, dataIndexInside)) : null;
    var textConfig = labelStyleHelper.createTextConfig(labelModel, opt, false);
    preFetchFromExtra(userProps, itemStyle);
    itemStyle = convertToEC4StyleForCustomSerise(itemStyle, textStyle, textConfig);
    userProps && applyUserPropsAfter(itemStyle, userProps);
    itemStyle.legacy = true;
    return itemStyle;
  }

  function styleEmphasis(userProps, dataIndexInside) {
    if (process.env.NODE_ENV !== 'production') {
      warnDeprecated('api.styleEmphasis', 'Please write literal style directly instead.');
    }

    dataIndexInside == null && (dataIndexInside = currDataIndexInside);
    var itemStyle = getItemStyleModel(dataIndexInside, EMPHASIS).getItemStyle();
    var labelModel = getLabelModel(dataIndexInside, EMPHASIS);
    var textStyle = labelStyleHelper.createTextStyle(labelModel, null, null, true, true);
    textStyle.text = labelModel.getShallow('show') ? retrieve3(customSeries.getFormattedLabel(dataIndexInside, EMPHASIS), customSeries.getFormattedLabel(dataIndexInside, NORMAL), getDefaultLabel(data, dataIndexInside)) : null;
    var textConfig = labelStyleHelper.createTextConfig(labelModel, null, true);
    preFetchFromExtra(userProps, itemStyle);
    itemStyle = convertToEC4StyleForCustomSerise(itemStyle, textStyle, textConfig);
    userProps && applyUserPropsAfter(itemStyle, userProps);
    itemStyle.legacy = true;
    return itemStyle;
  }

  function applyUserPropsAfter(itemStyle, extra) {
    for (var key in extra) {
      if (hasOwn(extra, key)) {
        itemStyle[key] = extra[key];
      }
    }
  }

  function preFetchFromExtra(extra, itemStyle) {
    if (extra) {
      extra.textFill && (itemStyle.textFill = extra.textFill);
      extra.textPosition && (itemStyle.textPosition = extra.textPosition);
    }
  }

  function visual(visualType, dataIndexInside) {
    dataIndexInside == null && (dataIndexInside = currDataIndexInside);

    if (hasOwn(STYLE_VISUAL_TYPE, visualType)) {
      var style_1 = data.getItemVisual(dataIndexInside, 'style');
      return style_1 ? style_1[STYLE_VISUAL_TYPE[visualType]] : null;
    }

    if (hasOwn(VISUAL_PROPS, visualType)) {
      return data.getItemVisual(dataIndexInside, visualType);
    }
  }

  function barLayout(opt) {
    if (coordSys.type === 'cartesian2d') {
      var baseAxis = coordSys.getBaseAxis();
      return getLayoutOnAxis(defaults({
        axis: baseAxis
      }, opt));
    }
  }

  function currentSeriesIndices() {
    return ecModel.getCurrentSeriesIndices();
  }

  function font(opt) {
    return labelStyleHelper.getFont(opt, ecModel);
  }
}

function wrapEncodeDef(data) {
  var encodeDef = {};
  each(data.dimensions, function (dimName, dataDimIndex) {
    var dimInfo = data.getDimensionInfo(dimName);

    if (!dimInfo.isExtraCoord) {
      var coordDim = dimInfo.coordDim;
      var dataDims = encodeDef[coordDim] = encodeDef[coordDim] || [];
      dataDims[dimInfo.coordDimIndex] = dataDimIndex;
    }
  });
  return encodeDef;
}

function createOrUpdateItem(el, dataIndex, elOption, seriesModel, group, data) {
  if (!elOption) {
    el && group.remove(el);
    return;
  }

  el = doCreateOrUpdateEl(el, dataIndex, elOption, seriesModel, group, true);
  el && data.setItemGraphicEl(dataIndex, el);
  enableHoverEmphasis(el, elOption.focus, elOption.blurScope);
  return el;
}

function doCreateOrUpdateEl(el, dataIndex, elOption, seriesModel, group, isRoot) {
  if (process.env.NODE_ENV !== 'production') {
    assert(elOption, 'should not have an null/undefined element setting');
  }

  var toBeReplacedIdx = -1;

  if (el && doesElNeedRecreate(el, elOption)) {
    toBeReplacedIdx = group.childrenRef().indexOf(el);
    el = null;
  }

  var isInit = !el;

  if (!el) {
    el = createEl(elOption);
  } else {
    el.clearStates();
  }

  attachedTxInfoTmp.normal.cfg = attachedTxInfoTmp.normal.conOpt = attachedTxInfoTmp.emphasis.cfg = attachedTxInfoTmp.emphasis.conOpt = attachedTxInfoTmp.blur.cfg = attachedTxInfoTmp.blur.conOpt = attachedTxInfoTmp.select.cfg = attachedTxInfoTmp.select.conOpt = null;
  attachedTxInfoTmp.isLegacy = false;
  doCreateOrUpdateAttachedTx(el, dataIndex, elOption, seriesModel, isInit, attachedTxInfoTmp);
  doCreateOrUpdateClipPath(el, dataIndex, elOption, seriesModel, isInit);
  updateElNormal(el, dataIndex, elOption, elOption.style, attachedTxInfoTmp, seriesModel, isInit, false);

  for (var i = 0; i < STATES.length; i++) {
    var stateName = STATES[i];

    if (stateName !== NORMAL) {
      var otherStateOpt = retrieveStateOption(elOption, stateName);
      var otherStyleOpt = retrieveStyleOptionOnState(elOption, otherStateOpt, stateName);
      updateElOnState(stateName, el, otherStateOpt, otherStyleOpt, attachedTxInfoTmp, isRoot, false);
    }
  }

  updateZ(el, elOption, seriesModel, attachedTxInfoTmp);

  if (elOption.type === 'group') {
    mergeChildren(el, dataIndex, elOption, seriesModel);
  }

  if (toBeReplacedIdx >= 0) {
    group.replaceAt(el, toBeReplacedIdx);
  } else {
    group.add(el);
  }

  return el;
}

function doesElNeedRecreate(el, elOption) {
  var elInner = inner(el);
  var elOptionType = elOption.type;
  var elOptionShape = elOption.shape;
  var elOptionStyle = elOption.style;
  return elOptionType != null && elOptionType !== elInner.customGraphicType || elOptionType === 'path' && hasOwnPathData(elOptionShape) && getPathData(elOptionShape) !== elInner.customPathData || elOptionType === 'image' && hasOwn(elOptionStyle, 'image') && elOptionStyle.image !== elInner.customImagePath;
}

function doCreateOrUpdateClipPath(el, dataIndex, elOption, seriesModel, isInit) {
  var clipPathOpt = elOption.clipPath;

  if (clipPathOpt === false) {
    if (el && el.getClipPath()) {
      el.removeClipPath();
    }
  } else if (clipPathOpt) {
    var clipPath = el.getClipPath();

    if (clipPath && doesElNeedRecreate(clipPath, clipPathOpt)) {
      clipPath = null;
    }

    if (!clipPath) {
      clipPath = createEl(clipPathOpt);

      if (process.env.NODE_ENV !== 'production') {
        assert(clipPath instanceof graphicUtil.Path, 'Only any type of `path` can be used in `clipPath`, rather than ' + clipPath.type + '.');
      }

      el.setClipPath(clipPath);
    }

    updateElNormal(clipPath, dataIndex, clipPathOpt, null, null, seriesModel, isInit, false);
  }
}

function doCreateOrUpdateAttachedTx(el, dataIndex, elOption, seriesModel, isInit, attachedTxInfo) {
  if (el.isGroup) {
    return;
  }

  processTxInfo(elOption, null, attachedTxInfo);
  processTxInfo(elOption, EMPHASIS, attachedTxInfo);
  var txConOptNormal = attachedTxInfo.normal.conOpt;
  var txConOptEmphasis = attachedTxInfo.emphasis.conOpt;
  var txConOptBlur = attachedTxInfo.blur.conOpt;
  var txConOptSelect = attachedTxInfo.select.conOpt;

  if (txConOptNormal != null || txConOptEmphasis != null || txConOptSelect != null || txConOptBlur != null) {
    var textContent = el.getTextContent();

    if (txConOptNormal === false) {
      textContent && el.removeTextContent();
    } else {
      txConOptNormal = attachedTxInfo.normal.conOpt = txConOptNormal || {
        type: 'text'
      };

      if (!textContent) {
        textContent = createEl(txConOptNormal);
        el.setTextContent(textContent);
      } else {
        textContent.clearStates();
      }

      var txConStlOptNormal = txConOptNormal && txConOptNormal.style;
      updateElNormal(textContent, dataIndex, txConOptNormal, txConStlOptNormal, null, seriesModel, isInit, true);

      for (var i = 0; i < STATES.length; i++) {
        var stateName = STATES[i];

        if (stateName !== NORMAL) {
          var txConOptOtherState = attachedTxInfo[stateName].conOpt;
          updateElOnState(stateName, textContent, txConOptOtherState, retrieveStyleOptionOnState(txConOptNormal, txConOptOtherState, stateName), null, false, true);
        }
      }

      txConStlOptNormal ? textContent.dirty() : textContent.markRedraw();
    }
  }
}

function processTxInfo(elOption, state, attachedTxInfo) {
  var stateOpt = !state ? elOption : retrieveStateOption(elOption, state);
  var styleOpt = !state ? elOption.style : retrieveStyleOptionOnState(elOption, stateOpt, EMPHASIS);
  var elType = elOption.type;
  var txCfg = stateOpt ? stateOpt.textConfig : null;
  var txConOptNormal = elOption.textContent;
  var txConOpt = !txConOptNormal ? null : !state ? txConOptNormal : retrieveStateOption(txConOptNormal, state);

  if (styleOpt && (attachedTxInfo.isLegacy || isEC4CompatibleStyle(styleOpt, elType, !!txCfg, !!txConOpt))) {
    attachedTxInfo.isLegacy = true;
    var convertResult = convertFromEC4CompatibleStyle(styleOpt, elType, !state);

    if (!txCfg && convertResult.textConfig) {
      txCfg = convertResult.textConfig;
    }

    if (!txConOpt && convertResult.textContent) {
      txConOpt = convertResult.textContent;
    }
  }

  if (!state && txConOpt) {
    var txConOptNormal_1 = txConOpt;
    !txConOptNormal_1.type && (txConOptNormal_1.type = 'text');

    if (process.env.NODE_ENV !== 'production') {
      txConOptNormal_1.type !== 'text' && assert(txConOptNormal_1.type === 'text', 'textContent.type must be "text"');
    }
  }

  var info = !state ? attachedTxInfo.normal : attachedTxInfo[state];
  info.cfg = txCfg;
  info.conOpt = txConOpt;
}

function retrieveStateOption(elOption, state) {
  return !state ? elOption : elOption ? elOption[state] : null;
}

function retrieveStyleOptionOnState(stateOptionNormal, stateOption, state) {
  var style = stateOption && stateOption.style;

  if (style == null && state === EMPHASIS && stateOptionNormal) {
    style = stateOptionNormal.styleEmphasis;
  }

  return style;
}

function mergeChildren(el, dataIndex, elOption, seriesModel) {
  var newChildren = elOption.children;
  var newLen = newChildren ? newChildren.length : 0;
  var mergeChildren = elOption.$mergeChildren;
  var byName = mergeChildren === 'byName' || elOption.diffChildrenByName;
  var notMerge = mergeChildren === false;

  if (!newLen && !byName && !notMerge) {
    return;
  }

  if (byName) {
    diffGroupChildren({
      oldChildren: el.children() || [],
      newChildren: newChildren || [],
      dataIndex: dataIndex,
      seriesModel: seriesModel,
      group: el
    });
    return;
  }

  notMerge && el.removeAll();
  var index = 0;

  for (; index < newLen; index++) {
    newChildren[index] && doCreateOrUpdateEl(el.childAt(index), dataIndex, newChildren[index], seriesModel, el, false);
  }

  for (var i = el.childCount() - 1; i >= index; i--) {
    doRemoveEl(el.childAt(i), seriesModel, el);
  }
}

function diffGroupChildren(context) {
  new DataDiffer(context.oldChildren, context.newChildren, getKey, getKey, context).add(processAddUpdate).update(processAddUpdate).remove(processRemove).execute();
}

function getKey(item, idx) {
  var name = item && item.name;
  return name != null ? name : GROUP_DIFF_PREFIX + idx;
}

function processAddUpdate(newIndex, oldIndex) {
  var context = this.context;
  var childOption = newIndex != null ? context.newChildren[newIndex] : null;
  var child = oldIndex != null ? context.oldChildren[oldIndex] : null;
  doCreateOrUpdateEl(child, context.dataIndex, childOption, context.seriesModel, context.group, false);
}

function processRemove(oldIndex) {
  var context = this.context;
  var child = context.oldChildren[oldIndex];
  doRemoveEl(child, context.seriesModel, context.group);
}

function doRemoveEl(el, seriesModel, group) {
  if (el) {
    var leaveToProps = inner(el).leaveToProps;
    leaveToProps ? graphicUtil.updateProps(el, leaveToProps, seriesModel, {
      cb: function () {
        group.remove(el);
      }
    }) : group.remove(el);
  }
}

function getPathData(shape) {
  return shape && (shape.pathData || shape.d);
}

function hasOwnPathData(shape) {
  return shape && (hasOwn(shape, 'pathData') || hasOwn(shape, 'd'));
}