diff --git a/app.js b/app.js
index acc7833..5261fed 100644
--- a/app.js
+++ b/app.js
@@ -12,7 +12,17 @@ const colorPalettes = {
dark: ['#4fc3f7', '#81c784', '#fff176', '#ff8a65', '#ba68c8', '#4dd0e1', '#ffab91', '#aed581', '#f48fb1'],
macarons: ['#2ec7c9', '#b6a2de', '#5ab1ef', '#ffb980', '#d87a80', '#8d98b3', '#e5cf0d', '#97b552', '#95706d'],
gradient: ['#7f7fd5', '#86a8e7', '#91eae4', '#ff6b6b', '#feca57', '#48dbfb', '#ff9ff3', '#54a0ff', '#5f27cd'],
- retro: ['#d4a5a5', '#95b9c7', '#f6e8c3', '#dfceb4', '#a4c3b5', '#c9b1ff', '#f5c7b8', '#b8d4e3', '#e8c8a0']
+ retro: ['#d4a5a5', '#95b9c7', '#f6e8c3', '#dfceb4', '#a4c3b5', '#c9b1ff', '#f5c7b8', '#b8d4e3', '#e8c8a0'],
+ ocean: ['#0077b6', '#00b4d8', '#90e0ef', '#caf0f8', '#023e8a', '#48cae4', '#ade8f4', '#0096c7', '#03045e'],
+ forest: ['#2d6a4f', '#40916c', '#52b788', '#74c69d', '#95d5b2', '#b7e4c7', '#d8f3dc', '#1b4332', '#344e41'],
+ sunset: ['#e85d04', '#f48c06', '#faa307', '#ffba08', '#dc2f02', '#d00000', '#9d0208', '#6a040f', '#370617'],
+ lavender: ['#7c3aed', '#8b5cf6', '#a78bfa', '#c4b5fd', '#ddd6fe', '#ede9fe', '#5b21b6', '#4c1d95', '#6d28d9'],
+ minimal: ['#111827', '#374151', '#6b7280', '#9ca3af', '#d1d5db', '#e5e7eb', '#f3f4f6', '#4b5563', '#1f2937'],
+ cherry: ['#e91e63', '#f06292', '#f48fb1', '#f8bbd0', '#fce4ec', '#c2185b', '#ad1457', '#880e4f', '#d81b60'],
+ midnight: ['#6c63ff', '#5a52d5', '#483fb5', '#7c79ff', '#3d3d5c', '#8b89ff', '#9d9bff', '#2c2c4a', '#b3b2ff'],
+ gold: ['#b8860b', '#daa520', '#f0c040', '#ffd700', '#ffe066', '#996515', '#cc9900', '#e6b800', '#8b6914'],
+ coral: ['#ff6f61', '#ff8a70', '#ffa07a', '#ffab91', '#ffccbc', '#e64a19', '#f4511e', '#ff5722', '#d84315'],
+ mint: ['#00bfa5', '#26a69a', '#4db6ac', '#80cbc4', '#b2dfdb', '#00897b', '#00796b', '#004d40', '#009688']
};
// ===== 示例数据 =====
@@ -718,3 +728,41 @@ function exportTable(format) {
a.click();
URL.revokeObjectURL(url);
}
+
+// ===== 快速切换风格 =====
+function quickSwitchTheme(theme) {
+ // 更新按钮状态
+ document.querySelectorAll('.theme-btn').forEach(btn => {
+ btn.classList.toggle('active', btn.dataset.theme === theme);
+ });
+
+ if (currentMode === 'chart') {
+ // 图表模式:更新主题选择器并重新渲染
+ document.getElementById('themeStyle').value = theme;
+ updateChart();
+ } else {
+ // 表格模式:更新主题选择器并重新请求
+ document.getElementById('tableTheme').value = theme;
+ updateTable();
+ }
+}
+
+// ===== 同步风格按钮状态(下拉框变更时) =====
+function syncThemeButtons(theme) {
+ document.querySelectorAll('.theme-btn').forEach(btn => {
+ btn.classList.toggle('active', btn.dataset.theme === theme);
+ });
+}
+
+// ===== 初始化风格按钮状态 =====
+function initThemeButtons() {
+ // 默认激活 default
+ document.querySelectorAll('.theme-btn').forEach(btn => {
+ btn.classList.toggle('active', btn.dataset.theme === 'default');
+ });
+}
+
+// 页面加载时初始化
+document.addEventListener('DOMContentLoaded', () => {
+ initThemeButtons();
+});
diff --git a/index.html b/index.html
index 960b248..0d3b1cb 100644
--- a/index.html
+++ b/index.html
@@ -65,12 +65,22 @@ C, 20, 30, 40
-
@@ -97,7 +107,7 @@ C, 20, 30, 40
-
+
@@ -108,6 +118,11 @@ C, 20, 30, 40
+
+
+
+
+
@@ -181,6 +196,72 @@ C, 20, 30, 40
+
+
diff --git a/server.js b/server.js
index 89fdb49..b693359 100644
--- a/server.js
+++ b/server.js
@@ -29,7 +29,17 @@ const colorPalettes = {
dark: ['#4fc3f7', '#81c784', '#fff176', '#ff8a65', '#ba68c8', '#4dd0e1', '#ffab91', '#aed581', '#f48fb1'],
macarons: ['#2ec7c9', '#b6a2de', '#5ab1ef', '#ffb980', '#d87a80', '#8d98b3', '#e5cf0d', '#97b552', '#95706d'],
gradient: ['#7f7fd5', '#86a8e7', '#91eae4', '#ff6b6b', '#feca57', '#48dbfb', '#ff9ff3', '#54a0ff', '#5f27cd'],
- retro: ['#d4a5a5', '#95b9c7', '#f6e8c3', '#dfceb4', '#a4c3b5', '#c9b1ff', '#f5c7b8', '#b8d4e3', '#e8c8a0']
+ retro: ['#d4a5a5', '#95b9c7', '#f6e8c3', '#dfceb4', '#a4c3b5', '#c9b1ff', '#f5c7b8', '#b8d4e3', '#e8c8a0'],
+ ocean: ['#0077b6', '#00b4d8', '#90e0ef', '#caf0f8', '#023e8a', '#48cae4', '#ade8f4', '#0096c7', '#03045e'],
+ forest: ['#2d6a4f', '#40916c', '#52b788', '#74c69d', '#95d5b2', '#b7e4c7', '#d8f3dc', '#1b4332', '#344e41'],
+ sunset: ['#e85d04', '#f48c06', '#faa307', '#ffba08', '#dc2f02', '#d00000', '#9d0208', '#6a040f', '#370617'],
+ lavender: ['#7c3aed', '#8b5cf6', '#a78bfa', '#c4b5fd', '#ddd6fe', '#ede9fe', '#5b21b6', '#4c1d95', '#6d28d9'],
+ minimal: ['#111827', '#374151', '#6b7280', '#9ca3af', '#d1d5db', '#e5e7eb', '#f3f4f6', '#4b5563', '#1f2937'],
+ cherry: ['#e91e63', '#f06292', '#f48fb1', '#f8bbd0', '#fce4ec', '#c2185b', '#ad1457', '#880e4f', '#d81b60'],
+ midnight: ['#6c63ff', '#5a52d5', '#483fb5', '#7c79ff', '#3d3d5c', '#8b89ff', '#9d9bff', '#2c2c4a', '#b3b2ff'],
+ gold: ['#b8860b', '#daa520', '#f0c040', '#ffd700', '#ffe066', '#996515', '#cc9900', '#e6b800', '#8b6914'],
+ coral: ['#ff6f61', '#ff8a70', '#ffa07a', '#ffab91', '#ffccbc', '#e64a19', '#f4511e', '#ff5722', '#d84315'],
+ mint: ['#00bfa5', '#26a69a', '#4db6ac', '#80cbc4', '#b2dfdb', '#00897b', '#00796b', '#004d40', '#009688']
};
// ===== 数据解析(与前端一致) =====
@@ -515,6 +525,51 @@ const tableThemes = {
borderColor: '#dee2e6',
stripeColor: '#f8f9fa',
titleColor: '#212529'
+ },
+ cherry: {
+ bgColor: '#fff5f7',
+ headerBg: '#e91e63',
+ headerColor: '#ffffff',
+ cellColor: '#880e4f',
+ borderColor: '#f48fb1',
+ stripeColor: '#fce4ec',
+ titleColor: '#880e4f'
+ },
+ midnight: {
+ bgColor: '#1a1a2e',
+ headerBg: '#6c63ff',
+ headerColor: '#ffffff',
+ cellColor: '#e0e0e0',
+ borderColor: '#3d3d5c',
+ stripeColor: '#22223a',
+ titleColor: '#e0e0e0'
+ },
+ gold: {
+ bgColor: '#fffef5',
+ headerBg: '#b8860b',
+ headerColor: '#ffffff',
+ cellColor: '#5c4a00',
+ borderColor: '#daa520',
+ stripeColor: '#fdf6e3',
+ titleColor: '#5c4a00'
+ },
+ coral: {
+ bgColor: '#fff5f2',
+ headerBg: '#ff6f61',
+ headerColor: '#ffffff',
+ cellColor: '#5d2b1f',
+ borderColor: '#ffab91',
+ stripeColor: '#fff0ed',
+ titleColor: '#5d2b1f'
+ },
+ mint: {
+ bgColor: '#f0fff8',
+ headerBg: '#00bfa5',
+ headerColor: '#ffffff',
+ cellColor: '#004d40',
+ borderColor: '#80cbc4',
+ stripeColor: '#e0f2f1',
+ titleColor: '#004d40'
}
};
@@ -769,7 +824,7 @@ app.get('/api/docs', (req, res) => {
data: { type: 'string', required: true, description: 'CSV 格式数据(第一行表头,第一列横坐标)' },
chartType: { type: 'string', default: 'bar', options: ['bar', 'line', 'bar-line'], description: '图表类型' },
title: { type: 'string', default: '', description: '图表标题' },
- theme: { type: 'string', default: 'default', options: ['default', 'dark', 'macarons', 'gradient', 'retro'], description: '主题风格' },
+ theme: { type: 'string', default: 'default', options: ['default', 'dark', 'macarons', 'gradient', 'retro', 'ocean', 'forest', 'sunset', 'lavender', 'minimal', 'cherry', 'midnight', 'gold', 'coral', 'mint'], description: '主题风格' },
showLegend: { type: 'boolean', default: true, description: '是否显示图例' },
showGrid: { type: 'boolean', default: true, description: '是否显示网格线' },
showLabel: { type: 'boolean', default: false, description: '是否显示数据标签' },
@@ -825,7 +880,7 @@ app.get('/api/docs', (req, res) => {
params: {
data: { type: 'string', required: true, description: 'CSV 格式数据(第一行表头)' },
title: { type: 'string', default: '', description: '表格标题' },
- theme: { type: 'string', default: 'default', options: ['default', 'dark', 'macarons', 'gradient', 'retro', 'ocean', 'forest', 'sunset', 'lavender', 'minimal'], description: '主题风格' },
+ theme: { type: 'string', default: 'default', options: ['default', 'dark', 'macarons', 'gradient', 'retro', 'ocean', 'forest', 'sunset', 'lavender', 'minimal', 'cherry', 'midnight', 'gold', 'coral', 'mint'], description: '主题风格' },
fontSize: { type: 'number', default: 14, description: '字体大小' },
cellPadding: { type: 'number', default: 12, description: '单元格内边距' },
borderWidth: { type: 'number', default: 1, description: '边框宽度' },
diff --git a/style.css b/style.css
index 49ff1e0..841554c 100644
--- a/style.css
+++ b/style.css
@@ -457,3 +457,73 @@ input[type="range"]::-moz-range-thumb {
border: none;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
+
+/* ===== 风格快速切换按钮区 ===== */
+.theme-buttons-section {
+ margin-top: 16px;
+ background: var(--panel-bg);
+ border-radius: var(--radius);
+ padding: 16px 20px;
+ box-shadow: var(--shadow);
+ border: 1px solid var(--border);
+}
+
+.theme-buttons-section h3 {
+ font-size: 0.95rem;
+ margin-bottom: 12px;
+ color: var(--text);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.theme-buttons-grid {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.theme-btn {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 12px;
+ border: 2px solid var(--border);
+ border-radius: 10px;
+ background: white;
+ cursor: pointer;
+ transition: all 0.2s;
+ min-width: 72px;
+}
+
+.theme-btn:hover {
+ border-color: var(--primary);
+ transform: translateY(-2px);
+ box-shadow: var(--shadow);
+}
+
+.theme-btn.active {
+ border-color: var(--primary);
+ background: rgba(79, 70, 229, 0.05);
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15);
+}
+
+.theme-preview {
+ display: block;
+ width: 40px;
+ height: 28px;
+ border-radius: 6px;
+ box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1);
+}
+
+.theme-name {
+ font-size: 0.75rem;
+ color: var(--text-light);
+ font-weight: 500;
+}
+
+.theme-btn.active .theme-name {
+ color: var(--primary);
+ font-weight: 600;
+}