@alicloud/cloud-charts
Version:

425 lines (415 loc) • 14 kB
JavaScript
;
import _extends from "@babel/runtime/helpers/extends";
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import Base from '../common/Base';
import errorWrap from '../common/errorWrap';
import themes from '../themes/index';
import { getShapeFactory } from '@antv/g2/esm/core';
import { propertyAssign, getDataIndexColor, propertyMap, getAreaColors } from '../common/common';
import highchartsDataToG2Data from '../common/dataAdapter';
import rectXAxis from '../common/rectXAxis';
import rectYAxis from '../common/rectYAxis';
import autoTimeScale from '../common/autoTimeScale';
import rectTooltip from '../common/rectTooltip';
import rectLegend from '../common/rectLegend';
import legendFilter from '../common/legendFilter';
import label from '../common/label';
import geomSize from '../common/geomSize';
import geomStyle from '../common/geomStyle';
import { activeRegionWithTheme } from '../common/interaction/index';
function getLegendItems(lineData, boxData, lineGeom, boxGeom, config) {
var result = [];
var reMap = {};
var lineColors = config.lineColors,
boxColors = config.boxColors;
function getItems(data, geom, shapeType, colors, style) {
data.forEach(function (d, i) {
var name = d.name,
visible = d.visible,
data = d.data;
if (reMap[name] || !data || data.length === 0) {
return;
} else {
reMap[name] = true;
}
var marker;
var shapeFactory = getShapeFactory(geom.shapeType);
if (shapeFactory) {
marker = shapeFactory.getMarker(shapeType, {
color: typeof colors === 'string' ? colors : Array.isArray(colors) ? colors[i % colors.length] : colors(name),
isInPolar: false
});
var symbol = marker.symbol;
// @ts-ignore
if (typeof symbol === 'string' && MarkerSymbols[symbol]) {
// @ts-ignore
marker.symbol = MarkerSymbols[symbol];
}
}
if (style) {
Object.assign(marker.style, style);
}
result.push({
id: name,
name: name,
value: name,
marker: marker,
unchecked: visible === false
});
});
}
getItems(boxData, boxGeom, 'box', boxColors);
var area = config.area,
spline = config.spline;
var lineShapeType = 'line';
var lineStyle = {};
if (area) {
lineShapeType = 'area';
}
if (spline) {
lineShapeType = 'smooth';
}
if (!area && spline) {
lineStyle.fill = null;
}
getItems(lineData, lineGeom, lineShapeType, lineColors, lineStyle);
return result;
}
export var Linebox = /*#__PURE__*/function (_Base) {
_inheritsLoose(Linebox, _Base);
function Linebox() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _Base.call.apply(_Base, [this].concat(args)) || this;
_this.chartName = 'G2Linebox';
_this.convertData = false;
_this.rawLineData = [];
_this.lineView = void 0;
_this.rawBoxData = [];
_this.boxView = void 0;
return _this;
}
var _proto = Linebox.prototype;
_proto.getDefaultConfig = function getDefaultConfig() {
return {
lineColors: themes.category_12.slice(1),
boxColors: themes.linear_10,
padding: 'auto',
xAxis: {
type: 'timeCat',
// 默认为线性
mask: 'auto',
labelFormatter: null,
// 可以强制覆盖,手动设置label
categories: null,
// autoRotate: false,
max: null,
min: null
},
yAxis: {
labelFormatter: null,
// 可以强制覆盖,手动设置label
max: null,
min: null
},
legend: {
align: 'left',
nameFormatter: null // 可以强制覆盖,手动设置label
},
tooltip: {
titleFormatter: null,
nameFormatter: null,
valueFormatter: null
},
area: false,
dodge: true,
marginRatio: 0,
grid: false,
symbol: false,
boxSize: null
};
};
_proto.beforeInit = function beforeInit(props) {
return _extends({
syncViewPadding: true
}, props);
};
_proto.init = function init(chart, config, data) {
var _this2 = this;
var rawLineData = [];
this.rawLineData = rawLineData;
var rawBoxData = [];
this.rawBoxData = rawBoxData;
(data || []).forEach(function (d) {
if (d.type === 'line') {
rawLineData.push(d);
} else if (d.type === 'box') {
rawBoxData.push(d);
}
});
var lineData = highchartsDataToG2Data(rawLineData, config, {});
var boxData = highchartsDataToG2Data(rawBoxData, config, {});
var defs = {
x: propertyAssign(propertyMap.axis, {
type: 'cat',
// fix 更新数据时x轴无法清除数据
sync: true
}, config.xAxis),
type: {
type: 'cat'
}
};
// 双轴
if (Array.isArray(config.yAxis)) {
config.yAxis.forEach(function (axis, yIndex) {
defs["y" + yIndex] = propertyAssign(propertyMap.axis, {
type: 'linear',
tickCount: 5,
nice: true
}, axis);
});
} else {
defs.y = propertyAssign(propertyMap.axis, {
type: 'linear',
tickCount: 5,
// 单轴时,必须同步度量,否则会两个度量叠加在一起
sync: true,
nice: true
}, config.yAxis);
}
autoTimeScale(defs, this.rawData, this.language || this.context.language);
chart.scale(defs);
// 设置X轴
rectXAxis(this, chart, config);
if (Array.isArray(config.yAxis)) {
config.yAxis.forEach(function (axis, yIndex) {
var axisColor = themes['widgets-axis-line'];
var yAxisConfig = {
line: {
style: {
stroke: axisColor
}
}
};
if (yIndex !== 0) {
yAxisConfig.grid = null;
// 因为是多个view组成的图表,所以这里需要移动位置
yAxisConfig.position = 'right';
}
rectYAxis(_this2, chart, _extends({}, config, {
yAxis: axis
}), "y" + yIndex, yAxisConfig);
});
} else {
// 设置单个Y轴
rectYAxis(this, chart, config);
}
rectTooltip(this, chart, config, {}, null, {
showCrosshairs: false,
showMarkers: false
});
// 正式开始绘图,创建两个不同的view
var boxView = chart.createView({
padding: config.padding === 'auto' ? 'auto' : 0
});
boxView.data(boxData);
this.boxView = boxView;
// Tooltip 背景区域
activeRegionWithTheme(boxView);
var lineView = chart.createView({
padding: config.padding === 'auto' ? 'auto' : 0
});
lineView.data(lineData);
this.lineView = lineView;
// 关闭一个View的X轴,避免重叠字体变粗
lineView.axis('x', false);
if (Array.isArray(config.yAxis)) {
config.yAxis.forEach(function (asix, yIndex) {
if (getDataIndexColor(config.boxColors, rawBoxData, yIndex)) {
drawBox(boxView, config, "y" + yIndex, 'type');
}
if (getDataIndexColor(config.lineColors, rawLineData, yIndex)) {
drawLine(lineView, config, "y" + yIndex, 'type');
}
});
} else {
// 单Y轴时同时关闭一个View的Y轴,避免重叠字体变粗
lineView.axis('y', false);
drawBox(boxView, config, 'y', 'type');
drawLine(lineView, config, 'y', 'type');
}
// 绘制辅助线,辅助背景区域
// viewGuide(config, lineView, rawLineData, boxView, rawBoxData);
legendFilter(this, boxView, 'rawBoxData');
legendFilter(this, lineView, 'rawLineData');
rectLegend(this, chart, config, {
items: getLegendItems(rawLineData, rawBoxData, lineView.geometries[0], boxView.geometries[0], config)
}, 'multiple');
};
_proto.changeData = function changeData(chart, config, data) {
var rawLineData = [];
this.rawLineData = rawLineData;
var rawBoxData = [];
this.rawBoxData = rawBoxData;
(data || []).forEach(function (d) {
if (d.type === 'line') {
rawLineData.push(d);
} else if (d.type === 'box') {
rawBoxData.push(d);
}
});
var lineData = highchartsDataToG2Data(rawLineData, config, {});
var boxData = highchartsDataToG2Data(rawBoxData, config, {});
this.boxView && this.boxView.data(boxData);
this.lineView && this.lineView.data(lineData);
if (this.boxView && this.lineView) {
var chartOptions = chart.getOptions();
var legend = chart.getController('legend');
var legendCos = legend.getComponents();
// 图例项可见,更新图例项
if (legend.visible && legendCos.length > 0 && typeof chartOptions.legends === 'object') {
chartOptions.legends.items = getLegendItems(rawLineData, rawBoxData, this.lineView.geometries[0], this.boxView.geometries[0], config);
// chart.legend({
// items: newItems
// });
}
}
// 更新数据后再次render,保证 padding 能正确计算。
chart.render(true);
};
return Linebox;
}(Base);
var Wlinebox = errorWrap(Linebox);
export default Wlinebox;
function drawBox(chart, config, yAxisKey, legendKey) {
if (yAxisKey === void 0) {
yAxisKey = 'y';
}
if (legendKey === void 0) {
legendKey = 'type';
}
var marginRatio = config.marginRatio,
dodge = config.dodge,
boxSize = config.boxSize,
boxColors = config.boxColors,
_config$boxMinSize = config.boxMinSize,
boxMinSize = _config$boxMinSize === void 0 ? 20 : _config$boxMinSize,
_config$boxMaxSize = config.boxMaxSize,
boxMaxSize = _config$boxMaxSize === void 0 ? 24 : _config$boxMaxSize;
var geomConfig = {
minColumnWidth: boxMinSize || null,
maxColumnWidth: boxMaxSize || null
};
var intervalGeom = chart.schema(geomConfig).position(['x', 'y']).shape('box').color(legendKey, boxColors).state({
active: {
style: function style(ele) {
var _ele$model;
return {
stroke: ele === null || ele === void 0 ? void 0 : (_ele$model = ele.model) === null || _ele$model === void 0 ? void 0 : _ele$model.color
};
}
},
selected: {
style: function style(ele) {
var _ele$model2;
return {
stroke: ele === null || ele === void 0 ? void 0 : (_ele$model2 = ele.model) === null || _ele$model2 === void 0 ? void 0 : _ele$model2.color
};
}
}
});
;
if (dodge !== false) {
intervalGeom.adjust([{
type: 'dodge',
marginRatio: marginRatio || 0.5 // 数值范围为 0 至 1,用于调整分组中各个柱子的间距
}]);
}
geomSize(intervalGeom, boxSize, null, yAxisKey, "x*" + yAxisKey + "*" + legendKey + "*extra");
geomStyle(intervalGeom, config.boxGeomStyle, {
lineWidth: 2
}, "x*" + yAxisKey + "*" + legendKey + "*extra");
return intervalGeom;
}
function drawLine(chart, config, yAxisKey, legendKey) {
if (yAxisKey === void 0) {
yAxisKey = 'y';
}
if (legendKey === void 0) {
legendKey = 'type';
}
var areaColors = config.areaColors || config.lineColors;
if (Array.isArray(config.lineColors) && Array.isArray(config.areaColors)) {
areaColors = mergeArray([], config.lineColors, config.areaColors);
}
if (Array.isArray(areaColors)) {
areaColors = getAreaColors(areaColors);
}
var lineGeom = null;
var areaGeom = null;
var lineWidth = config.lineWidth;
// 区域、堆叠、平滑曲线
var lineShape = config.spline ? 'smooth' : 'line';
var areaShape = config.spline ? 'smooth' : 'area';
var stack = config.stack;
if (config.area && stack) {
areaGeom = chart.area().position(['x', yAxisKey]).color(legendKey, areaColors).tooltip(false).shape(areaShape).adjust('stack');
lineGeom = chart.line().position(['x', yAxisKey]).color(legendKey, config.lineColors).shape(lineShape).adjust('stack');
} else if (config.area && !stack) {
areaGeom = chart.area().position(['x', yAxisKey]).color(legendKey, areaColors).tooltip(false).shape(areaShape);
lineGeom = chart.line().position(['x', yAxisKey]).color(legendKey, config.lineColors).shape(lineShape);
} else {
lineGeom = chart.line().position(['x', yAxisKey]).color(legendKey, config.lineColors).shape(lineShape);
}
if (areaGeom && typeof config.area === 'object') {
if (config.area.geomStyle) {
geomStyle(areaGeom, config.area.geomStyle, {}, "x*" + yAxisKey + "*type*extra");
}
}
geomStyle(lineGeom, config.lineGeomStyle, {
lineWidth: lineWidth || themes['widgets-line-width'],
lineJoin: 'round'
}, "x*" + yAxisKey + "*" + legendKey + "*extra");
label({
geom: lineGeom,
config: config,
field: yAxisKey,
extraConfigKey: 'lineLabel'
});
// 曲线默认点
if (config.symbol) {
var pointGeom = null;
if (config.area && stack) {
pointGeom = chart.point().adjust('stack').position(['x', yAxisKey]).color(legendKey, config.lineColors).shape('circle').size(3);
} else {
pointGeom = chart.point().position(['x', yAxisKey]).color(legendKey, config.lineColors).shape('circle').size(3);
}
if (typeof config.symbol === 'object') {
geomSize(pointGeom, config.symbol.size, 3, yAxisKey, legendKey);
if (config.symbol.geomStyle) {
geomStyle(pointGeom, config.symbol.geomStyle, {}, "x*" + yAxisKey + "*" + legendKey + "*extra");
}
}
}
return lineGeom;
}
function mergeArray(target) {
for (var _len2 = arguments.length, source = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
source[_key2 - 1] = arguments[_key2];
}
source.forEach(function (s) {
if (!s || s.length === 0) {
return;
}
s.forEach(function (item, i) {
if (i >= target.length) {
target.push(item);
} else {
target[i] = item;
}
});
});
return target;
}