| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965 | 
/** 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 { bind, each, indexOf, curry, extend, normalizeCssArray, isFunction } from 'zrender/lib/core/util.js';import * as graphic from '../../util/graphic.js';import { getECData } from '../../util/innerStore.js';import { isHighDownDispatcher, setAsHighDownDispatcher, setDefaultStateProxy, enableHoverFocus, Z2_EMPHASIS_LIFT } from '../../util/states.js';import DataDiffer from '../../data/DataDiffer.js';import * as helper from '../helper/treeHelper.js';import Breadcrumb from './Breadcrumb.js';import RoamController from '../../component/helper/RoamController.js';import BoundingRect from 'zrender/lib/core/BoundingRect.js';import * as matrix from 'zrender/lib/core/matrix.js';import * as animationUtil from '../../util/animation.js';import makeStyleMapper from '../../model/mixin/makeStyleMapper.js';import ChartView from '../../view/Chart.js';import Displayable from 'zrender/lib/graphic/Displayable.js';import { makeInner, convertOptionIdName } from '../../util/model.js';import { windowOpen } from '../../util/format.js';import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle.js';var Group = graphic.Group;var Rect = graphic.Rect;var DRAG_THRESHOLD = 3;var PATH_LABEL_NOAMAL = 'label';var PATH_UPPERLABEL_NORMAL = 'upperLabel'; // Should larger than emphasis states lift zvar Z2_BASE = Z2_EMPHASIS_LIFT * 10; // Should bigger than every z2.var Z2_BG = Z2_EMPHASIS_LIFT * 2;var Z2_CONTENT = Z2_EMPHASIS_LIFT * 3;var getStateItemStyle = makeStyleMapper([['fill', 'color'], // `borderColor` and `borderWidth` has been occupied,// so use `stroke` to indicate the stroke of the rect.['stroke', 'strokeColor'], ['lineWidth', 'strokeWidth'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.// So do not transfer decal directly.]);var getItemStyleNormal = function (model) {  // Normal style props should include emphasis style props.  var itemStyle = getStateItemStyle(model); // Clear styles set by emphasis.  itemStyle.stroke = itemStyle.fill = itemStyle.lineWidth = null;  return itemStyle;};var inner = makeInner();var TreemapView =/** @class */function (_super) {  __extends(TreemapView, _super);  function TreemapView() {    var _this = _super !== null && _super.apply(this, arguments) || this;    _this.type = TreemapView.type;    _this._state = 'ready';    _this._storage = createStorage();    return _this;  }  /**   * @override   */  TreemapView.prototype.render = function (seriesModel, ecModel, api, payload) {    var models = ecModel.findComponents({      mainType: 'series',      subType: 'treemap',      query: payload    });    if (indexOf(models, seriesModel) < 0) {      return;    }    this.seriesModel = seriesModel;    this.api = api;    this.ecModel = ecModel;    var types = ['treemapZoomToNode', 'treemapRootToNode'];    var targetInfo = helper.retrieveTargetInfo(payload, types, seriesModel);    var payloadType = payload && payload.type;    var layoutInfo = seriesModel.layoutInfo;    var isInit = !this._oldTree;    var thisStorage = this._storage; // Mark new root when action is treemapRootToNode.    var reRoot = payloadType === 'treemapRootToNode' && targetInfo && thisStorage ? {      rootNodeGroup: thisStorage.nodeGroup[targetInfo.node.getRawIndex()],      direction: payload.direction    } : null;    var containerGroup = this._giveContainerGroup(layoutInfo);    var hasAnimation = seriesModel.get('animation');    var renderResult = this._doRender(containerGroup, seriesModel, reRoot);    hasAnimation && !isInit && (!payloadType || payloadType === 'treemapZoomToNode' || payloadType === 'treemapRootToNode') ? this._doAnimation(containerGroup, renderResult, seriesModel, reRoot) : renderResult.renderFinally();    this._resetController(api);    this._renderBreadcrumb(seriesModel, api, targetInfo);  };  TreemapView.prototype._giveContainerGroup = function (layoutInfo) {    var containerGroup = this._containerGroup;    if (!containerGroup) {      // FIXME      // 加一层containerGroup是为了clip,但是现在clip功能并没有实现。      containerGroup = this._containerGroup = new Group();      this._initEvents(containerGroup);      this.group.add(containerGroup);    }    containerGroup.x = layoutInfo.x;    containerGroup.y = layoutInfo.y;    return containerGroup;  };  TreemapView.prototype._doRender = function (containerGroup, seriesModel, reRoot) {    var thisTree = seriesModel.getData().tree;    var oldTree = this._oldTree; // Clear last shape records.    var lastsForAnimation = createStorage();    var thisStorage = createStorage();    var oldStorage = this._storage;    var willInvisibleEls = [];    function doRenderNode(thisNode, oldNode, parentGroup, depth) {      return renderNode(seriesModel, thisStorage, oldStorage, reRoot, lastsForAnimation, willInvisibleEls, thisNode, oldNode, parentGroup, depth);    } // Notice: When thisTree and oldTree are the same tree (see list.cloneShallow),    // the oldTree is actually losted, so we cannot find all of the old graphic    // elements from tree. So we use this strategy: make element storage, move    // from old storage to new storage, clear old storage.    dualTravel(thisTree.root ? [thisTree.root] : [], oldTree && oldTree.root ? [oldTree.root] : [], containerGroup, thisTree === oldTree || !oldTree, 0); // Process all removing.    var willDeleteEls = clearStorage(oldStorage);    this._oldTree = thisTree;    this._storage = thisStorage;    return {      lastsForAnimation: lastsForAnimation,      willDeleteEls: willDeleteEls,      renderFinally: renderFinally    };    function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, depth) {      // When 'render' is triggered by action,      // 'this' and 'old' may be the same tree,      // we use rawIndex in that case.      if (sameTree) {        oldViewChildren = thisViewChildren;        each(thisViewChildren, function (child, index) {          !child.isRemoved() && processNode(index, index);        });      } // Diff hierarchically (diff only in each subtree, but not whole).      // because, consistency of view is important.      else {          new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey).add(processNode).update(processNode).remove(curry(processNode, null)).execute();        }      function getKey(node) {        // Identify by name or raw index.        return node.getId();      }      function processNode(newIndex, oldIndex) {        var thisNode = newIndex != null ? thisViewChildren[newIndex] : null;        var oldNode = oldIndex != null ? oldViewChildren[oldIndex] : null;        var group = doRenderNode(thisNode, oldNode, parentGroup, depth);        group && dualTravel(thisNode && thisNode.viewChildren || [], oldNode && oldNode.viewChildren || [], group, sameTree, depth + 1);      }    }    function clearStorage(storage) {      var willDeleteEls = createStorage();      storage && each(storage, function (store, storageName) {        var delEls = willDeleteEls[storageName];        each(store, function (el) {          el && (delEls.push(el), inner(el).willDelete = true);        });      });      return willDeleteEls;    }    function renderFinally() {      each(willDeleteEls, function (els) {        each(els, function (el) {          el.parent && el.parent.remove(el);        });      });      each(willInvisibleEls, function (el) {        el.invisible = true; // Setting invisible is for optimizing, so no need to set dirty,        // just mark as invisible.        el.dirty();      });    }  };  TreemapView.prototype._doAnimation = function (containerGroup, renderResult, seriesModel, reRoot) {    var durationOption = seriesModel.get('animationDurationUpdate');    var easingOption = seriesModel.get('animationEasing'); // TODO: do not support function until necessary.    var duration = (isFunction(durationOption) ? 0 : durationOption) || 0;    var easing = (isFunction(easingOption) ? null : easingOption) || 'cubicOut';    var animationWrap = animationUtil.createWrap(); // Make delete animations.    each(renderResult.willDeleteEls, function (store, storageName) {      each(store, function (el, rawIndex) {        if (el.invisible) {          return;        }        var parent = el.parent; // Always has parent, and parent is nodeGroup.        var target;        var innerStore = inner(parent);        if (reRoot && reRoot.direction === 'drillDown') {          target = parent === reRoot.rootNodeGroup // This is the content element of view root.          // Only `content` will enter this branch, because          // `background` and `nodeGroup` will not be deleted.          ? {            shape: {              x: 0,              y: 0,              width: innerStore.nodeWidth,              height: innerStore.nodeHeight            },            style: {              opacity: 0            }          } // Others.          : {            style: {              opacity: 0            }          };        } else {          var targetX = 0;          var targetY = 0;          if (!innerStore.willDelete) {            // Let node animate to right-bottom corner, cooperating with fadeout,            // which is appropriate for user understanding.            // Divided by 2 for reRoot rolling up effect.            targetX = innerStore.nodeWidth / 2;            targetY = innerStore.nodeHeight / 2;          }          target = storageName === 'nodeGroup' ? {            x: targetX,            y: targetY,            style: {              opacity: 0            }          } : {            shape: {              x: targetX,              y: targetY,              width: 0,              height: 0            },            style: {              opacity: 0            }          };        } // TODO: do not support delay until necessary.        target && animationWrap.add(el, target, duration, 0, easing);      });    }); // Make other animations    each(this._storage, function (store, storageName) {      each(store, function (el, rawIndex) {        var last = renderResult.lastsForAnimation[storageName][rawIndex];        var target = {};        if (!last) {          return;        }        if (el instanceof graphic.Group) {          if (last.oldX != null) {            target.x = el.x;            target.y = el.y;            el.x = last.oldX;            el.y = last.oldY;          }        } else {          if (last.oldShape) {            target.shape = extend({}, el.shape);            el.setShape(last.oldShape);          }          if (last.fadein) {            el.setStyle('opacity', 0);            target.style = {              opacity: 1            };          } // When animation is stopped for succedent animation starting,          // el.style.opacity might not be 1          else if (el.style.opacity !== 1) {              target.style = {                opacity: 1              };            }        }        animationWrap.add(el, target, duration, 0, easing);      });    }, this);    this._state = 'animating';    animationWrap.finished(bind(function () {      this._state = 'ready';      renderResult.renderFinally();    }, this)).start();  };  TreemapView.prototype._resetController = function (api) {    var controller = this._controller; // Init controller.    if (!controller) {      controller = this._controller = new RoamController(api.getZr());      controller.enable(this.seriesModel.get('roam'));      controller.on('pan', bind(this._onPan, this));      controller.on('zoom', bind(this._onZoom, this));    }    var rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight());    controller.setPointerChecker(function (e, x, y) {      return rect.contain(x, y);    });  };  TreemapView.prototype._clearController = function () {    var controller = this._controller;    if (controller) {      controller.dispose();      controller = null;    }  };  TreemapView.prototype._onPan = function (e) {    if (this._state !== 'animating' && (Math.abs(e.dx) > DRAG_THRESHOLD || Math.abs(e.dy) > DRAG_THRESHOLD)) {      // These param must not be cached.      var root = this.seriesModel.getData().tree.root;      if (!root) {        return;      }      var rootLayout = root.getLayout();      if (!rootLayout) {        return;      }      this.api.dispatchAction({        type: 'treemapMove',        from: this.uid,        seriesId: this.seriesModel.id,        rootRect: {          x: rootLayout.x + e.dx,          y: rootLayout.y + e.dy,          width: rootLayout.width,          height: rootLayout.height        }      });    }  };  TreemapView.prototype._onZoom = function (e) {    var mouseX = e.originX;    var mouseY = e.originY;    if (this._state !== 'animating') {      // These param must not be cached.      var root = this.seriesModel.getData().tree.root;      if (!root) {        return;      }      var rootLayout = root.getLayout();      if (!rootLayout) {        return;      }      var rect = new BoundingRect(rootLayout.x, rootLayout.y, rootLayout.width, rootLayout.height);      var layoutInfo = this.seriesModel.layoutInfo; // Transform mouse coord from global to containerGroup.      mouseX -= layoutInfo.x;      mouseY -= layoutInfo.y; // Scale root bounding rect.      var m = matrix.create();      matrix.translate(m, m, [-mouseX, -mouseY]);      matrix.scale(m, m, [e.scale, e.scale]);      matrix.translate(m, m, [mouseX, mouseY]);      rect.applyTransform(m);      this.api.dispatchAction({        type: 'treemapRender',        from: this.uid,        seriesId: this.seriesModel.id,        rootRect: {          x: rect.x,          y: rect.y,          width: rect.width,          height: rect.height        }      });    }  };  TreemapView.prototype._initEvents = function (containerGroup) {    var _this = this;    containerGroup.on('click', function (e) {      if (_this._state !== 'ready') {        return;      }      var nodeClick = _this.seriesModel.get('nodeClick', true);      if (!nodeClick) {        return;      }      var targetInfo = _this.findTarget(e.offsetX, e.offsetY);      if (!targetInfo) {        return;      }      var node = targetInfo.node;      if (node.getLayout().isLeafRoot) {        _this._rootToNode(targetInfo);      } else {        if (nodeClick === 'zoomToNode') {          _this._zoomToNode(targetInfo);        } else if (nodeClick === 'link') {          var itemModel = node.hostTree.data.getItemModel(node.dataIndex);          var link = itemModel.get('link', true);          var linkTarget = itemModel.get('target', true) || 'blank';          link && windowOpen(link, linkTarget);        }      }    }, this);  };  TreemapView.prototype._renderBreadcrumb = function (seriesModel, api, targetInfo) {    var _this = this;    if (!targetInfo) {      targetInfo = seriesModel.get('leafDepth', true) != null ? {        node: seriesModel.getViewRoot()      } // FIXME      // better way?      // Find breadcrumb tail on center of containerGroup.      : this.findTarget(api.getWidth() / 2, api.getHeight() / 2);      if (!targetInfo) {        targetInfo = {          node: seriesModel.getData().tree.root        };      }    }    (this._breadcrumb || (this._breadcrumb = new Breadcrumb(this.group))).render(seriesModel, api, targetInfo.node, function (node) {      if (_this._state !== 'animating') {        helper.aboveViewRoot(seriesModel.getViewRoot(), node) ? _this._rootToNode({          node: node        }) : _this._zoomToNode({          node: node        });      }    });  };  /**   * @override   */  TreemapView.prototype.remove = function () {    this._clearController();    this._containerGroup && this._containerGroup.removeAll();    this._storage = createStorage();    this._state = 'ready';    this._breadcrumb && this._breadcrumb.remove();  };  TreemapView.prototype.dispose = function () {    this._clearController();  };  TreemapView.prototype._zoomToNode = function (targetInfo) {    this.api.dispatchAction({      type: 'treemapZoomToNode',      from: this.uid,      seriesId: this.seriesModel.id,      targetNode: targetInfo.node    });  };  TreemapView.prototype._rootToNode = function (targetInfo) {    this.api.dispatchAction({      type: 'treemapRootToNode',      from: this.uid,      seriesId: this.seriesModel.id,      targetNode: targetInfo.node    });  };  /**   * @public   * @param {number} x Global coord x.   * @param {number} y Global coord y.   * @return {Object} info If not found, return undefined;   * @return {number} info.node Target node.   * @return {number} info.offsetX x refer to target node.   * @return {number} info.offsetY y refer to target node.   */  TreemapView.prototype.findTarget = function (x, y) {    var targetInfo;    var viewRoot = this.seriesModel.getViewRoot();    viewRoot.eachNode({      attr: 'viewChildren',      order: 'preorder'    }, function (node) {      var bgEl = this._storage.background[node.getRawIndex()]; // If invisible, there might be no element.      if (bgEl) {        var point = bgEl.transformCoordToLocal(x, y);        var shape = bgEl.shape; // For performance consideration, don't use 'getBoundingRect'.        if (shape.x <= point[0] && point[0] <= shape.x + shape.width && shape.y <= point[1] && point[1] <= shape.y + shape.height) {          targetInfo = {            node: node,            offsetX: point[0],            offsetY: point[1]          };        } else {          return false; // Suppress visit subtree.        }      }    }, this);    return targetInfo;  };  TreemapView.type = 'treemap';  return TreemapView;}(ChartView);/** * @inner */function createStorage() {  return {    nodeGroup: [],    background: [],    content: []  };}/** * @inner * @return Return undefined means do not travel further. */function renderNode(seriesModel, thisStorage, oldStorage, reRoot, lastsForAnimation, willInvisibleEls, thisNode, oldNode, parentGroup, depth) {  // Whether under viewRoot.  if (!thisNode) {    // Deleting nodes will be performed finally. This method just find    // element from old storage, or create new element, set them to new    // storage, and set styles.    return;  } // -------------------------------------------------------------------  // Start of closure variables available in "Procedures in renderNode".  var thisLayout = thisNode.getLayout();  var data = seriesModel.getData();  var nodeModel = thisNode.getModel(); // Only for enabling highlight/downplay. Clear firstly.  // Because some node will not be rendered.  data.setItemGraphicEl(thisNode.dataIndex, null);  if (!thisLayout || !thisLayout.isInView) {    return;  }  var thisWidth = thisLayout.width;  var thisHeight = thisLayout.height;  var borderWidth = thisLayout.borderWidth;  var thisInvisible = thisLayout.invisible;  var thisRawIndex = thisNode.getRawIndex();  var oldRawIndex = oldNode && oldNode.getRawIndex();  var thisViewChildren = thisNode.viewChildren;  var upperHeight = thisLayout.upperHeight;  var isParent = thisViewChildren && thisViewChildren.length;  var itemStyleNormalModel = nodeModel.getModel('itemStyle');  var itemStyleEmphasisModel = nodeModel.getModel(['emphasis', 'itemStyle']);  var itemStyleBlurModel = nodeModel.getModel(['blur', 'itemStyle']);  var itemStyleSelectModel = nodeModel.getModel(['select', 'itemStyle']);  var borderRadius = itemStyleNormalModel.get('borderRadius') || 0; // End of closure ariables available in "Procedures in renderNode".  // -----------------------------------------------------------------  // Node group  var group = giveGraphic('nodeGroup', Group);  if (!group) {    return;  }  parentGroup.add(group); // x,y are not set when el is above view root.  group.x = thisLayout.x || 0;  group.y = thisLayout.y || 0;  group.markRedraw();  inner(group).nodeWidth = thisWidth;  inner(group).nodeHeight = thisHeight;  if (thisLayout.isAboveViewRoot) {    return group;  } // Background  var bg = giveGraphic('background', Rect, depth, Z2_BG);  bg && renderBackground(group, bg, isParent && thisLayout.upperLabelHeight);  var emphasisModel = nodeModel.getModel('emphasis');  var focus = emphasisModel.get('focus');  var blurScope = emphasisModel.get('blurScope');  var isDisabled = emphasisModel.get('disabled');  var focusOrIndices = focus === 'ancestor' ? thisNode.getAncestorsIndices() : focus === 'descendant' ? thisNode.getDescendantIndices() : focus; // No children, render content.  if (isParent) {    // Because of the implementation about "traverse" in graphic hover style, we    // can not set hover listener on the "group" of non-leaf node. Otherwise the    // hover event from the descendents will be listenered.    if (isHighDownDispatcher(group)) {      setAsHighDownDispatcher(group, false);    }    if (bg) {      setAsHighDownDispatcher(bg, !isDisabled); // Only for enabling highlight/downplay.      data.setItemGraphicEl(thisNode.dataIndex, bg);      enableHoverFocus(bg, focusOrIndices, blurScope);    }  } else {    var content = giveGraphic('content', Rect, depth, Z2_CONTENT);    content && renderContent(group, content);    bg.disableMorphing = true;    if (bg && isHighDownDispatcher(bg)) {      setAsHighDownDispatcher(bg, false);    }    setAsHighDownDispatcher(group, !isDisabled); // Only for enabling highlight/downplay.    data.setItemGraphicEl(thisNode.dataIndex, group);    enableHoverFocus(group, focusOrIndices, blurScope);  }  return group; // ----------------------------  // | Procedures in renderNode |  // ----------------------------  function renderBackground(group, bg, useUpperLabel) {    var ecData = getECData(bg); // For tooltip.    ecData.dataIndex = thisNode.dataIndex;    ecData.seriesIndex = seriesModel.seriesIndex;    bg.setShape({      x: 0,      y: 0,      width: thisWidth,      height: thisHeight,      r: borderRadius    });    if (thisInvisible) {      // If invisible, do not set visual, otherwise the element will      // change immediately before animation. We think it is OK to      // remain its origin color when moving out of the view window.      processInvisible(bg);    } else {      bg.invisible = false;      var style = thisNode.getVisual('style');      var visualBorderColor = style.stroke;      var normalStyle = getItemStyleNormal(itemStyleNormalModel);      normalStyle.fill = visualBorderColor;      var emphasisStyle = getStateItemStyle(itemStyleEmphasisModel);      emphasisStyle.fill = itemStyleEmphasisModel.get('borderColor');      var blurStyle = getStateItemStyle(itemStyleBlurModel);      blurStyle.fill = itemStyleBlurModel.get('borderColor');      var selectStyle = getStateItemStyle(itemStyleSelectModel);      selectStyle.fill = itemStyleSelectModel.get('borderColor');      if (useUpperLabel) {        var upperLabelWidth = thisWidth - 2 * borderWidth;        prepareText( // PENDING: convert ZRColor to ColorString for text.        bg, visualBorderColor, style.opacity, {          x: borderWidth,          y: 0,          width: upperLabelWidth,          height: upperHeight        });      } // For old bg.      else {          bg.removeTextContent();        }      bg.setStyle(normalStyle);      bg.ensureState('emphasis').style = emphasisStyle;      bg.ensureState('blur').style = blurStyle;      bg.ensureState('select').style = selectStyle;      setDefaultStateProxy(bg);    }    group.add(bg);  }  function renderContent(group, content) {    var ecData = getECData(content); // For tooltip.    ecData.dataIndex = thisNode.dataIndex;    ecData.seriesIndex = seriesModel.seriesIndex;    var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0);    var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0);    content.culling = true;    content.setShape({      x: borderWidth,      y: borderWidth,      width: contentWidth,      height: contentHeight,      r: borderRadius    });    if (thisInvisible) {      // If invisible, do not set visual, otherwise the element will      // change immediately before animation. We think it is OK to      // remain its origin color when moving out of the view window.      processInvisible(content);    } else {      content.invisible = false;      var nodeStyle = thisNode.getVisual('style');      var visualColor = nodeStyle.fill;      var normalStyle = getItemStyleNormal(itemStyleNormalModel);      normalStyle.fill = visualColor;      normalStyle.decal = nodeStyle.decal;      var emphasisStyle = getStateItemStyle(itemStyleEmphasisModel);      var blurStyle = getStateItemStyle(itemStyleBlurModel);      var selectStyle = getStateItemStyle(itemStyleSelectModel); // PENDING: convert ZRColor to ColorString for text.      prepareText(content, visualColor, nodeStyle.opacity, null);      content.setStyle(normalStyle);      content.ensureState('emphasis').style = emphasisStyle;      content.ensureState('blur').style = blurStyle;      content.ensureState('select').style = selectStyle;      setDefaultStateProxy(content);    }    group.add(content);  }  function processInvisible(element) {    // Delay invisible setting utill animation finished,    // avoid element vanish suddenly before animation.    !element.invisible && willInvisibleEls.push(element);  }  function prepareText(rectEl, visualColor, visualOpacity, // Can be null/undefined  upperLabelRect) {    var normalLabelModel = nodeModel.getModel(upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL);    var defaultText = convertOptionIdName(nodeModel.get('name'), null);    var isShow = normalLabelModel.getShallow('show');    setLabelStyle(rectEl, getLabelStatesModels(nodeModel, upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL), {      defaultText: isShow ? defaultText : null,      inheritColor: visualColor,      defaultOpacity: visualOpacity,      labelFetcher: seriesModel,      labelDataIndex: thisNode.dataIndex    });    var textEl = rectEl.getTextContent();    if (!textEl) {      return;    }    var textStyle = textEl.style;    var textPadding = normalizeCssArray(textStyle.padding || 0);    if (upperLabelRect) {      rectEl.setTextConfig({        layoutRect: upperLabelRect      });      textEl.disableLabelLayout = true;    }    textEl.beforeUpdate = function () {      var width = Math.max((upperLabelRect ? upperLabelRect.width : rectEl.shape.width) - textPadding[1] - textPadding[3], 0);      var height = Math.max((upperLabelRect ? upperLabelRect.height : rectEl.shape.height) - textPadding[0] - textPadding[2], 0);      if (textStyle.width !== width || textStyle.height !== height) {        textEl.setStyle({          width: width,          height: height        });      }    };    textStyle.truncateMinChar = 2;    textStyle.lineOverflow = 'truncate';    addDrillDownIcon(textStyle, upperLabelRect, thisLayout);    var textEmphasisState = textEl.getState('emphasis');    addDrillDownIcon(textEmphasisState ? textEmphasisState.style : null, upperLabelRect, thisLayout);  }  function addDrillDownIcon(style, upperLabelRect, thisLayout) {    var text = style ? style.text : null;    if (!upperLabelRect && thisLayout.isLeafRoot && text != null) {      var iconChar = seriesModel.get('drillDownIcon', true);      style.text = iconChar ? iconChar + ' ' + text : text;    }  }  function giveGraphic(storageName, Ctor, depth, z) {    var element = oldRawIndex != null && oldStorage[storageName][oldRawIndex];    var lasts = lastsForAnimation[storageName];    if (element) {      // Remove from oldStorage      oldStorage[storageName][oldRawIndex] = null;      prepareAnimationWhenHasOld(lasts, element);    } // If invisible and no old element, do not create new element (for optimizing).    else if (!thisInvisible) {        element = new Ctor();        if (element instanceof Displayable) {          element.z2 = calculateZ2(depth, z);        }        prepareAnimationWhenNoOld(lasts, element);      } // Set to thisStorage    return thisStorage[storageName][thisRawIndex] = element;  }  function prepareAnimationWhenHasOld(lasts, element) {    var lastCfg = lasts[thisRawIndex] = {};    if (element instanceof Group) {      lastCfg.oldX = element.x;      lastCfg.oldY = element.y;    } else {      lastCfg.oldShape = extend({}, element.shape);    }  } // If a element is new, we need to find the animation start point carefully,  // otherwise it will looks strange when 'zoomToNode'.  function prepareAnimationWhenNoOld(lasts, element) {    var lastCfg = lasts[thisRawIndex] = {};    var parentNode = thisNode.parentNode;    var isGroup = element instanceof graphic.Group;    if (parentNode && (!reRoot || reRoot.direction === 'drillDown')) {      var parentOldX = 0;      var parentOldY = 0; // New nodes appear from right-bottom corner in 'zoomToNode' animation.      // For convenience, get old bounding rect from background.      var parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()];      if (!reRoot && parentOldBg && parentOldBg.oldShape) {        parentOldX = parentOldBg.oldShape.width;        parentOldY = parentOldBg.oldShape.height;      } // When no parent old shape found, its parent is new too,      // so we can just use {x:0, y:0}.      if (isGroup) {        lastCfg.oldX = 0;        lastCfg.oldY = parentOldY;      } else {        lastCfg.oldShape = {          x: parentOldX,          y: parentOldY,          width: 0,          height: 0        };      }    } // Fade in, user can be aware that these nodes are new.    lastCfg.fadein = !isGroup;  }} // We cannot set all background with the same z, because the behaviour of// drill down and roll up differ background creation sequence from tree// hierarchy sequence, which cause lower background elements to overlap// upper ones. So we calculate z based on depth.// Moreover, we try to shrink down z interval to [0, 1] to avoid that// treemap with large z overlaps other components.function calculateZ2(depth, z2InLevel) {  return depth * Z2_BASE + z2InLevel;}export default TreemapView;
 |