@alicloud/cloud-charts
Version:

400 lines (341 loc) • 12.5 kB
JavaScript
;
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
import { getStatusColor, pxToNumber } from './common';
import themes from '../themes';
import { warn } from './log';
/**
* 绘制辅助标记通用函数
*
* @param {Chart} chart 图表实例
* @param {object} config 图表配置项
*
* */
export default function (chart, config) {
var guide = config.guide;
if (!guide || guide.visible === false) {
return;
}
var guideLine = guide.line,
guideArea = guide.area,
guideFilter = guide.filter,
other = _objectWithoutPropertiesLoose(guide, ["line", "area", "filter"]);
if (guideLine) {
if (Array.isArray(guideLine)) {
guideLine.forEach(function (line) {
drawGuideLine(chart, line, config);
});
} else {
drawGuideLine(chart, guideLine, config);
}
}
if (guideArea) {
if (Array.isArray(guideArea)) {
guideArea.forEach(function (area) {
drawGuideArea(chart, area);
});
} else {
drawGuideArea(chart, guideArea);
}
}
if (guideFilter) {
if (Array.isArray(guideFilter)) {
guideFilter.forEach(function (filter) {
drawGuideFilter(chart, filter, config);
});
} else {
drawGuideFilter(chart, guideFilter, config);
}
}
if (!guideLine && !guideArea && !guideFilter && Object.keys(other).length > 0) {
warn('config.guide', '配置异常,请使用 guide.line、guide.area、guide.filter');
}
}
export function drawGuideLine(chart, guideLine, config) {
var _guideLine$top = guideLine.top,
top = _guideLine$top === void 0 ? true : _guideLine$top,
text = guideLine.text,
status = guideLine.status,
axis = guideLine.axis,
value = guideLine.value,
start = guideLine.start,
end = guideLine.end,
_guideLine$style = guideLine.style,
style = _guideLine$style === void 0 ? {} : _guideLine$style;
var rawText = text || '';
var _ref = typeof rawText === 'string' ? {
title: rawText
} : rawText,
title = _ref.title,
titlePosition = _ref.position,
titleAlign = _ref.align,
_ref$style = _ref.style,
textStyle = _ref$style === void 0 ? {} : _ref$style,
offsetY = _ref.offsetY,
offsetX = _ref.offsetX,
textConfig = _objectWithoutPropertiesLoose(_ref, ["title", "position", "align", "style", "offsetY", "offsetX"]);
var color = getStatusColor(status); // 更新处理文本位置
var defaultOffsetY = pxToNumber(themes['widgets-font-size-1']);
var defaultOffsetX = 0;
warn('config.guide', '辅助线暂时不支持柱图镜面和横向的时候开启渐变');
if (offsetY !== undefined) {
defaultOffsetY = offsetY; // 不是镜面和横向的时候
} else if (!(config !== null && config !== void 0 && config.facet) || (config === null || config === void 0 ? void 0 : config.column) !== false) {
if (axis === 'y') {
defaultOffsetY = -(pxToNumber(themes['widgets-font-size-1']) / 2);
}
}
if (offsetX !== undefined) {
defaultOffsetX = offsetX;
} else if (!(config !== null && config !== void 0 && config.facet) || (config === null || config === void 0 ? void 0 : config.column) !== false) {
if (axis === 'y') {
defaultOffsetX = pxToNumber(themes['widgets-font-size-1']) * (typeof rawText === 'string' ? rawText === null || rawText === void 0 ? void 0 : rawText.length : 3) + 8;
}
}
var guideConfig = {
top: top,
style: _extends({
stroke: color
}, style),
text: _extends({
content: title || '',
position: titlePosition || 'start',
style: _extends({
fill: color,
textAlign: titleAlign || ((titlePosition || 'start') !== 'start' ? 'start' : 'end')
}, textStyle),
// X 轴时关闭自动旋转
autoRotate: axis !== 'x',
offsetY: defaultOffsetY,
offsetX: defaultOffsetX
}, textConfig),
// @ts-ignore
start: undefined,
// @ts-ignore
end: undefined
}; // 判断value时需要注意数字0是假值,但是是一个合理的guide value
if (axis && (value || value === 0)) {
if (axis === 'x') {
// y 轴是分类型数据的情况比较少,暂时不处理
guideConfig.start = [value, 'min'];
guideConfig.end = [value, 'max']; // x 轴辅助线,修改position和textAlign默认值
guideConfig.text.position = titlePosition || 'end';
guideConfig.text.style.textAlign = titleAlign || 'center';
guideConfig.text.offsetY = offsetY || 0;
} else if (axis === 'y' || /y\d/.test(axis)) {
// 形似 y0, y1 ...的axis,说明是多Y轴,多轴的情况下,start/end 必须返回原始数据格式才能正确匹配y轴度量
// 函数接受两个参数 xScales 和 yScales
guideConfig.start = function (xScales) {
var _ref3;
if (!Array.isArray(xScales) && (xScales.isCategory || xScales.x && xScales.x.isCategory)) {
var _ref2;
// 如果x轴是分类型数据,使用[-0.5, length - 0.5]的索引值来让辅助线铺满绘图区域
return _ref2 = {
x: -0.5
}, _ref2[axis] = value, _ref2;
}
return _ref3 = {
x: 'min'
}, _ref3[axis] = value, _ref3;
}; // 函数接受两个参数 xScales 和 yScales
guideConfig.end = function (xScales) {
var _ref6;
if (!Array.isArray(xScales)) {
// 如果x轴是分类型数据,使用[-0.5, length - 0.5]的索引值来让辅助线铺满绘图区域
if (xScales.x && xScales.x.isCategory) {
var _ref4;
return _ref4 = {
x: xScales.x.values.length - 0.5
}, _ref4[axis] = value, _ref4;
}
if (xScales.isCategory) {
var _ref5;
// @ts-ignore G2 的类型声明和实际传入不同,暂时忽略报错
return _ref5 = {
x: xScales.values.length - 0.5
}, _ref5[axis] = value, _ref5;
}
}
return _ref6 = {
x: 'max'
}, _ref6[axis] = value, _ref6;
};
}
}
if (start) {
guideConfig.start = start;
}
if (end) {
guideConfig.end = end;
}
if (guideConfig.start && guideConfig.end) {
chart.annotation().line(guideConfig);
} else {
warn('config.guide', 'line 定义不全');
}
}
export function drawGuideArea(chart, guideArea) {
var _guideArea$top = guideArea.top,
top = _guideArea$top === void 0 ? true : _guideArea$top,
status = guideArea.status,
axis = guideArea.axis,
value = guideArea.value,
start = guideArea.start,
end = guideArea.end,
_guideArea$style = guideArea.style,
style = _guideArea$style === void 0 ? {} : _guideArea$style;
var color = getStatusColor(status);
var guideConfig = {
top: top,
style: _extends({
fill: color
}, style),
// @ts-ignore
start: undefined,
// @ts-ignore
end: undefined
};
if (axis && Array.isArray(value) && value.length > 1) {
if (axis === 'x') {
// y 轴是分类型数据的情况比较少,暂时不处理
guideConfig.start = [value[0], 'min'];
guideConfig.end = [value[1], 'max'];
} else if (axis === 'y' || /y\d/.test(axis)) {
// 形似 y0, y1 ...的axis,说明是多Y轴,多轴的情况下,start/end 必须返回原始数据格式才能正确匹配y轴度量
// 函数接受两个参数 xScales 和 yScales
guideConfig.start = function (xScales) {
var _ref8;
if (!Array.isArray(xScales) && (xScales.isCategory || xScales.x && xScales.x.isCategory)) {
var _ref7;
// 如果x轴是分类型数据,使用[-0.5, length - 0.5]的索引值来让辅助线铺满绘图区域
return _ref7 = {
x: -0.5
}, _ref7[axis] = value[0], _ref7;
}
return _ref8 = {
x: 'min'
}, _ref8[axis] = value[0], _ref8;
}; // 函数接受两个参数 xScales 和 yScales
guideConfig.end = function (xScales) {
var _ref11;
if (!Array.isArray(xScales)) {
// 如果x轴是分类型数据,使用[-0.5, length - 0.5]的索引值来让辅助线铺满绘图区域
if (xScales.x && xScales.x.isCategory) {
var _ref9;
return _ref9 = {
x: xScales.x.values.length - 0.5
}, _ref9[axis] = value[1], _ref9;
}
if (xScales.isCategory) {
var _ref10;
// @ts-ignore G2 的类型声明和实际传入不同,暂时忽略报错
return _ref10 = {
x: xScales.values.length - 0.5
}, _ref10[axis] = value[1], _ref10;
}
}
return _ref11 = {
x: 'max'
}, _ref11[axis] = value[1], _ref11;
};
}
}
if (start) {
guideConfig.start = start;
}
if (end) {
guideConfig.end = end;
}
if (guideConfig.start && guideConfig.end) {
chart.annotation().region(guideConfig);
} else {
warn('config.guide', 'area 定义不全');
}
}
export function drawGuideFilter(chart, guideFilter, config) {
var _guideFilter$top = guideFilter.top,
top = _guideFilter$top === void 0 ? true : _guideFilter$top,
status = guideFilter.status,
axis = guideFilter.axis,
value = guideFilter.value,
start = guideFilter.start,
end = guideFilter.end,
apply = guideFilter.apply,
style = guideFilter.style,
_guideFilter$useGradi = guideFilter.useGradient,
useGradient = _guideFilter$useGradi === void 0 ? false : _guideFilter$useGradi;
var color = getStatusColor(status);
var guideColor = color; // 如果镜面或横向不处理
if (!!(config !== null && config !== void 0 && config.facet) || (config === null || config === void 0 ? void 0 : config.column) === false) {
guideColor = color;
} else if (axis === 'y' && useGradient) {
// TODO 考虑方向
guideColor = "l(90) 0:" + color + " 1:" + color + "00";
}
var guideConfig = {
top: top,
color: guideColor,
apply: apply,
style: style,
// @ts-ignore
start: undefined,
// @ts-ignore
end: undefined
};
if (axis && Array.isArray(value) && value.length > 1) {
if (axis === 'x') {
// y 轴是分类型数据的情况比较少,暂时不处理
guideConfig.start = [value[0], 'min'];
guideConfig.end = [value[1], 'max'];
} else if (axis === 'y' || /y\d/.test(axis)) {
// 形似 y0, y1 ...的axis,说明是多Y轴,多轴的情况下,start/end 必须返回原始数据格式才能正确匹配y轴度量
// 函数接受两个参数 xScales 和 yScales
guideConfig.start = function (xScales) {
var _ref13;
if (!Array.isArray(xScales) && (xScales.isCategory || xScales.x && xScales.x.isCategory)) {
var _ref12;
// 如果x轴是分类型数据,使用[-0.5, length - 0.5]的索引值来让辅助线铺满绘图区域
return _ref12 = {
x: -0.5
}, _ref12[axis] = value[0], _ref12;
}
return _ref13 = {
x: 'min'
}, _ref13[axis] = value[0], _ref13;
}; // 函数接受两个参数 xScales 和 yScales
guideConfig.end = function (xScales) {
var _ref16;
if (!Array.isArray(xScales)) {
// 如果x轴是分类型数据,使用[-0.5, length - 0.5]的索引值来让辅助线铺满绘图区域
if (xScales.x && xScales.x.isCategory) {
var _ref14;
return _ref14 = {
x: xScales.x.values.length - 0.5
}, _ref14[axis] = value[1], _ref14;
}
if (xScales.isCategory) {
var _ref15;
// @ts-ignore G2 的类型声明和实际传入不同,暂时忽略报错
return _ref15 = {
x: xScales.values.length - 0.5
}, _ref15[axis] = value[1], _ref15;
}
}
return _ref16 = {
x: 'max'
}, _ref16[axis] = value[1], _ref16;
};
}
}
if (start) {
guideConfig.start = start;
}
if (end) {
guideConfig.end = end;
}
if (guideConfig.start && guideConfig.end) {
chart.annotation().regionFilter(guideConfig);
} else {
warn('config.guide', 'filter 定义不全');
}
}