@alicloud/cloud-charts
Version:

284 lines (271 loc) • 12.4 kB
JavaScript
import React from 'react';
import { warn } from '../common/log';
import { numberDecimal } from '../common/common';
import themes from '../themes';
import { cloneDeep } from 'lodash';
import { FullCrossName } from '../constants';
/** 大数据判断条件 */
export var BigDataJudgement = /*#__PURE__*/function (BigDataJudgement) {
BigDataJudgement[BigDataJudgement["Length"] = 0] = "Length";
BigDataJudgement[BigDataJudgement["Area"] = 1] = "Area";
BigDataJudgement[BigDataJudgement["Polar"] = 2] = "Polar";
BigDataJudgement[BigDataJudgement["Number"] = 3] = "Number";
return BigDataJudgement;
}({});
/** 大数据处理 */
/** 判断是否是大数据(初始化) */
export function isBigDataInit(chartName, judgements, dataSize, width, height, mainAxis) {
if (mainAxis === void 0) {
mainAxis = 'x';
}
if (!dataSize || !width || !height) {
return false;
}
var res = false;
judgements === null || judgements === void 0 ? void 0 : judgements.forEach(function (judgement) {
var type = judgement.type,
threshold = judgement.threshold,
_judgement$period = judgement.period,
period = _judgement$period === void 0 ? 'init' : _judgement$period,
message = judgement.message;
if (period === 'init') {
var isBigData = false;
if (type === BigDataJudgement.Length) {
var length = mainAxis === 'x' ? width !== null && width !== void 0 ? width : 0 : height !== null && height !== void 0 ? height : 0;
isBigData = length > 0 && length / dataSize < threshold;
} else if (type === BigDataJudgement.Area) {
isBigData = height * width / dataSize < threshold;
} else if (type === BigDataJudgement.Number) {
isBigData = dataSize > threshold;
} else if (type === BigDataJudgement.Polar) {
var radius = Math.min(height, width);
isBigData = radius < threshold;
}
res = res || isBigData;
if (isBigData && message) {
warn(chartName, message);
}
}
});
return res;
}
/** 判断是否是大数据(绘制前) */
export function isBigDataBeforePaint(chartName, judgements, chart, dataSize, mainAxis) {
if (mainAxis === void 0) {
mainAxis = 'x';
}
var res = false;
judgements === null || judgements === void 0 ? void 0 : judgements.forEach(function (judgement) {
var type = judgement.type,
threshold = judgement.threshold,
_judgement$period2 = judgement.period,
period = _judgement$period2 === void 0 ? 'init' : _judgement$period2,
message = judgement.message;
if (period === 'before_paint') {
var isBigData = false;
var _ref = (chart === null || chart === void 0 ? void 0 : chart.coordinateBBox) || {},
_ref$width = _ref.width,
width = _ref$width === void 0 ? 0 : _ref$width,
_ref$height = _ref.height,
height = _ref$height === void 0 ? 0 : _ref$height;
if (type === BigDataJudgement.Length) {
var length = mainAxis === 'x' ? width : height;
isBigData = length > 0 && length / dataSize < threshold;
} else if (type === BigDataJudgement.Area) {
isBigData = height * width / dataSize < threshold;
} else if (type === BigDataJudgement.Number) {
isBigData = dataSize > threshold;
}
if (type === BigDataJudgement.Polar) {
var _chart$coordinateBBox, _chart$coordinateBBox2;
var radius = Math.min(chart === null || chart === void 0 ? void 0 : (_chart$coordinateBBox = chart.coordinateBBox) === null || _chart$coordinateBBox === void 0 ? void 0 : _chart$coordinateBBox.height, chart === null || chart === void 0 ? void 0 : (_chart$coordinateBBox2 = chart.coordinateBBox) === null || _chart$coordinateBBox2 === void 0 ? void 0 : _chart$coordinateBBox2.width);
isBigData = radius < threshold;
}
res = res || isBigData;
if (isBigData && message) {
warn(chartName, message);
}
}
});
return res;
}
/** 柱图大数据处理方式:开启slider */
export function processBarBigData(chartObj, data) {
var dataSize = chartObj.dataSize;
var _chartObj$props = chartObj.props,
force = _chartObj$props.force,
config = _chartObj$props.config;
// force时不进行处理
if (force === true || (force === null || force === void 0 ? void 0 : force.bigdata) === true) {
return {};
}
return {
config: {
slider: config !== null && config !== void 0 && config.slider ? config === null || config === void 0 ? void 0 : config.slider : {
start: 1 - Math.max(Number((30 / dataSize).toFixed(2)), 0.01),
end: 1
}
}
};
}
/** 线图大数据处理方式: */
export function processLineBigData(chartObj, data) {
var _chartObj$chartRule, _config$xAxis;
var dataSize = chartObj.dataSize;
var _chartObj$props2 = chartObj.props,
force = _chartObj$props2.force,
config = _chartObj$props2.config;
var chartId = chartObj === null || chartObj === void 0 ? void 0 : (_chartObj$chartRule = chartObj.chartRule) === null || _chartObj$chartRule === void 0 ? void 0 : _chartObj$chartRule.id;
// 开启force时不进行大数据处理
if (force === true || (force === null || force === void 0 ? void 0 : force.bigdata) === true) {
return {};
}
var shouldArea = false;
// 堆叠图对面积不做关闭
if (chartId.includes('stack')) {
shouldArea = true;
}
var needSlider = true;
// 仅cat类型的线图需要自动开启slider
if ((config === null || config === void 0 ? void 0 : (_config$xAxis = config.xAxis) === null || _config$xAxis === void 0 ? void 0 : _config$xAxis.type) !== 'cat') {
needSlider = false;
}
return {
config: {
symbol: false,
spline: false,
area: shouldArea,
slider: config !== null && config !== void 0 && config.slider ? config === null || config === void 0 ? void 0 : config.slider : needSlider ? {
start: 1 - Math.max(Number((30 / dataSize).toFixed(2)), 0.01),
end: 1
} : false
}
};
}
/** 饼图大数据处理方式:合并数据 */
export function processPieBigData(chartObj, data) {
var _props$config;
var dataSize = chartObj.dataSize,
props = chartObj.props;
// const { force } = chartObj.props;
// const chartName = chartObj?.chartRule?.name;
// if (force === true) {
// return {};
// }
if (props !== null && props !== void 0 && (_props$config = props.config) !== null && _props$config !== void 0 && _props$config.autoFormat && dataSize > 5) {
var _props$config2, _tempData$reverse;
// 数据排序
if ((props === null || props === void 0 ? void 0 : (_props$config2 = props.config) === null || _props$config2 === void 0 ? void 0 : _props$config2.autoSort) !== false) {
data.sort(function (a, b) {
return b.y - a.y;
});
}
// 计算总数据
var total = data.reduce(function (pre, cur) {
return pre + cur.y;
}, 0);
// 数据逆序计算,需要动态计算出从第几个数据开始合并为其他
var remainReverseIndex = 0;
// 用于计算剩余数量总和,当总和占total的占比小于10%的时候,将当前数据索引保存,作为其他
var tempRemainCount = 0;
var tempData = cloneDeep(data);
tempData === null || tempData === void 0 ? void 0 : (_tempData$reverse = tempData.reverse()) === null || _tempData$reverse === void 0 ? void 0 : _tempData$reverse.forEach(function (a, index) {
var _props$config$autoFor, _props$config3, _props$config3$autoFo;
tempRemainCount += a.y;
if (numberDecimal(tempRemainCount / total <= ((_props$config$autoFor = props === null || props === void 0 ? void 0 : (_props$config3 = props.config) === null || _props$config3 === void 0 ? void 0 : (_props$config3$autoFo = _props$config3.autoFormat) === null || _props$config3$autoFo === void 0 ? void 0 : _props$config3$autoFo.percent) !== null && _props$config$autoFor !== void 0 ? _props$config$autoFor : 0.1))) {
remainReverseIndex = index;
}
});
if (remainReverseIndex !== data.length) {
var remainIndex = data.length - (remainReverseIndex + 1);
// 计算剩余占比
var remainTotal = numberDecimal(data.slice(remainIndex, data.length).reduce(function (pre, cur) {
return pre + cur.y;
}, 0));
var newData = [].concat(data.slice(0, remainIndex), [{
x: '其他',
y: remainTotal,
extra: data.slice(remainIndex, data.length)
}]);
return {
data: newData,
config: {
autoSort: false,
colors: themes.category_12.slice(0, remainIndex).concat(themes['widgets-axis-line']),
tooltip: {
reactContent: function reactContent(title, data) {
var _data$0$data$extra, _data$, _data$$data;
var extraData = (_data$0$data$extra = data === null || data === void 0 ? void 0 : (_data$ = data[0]) === null || _data$ === void 0 ? void 0 : (_data$$data = _data$.data) === null || _data$$data === void 0 ? void 0 : _data$$data.extra) !== null && _data$0$data$extra !== void 0 ? _data$0$data$extra : [];
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: "g2-tooltip-title"
}), /*#__PURE__*/React.createElement("ul", {
className: "g2-tooltip-list"
}, data.map(function (el) {
return /*#__PURE__*/React.createElement("li", {
className: FullCrossName + "-tooltip-extra-list-item g2-tooltip-list-item",
style: {
display: 'flex',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
className: "g2-tooltip-marker",
style: {
width: '6px',
height: '6px',
borderRadius: '50%',
backgroundColor: el.color
}
}), /*#__PURE__*/React.createElement("div", {
className: "g2-tooltip-name"
}, el.name), ":", /*#__PURE__*/React.createElement("div", {
className: "g2-tooltip-value",
style: {
flex: 1,
textAlign: 'end'
}
}, el.value));
})), (extraData === null || extraData === void 0 ? void 0 : extraData.length) > 0 && /*#__PURE__*/React.createElement("div", {
className: FullCrossName + "-tooltip-extra"
}, /*#__PURE__*/React.createElement("div", {
className: FullCrossName + "-tooltip-extra-divide",
style: {
height: 1,
width: '100%',
backgroundColor: themes['widgets-color-cold-grey-14'],
marginBottom: 12
}
})), (extraData === null || extraData === void 0 ? void 0 : extraData.length) > 0 && /*#__PURE__*/React.createElement("ul", {
className: FullCrossName + "-tooltip-extra-list g2-tooltip-list"
}, extraData.map(function (el, index) {
return /*#__PURE__*/React.createElement("li", {
className: FullCrossName + "-tooltip-extra-list-item g2-tooltip-list-item",
style: {
display: 'flex',
alignItems: 'center'
}
}, /*#__PURE__*/React.createElement("div", {
className: FullCrossName + "-tooltip-extra-marker g2-tooltip-marker",
style: {
width: '6px',
height: '6px',
borderRadius: '50%',
backgroundColor: themes.category_20[remainIndex + index]
}
}), /*#__PURE__*/React.createElement("div", {
className: FullCrossName + "-tooltip-extra-name g2-tooltip-name"
}, el.x), ":", /*#__PURE__*/React.createElement("div", {
className: FullCrossName + "-tooltip-extra-value g2-tooltip-value",
style: {
flex: 1,
textAlign: 'end'
}
}, el.y));
})));
}
}
}
};
}
}
return {};
}