使用select标签与多Canvas结合Chart.js实现下拉切换图表
使用Select下拉框结合Chart.js切换多种数据可视化图表
嘿,我已经帮你把需求落地成可运行的代码啦!下面是完整的实现,通过一个下拉选择框就能轻松切换你需要的四种Chart.js数据可视化图表:折线图、柱状图、饼图和雷达图。
实现思路
- 用
<select>控件提供图表类型选择入口 - 为每种图表创建独立的
<canvas>元素,初始仅显示默认图表 - 通过监听下拉框的
change事件,切换对应canvas的显示/隐藏状态 - 保留了你提供的所有图表样式和数据配置,同时修正了代码中的小错误(比如雷达图的
option拼写问题)
完整代码
HTML部分
<!-- 图表选择下拉框 --> <select id="chartSelector" style="padding: 8px; font-size: 16px; margin-bottom: 16px;"> <option value="line">温哥华人口数据折线图</option> <option value="bar">温哥华降水量柱状图</option> <option value="pie">温哥华族群分布饼图</option> <option value="radar">温哥华居民活动偏好雷达图</option> </select> <!-- 图表Canvas容器 --> <div style="width: 80%; margin: 0 auto;"> <canvas id="lineChart" style="display: block;"></canvas> <canvas id="barChart" style="display: none;"></canvas> <canvas id="pieChart" style="display: none;"></canvas> <canvas id="radarChart" style="display: none;"></canvas> </div> <!-- 引入Chart.js库 --> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
JavaScript部分
// 初始化折线图 var lineChart = new Chart(document.getElementById("lineChart"), { type:'line', data: { labels: ["2000", "2005", "2010", "2015", "2018"], datasets: [{ label: 'Vancouver Population Data', data: [195000,2093000,2278000,2485000,2597000], borderColor: ['rgba(255,99,132,1)'], backgroundColor:['rgba(255,200,200,0.3)'], borderWidth: 1, pointBackgroundColor:"red", pointBorderColor: "rgba(250,10,10,0.1)", pointBorderWidth:"10", pointStyle:"rectRounded", pointHoverBackgroundColor:"rgba(255,0,0,0.5)", pointHoverBorderColor: "rgba(255,255,100,0.7)", pointHoverRadius:"10", tension: 0 // 禁用贝塞尔曲线,保持折线笔直 }] }, options: { title:{ display:true, text:"Vancouver Population", fontSize:20, fontColor:"rgba(20,20,20,1)" }, legend:{ display:false }, scales: { yAxes:[{ ticks: { beginAtZero:true, callback: function(value){ return value + " people" } } }] }, hover:{ animationDuration:0 }, responsiveAnimationDuration:0 } }); // 初始化柱状图 var barChart = new Chart(document.getElementById("barChart"), { type:'bar', data: { labels:["May 2017", "June 2017", "July 2017", "Aug 2017","Sep 2017","Oct 2017","Nov 2017","Dec 2017","Jan 2018","Feb 2018","Mar 2018","Apr 2018","May 2018"], datasets:[{ label:"Precipitation Data", data:[102.2,46.4,1.8,5.0,29.4,114.8,197.0,170.6,249.4,105.8,111.8,134.8,1.4], backgroundColor: [ 'rgba(255,99,132,0.5)', 'rgba(155,130,32,0.5)', 'rgba(105,9,132,0.5)', 'rgba(15,130,202,0.5)', 'rgba(15,250,252,0.5)', 'rgba(205,100,32,0.5)', 'rgba(0,205,0,0.5)', 'rgba(55,15,52,0.5)', 'rgba(255,0,0,0.5)', 'rgba(25,59,52,0.5)', 'rgba(0,100,55,0.5)', 'rgba(200,111,199,0.5)' ], borderColor: [ 'rgba(255,99,132,1)', 'rgba(155,130,32,1)', 'rgba(105,9,132,1)', 'rgba(15,130,202,1)', 'rgba(15,250,252,1)', 'rgba(205,100,32,1)', 'rgba(0,205,0,1)', 'rgba(55,15,52,1)', 'rgba(255,0,0,1)', 'rgba(25,59,52,1)', 'rgba(0,100,55,1)', 'rgba(200,111,199,1)' ], borderWidth:"1" }] }, options: { title:{ display:true, text:"Vancouver Precipitation", fontSize:20, fontColor:"rgba(10,0,20,0.9)" }, legend:{ display:false }, scales:{ yAxes:[{ ticks:{ beginAtZero:true, callback: function(value){ return value + " mm" } } }] } } }); // 初始化饼图 var pieChart = new Chart(document.getElementById("pieChart"),{ type:'pie', data:{ labels:['European Candadian','Chinese','South Asia','Fillipino','Southeast Asian','Japanese','Latin American','Mixed visible minority','Korean','Aboriginal','West Asian','Black','Arab'], datasets:[{ label:"Ethnicity", data:[46.2,27.7,6,6,3,1.7,1.6,1.5,1.5,2,1.2,1,0.5], backgroundColor: [ 'rgba(255,99,132,0.5)', 'rgba(155,130,32,0.5)', 'rgba(105,9,132,0.5)', 'rgba(15,130,202,0.5)', 'rgba(15,250,252,0.5)', 'rgba(205,100,32,0.5)', 'rgba(0,205,0,0.5)', 'rgba(55,15,52,0.5)', 'rgba(255,0,0,0.5)', 'rgba(25,59,52,0.5)', 'rgba(0,100,55,0.5)', 'rgba(200,231,50,0.5)', 'rgba(155,22,30,0.5)' ], borderWidth:[1] }] }, options:{ title:{ display:true, text:"Vancouver Ethnicity", fontSize:"20", fontColor:"rgba(20,20,20,1)" } } }); // 初始化雷达图 Chart.defaults.scale.ticks.beginAtZero = true; var radarChart = new Chart(document.getElementById("radarChart"), { type:'radar', data:{ labels:['Hiking','Sporting Events','Stanley Park','Skiing & Snowboarding','Beaches','eating'], datasets:[{ label:"Male", data:[50,70,80,60,20,70], backgroundColor:['rgba(255,155,32,0.5)'], borderWidth:1, pointBackgroundColor:["yellow","black","green","white","skyblue","red"], pointHoverBackgroundColor:["black"], pointStyle:["triangle"] }, { label:"Female", data:[60,30,80,20,50,60], backgroundColor:['rgba(155,15,132,0.5)'], borderWidth:1, pointBackgroundColor:["yellow","black","green","white","skyblue","red"], pointHoverBackgroundColor:["black"], pointStyle:["triangle"] }] }, options:{ title:{ display:true, text:"Activities in Vancouver", fontSize:"20", fontColor:"rgba(10,0,20,0.9)" }, legend:{ display:true, position:'right' } } }); // 下拉框切换逻辑 document.getElementById('chartSelector').addEventListener('change', function(e) { // 隐藏所有图表Canvas document.querySelectorAll('canvas').forEach(canvas => { canvas.style.display = 'none'; }); // 显示选中的图表Canvas const targetChart = document.getElementById(`${e.target.value}Chart`); if (targetChart) { targetChart.style.display = 'block'; } });
额外优化说明
- 修正了雷达图代码中的
option拼写错误(改为正确的options) - 移除了重复的
var ctx声明,直接通过document.getElementById获取DOM元素 - 为下拉框和图表容器添加了基础样式,提升视觉体验
- 雷达图的数据改为数值类型(原代码是字符串,可能导致渲染问题)
内容的提问来源于stack exchange,提问作者Jun Jung
相关产品推荐
相关产品推荐

