Google Sheets侧边栏中Google Charts无法随页面宽度自适应问题
Google Sheets侧边栏中Google Charts自适应布局问题解决
问题描述
在Google Sheets侧边栏(宽度约300px)中使用Google Charts时遇到布局问题:当Chrome浏览器页面出现滚动条时,图表无法随页面宽度变化自适应调整,会超出父div容器并忽略右侧内边距,希望图表能保持左右边距一致,若图表过宽则自动调整宽度以适配容器。目前文本内容可正常适配,但图表这类元素无法实现该效果。
复现代码
Code.gs
function onOpen() { SpreadsheetApp.getUi().createMenu("My Menu") .addItem("My Item", "showForm") .addToUi(); } function include (filename) { return HtmlService.createHtmlOutputFromFile(filename).getContent(); } function showForm() { var htmlWidget = HtmlService.createTemplateFromFile('Form'); SpreadsheetApp.getUi().showSidebar(htmlWidget.evaluate().setTitle("My Form")); }
Form.html
<!DOCTYPE html> <html> <head> <base target="_top"> <?!= include('Form-CSS'); ?> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript"> google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Topping'); data.addColumn('number', 'Slices'); data.addRows([ ['Mushrooms', 3], ['Onions', 1], ['Olives', 1], ['Zucchini', 1], ['Pepperoni', 2] ]); var options = {'title':'How Much Pizza I Ate Last Night', 'width':'100%'}; var chart = new google.visualization.PieChart(document.getElementById('mychart')); chart.draw(data, options); } </script> </head> <body> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Button 1</label> <div class="collapsible-content"> <div class="content-inner"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id sem urna. Donec nec elit eu turpis maximus aliquam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed non libero laoreet, interdum lacus eu, egestas augue. Donec at semper velit. Cras ante turpis, ultricies non ante at, dapibus suscipit leo. Morbi quis ex quam. Sed feugiat nibh ac tempus facilisis. Praesent ullamcorper placerat libero, tempus gravida eros scelerisque vel. Pellentesque quis luctus velit, nec consequat est. Sed ac arcu a nisl viverra rutrum ut id ex. Vestibulum vel semper massa, sit amet accumsan mauris. Donec gravida augue magna, id laoreet dui rutrum ac. Sed et porta magna.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id sem urna. Donec nec elit eu turpis maximus aliquam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed non libero laoreet, interdum lacus eu, egestas augue. Donec at semper velit. Cras ante turpis, ultricies non ante at, dapibus suscipit leo. Morbi quis ex quam. Sed feugiat nibh ac tempus facilisis. Praesent ullamcorper placerat libero, tempus gravida eros scelerisque vel. Pellentesque quis luctus velit, nec consequat est. Sed ac arcu a nisl viverra rutrum ut id ex. Vestibulum vel semper massa, sit amet accumsan mauris. Donec gravida augue magna, id laoreet dui rutrum ac. Sed et porta magna.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id sem urna. Donec nec elit eu turpis maximus aliquam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed non libero laoreet, interdum lacus eu, egestas augue. Donec at semper velit. Cras ante turpis, ultricies non ante at, dapibus suscipit leo. Morbi quis ex quam. Sed feugiat nibh ac tempus facilisis. Praesent ullamcorper placerat libero, tempus gravida eros scelerisque vel. Pellentesque quis luctus velit, nec consequat est. Sed ac arcu a nisl viverra rutrum ut id ex. Vestibulum vel semper massa, sit amet accumsan mauris. Donec gravida augue magna, id laoreet dui rutrum ac. Sed et porta magna.</p> </div> </div> </div> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Button 2</label> <div class="collapsible-content"> <div class="content-inner"> <div id="mychart" style="width: auto; max-width: 100%"></div> </div> </div> </div> </body> </html>
Form-CSS
<style> @import url('https://fonts.googleapis.com/css2?family='Roboto'&display=swap'); body { background-color: white; font-family: 'Roboto', sans-serif; font-size: 14px; } .wrap-collapsible { margin-bottom: 8px; } input[type='checkbox'] { display: none; } .lbl-toggle { display: block; font-weight: bold; font-family: 'Roboto', sans-serif; font-size: 18px; text-align: left; padding: 5px 10px 5px; color: black; background: coral; cursor: pointer; border: 1px solid black; transition: 0.2s ease-out; } .lbl-toggle::before { content: '\25B6'; color: black; font-weight: bold; font-size: 12px; float: right; margin-top: 7px; margin-left: 0px; transition: transform 0.2s ease-out; } .toggle:checked+.lbl-toggle::before { transform: rotate(90deg); } .collapsible-content { max-height: 0px; overflow: hidden; transition: max-height 0.2s ease-in-out; } .toggle:checked+.lbl-toggle+.collapsible-content { max-height: 300vh; } .collapsible-content .content-inner { background: bisque; border-left: 1px solid black; border-right: 1px solid black; border-bottom: 1px solid black; padding: 5px; } </style>
解决方案
核心问题分析
Google Charts初始化时会基于容器的初始宽度渲染,当Chrome出现滚动条时,侧边栏的可用宽度会被滚动条占用一部分,但图表不会自动重新计算尺寸;同时原代码中图表容器的width: auto和max-width:100%没有考虑父容器的内边距,导致图表超出右侧边界。
具体修复步骤
- 修正容器CSS样式
确保图表容器的宽度计算包含内边距,同时限制最大宽度为父容器的可用空间:
在Form-CSS中添加:
#mychart { width: 100%; max-width: calc(100% - 10px); /* 抵消content-inner的左右padding各5px */ box-sizing: border-box; }
- 添加窗口 resize 监听,动态重绘图表
当浏览器滚动条出现/消失时,触发图表重新绘制,适配当前容器宽度:
修改Form.html中的JavaScript部分:
google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawChart); // 监听窗口尺寸变化,重绘图表 window.addEventListener('resize', drawChart); function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Topping'); data.addColumn('number', 'Slices'); data.addRows([ ['Mushrooms', 3], ['Onions', 1], ['Olives', 1], ['Zucchini', 1], ['Pepperoni', 2] ]); // 获取容器实际可用宽度 const chartContainer = document.getElementById('mychart'); const containerWidth = chartContainer.offsetWidth; var options = { 'title':'How Much Pizza I Ate Last Night', 'width': containerWidth }; var chart = new google.visualization.PieChart(chartContainer); chart.draw(data, options); }
- 修复字体导入错误
原Form-CSS中的字体URL存在语法错误,修正为:
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
修改后的完整代码
修改后的Form.html
<!DOCTYPE html> <html> <head> <base target="_top"> <?!= include('Form-CSS'); ?> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript"> google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawChart); // 监听窗口尺寸变化,重绘图表 window.addEventListener('resize', drawChart); function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Topping'); data.addColumn('number', 'Slices'); data.addRows([ ['Mushrooms', 3], ['Onions', 1], ['Olives', 1], ['Zucchini', 1], ['Pepperoni', 2] ]); // 获取容器实际可用宽度 const chartContainer = document.getElementById('mychart'); const containerWidth = chartContainer.offsetWidth; var options = { 'title':'How Much Pizza I Ate Last Night', 'width': containerWidth }; var chart = new google.visualization.PieChart(chartContainer); chart.draw(data, options); } </script> </head> <body> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Button 1</label> <div class="collapsible-content"> <div class="content-inner"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id sem urna. Donec nec elit eu turpis maximus aliquam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed non libero laoreet, interdum lacus eu, egestas augue. Donec at semper velit. Cras ante turpis, ultricies non ante at, dapibus suscipit leo. Morbi quis ex quam. Sed feugiat nibh ac tempus facilisis. Praesent ullamcorper placerat libero, tempus gravida eros scelerisque vel. Pellentesque quis luctus velit, nec consequat est. Sed ac arcu a nisl viverra rutrum ut id ex. Vestibulum vel semper massa, sit amet accumsan mauris. Donec gravida augue magna, id laoreet dui rutrum ac. Sed et porta magna.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id sem urna. Donec nec elit eu turpis maximus aliquam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed non libero laoreet, interdum lacus eu, egestas augue. Donec at semper velit. Cras ante turpis, ultricies non ante at, dapibus suscipit leo. Morbi quis ex quam. Sed feugiat nibh ac tempus facilisis. Praesent ullamcorper placerat libero, tempus gravida eros scelerisque vel. Pellentesque quis luctus velit, nec consequat est. Sed ac arcu a nisl viverra rutrum ut id ex. Vestibulum vel semper massa, sit amet accumsan mauris. Donec gravida augue magna, id laoreet dui rutrum ac. Sed et porta magna.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed id sem urna. Donec nec elit eu turpis maximus aliquam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed non libero laoreet, interdum lacus eu, egestas augue. Donec at semper velit. Cras ante turpis, ultricies non ante at, dapibus suscipit leo. Morbi quis ex quam. Sed feugiat nibh ac tempus facilisis. Praesent ullamcorper placerat libero, tempus gravida eros scelerisque vel. Pellentesque quis luctus velit, nec consequat est. Sed ac arcu a nisl viverra rutrum ut id ex. Vestibulum vel semper massa, sit amet accumsan mauris. Donec gravida augue magna, id laoreet dui rutrum ac. Sed et porta magna.</p> </div> </div> </div> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Button 2</label> <div class="collapsible-content"> <div class="content-inner"> <div id="mychart"></div> </div> </div> </div> </body> </html>
修改后的Form-CSS
<style> @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap'); body { background-color: white; font-family: 'Roboto', sans-serif; font-size: 14px; } .wrap-collapsible { margin-bottom: 8px; } input[type='checkbox'] { display: none; } .lbl-toggle { display: block; font-weight: bold; font-family: 'Roboto', sans-serif; font-size: 18px; text-align: left; padding: 5px 10px 5px; color: black; background: coral; cursor: pointer; border: 1px solid black; transition: 0.2s ease-out; } .lbl-toggle::before { content: '\25B6'; color: black; font-weight: bold; font-size: 12px; float: right; margin-top: 7px; margin-left: 0px; transition: transform 0.2s ease-out; } .toggle:checked+.lbl-toggle::before { transform: rotate(90deg); } .collapsible-content { max-height: 0px; overflow: hidden; transition: max-height 0.2s ease-in-out; } .toggle:checked+.lbl-toggle+.collapsible-content { max-height: 300vh; } .collapsible-content .content-inner { background: bisque; border-left: 1px solid black; border-right: 1px solid black; border-bottom: 1px solid black; padding: 5px; } #mychart { width: 100%; max-width: calc(100% - 10px); box-sizing: border-box; } </style>
内容的提问来源于stack exchange,提问作者MeesterZee
相关产品推荐
相关产品推荐

