feat: 单图模式新增双Y轴 + 下载按钮缩小

- 图表模式新增双Y轴:左右两个坐标轴,量度可不同
  - 显示选项加"双Y轴"开关,启用后显示右轴名称输入
  - 每个系列在系列配置中可选择左轴/右轴
  - 后端 /api/chart 支持 dualYAxis + rightAxisSeries + rightAxisName(POST/GET 均可)
- 导出设置折叠栏下载按钮改小,避免挤占
This commit is contained in:
2026-08-19 12:59:46 +08:00
parent d9b3253fa0
commit 6a696daeb8
6 changed files with 122 additions and 10 deletions
+54 -1
View File
@@ -3,6 +3,7 @@ let chartInstance = null;
let parsedData = null;
let seriesColors = [];
let seriesOrder = [];
let seriesAxis = []; // 每个系列所属轴:0=左轴 1=右轴
let currentMode = 'chart'; // 'chart' or 'table'
let tableImageBlob = null;
@@ -131,6 +132,7 @@ function generateChart() {
seriesOrder = parsedData.seriesNames.map((_, i) => i);
const palette = colorPalettes[document.getElementById('themeStyle').value] || colorPalettes.default;
seriesColors = parsedData.seriesNames.map((_, i) => palette[i % palette.length]);
seriesAxis = parsedData.seriesNames.map(() => 0);
// 渲染系列配置
renderSeriesConfig();
@@ -172,6 +174,8 @@ function updateChart() {
const stackMode = document.getElementById('stackMode').checked;
const smoothLine = document.getElementById('smoothLine').checked;
const enableSplit = document.getElementById('enableSplit').checked;
const dualAxis = document.getElementById('dualAxis').checked;
const rightAxisName = document.getElementById('rightAxisName').value;
// 显示/隐藏分割配置
document.getElementById('splitConfig').style.display = enableSplit ? 'block' : 'none';
@@ -248,6 +252,11 @@ function updateChart() {
};
}
// 双Y轴:按系列指定左右轴
if (dualAxis) {
seriesItem.yAxisIndex = (seriesAxis[origIdx] === 1) ? 1 : 0;
}
return seriesItem;
});
@@ -379,7 +388,30 @@ function updateChart() {
},
axisTick: { show: false }
},
yAxis: {
yAxis: dualAxis ? [
{
type: 'value',
name: '左轴',
nameTextStyle: { color: textColor, fontSize: 11, padding: [0, 0, 0, 4] },
axisLine: { show: false },
axisTick: { show: false },
axisLabel: { color: textColor, fontSize: 11 },
splitLine: {
show: showGrid,
lineStyle: { color: theme === 'dark' ? '#333' : '#f0f0f0', type: 'dashed' }
}
},
{
type: 'value',
name: rightAxisName || '右轴',
position: 'right',
nameTextStyle: { color: textColor, fontSize: 11, padding: [0, 4, 0, 0] },
axisLine: { show: false },
axisTick: { show: false },
axisLabel: { color: textColor, fontSize: 11 },
splitLine: { show: false }
}
] : {
type: 'value',
axisLine: { show: false },
axisTick: { show: false },
@@ -466,6 +498,13 @@ function renderSeriesConfig() {
seriesOrder.forEach((origIdx, displayIdx) => {
const name = parsedData.seriesNames[origIdx];
const color = seriesColors[origIdx];
const dualAxis = document.getElementById('dualAxis').checked;
const axisSelect = dualAxis ? `
<select onchange="updateSeriesAxis(${origIdx}, this.value)" title="所属坐标轴">
<option value="0" ${seriesAxis[origIdx] === 0 ? 'selected' : ''}>左轴</option>
<option value="1" ${seriesAxis[origIdx] === 1 ? 'selected' : ''}>右轴</option>
</select>
` : '';
const item = document.createElement('div');
item.className = 'series-item';
@@ -481,6 +520,7 @@ function renderSeriesConfig() {
<option value="bar">柱状</option>
<option value="line">折线</option>
</select>
${axisSelect}
`;
// 拖拽事件
@@ -566,6 +606,19 @@ function updateSeriesType(origIdx, type) {
updateChart();
}
// ===== 双Y轴 =====
function onDualAxisChange() {
const on = document.getElementById('dualAxis').checked;
document.getElementById('rightAxisGroup').style.display = on ? 'block' : 'none';
renderSeriesConfig(); // 显示/隐藏系列轴选择
updateChart();
}
function updateSeriesAxis(origIdx, axis) {
seriesAxis[origIdx] = parseInt(axis) || 0;
updateChart();
}
// ===== 工具函数 =====
function adjustColor(hex, amount) {
hex = hex.replace('#', '');