in src/Wlinebar/index.tsx [242:528]
init(chart: Chart, config: WlinebarConfig, data: ChartData) {
const rawLineData: DataAdapterData[] = [];
this.rawLineData = rawLineData;
const rawBarData: DataAdapterData[] = [];
this.rawBarData = rawBarData;
(data || []).forEach((d: DataAdapterData) => {
if (d.type === 'line') {
rawLineData.push(d);
} else if (d.type === 'bar') {
rawBarData.push(d);
}
});
const lineData = highchartsDataToG2Data(rawLineData, config as DataAdapterConfig, {
// type: 'lineType',
});
const barData = highchartsDataToG2Data(rawBarData, config as DataAdapterConfig, {
// type: 'barType',
});
const defs: Record<string, Types.ScaleOption> = {
x: propertyAssign(
propertyMap.axis,
{
type: 'cat',
// fix 更新数据时x轴无法清除数据
// sync: 'x',
tickCount: null
},
config.xAxis,
),
type: {
type: 'cat',
},
};
if (Array.isArray(config.yAxis)) {
config.yAxis.forEach((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((axis, yIndex) => {
const axisColor =
// getDataIndexColor(config.lineColors, rawLineData, yIndex) ||
// getDataIndexColor(config.barColors, rawBarData, yIndex) ||
themes['widgets-axis-line'];
const yAxisConfig: Types.AxisCfg = {
line: {
style: {
stroke: axisColor,
},
},
};
if (yIndex !== 0) {
yAxisConfig.grid = null;
// 因为是多个view组成的图表,所以这里需要移动位置
yAxisConfig.position = 'right';
}
rectYAxis(this, chart, { ...config, yAxis: axis }, `y${yIndex}`, yAxisConfig);
});
} else {
// 设置单个Y轴
rectYAxis(this, chart, config as { yAxis: (Types.ScaleOption & YAxisConfig) | false });
}
// 设置图例
// const legendStyle = {
// ...legendHtmlContainer,
// display: 'inline-block',
// position: 'relative',
// };
// // const legendItemStyle = {
// // ...legendHtmlListItem,
// // };
// if (config.legend !== false) {
// const { position, align } = config.legend || {};
//
// // if (position === 'top') {
// // legendStyle.top = themes['widgets-font-size-1'];
// // }
//
// if (align === 'right') {
// legendStyle.marginLeft = themes['widgets-font-size-1'];
// } else if (align === 'left') {
// legendStyle.marginRight = themes['widgets-font-size-1'];
// } else if (align === 'center') {
// legendStyle.marginRight = themes['widgets-font-size-1'];
// } else {
// // 默认放到左边
// legendStyle.marginRight = themes['widgets-font-size-1'];
// }
//
// if (position === 'bottom') {
// legendStyle.top = '100%';
// legendStyle.transform = 'translate(0, -100%)';
// legendStyle.overflow = 'visible';
// legendStyle.verticalAlign = 'top';
//
// // legendItemStyle.marginBottom = 0;
// // legendItemStyle.marginTop = themes['widgets-font-size-1'];
// }
// }
// tooltip
rectTooltip(this, chart, config, {}, null, {
showCrosshairs: false,
showMarkers: false,
});
// 正式开始绘图,创建两个不同的view
const barView = chart.createView({
padding: config.padding === 'auto' ? 'auto' : 0,
});
barView.data(barData);
this.barView = barView;
// Tooltip 背景区域
activeRegionWithTheme(barView);
const lineView = chart.createView({
padding: config.padding === 'auto' ? 'auto' : 0,
});
lineView.data(lineData);
this.lineView = lineView;
// 关闭一个View的X轴,避免重叠字体变粗
// 用于解决缩放后线视图位移的问题
lineView.axis('x', {
top: false,
line: null,
subTickLine: null,
tickLine: null,
grid: null,
animate: false,
label: {
style: {
fill: "rgba(0,0,0,0)"
}
}
});
if (Array.isArray(config.yAxis)) {
config.yAxis.forEach((asix, yIndex) => {
if (getDataIndexColor(config.barColors, rawBarData, yIndex)) {
drawBar(barView, config, `y${yIndex}`, 'type');
}
if (getDataIndexColor(config.lineColors, rawLineData, yIndex)) {
drawLine(lineView, config, `y${yIndex}`, 'type');
}
});
} else {
// 单Y轴时同时关闭一个View的Y轴,避免重叠字体变粗
lineView.axis('y', false);
drawBar(barView, config, 'y', 'type');
drawLine(lineView, config, 'y', 'type');
}
// 绘制辅助线,辅助背景区域
viewGuide(config, lineView, rawLineData, barView, rawBarData);
legendFilter(this, barView, 'rawBarData');
legendFilter(this, lineView, 'rawLineData');
rectLegend(
this,
chart,
config,
{
items: getLegendItems(rawLineData, rawBarData, lineView.geometries[0], barView.geometries[0], config),
},
'multiple',
);
rectZoom(chart, config, getText('reset', this.language || this.context.language, this.context.locale));
// 判断是否要加padding
chart.on('beforepaint', () => {
chart.views.forEach((view: any) => {
if (view?.geometries?.length === 0) {
return;
}
// 柱图还是线图
const chartType = view?.geometries?.[0]?.shapeType === 'interval' ? 'bar' : 'line';
// y轴刻度最大值
const yAxisKey =
'y' in view?.geometries?.[0]?.scales ? 'y' : 'y0' in view?.geometries?.[0]?.scales ? 'y0' : 'y1';
const axisMax = view?.geometries?.[0]?.scales?.[yAxisKey]?.max;
// y轴高度
const height = view?.coordinateBBox?.height;
// 是否显示label,且label在top
const showLabel =
config?.[`${chartType}Label`] === true ||
(typeof config?.[`${chartType}Label`] === 'object' &&
config?.[`${chartType}Label`]?.visible !== false &&
(config?.[`${chartType}Label`]?.position === undefined ||
config?.[`${chartType}Label`]?.position === 'top'));
// 是否隐藏legend,或legend不在top
const hideLegend =
config?.legend === false ||
(typeof config?.legend === 'object' &&
(config?.legend?.visible === false || (config?.legend?.position && config?.legend?.position !== 'top')));
if (!config?.appendPadding && showLabel && hideLegend) {
const valueMap: Record<string, number> = {};
(view?.filteredData || []).forEach((d: any) => {
if (chartType === 'bar') {
const xValue = `${d.x}-${config?.stack ? '' : d.dodge || ''}`;
if (!(xValue in valueMap)) {
valueMap[xValue] = 0;
}
// 区间柱状图
if (Array.isArray(d?.[yAxisKey])) {
valueMap[xValue] += d?.[yAxisKey] || 0;
} else {
// 堆叠、分组堆叠、普通柱图
valueMap[xValue] += d?.[yAxisKey] || 0;
}
} else {
valueMap[d.x] = d?.[yAxisKey] || 0;
}
});
const maxY = Math.max(...Object.values(valueMap));
// 判断最高的柱子距离顶部的间距是否过小
const dis = (1 - maxY / axisMax) * height;
if (dis < 20) {
chart.appendPadding = [20, 0, 0, 0];
} else {
chart.appendPadding = undefined;
}
}
});
});
// chart.on('afterrender', () => {
// // chart.getLegendAttributes()
// // console.log('getLegendAttributes', barView.geometries[0].getAttribute('shape'));
// // console.log('getLegendAttributes', lineView.geometries[0].getAttribute('shape'));
// lineView.geometries.forEach((geom) => {
// const shapeAttr = geom.getAttribute('shape');
//
// const shape = getMappingValue(shapeAttr, '机房3', 'point');
// let marker = geom.getShapeMarker(shape, {
// color: 'red',
// isInPolar: false,
// });
//
// console.log(marker);
// })
// // console.log(getLegendItems(rawLineData, rawBarData, lineView.geometries[0], barView.geometries[0], config));
//
// // console.log(chart.getController('legend'));
// })
}