cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
386 lines (385 loc) • 13.2 kB
JavaScript
import "../../echarts/lib/echarts.mjs";
import { parsePercent as parsePercent$1 } from "../../echarts/lib/util/number.mjs";
import LiquidShape from "./liquidFillShape.mjs";
import { extendChartView } from "../../echarts/lib/export/api.mjs";
import { initProps, updateProps } from "../../echarts/lib/animation/basicTransition.mjs";
import Group from "../../zrender/lib/graphic/Group.mjs";
import { enableHoverEmphasis } from "../../echarts/lib/util/states.mjs";
import { createTextStyle } from "../../echarts/lib/export/api/helper.mjs";
import Rect from "../../zrender/lib/graphic/shape/Rect.mjs";
import ZRText from "../../zrender/lib/graphic/Text.mjs";
import CompoundPath from "../../zrender/lib/graphic/CompoundPath.mjs";
import { makePath } from "../../echarts/lib/util/graphic.mjs";
import BoundingRect from "../../zrender/lib/core/BoundingRect.mjs";
import { createSymbol } from "../../echarts/lib/util/symbol.mjs";
import Circle from "../../zrender/lib/graphic/shape/Circle.mjs";
var parsePercent = parsePercent$1;
function isPathSymbol(symbol) {
return symbol && symbol.indexOf("path://") === 0;
}
extendChartView({
type: "liquidFill",
render: function(seriesModel, ecModel, api) {
var self = this;
var group = this.group;
group.removeAll();
var data = seriesModel.getData();
var itemModel = data.getItemModel(0);
var center = itemModel.get("center");
var radius = itemModel.get("radius");
var width = api.getWidth();
var height = api.getHeight();
var size = Math.min(width, height);
var outlineDistance = 0;
var outlineBorderWidth = 0;
var showOutline = seriesModel.get("outline.show");
if (showOutline) {
outlineDistance = seriesModel.get("outline.borderDistance");
outlineBorderWidth = parsePercent(
seriesModel.get("outline.itemStyle.borderWidth"),
size
);
}
var cx = parsePercent(center[0], width);
var cy = parsePercent(center[1], height);
var outterRadius;
var innerRadius;
var paddingRadius;
var isFillContainer = false;
var symbol = seriesModel.get("shape");
if (symbol === "container") {
isFillContainer = true;
outterRadius = [
width / 2,
height / 2
];
innerRadius = [
outterRadius[0] - outlineBorderWidth / 2,
outterRadius[1] - outlineBorderWidth / 2
];
paddingRadius = [
parsePercent(outlineDistance, width),
parsePercent(outlineDistance, height)
];
radius = [
Math.max(innerRadius[0] - paddingRadius[0], 0),
Math.max(innerRadius[1] - paddingRadius[1], 0)
];
} else {
outterRadius = parsePercent(radius, size) / 2;
innerRadius = outterRadius - outlineBorderWidth / 2;
paddingRadius = parsePercent(outlineDistance, size);
radius = Math.max(innerRadius - paddingRadius, 0);
}
if (showOutline) {
var outline = getOutline();
outline.style.lineWidth = outlineBorderWidth;
group.add(getOutline());
}
var left = isFillContainer ? 0 : cx - radius;
var top = isFillContainer ? 0 : cy - radius;
var wavePath = null;
group.add(getBackground());
var oldData = this._data;
var waves = [];
data.diff(oldData).add(function(idx) {
var wave = getWave(idx, false);
var waterLevel = wave.shape.waterLevel;
wave.shape.waterLevel = isFillContainer ? height / 2 : radius;
initProps(wave, {
shape: {
waterLevel
}
}, seriesModel);
wave.z2 = 2;
setWaveAnimation(idx, wave, null);
group.add(wave);
data.setItemGraphicEl(idx, wave);
waves.push(wave);
}).update(function(newIdx, oldIdx) {
var waveElement = oldData.getItemGraphicEl(oldIdx);
var newWave = getWave(newIdx, false, waveElement);
var shape = {};
var shapeAttrs = ["amplitude", "cx", "cy", "phase", "radius", "radiusY", "waterLevel", "waveLength"];
for (var i = 0; i < shapeAttrs.length; ++i) {
var attr = shapeAttrs[i];
if (newWave.shape.hasOwnProperty(attr)) {
shape[attr] = newWave.shape[attr];
}
}
var style = {};
var styleAttrs = ["fill", "opacity", "shadowBlur", "shadowColor"];
for (var i = 0; i < styleAttrs.length; ++i) {
var attr = styleAttrs[i];
if (newWave.style.hasOwnProperty(attr)) {
style[attr] = newWave.style[attr];
}
}
if (isFillContainer) {
shape.radiusY = height / 2;
}
updateProps(waveElement, {
shape,
x: newWave.x,
y: newWave.y
}, seriesModel);
if (seriesModel.isUniversalTransitionEnabled && seriesModel.isUniversalTransitionEnabled()) {
updateProps(waveElement, {
style
}, seriesModel);
} else {
waveElement.useStyle(style);
}
var oldWaveClipPath = waveElement.getClipPath();
var newWaveClipPath = newWave.getClipPath();
waveElement.setClipPath(newWave.getClipPath());
waveElement.shape.inverse = newWave.inverse;
if (oldWaveClipPath && newWaveClipPath && self._shape === symbol && !isPathSymbol(symbol)) {
updateProps(newWaveClipPath, {
shape: oldWaveClipPath.shape
}, seriesModel, { isFrom: true });
}
setWaveAnimation(newIdx, waveElement, waveElement);
group.add(waveElement);
data.setItemGraphicEl(newIdx, waveElement);
waves.push(waveElement);
}).remove(function(idx) {
var wave = oldData.getItemGraphicEl(idx);
group.remove(wave);
}).execute();
if (itemModel.get("label.show")) {
group.add(getText(waves));
}
this._shape = symbol;
this._data = data;
function getPath(r, isForClipping) {
if (symbol) {
if (isPathSymbol(symbol)) {
var path = makePath(symbol.slice(7), {});
var bouding = path.getBoundingRect();
var w = bouding.width;
var h = bouding.height;
if (w > h) {
h = r * 2 / w * h;
w = r * 2;
} else {
w = r * 2 / h * w;
h = r * 2;
}
var left2 = isForClipping ? 0 : cx - w / 2;
var top2 = isForClipping ? 0 : cy - h / 2;
path = makePath(
symbol.slice(7),
{},
new BoundingRect(left2, top2, w, h)
);
if (isForClipping) {
path.x = -w / 2;
path.y = -h / 2;
}
return path;
} else if (isFillContainer) {
var x = isForClipping ? -r[0] : cx - r[0];
var y = isForClipping ? -r[1] : cy - r[1];
return createSymbol(
"rect",
x,
y,
r[0] * 2,
r[1] * 2
);
} else {
var x = isForClipping ? -r : cx - r;
var y = isForClipping ? -r : cy - r;
if (symbol === "pin") {
y += r;
} else if (symbol === "arrow") {
y -= r;
}
return createSymbol(symbol, x, y, r * 2, r * 2);
}
}
return new Circle({
shape: {
cx: isForClipping ? 0 : cx,
cy: isForClipping ? 0 : cy,
r
}
});
}
function getOutline() {
var outlinePath = getPath(outterRadius);
outlinePath.style.fill = null;
outlinePath.setStyle(seriesModel.getModel("outline.itemStyle").getItemStyle());
return outlinePath;
}
function getBackground() {
var strokePath = getPath(radius);
strokePath.setStyle(seriesModel.getModel("backgroundStyle").getItemStyle());
strokePath.style.fill = null;
strokePath.z2 = 5;
var fillPath = getPath(radius);
fillPath.setStyle(seriesModel.getModel("backgroundStyle").getItemStyle());
fillPath.style.stroke = null;
var group2 = new Group();
group2.add(strokePath);
group2.add(fillPath);
return group2;
}
function getWave(idx, isInverse, oldWave) {
var radiusX = isFillContainer ? radius[0] : radius;
var radiusY = isFillContainer ? height / 2 : radius;
var itemModel2 = data.getItemModel(idx);
var itemStyleModel = itemModel2.getModel("itemStyle");
var phase = itemModel2.get("phase");
var amplitude = parsePercent(
itemModel2.get("amplitude"),
radiusY * 2
);
var waveLength = parsePercent(
itemModel2.get("waveLength"),
radiusX * 2
);
var value = data.get("value", idx);
var waterLevel = radiusY - value * radiusY * 2;
phase = oldWave ? oldWave.shape.phase : phase === "auto" ? idx * Math.PI / 4 : phase;
var normalStyle = itemStyleModel.getItemStyle();
if (!normalStyle.fill) {
var seriesColor = seriesModel.get("color");
var id = idx % seriesColor.length;
normalStyle.fill = seriesColor[id];
}
var x = radiusX * 2;
var wave = new LiquidShape({
shape: {
waveLength,
radius: radiusX,
radiusY,
cx: x,
cy: 0,
waterLevel,
amplitude,
phase,
inverse: isInverse
},
style: normalStyle,
x: cx,
y: cy
});
wave.shape._waterLevel = waterLevel;
var hoverStyle = itemModel2.getModel("emphasis.itemStyle").getItemStyle();
hoverStyle.lineWidth = 0;
wave.ensureState("emphasis").style = hoverStyle;
enableHoverEmphasis(wave);
var clip = getPath(radius, true);
clip.setStyle({
fill: "white"
});
wave.setClipPath(clip);
return wave;
}
function setWaveAnimation(idx, wave, oldWave) {
var itemModel2 = data.getItemModel(idx);
var maxSpeed = itemModel2.get("period");
var direction = itemModel2.get("direction");
var value = data.get("value", idx);
var phase = itemModel2.get("phase");
phase = oldWave ? oldWave.shape.phase : phase === "auto" ? idx * Math.PI / 4 : phase;
var defaultSpeed = function(maxSpeed2) {
var cnt = data.count();
return cnt === 0 ? maxSpeed2 : maxSpeed2 * (0.2 + (cnt - idx) / cnt * 0.8);
};
var speed = 0;
if (maxSpeed === "auto") {
speed = defaultSpeed(5e3);
} else {
speed = typeof maxSpeed === "function" ? maxSpeed(value, idx) : maxSpeed;
}
var phaseOffset = 0;
if (direction === "right" || direction == null) {
phaseOffset = Math.PI;
} else if (direction === "left") {
phaseOffset = -Math.PI;
} else if (direction === "none") {
phaseOffset = 0;
} else {
console.error("Illegal direction value for liquid fill.");
}
if (direction !== "none" && itemModel2.get("waveAnimation")) {
wave.animate("shape", true).when(0, {
phase
}).when(speed / 2, {
phase: phaseOffset + phase
}).when(speed, {
phase: phaseOffset * 2 + phase
}).during(function() {
if (wavePath) {
wavePath.dirty(true);
}
}).start();
}
}
function getText(waves2) {
var labelModel = itemModel.getModel("label");
function formatLabel() {
var formatted = seriesModel.getFormattedLabel(0, "normal");
var defaultVal = data.get("value", 0) * 100;
var defaultLabel = data.getName(0) || seriesModel.name;
if (!isNaN(defaultVal)) {
defaultLabel = defaultVal.toFixed(0) + "%";
}
return formatted == null ? defaultLabel : formatted;
}
var textRectOption = {
z2: 10,
shape: {
x: left,
y: top,
width: (isFillContainer ? radius[0] : radius) * 2,
height: (isFillContainer ? radius[1] : radius) * 2
},
style: {
fill: "transparent"
},
textConfig: {
position: labelModel.get("position") || "inside"
},
silent: true
};
var textOption = {
style: {
text: formatLabel(),
textAlign: labelModel.get("align"),
textVerticalAlign: labelModel.get("baseline")
}
};
Object.assign(textOption.style, createTextStyle(labelModel));
var outsideTextRect = new Rect(textRectOption);
var insideTextRect = new Rect(textRectOption);
insideTextRect.disableLabelAnimation = true;
outsideTextRect.disableLabelAnimation = true;
var outsideText = new ZRText(textOption);
var insideText = new ZRText(textOption);
outsideTextRect.setTextContent(outsideText);
insideTextRect.setTextContent(insideText);
var insColor = labelModel.get("insideColor");
insideText.style.fill = insColor;
var group2 = new Group();
group2.add(outsideTextRect);
group2.add(insideTextRect);
var boundingCircle = getPath(radius, true);
wavePath = new CompoundPath({
shape: {
paths: waves2
},
x: cx,
y: cy
});
wavePath.setClipPath(boundingCircle);
insideTextRect.setClipPath(wavePath);
return group2;
}
},
dispose: function() {
}
});