Files
railwaysystem/RuoYi-Vue/ruoyi-ui/node_modules1/@antv/g6-element/lib/nodes/donut.js
T
2026-09-10 15:40:10 +08:00

324 lines
9.9 KiB
JavaScript

"use strict";
var _tslib = require("tslib");
var _g6Core = require("@antv/g6-core");
var _util = require("@antv/util");
var defaultSubjectColors = _g6Core.Util.defaultSubjectColors;
var FAN_NAME_PREFIX = 'fan-shape-';
/**
* calculate the total value and format single value for each fan
* @param donutAttrs
* @param donutColorMap
* @returns
*/
var getDonutConfig = function getDonutConfig(donutAttrs, donutColorMap) {
var totalValue = 0;
var configs = [];
Object.keys(donutAttrs).forEach(function (name) {
var value = +donutAttrs[name];
if (isNaN(value)) return;
configs.push({
key: name,
value: value,
color: donutColorMap[name]
});
totalValue += value;
});
return {
totalValue: totalValue,
configs: configs
};
};
/**
* calculate the lineWidth and radius for fan shapes according to the keyShape's radius
* @param keyShape
* @returns
*/
var getDonutSize = function getDonutSize(keyShape) {
var keyShapeR = keyShape.attr('r');
var innerR = 0.6 * keyShapeR; // 甜甜圈的内环半径
var arcR = (keyShapeR + innerR) / 2; // 内环半径与外环半径的平均值
var lineWidth = keyShapeR - innerR;
return {
lineWidth: lineWidth,
arcR: arcR
};
};
/**
* draws one fan shape and returns the next position and angle
* @param group
* @param fanConfig
* @returns
*/
var drawFan = function drawFan(group, fanConfig) {
var arcR = fanConfig.arcR,
arcBegin = fanConfig.arcBegin,
beginAngle = fanConfig.beginAngle,
config = fanConfig.config,
fanIndex = fanConfig.fanIndex,
lineWidth = fanConfig.lineWidth,
totalValue = fanConfig.totalValue,
_a = fanConfig.drawWhole,
drawWhole = _a === void 0 ? false : _a,
_b = fanConfig.updateShape,
updateShape = _b === void 0 ? undefined : _b;
var percent = config.value / totalValue;
if (percent < 0.001) {
// too small to add a fan
return {
beginAngle: beginAngle,
arcBegin: arcBegin,
shape: undefined,
shouldEnd: false
};
}
var arcEnd, endAngle, isBig;
// draw a path represents the whole circle, or the percentage is close to 1
if (drawWhole || percent > 0.999) {
arcEnd = [arcR, 0.0001]; // [arcR * cos(2 * PI), -arcR * sin(2 * PI)]
isBig = 1;
} else {
var angle = percent * Math.PI * 2;
endAngle = beginAngle + angle;
arcEnd = [arcR * Math.cos(endAngle), -arcR * Math.sin(endAngle)];
isBig = angle > Math.PI ? 1 : 0;
}
var style = {
path: [['M', arcBegin[0], arcBegin[1]], ['A', arcR, arcR, 0, isBig, 0, arcEnd[0], arcEnd[1]]],
stroke: config.color || (updateShape === null || updateShape === void 0 ? void 0 : updateShape.attr('stroke')) || defaultSubjectColors[fanIndex % defaultSubjectColors.length],
lineWidth: lineWidth
};
if (updateShape) {
// update
updateShape.attr(style);
} else {
// draw
group['shapeMap']["".concat(FAN_NAME_PREFIX).concat(fanIndex)] = group.addShape('path', {
attrs: style,
name: "".concat(FAN_NAME_PREFIX).concat(fanIndex),
draggable: true
});
}
return {
beginAngle: endAngle,
arcBegin: arcEnd,
shape: group['shapeMap']["".concat(FAN_NAME_PREFIX).concat(fanIndex)],
shouldEnd: drawWhole || percent > 0.999
};
};
/**
* draws the fan shapes
* @param cfg
* @param group
* @param keyShape
* @returns
*/
var drawFans = function drawFans(cfg, group, keyShape) {
var _a = cfg.donutAttrs,
donutAttrs = _a === void 0 ? {} : _a,
_b = cfg.donutColorMap,
donutColorMap = _b === void 0 ? {} : _b;
var attrNum = Object.keys(donutAttrs).length;
if (donutAttrs && attrNum > 1) {
var _c = getDonutConfig(donutAttrs, donutColorMap),
configs = _c.configs,
totalValue = _c.totalValue;
if (totalValue) {
var _d = getDonutSize(keyShape),
lineWidth = _d.lineWidth,
arcR = _d.arcR;
var arcBegin = [arcR, 0];
var beginAngle = 0;
if (attrNum === 1) {
// draw a path represents a circle
drawFan(group, {
arcR: arcR,
arcBegin: arcBegin,
beginAngle: beginAngle,
config: configs[0],
fanIndex: 0,
lineWidth: lineWidth,
totalValue: totalValue,
drawWhole: true
});
return;
}
for (var i = 0; i < configs.length; i++) {
var result = drawFan(group, {
arcR: arcR,
arcBegin: arcBegin,
beginAngle: beginAngle,
config: configs[i],
fanIndex: i,
lineWidth: lineWidth,
totalValue: totalValue
});
if (result.shouldEnd) return;
arcBegin = result.arcBegin;
beginAngle = result.beginAngle;
}
}
}
};
/**
* utilizes the existing fan shapes, update them with new configs
* removes the redundent fan shapes
* or adds more fan shapes
* @param cfg
* @param item
* @param keyShape
*/
var updateFans = function updateFans(cfg, item, keyShape) {
var donutAttrs = cfg.donutAttrs,
_a = cfg.donutColorMap,
donutColorMap = _a === void 0 ? {} : _a;
var visitMap = {};
var group = item.getContainer();
if (donutAttrs) {
var _b = getDonutConfig(donutAttrs, donutColorMap),
configs = _b.configs,
totalValue = _b.totalValue;
if (totalValue) {
var _c = getDonutSize(keyShape),
lineWidth = _c.lineWidth,
arcR = _c.arcR;
var arcBegin = [arcR, 0];
var beginAngle = 0;
for (var i = 0; i < configs.length; i++) {
var shapeName = "".concat(FAN_NAME_PREFIX).concat(i);
var result = drawFan(group, {
arcR: arcR,
arcBegin: arcBegin,
beginAngle: beginAngle,
config: configs[i],
fanIndex: i,
lineWidth: lineWidth,
totalValue: totalValue,
drawWhole: configs.length === 1,
updateShape: group['shapeMap'][shapeName]
});
if (result.shape) visitMap[shapeName] = true;
if (result.shouldEnd) break;
arcBegin = result.arcBegin;
beginAngle = result.beginAngle;
}
}
}
// remove the old shapes which are not visited, including the situation taht donutAttrs is empty
var fanKeys = Object.keys(group['shapeMap']).filter(function (key) {
return key.includes(FAN_NAME_PREFIX);
});
fanKeys.forEach(function (key) {
if (!visitMap[key]) {
group['shapeMap'][key].remove(true);
delete group['shapeMap'][key];
}
});
};
// 饼图节点
(0, _g6Core.registerNode)('donut', {
// 自定义节点时的配置
options: {
size: _g6Core.BaseGlobal.defaultNode.size,
style: {
x: 0,
y: 0,
stroke: _g6Core.BaseGlobal.defaultNode.style.stroke,
fill: _g6Core.BaseGlobal.defaultNode.style.fill,
lineWidth: _g6Core.BaseGlobal.defaultNode.style.lineWidth
},
labelCfg: {
style: {
fill: _g6Core.BaseGlobal.nodeLabel.style.fill,
fontSize: _g6Core.BaseGlobal.nodeLabel.style.fontSize,
fontFamily: _g6Core.BaseGlobal.windowFontFamily
}
},
// 节点上左右上下四个方向上的链接circle配置
linkPoints: {
top: false,
right: false,
bottom: false,
left: false,
// circle的大小
size: _g6Core.BaseGlobal.defaultNode.linkPoints.size,
lineWidth: _g6Core.BaseGlobal.defaultNode.linkPoints.lineWidth,
fill: _g6Core.BaseGlobal.defaultNode.linkPoints.fill,
stroke: _g6Core.BaseGlobal.defaultNode.linkPoints.stroke
},
// 节点中icon配置
icon: {
// 是否显示icon,值为 false 则不渲染icon
show: false,
// icon的地址,字符串类型
img: 'https://gw.alipayobjects.com/zos/bmw-prod/5d015065-8505-4e7a-baec-976f81e3c41d.svg',
width: 20,
height: 20
},
stateStyles: (0, _tslib.__assign)({}, _g6Core.BaseGlobal.nodeStateStyles)
},
shapeType: 'circle',
// 文本位置
labelPosition: 'center',
drawShape: function drawShape(cfg, group) {
var _a = (this.mergeStyle || this.getOptions(cfg)).icon,
defaultIcon = _a === void 0 ? {} : _a;
var style = this.getShapeStyle(cfg);
var icon = (0, _util.deepMix)({}, defaultIcon, cfg.icon);
var keyShape = group.addShape('circle', {
attrs: style,
className: "".concat(this.type, "-keyShape"),
draggable: true,
name: "".concat(this.type, "-keyShape")
});
group['shapeMap']["".concat(this.type, "-keyShape")] = keyShape;
var width = icon.width,
height = icon.height,
show = icon.show,
text = icon.text;
if (show) {
if (text) {
group['shapeMap']["".concat(this.type, "-icon")] = group.addShape('text', {
attrs: (0, _tslib.__assign)({
x: 0,
y: 0,
fontSize: 12,
fill: '#000',
stroke: '#000',
textBaseline: 'middle',
textAlign: 'center'
}, icon),
className: "".concat(this.type, "-icon"),
name: "".concat(this.type, "-icon"),
draggable: true
});
} else {
group['shapeMap']["".concat(this.type, "-icon")] = group.addShape('image', {
attrs: (0, _tslib.__assign)({
x: -width / 2,
y: -height / 2
}, icon),
className: "".concat(this.type, "-icon"),
name: "".concat(this.type, "-icon"),
draggable: true
});
}
}
// draw the fan shapes
drawFans(cfg, group, keyShape);
this.drawLinkPoints(cfg, group);
return keyShape;
},
updateShape: function updateShape(cfg, item, keyShapeStyle, hasIcon, updateType) {
// here cfg is merged configure including old model and new configs
var keyShape = item.get('keyShape');
keyShape.attr((0, _tslib.__assign)({}, keyShapeStyle));
updateFans(cfg, item, keyShape);
if (!undefined || (updateType === null || updateType === void 0 ? void 0 : updateType.includes('label'))) {
this.updateLabel(cfg, item, updateType);
}
if (hasIcon) {
this.updateIcon(cfg, item);
}
}
}, 'circle');