cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
692 lines (691 loc) • 25 kB
JavaScript
import { __extends } from "../../../../tslib/tslib.es6.mjs";
import { indexOf, each, curry, extend, bind, isFunction, normalizeCssArray } from "../../../../zrender/lib/core/util.mjs";
import { getECData } from "../../util/innerStore.mjs";
import { isHighDownDispatcher, setAsHighDownDispatcher, enableHoverFocus, setDefaultStateProxy, Z2_EMPHASIS_LIFT } from "../../util/states.mjs";
import DataDiffer from "../../data/DataDiffer.mjs";
import { retrieveTargetInfo, aboveViewRoot } from "../helper/treeHelper.mjs";
import Breadcrumb from "./Breadcrumb.mjs";
import RoamController from "../../component/helper/RoamController.mjs";
import BoundingRect from "../../../../zrender/lib/core/BoundingRect.mjs";
import { translate, scale, create } from "../../../../zrender/lib/core/matrix.mjs";
import { createWrap } from "../../util/animation.mjs";
import makeStyleMapper from "../../model/mixin/makeStyleMapper.mjs";
import ChartView from "../../view/Chart.mjs";
import Displayable from "../../../../zrender/lib/graphic/Displayable.mjs";
import { makeInner, convertOptionIdName } from "../../util/model.mjs";
import { windowOpen } from "../../util/format.mjs";
import { setLabelStyle, getLabelStatesModels } from "../../label/labelStyle.mjs";
import Group$1 from "../../../../zrender/lib/graphic/Group.mjs";
import Rect$1 from "../../../../zrender/lib/graphic/shape/Rect.mjs";
var Group = Group$1;
var Rect = Rect$1;
var DRAG_THRESHOLD = 3;
var PATH_LABEL_NOAMAL = "label";
var PATH_UPPERLABEL_NORMAL = "upperLabel";
var Z2_BASE = Z2_EMPHASIS_LIFT * 10;
var Z2_BG = Z2_EMPHASIS_LIFT * 2;
var Z2_CONTENT = Z2_EMPHASIS_LIFT * 3;
var getStateItemStyle = makeStyleMapper([
["fill", "color"],
["stroke", "strokeColor"],
["lineWidth", "strokeWidth"],
["shadowBlur"],
["shadowOffsetX"],
["shadowOffsetY"],
["shadowColor"]
]);
var getItemStyleNormal = function(model) {
var itemStyle = getStateItemStyle(model);
itemStyle.stroke = itemStyle.fill = itemStyle.lineWidth = null;
return itemStyle;
};
var inner = makeInner();
var TreemapView = function(_super) {
__extends(TreemapView2, _super);
function TreemapView2() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = TreemapView2.type;
_this._state = "ready";
_this._storage = createStorage();
return _this;
}
TreemapView2.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 = retrieveTargetInfo(payload, types, seriesModel);
var payloadType = payload && payload.type;
var layoutInfo = seriesModel.layoutInfo;
var isInit = !this._oldTree;
var thisStorage = this._storage;
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);
};
TreemapView2.prototype._giveContainerGroup = function(layoutInfo) {
var containerGroup = this._containerGroup;
if (!containerGroup) {
containerGroup = this._containerGroup = new Group();
this._initEvents(containerGroup);
this.group.add(containerGroup);
}
containerGroup.x = layoutInfo.x;
containerGroup.y = layoutInfo.y;
return containerGroup;
};
TreemapView2.prototype._doRender = function(containerGroup, seriesModel, reRoot) {
var thisTree = seriesModel.getData().tree;
var oldTree = this._oldTree;
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);
}
dualTravel(thisTree.root ? [thisTree.root] : [], oldTree && oldTree.root ? [oldTree.root] : [], containerGroup, thisTree === oldTree || !oldTree, 0);
var willDeleteEls = clearStorage(oldStorage);
this._oldTree = thisTree;
this._storage = thisStorage;
return {
lastsForAnimation,
willDeleteEls,
renderFinally
};
function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, depth) {
if (sameTree) {
oldViewChildren = thisViewChildren;
each(thisViewChildren, function(child, index) {
!child.isRemoved() && processNode(index, index);
});
} else {
new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey).add(processNode).update(processNode).remove(curry(processNode, null)).execute();
}
function getKey(node) {
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 willDeleteEls2 = createStorage();
storage && each(storage, function(store, storageName) {
var delEls = willDeleteEls2[storageName];
each(store, function(el) {
el && (delEls.push(el), inner(el).willDelete = true);
});
});
return willDeleteEls2;
}
function renderFinally() {
each(willDeleteEls, function(els) {
each(els, function(el) {
el.parent && el.parent.remove(el);
});
});
each(willInvisibleEls, function(el) {
el.invisible = true;
el.dirty();
});
}
};
TreemapView2.prototype._doAnimation = function(containerGroup, renderResult, seriesModel, reRoot) {
var durationOption = seriesModel.get("animationDurationUpdate");
var easingOption = seriesModel.get("animationEasing");
var duration = (isFunction(durationOption) ? 0 : durationOption) || 0;
var easing = (isFunction(easingOption) ? null : easingOption) || "cubicOut";
var animationWrap = createWrap();
each(renderResult.willDeleteEls, function(store, storageName) {
each(store, function(el, rawIndex) {
if (el.invisible) {
return;
}
var parent = el.parent;
var target;
var innerStore = inner(parent);
if (reRoot && reRoot.direction === "drillDown") {
target = parent === reRoot.rootNodeGroup ? {
shape: {
x: 0,
y: 0,
width: innerStore.nodeWidth,
height: innerStore.nodeHeight
},
style: {
opacity: 0
}
} : {
style: {
opacity: 0
}
};
} else {
var targetX = 0;
var targetY = 0;
if (!innerStore.willDelete) {
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
}
};
}
target && animationWrap.add(el, target, duration, 0, easing);
});
});
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 Group$1) {
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
};
} 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();
};
TreemapView2.prototype._resetController = function(api) {
var controller = this._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);
});
};
TreemapView2.prototype._clearController = function() {
var controller = this._controller;
if (controller) {
controller.dispose();
controller = null;
}
};
TreemapView2.prototype._onPan = function(e) {
if (this._state !== "animating" && (Math.abs(e.dx) > DRAG_THRESHOLD || Math.abs(e.dy) > DRAG_THRESHOLD)) {
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
}
});
}
};
TreemapView2.prototype._onZoom = function(e) {
var mouseX = e.originX;
var mouseY = e.originY;
if (this._state !== "animating") {
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;
mouseX -= layoutInfo.x;
mouseY -= layoutInfo.y;
var m = create();
translate(m, m, [-mouseX, -mouseY]);
scale(m, m, [e.scale, e.scale]);
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
}
});
}
};
TreemapView2.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);
};
TreemapView2.prototype._renderBreadcrumb = function(seriesModel, api, targetInfo) {
var _this = this;
if (!targetInfo) {
targetInfo = seriesModel.get("leafDepth", true) != null ? {
node: seriesModel.getViewRoot()
} : 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") {
aboveViewRoot(seriesModel.getViewRoot(), node) ? _this._rootToNode({
node
}) : _this._zoomToNode({
node
});
}
});
};
TreemapView2.prototype.remove = function() {
this._clearController();
this._containerGroup && this._containerGroup.removeAll();
this._storage = createStorage();
this._state = "ready";
this._breadcrumb && this._breadcrumb.remove();
};
TreemapView2.prototype.dispose = function() {
this._clearController();
};
TreemapView2.prototype._zoomToNode = function(targetInfo) {
this.api.dispatchAction({
type: "treemapZoomToNode",
from: this.uid,
seriesId: this.seriesModel.id,
targetNode: targetInfo.node
});
};
TreemapView2.prototype._rootToNode = function(targetInfo) {
this.api.dispatchAction({
type: "treemapRootToNode",
from: this.uid,
seriesId: this.seriesModel.id,
targetNode: targetInfo.node
});
};
TreemapView2.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 (bgEl) {
var point = bgEl.transformCoordToLocal(x, y);
var shape = bgEl.shape;
if (shape.x <= point[0] && point[0] <= shape.x + shape.width && shape.y <= point[1] && point[1] <= shape.y + shape.height) {
targetInfo = {
node,
offsetX: point[0],
offsetY: point[1]
};
} else {
return false;
}
}
}, this);
return targetInfo;
};
TreemapView2.type = "treemap";
return TreemapView2;
}(ChartView);
function createStorage() {
return {
nodeGroup: [],
background: [],
content: []
};
}
function renderNode(seriesModel, thisStorage, oldStorage, reRoot, lastsForAnimation, willInvisibleEls, thisNode, oldNode, parentGroup, depth) {
if (!thisNode) {
return;
}
var thisLayout = thisNode.getLayout();
var data = seriesModel.getData();
var nodeModel = thisNode.getModel();
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;
var group = giveGraphic("nodeGroup", Group);
if (!group) {
return;
}
parentGroup.add(group);
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;
}
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;
if (isParent) {
if (isHighDownDispatcher(group)) {
setAsHighDownDispatcher(group, false);
}
if (bg) {
setAsHighDownDispatcher(bg, !isDisabled);
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);
data.setItemGraphicEl(thisNode.dataIndex, group);
enableHoverFocus(group, focusOrIndices, blurScope);
}
return group;
function renderBackground(group2, bg2, useUpperLabel) {
var ecData = getECData(bg2);
ecData.dataIndex = thisNode.dataIndex;
ecData.seriesIndex = seriesModel.seriesIndex;
bg2.setShape({
x: 0,
y: 0,
width: thisWidth,
height: thisHeight,
r: borderRadius
});
if (thisInvisible) {
processInvisible(bg2);
} else {
bg2.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(
bg2,
visualBorderColor,
style.opacity,
{
x: borderWidth,
y: 0,
width: upperLabelWidth,
height: upperHeight
}
);
} else {
bg2.removeTextContent();
}
bg2.setStyle(normalStyle);
bg2.ensureState("emphasis").style = emphasisStyle;
bg2.ensureState("blur").style = blurStyle;
bg2.ensureState("select").style = selectStyle;
setDefaultStateProxy(bg2);
}
group2.add(bg2);
}
function renderContent(group2, content2) {
var ecData = getECData(content2);
ecData.dataIndex = thisNode.dataIndex;
ecData.seriesIndex = seriesModel.seriesIndex;
var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0);
var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0);
content2.culling = true;
content2.setShape({
x: borderWidth,
y: borderWidth,
width: contentWidth,
height: contentHeight,
r: borderRadius
});
if (thisInvisible) {
processInvisible(content2);
} else {
content2.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);
prepareText(content2, visualColor, nodeStyle.opacity, null);
content2.setStyle(normalStyle);
content2.ensureState("emphasis").style = emphasisStyle;
content2.ensureState("blur").style = blurStyle;
content2.ensureState("select").style = selectStyle;
setDefaultStateProxy(content2);
}
group2.add(content2);
}
function processInvisible(element) {
!element.invisible && willInvisibleEls.push(element);
}
function prepareText(rectEl, visualColor, visualOpacity, 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,
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, thisLayout2) {
var text = style ? style.text : null;
if (!upperLabelRect && thisLayout2.isLeafRoot && text != null) {
var iconChar = seriesModel.get("drillDownIcon", true);
style.text = iconChar ? iconChar + " " + text : text;
}
}
function giveGraphic(storageName, Ctor, depth2, z) {
var element = oldRawIndex != null && oldStorage[storageName][oldRawIndex];
var lasts = lastsForAnimation[storageName];
if (element) {
oldStorage[storageName][oldRawIndex] = null;
prepareAnimationWhenHasOld(lasts, element);
} else if (!thisInvisible) {
element = new Ctor();
if (element instanceof Displayable) {
element.z2 = calculateZ2(depth2, z);
}
prepareAnimationWhenNoOld(lasts, element);
}
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);
}
}
function prepareAnimationWhenNoOld(lasts, element) {
var lastCfg = lasts[thisRawIndex] = {};
var parentNode = thisNode.parentNode;
var isGroup = element instanceof Group$1;
if (parentNode && (!reRoot || reRoot.direction === "drillDown")) {
var parentOldX = 0;
var parentOldY = 0;
var parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()];
if (!reRoot && parentOldBg && parentOldBg.oldShape) {
parentOldX = parentOldBg.oldShape.width;
parentOldY = parentOldBg.oldShape.height;
}
if (isGroup) {
lastCfg.oldX = 0;
lastCfg.oldY = parentOldY;
} else {
lastCfg.oldShape = {
x: parentOldX,
y: parentOldY,
width: 0,
height: 0
};
}
}
lastCfg.fadein = !isGroup;
}
}
function calculateZ2(depth, z2InLevel) {
return depth * Z2_BASE + z2InLevel;
}
var TreemapView$1 = TreemapView;
export { TreemapView$1 as default };