如何在模态框(modal)中正常显示Google Line Chart折线图
问题原因
- 核心原因是默认隐藏的模态框容器宽高为0:Google Chart绘制时需要读取目标DOM的实际可见宽高计算渲染参数,而模态框默认设置了
display: none,浏览器对隐藏元素返回的宽高值均为0,导致图表按0尺寸渲染,最终无法看到内容。 - 原有代码触发时机错误:你当前的
drawChart函数是在页面加载完成后立即执行,此时模态框还未触发显示,容器处于隐藏状态,自然无法正常绘制。 - 容器样式书写不规范:你的图表容器
div写了两个重复的style属性,浏览器只会识别第一个style,第二个包含宽度设置的style会被直接忽略,也可能导致尺寸计算异常。
修复方案
1. 先修复容器样式错误
将两个style属性合并为一个,确保宽高配置生效:
<div id="curve_chart" style="height: 160px; text-align: right; width: 720px;"></div>
2. 修改图表触发时机
不要在页面加载时就绘制图表,改为模态框完全显示后再触发绘制。以你使用的模态框逻辑为例,修改打开模态框的按钮点击事件:
var modal = document.getElementById("myModal"); var btn = document.getElementById("myBtn"); btn.onclick = function() { // 先显示模态框 modal.style.display = "block"; // 模态框显示后再绘制图表 drawChart(); }
3. (可选)优化重复绘制问题
可以将图表实例、数据、配置提前初始化,避免每次打开模态框都重复创建实例,提升性能:
// 全局存储图表实例、数据、配置 var chart = null; var chartData = null; var chartOptions = null; google.charts.load('current', {'packages':['corechart', 'line']}); // 页面加载时只初始化数据和配置,不绘制 google.charts.setOnLoadCallback(initChartConfig); function initChartConfig() { chartData = google.visualization.arrayToDataTable([ ['Time', 'CO', 'Limit'], <?php $Limit = 1; foreach ( $co as $key=>$value ) { $now = new DateTime($timer[$key]); $date=$now->format('d/m/y H:i'); echo "['$date', $value, $Limit],"; } ?> ]); chartOptions = { tooltip: {isHtml: true}, chartArea: { height: '100%', width: '100%', top: 10, left: 32, right: 16, bottom: 48 }, height: '100%', width: '100%', vAxis: { minValue: 0 ,maxValue: 2.0, gridlines: {color: '#ccc', interval: 1, count: 4 }, format: '#.0' }, seriesType: "line", backgroundColor: { fill: '#f8f8f8', stroke: '#ccc', strokeWidth: 1, strokeSize: 1 }, series: { 0: { color: '#2d84b4' }, 1: { type: "steppedArea", color: '#FF0000', visibleInLegend: false, areaOpacity: 0, enableInteractivity: false } }, }; } function drawChart() { if(!chart) { chart = new google.visualization.LineChart(document.getElementById('curve_chart')); } chart.draw(chartData, chartOptions); }
如果你的模态框有淡入等过渡动画,可以在触发绘制前加100ms左右的延迟,等容器尺寸完全稳定后再绘制:
btn.onclick = function() { modal.style.display = "block"; setTimeout(() => drawChart(), 100); }
内容的提问来源于stack exchange,提问作者Periklis Kakarakidis
相关产品推荐
相关产品推荐

