如何通过按钮切换显示Chart.js中的两个柱状图
问题描述
现有两个Chart.js柱状图:
- id为
myChart的图表(1-11月数据),支持通过日期范围筛选按钮和重置按钮修改数据 - id为
myChart2的图表(9-11月数据),仅用于展示
需求:
- 页面默认显示
myChart2 - 点击Filter按钮时,切换显示
myChart并应用日期筛选 - 点击Reset按钮时,切回显示
myChart2
此前尝试复选框切换方案不符合需求,寻求可行解决方法。
解决方法
核心思路是通过CSS的display属性控制两个图表的显示与隐藏,同时调整按钮逻辑,在切换图表时完成对应操作:
- 初始状态设置
myChart隐藏、myChart2显示 - 修改
filterDate函数,先切换显示myChart再执行筛选逻辑 - 修改
resetDate函数,先重置myChart数据,再切回显示myChart2
修改后的HTML代码
<div class="col-sm-12 form-inline button-container"> <!-- DATE RANGE FILTER AND RESET --> <label class="mr-sm-2">Start Date: </label> <input id = "start" type= "date" class="form-control mb-2 mr-sm-2"> <label class="mr-sm-2">End Date: </label> <input id = "end" type = "date" class="form-control mb-2 mr-sm-2"> <button class = "btn btn-success mb-2 mr-2" name = "search" onclick = "filterDate()"><i class="fa-solid fa-magnifying-glass"></i> Filter </button> <button class = "btn btn-info mb-2 mr-2" onclick = "resetDate()"><i class="fa-solid fa-arrows-rotate"></i> Reset </button> <button class = "btn btn-info mb-2 mr-2" onclick = "window.print();"><i class="fa-solid fa-print"></i> Print </button> </div> <div class="container chart-container"> <div class="sub-chart-container"> <!-- CHART --> <canvas id="myChart" style="display: none;"></canvas> <canvas id="myChart2"></canvas> </div> </div>
修改后的JS代码
<script type="text/javascript"> // setup // Date Array const dateArrayJS = <?php echo json_encode($dateArray); ?> const dateChartJS = dateArrayJS.map((day, index) => { let dayjs = new Date(day); return dayjs.setHours(0, 0, 0, 0); }); // Report Array const reportsArrayJS = <?php echo json_encode($reportsArray); ?>; const reportsChartJS = reportsArrayJS; console.log(new Date('2022-01-01 00:00:00 GMT+0800')); // Converted Dates for Filter const convertedDates = dateArrayJS.map(date => new Date(date).setHours(0,0,0,0)); console.log(convertedDates); // data const data = { labels: dateChartJS, datasets: [{ label: 'Reports Recorded', data: reportsChartJS, backgroundColor: 'rgba(255, 26, 104, 0.2)', borderColor: 'rgba(255, 26, 104, 1)', borderWidth: 1, skipNull: true }] }; // config const config = { type: 'bar', data: data, options: { responsive: true, maintainAspectRatio: true, plugins: { legend: { display: false }, title: { display: true, text: 'Total number of reports received by month' }, tooltip: { enabled: false } }, scales: { x: { type: 'time', time: { unit: 'month' } }, y: { max: 20, beginAtZero: true } } } }; // setup 2 // Date Array 2 const dateArrayJS2 = <?php echo json_encode($dateArray2); ?> const dateChartJS2 = dateArrayJS2.map((day, index) => { let dayjs = new Date(day); return dayjs.setHours(0, 0, 0, 0); }); // Report Array 2 const reportsArrayJS2 = <?php echo json_encode($reportsArray2); ?>; const reportsChartJS2 = reportsArrayJS2; console.log(new Date('2022-01-01 00:00:00 GMT+0800')); // data 2 const data2 = { labels: dateChartJS2, datasets: [{ label: 'Reports Recorded', data: reportsChartJS2, backgroundColor: 'rgba(255, 26, 104, 0.2)', borderColor: 'rgba(255, 26, 104, 1)', borderWidth: 1, skipNull: true }] }; // config 2 const config2 = { type: 'bar', data: data2, options: { responsive: true, maintainAspectRatio: true, plugins: { legend: { display: false }, title: { display: true, text: 'Total number of reports received by month' }, tooltip: { enabled: false } }, scales: { x: { type: 'time', time: { unit: 'month' } }, y: { max: 20, beginAtZero: true } } } }; // render chart const myChart = new Chart( document.getElementById('myChart'), config ); // render chart 2 const myChart2 = new Chart( document.getElementById('myChart2'), config2 ); function filterDate(){ // 切换显示myChart,隐藏myChart2 document.getElementById('myChart').style.display = 'block'; document.getElementById('myChart2').style.display = 'none'; const start1 = new Date(document.getElementById('start').value); const start = start1.setHours(0,0,0,0); const end1 = new Date(document.getElementById('end').value); const end = end1.setHours(0,0,0,0); const filterDates = convertedDates.filter(date => date >= start && date <= end) myChart.config.data.labels = filterDates; const startArray = convertedDates.indexOf(filterDates[0]) const endArray = convertedDates.indexOf(filterDates[filterDates.length - 1]) console.log(endArray); const copyreportsChartJS = [...reportsChartJS]; copyreportsChartJS.splice(endArray + 1, filterDates.length); copyreportsChartJS.splice(0, startArray); console.log(copyreportsChartJS); myChart.config.data.datasets[0].data = copyreportsChartJS; myChart.update(); } function resetDate(){ // 重置myChart的数据 myChart.config.data.labels = convertedDates; myChart.config.data.datasets[0].data = reportsChartJS; myChart.update(); // 切换回显示myChart2,隐藏myChart document.getElementById('myChart').style.display = 'none'; document.getElementById('myChart2').style.display = 'block'; } </script>
代码说明
- HTML部分:给
myChart添加style="display: none;",确保页面加载时默认显示myChart2 - filterDate函数:执行筛选逻辑前,先切换图表显示状态,让用户看到筛选后的
myChart - resetDate函数:先将
myChart恢复为原始数据,再切回显示默认的myChart2
内容的提问来源于stack exchange,提问作者RZA
相关产品推荐
相关产品推荐

