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
+47 -7
View File
@@ -113,7 +113,10 @@ function buildChartOption(params) {
leftLabel = '左侧',
rightLabel = '右侧',
splitStyle = 'solid',
seriesColors: customColors = null
seriesColors: customColors = null,
dualYAxis = false,
rightAxisSeries = null,
rightAxisName = ''
} = params;
const parsedData = parseData(data);
@@ -148,6 +151,12 @@ function buildChartOption(params) {
}
};
// 双Y轴:rightAxisSeries 指定右轴系列名
if (dualYAxis) {
const rightNames = Array.isArray(rightAxisSeries) ? rightAxisSeries : (rightAxisSeries ? [rightAxisSeries] : []);
seriesItem.yAxisIndex = rightNames.includes(name) ? 1 : 0;
}
if (stackMode) {
seriesItem.stack = 'total';
}
@@ -159,8 +168,7 @@ function buildChartOption(params) {
seriesItem.areaStyle = theme === 'gradient' ? { opacity: 0.15 } : undefined;
}
if (type === 'bar') {
seriesItem.barMaxWidth = 40;
if (type === 'bar') {seriesItem.barMaxWidth = 40;
seriesItem.itemStyle.borderRadius = stackMode ? [0, 0, 0, 0] : [4, 4, 0, 0];
}
@@ -269,7 +277,33 @@ function buildChartOption(params) {
},
axisTick: { show: false }
},
yAxis: {
yAxis: dualYAxis ? [
{
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 },
@@ -366,6 +400,9 @@ app.get('/api/chart', (req, res) => {
leftLabel: req.query.leftLabel || '左侧',
rightLabel: req.query.rightLabel || '右侧',
splitStyle: req.query.splitStyle || 'solid',
dualYAxis: req.query.dualYAxis === 'true',
rightAxisSeries: req.query.rightAxisSeries ? req.query.rightAxisSeries.split(',') : null,
rightAxisName: req.query.rightAxisName || '',
width: parseInt(req.query.width) || 800,
height: parseInt(req.query.height) || 500,
format: req.query.format || 'png',
@@ -882,7 +919,7 @@ app.get('/api/health', (req, res) => {
res.json({
status: 'ok',
service: 'data-chart-tool',
version: '1.10.1',
version: '1.11.0',
endpoints: {
'POST /api/chart': '生成图表图片(JSON body',
'GET /api/chart': '生成图表图片(URL 参数)',
@@ -897,7 +934,7 @@ app.get('/api/health', (req, res) => {
app.get('/api/docs', (req, res) => {
res.json({
name: '数据可视化图表生成器 API',
version: '1.10.1',
version: '1.11.0',
endpoints: [
{
method: 'POST',
@@ -922,7 +959,10 @@ app.get('/api/docs', (req, res) => {
width: { type: 'number', default: 800, description: '图片宽度(px)' },
height: { type: 'number', default: 500, description: '图片高度(px)' },
format: { type: 'string', default: 'png', options: ['png'], description: '输出格式' },
pixelRatio: { type: 'number', default: 2, description: '像素倍率(清晰度)' }
pixelRatio: { type: 'number', default: 2, description: '像素倍率(清晰度)' },
dualYAxis: { type: 'boolean', default: false, description: '是否启用双Y轴(左右量度不同)' },
rightAxisSeries: { type: 'array', default: null, description: '右轴系列名列表(如 ["利润"],指定哪些系列用右轴)' },
rightAxisName: { type: 'string', default: '', description: '右轴名称' }
},
returns: 'image/png',
example: {