text: /*
  * 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 * as graphic from '../../util/graphic';
  import * as layout from '../../util/layout';
  import * as zrUtil from '@ftf/zrender/src/core/util';
  import {wrapTreePathInfo} from '../helper/treeHelper';
  
  var TEXT_PADDING = 8;
  var ITEM_GAP = 8;
  var ARRAY_LENGTH = 5;
  
  function Breadcrumb(containerGroup) {
      /**
       * @private
       * @type {module:zrender/container/Group}
       */
      this.group = new graphic.Group();
  
      containerGroup.add(this.group);
  }
  
  Breadcrumb.prototype = {
  
      constructor: Breadcrumb,
  
      render: function (seriesModel, api, targetNode, onSelect) {
          var model = seriesModel.getModel('breadcrumb');
          var thisGroup = this.group;
  
          thisGroup.removeAll();
  
          if (!model.get('show') || !targetNode) {
              return;
          }
  
          var normalStyleModel = model.getModel('itemStyle');
          // var emphasisStyleModel = model.getModel('emphasis.itemStyle');
          var textStyleModel = normalStyleModel.getModel('textStyle');
  
          var layoutParam = {
              pos: {
                  left: model.get('left'),
                  right: model.get('right'),
                  top: model.get('top'),
                  bottom: model.get('bottom')
              },
              box: {
                  width: api.getWidth(),
                  height: api.getHeight()
              },
              emptyItemWidth: model.get('emptyItemWidth'),
              totalWidth: 0,
              renderList: []
          };
  
          this._prepare(targetNode, layoutParam, textStyleModel);
          this._renderContent(seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect);
  
          layout.positionElement(thisGroup, layoutParam.pos, layoutParam.box);
      },
  
      /**
       * Prepare render list and total width
       * @private
       */
      _prepare: function (targetNode, layoutParam, textStyleModel) {
          for (var node = targetNode; node; node = node.parentNode) {
              var text = node.getModel().get('name');
              var textRect = textStyleModel.getTextRect(text);
              var itemWidth = Math.max(
                  textRect.width + TEXT_PADDING * 2,
                  layoutParam.emptyItemWidth
              );
              layoutParam.totalWidth += itemWidth + ITEM_GAP;
              layoutParam.renderList.push({node: node, text: text, width: itemWidth});
          }
      },
  
      /**
       * @private
       */
      _renderContent: function (
          seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect
      ) {
          // Start rendering.
          var lastX = 0;
          var emptyItemWidth = layoutParam.emptyItemWidth;
          var height = seriesModel.get('breadcrumb.height');
          var availableSize = layout.getAvailableSize(layoutParam.pos, layoutParam.box);
          var totalWidth = layoutParam.totalWidth;
          var renderList = layoutParam.renderList;
  
          for (var i = renderList.length - 1; i >= 0; i--) {
              var item = renderList[i];
              var itemNode = item.node;
              var itemWidth = item.width;
              var text = item.text;
  
              // Hdie text and shorten width if necessary.
              if (totalWidth > availableSize.width) {
                  totalWidth -= itemWidth - emptyItemWidth;
                  itemWidth = emptyItemWidth;
                  text = null;
              }
  
              var el = new graphic.Polygon({
                  shape: {
                      points: makeItemPoints(
                          lastX, 0, itemWidth, height,
                          i === renderList.length - 1, i === 0
                      )
                  },
                  style: zrUtil.defaults(
                      normalStyleModel.getItemStyle(),
                      {
                          lineJoin: 'bevel',
                          text: text,
                          textFill: textStyleModel.getTextColor(),
                          textFont: textStyleModel.getFont()
                      }
                  ),
                  z: 10,
                  onclick: zrUtil.curry(onSelect, itemNode)
              });
              this.group.add(el);
  
              packEventData(el, seriesModel, itemNode);
  
              lastX += itemWidth + ITEM_GAP;
          }
      },
  
      /**
       * @override
       */
      remove: function () {
          this.group.removeAll();
      }
  };
  
  function makeItemPoints(x, y, itemWidth, itemHeight, head, tail) {
      var points = [
          [head ? x : x - ARRAY_LENGTH, y],
          [x + itemWidth, y],
          [x + itemWidth, y + itemHeight],
          [head ? x : x - ARRAY_LENGTH, y + itemHeight]
      ];
      !tail && points.splice(2, 0, [x + itemWidth + ARRAY_LENGTH, y + itemHeight / 2]);
      !head && points.push([x, y + itemHeight / 2]);
      return points;
  }
  
  // Package custom mouse event.
  function packEventData(el, seriesModel, itemNode) {
      el.eventData = {
          componentType: 'series',
          componentSubType: 'treemap',
          componentIndex: seriesModel.componentIndex,
          seriesIndex: seriesModel.componentIndex,
          seriesName: seriesModel.name,
          seriesType: 'treemap',
          selfType: 'breadcrumb', // Distinguish with click event on treemap node.
          nodeData: {
              dataIndex: itemNode && itemNode.dataIndex,
              name: itemNode && itemNode.name
          },
          treePathInfo: itemNode && wrapTreePathInfo(itemNode, seriesModel)
      };
  }
  
  export default Breadcrumb;