<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Sales Chart - Chart.js</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
align-items: center;
color: #333;
}
.container {
width: 90%;
max-width: 1000px;
background: white;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
padding: 20px;
margin-top: 20px;
}
h1 {
color: #2c3e50;
text-align: center;
margin-bottom: 10px;
}
.chart-container {
position: relative;
height: 400px;
width: 100%;
margin: 20px 0;
transition: all 0.3s ease;
transform-origin: center top;
}
.controls {
display: flex;
flex-wrap: wrap;
gap: 15px;
justify-content: center;
margin-bottom: 20px;
padding: 15px;
background: #f8f9fa;
border-radius: 8px;
}
.control-group {
display: flex;
align-items: center;
gap: 8px;
}
label {
font-weight: 500;
font-size: 14px;
color: #495057;
}
button, select, input {
padding: 8px 12px;
border: 1px solid #ced4da;
border-radius: 4px;
background-color: white;
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
}
button:hover, select:hover {
background-color: #e9ecef;
}
button.active {
background-color: #4e73df;
color: white;
border-color: #4e73df;
}
input[type="range"] {
width: 120px;
}
.value-display {
min-width: 40px;
text-align: center;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h1>Interactive Sales Dashboard</h1>
<!-- 控制面板 -->
<div class="controls">
<div class="control-group">
<label>Bar Width:</label>
<input type="range" id="barWidth" min="0.1" max="1" step="0.1" value="0.6">
<span id="barWidthValue" class="value-display">0.6</span>
</div>
<div class="control-group">
<label>Y-Axis Start:</label>
<input type="number" id="yAxisMin" min="0" max="50000" step="5000" value="0">
<span id="yAxisMinValue" class="value-display">0</span>
</div>
<div class="control-group">
<label>Width (X):</label>
<input type="range" id="canvasWidth" min="50" max="150" step="10" value="100">
<span id="canvasWidthValue" class="value-display">100%</span>
</div>
<div class="control-group">
<label>Height (Y):</label>
<input type="range" id="canvasHeight" min="50" max="150" step="10" value="100">
<span id="canvasHeightValue" class="value-display">100%</span>
</div>
<button id="resetBtn">Reset Settings</button>
</div>
<!-- 图表容器 -->
<div class="chart-container">
<canvas id="salesChart"></canvas>
</div>
</div>
<script>
// 初始化数据
const data = {
labels: ["Electronics", "Clothing", "Home Goods", "Sports Equipment"],
datasets: [{
data: [120000, 85000, 95000, 60000],
backgroundColor: ["#4e73df", "#1cc88a", "#36b9cc", "#f6c23e"],
borderColor: "#ffffff",
borderWidth: 1,
borderRadius: 4,
barPercentage: 0.6 // 默认柱宽
}]
};
// 创建图表
let myChart;
function initChart() {
const ctx = document.getElementById('salesChart').getContext('2d');
myChart = new Chart(ctx, {
type: 'bar', // 固定为柱状图
data: data,
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
title: {
display: true,
text: 'Sales by Category (2023)',
font: { size: 16 }
},
datalabels: {
anchor: 'end',
align: 'top',
formatter: (value) => value.toLocaleString(),
color: '#333',
font: { weight: 'bold' }
}
},
scales: {
y: {
beginAtZero: false,
min: parseInt(document.getElementById('yAxisMin').value),
ticks: {
callback: (value) => value.toString()
}
}
}
},
plugins: [ChartDataLabels]
});
}
// 交互控制
document.getElementById('barWidth').addEventListener('input', function() {
const value = parseFloat(this.value);
document.getElementById('barWidthValue').textContent = value;
myChart.data.datasets[0].barPercentage = value;
myChart.update();
});
document.getElementById('yAxisMin').addEventListener('input', function() {
const value = parseInt(this.value);
document.getElementById('yAxisMinValue').textContent = value;
myChart.options.scales.y.min = value;
myChart.update();
});
// 画布尺寸调整功能
function updateCanvasSize() {
const widthScale = parseInt(document.getElementById('canvasWidth').value) / 100;
const heightScale = parseInt(document.getElementById('canvasHeight').value) / 100;
const container = document.querySelector('.chart-container');
container.style.transform = `scale(${widthScale}, ${heightScale})`;
document.getElementById('canvasWidthValue').textContent = `${document.getElementById('canvasWidth').value}%`;
document.getElementById('canvasHeightValue').textContent = `${document.getElementById('canvasHeight').value}%`;
if(myChart) {
// 延迟执行以确保变换完成
setTimeout(() => myChart.resize(), 100);
}
}
// 为两个滑块添加事件监听
document.getElementById('canvasWidth').addEventListener('input', updateCanvasSize);
document.getElementById('canvasHeight').addEventListener('input', updateCanvasSize);
document.getElementById('resetBtn').addEventListener('click', function() {
document.getElementById('barWidth').value = 0.6;
document.getElementById('yAxisMin').value = 0;
document.getElementById('canvasWidth').value = 100;
document.getElementById('canvasHeight').value = 100;
document.getElementById('barWidthValue').textContent = '0.6';
document.getElementById('yAxisMinValue').textContent = '0';
document.getElementById('canvasWidthValue').textContent = '100%';
document.getElementById('canvasHeightValue').textContent = '100%';
const container = document.querySelector('.chart-container');
container.style.transform = 'scale(1, 1)';
myChart.destroy();
initChart();
});
// 初始化
document.addEventListener('DOMContentLoaded', initChart);
</script>
</body>
</html>