gpt4 book ai didi

javascript - 在隐藏的 Bootstrap 选项卡 Pane 上重绘谷歌图表

转载 作者:数据小太阳 更新时间:2023-10-29 05:52:18 24 4
gpt4 key购买 nike

我在我的网络应用程序中使用谷歌散点图,它加载到文档就绪。我最近做了一些重组,并试图将页面内容划分到不同的 Bootstrap 选项卡中。

如果我在事件选项卡 Pane 上加载图形,它工作正常并且图形的宽度、高度参数是正确的。但是,如果我将图形移动到隐藏选项卡,则图形无法使用传递给函数的参数(特别是宽度和高度)正确加载。目前我正在调用文档准备好的图表。

这是我的代码

HTML

<div class="layout layout-stack-sm layout-main-right">
<div class="col-sm-3 layout-sidebar">
<div class="col-sm-12">
<ul id="myTab" class="nav nav-layout-sidebar nav-stacked">
<li class="active">
<a href="#quick-stats" data-toggle="tab">
<i class="fa fa-th"></i>
&nbsp;&nbsp;Quick Stats
</a>
</li>
<li>
<a href="#engagement-graph" data-toggle="tab">
<i class="fa fa-bar-chart-o"></i>
&nbsp;&nbsp;Engagement graph
</a>
</li>
</ul>
</div>
</div> <!-- layout sidebar -->

<div class="col-sm-9 layout-main">
<div class="tab-content stacked-content">
<div class="tab-pane fade in active" id="quick-stats">
Some content
</div>
<div class="tab-pane fade" id="engagement-graph">
<div id="myMoodPage">
<div class="graph" id="graph">
</div>
</div>
</div>
</div>
</div>

在文档就绪时加载图表

<script type="text/javascript" src="https://www.google.com/jsapi">
</script>
<script type="text/javascript">
google.load("visualization", "1", {packages: ["corechart"]});

$(document).ready(function () {
$('#myMoodPage').myMood({
graphDataUrl: '<?php echo $this->url('my_mood/mood_graph_data'); ?>',
graphData: <?php echo $graphData; ?>,
titles: ['<?php echo $this->translate('time'); ?>', '<?php echo $this->translate('mood'); ?>', '<?php echo $this->translate('avg'); ?>']
});
});

function updatePageCharts() {
$('#myMoodPage').myMood('loadGraph');
}

$("a[href='#engagement-graph']").on('shown.bs.tab', function (e) {
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawChart
});
});

</script>

这是我的主要 JS 文件,我在其中定义图形参数和其他内容(实际上与这个问题无关,但为了完整起见,我发布了整个函数)

(function ($) {
$.widget("ui.myMood", {
options: {
graphDataUrl: "",
graphData: {},
titles: ["time", "mood", "avg"]
},
_create: function () {
var self = this;
this.periodSelect = this.element.find('select[name="period"]');
this.questionSelect = this.element.find('select[name="question"]');
this.graphContainer = this.element.find(".statistics");
this.atStart = this.element.find("#atStart .value");
this.highest = this.element.find("#highest .value");
this.lowest = this.element.find("#lowest .value");
this.current = this.element.find("#current .value");
this.last30 = this.element.find("#last30 .value");
this.last30Trend = this.element.find("#last30");
this.week = this.element.find("#week .value");
this.weekTrend = this.element.find("#week");
this.graphId = "graph";
this.selectedFilterName = this.options.titles[2];
this.periodSelect.change(function () {
self.loadGraph()
});
this.questionSelect.change(function () {
self.loadGraph();
self.selectedFilterName = self.questionSelect.find("option:selected").text()
});
this.setGraphData(this.options.graphData);
return this
},
loadGraph: function () {
var self = this;
var data = {
period: self.periodSelect.val(),
question: self.questionSelect.val()
};
var success = function (data) {
self.setGraphData(data)
};
$.ajax({
type: "POST",
url: self.options.graphDataUrl,
data: data,
success: success
})
},
setGraphData: function (data) {
var self = this;
this.atStart.text(data.atStart);
this.highest.text(data.highest);
this.lowest.text(data.lowest);
this.current.text(data.current);
this.last30.text(data.last30.val);
this.last30Trend.find(".up, .down").hide();
this.last30Trend.removeClass("incr");
this.last30Trend.removeClass("decr");
if (Number(data.last30.trend) > 0) {
this.last30Trend.find(".up").show();
this.last30Trend.addClass("incr")
}
if (Number(data.last30.trend) < 0) {
this.last30Trend.find(".down").show();
this.last30Trend.addClass("decr")
}
this.week.text(data.week.val);
this.weekTrend.find(".up, .down").hide();
this.weekTrend.removeClass("incr");
this.weekTrend.removeClass("decr");
if (Number(data.week.trend) > 0) {
this.weekTrend.find(".up").show();
this.weekTrend.addClass("incr")
}
if (Number(data.week.trend) < 0) {
this.weekTrend.find(".down").show();
this.weekTrend.addClass("decr")
}
var moodData = data.mood;
var dataArray = new Array();
for (i in moodData) {
if (moodData[i].avg == null) {
moodData[i].avg = undefined
}
if (moodData[i].mood == null) {
moodData[i].mood = undefined
}
if (moodData[i].team == null) {
moodData[i].team = undefined
}
var moodText = '<div style="border-radius: 2px; padding: 10px; color: #ffffff; font-weight: bold; background-color: #9c3b8a;">';
if (moodData[i].event != null) {
moodText += moodData[i].event + " "
}
moodText += moodData[i].mood;
if (moodData[i].comment) {
moodText += "<br>" + moodData[i].comment
}
moodText += "</div>";
var avgText = '<div style="border-radius: 2px; padding: 10px; color: #ffffff; font-weight: bold; background-color: #15426c;">';
if (moodData[i].event != null) {
avgText += moodData[i].event + " "
}
avgText += moodData[i].avg;
if (moodData[i].publicComment) {
avgText += "<br>" + moodData[i].publicComment
}
avgText += "</div>";
var row = [new Date(moodData[i].time * 1000), Number(moodData[i].mood), moodText, Number(moodData[i].avg), avgText, false];
dataArray.push(row)
}
if (google) {
drawChart()
} else {
google.setOnLoadCallback(drawChart)
}

function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn("date", self.options.titles[0]);
dataTable.addColumn("number", self.options.titles[1]);
dataTable.addColumn({
type: "string",
role: "tooltip",
p: {
html: true
}
});
dataTable.addColumn("number", self.selectedFilterName);
dataTable.addColumn({
type: "string",
role: "tooltip",
p: {
html: true
}
});
dataTable.addColumn({
type: "boolean",
role: "certainty"
});
dataTable.addRows(dataArray);
var dataView = new google.visualization.DataView(dataTable);
var chart = new google.visualization.ScatterChart(document.getElementById(self.graphId));
var options = {
legend: {
position: "bottom"
},
interpolateNulls: true,
chartArea: {
left: 25,
top: 25,
width: '92%',
height: '80%'
},
backgroundColor: "#ffffff",
vAxis: {
minValue: 0,
maxValue: 6,
viewWindow: {
min: 0,
max: 6
}
},
tooltip: {
isHtml: true
},
series: {
0: {
color: "#9c3b8a",
lineWidth: 2,
pointSize: 6
},
1: {
color: "#15426c",
lineWidth: 1,
pointSize: 3
}
}
};
chart.draw(dataView, options)
}
}
})
})(jQuery);

我试过像这样重新加载图表,但没有成功

$("a[href='#engagement-graph']").on('shown.bs.tab', function (e) {
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawChart
});
});

两种不同情况下的截图

在事件选项卡 Pane 上加载 enter image description here

在隐藏的选项卡 Pane 上加载 enter image description here

最佳答案

在隐藏的 div 中绘制图表(这通常是标签界面的实现方式)破坏了 Visualization API 中的维度检测算法,这就是为什么在除开始时打开的标签之外的任何标签中绘制图表时图表绘制奇怪的原因。

您只能加载一次 API; Visualization API 对 google.load 的后续调用将被忽略,这就是为什么您的“shown.bs.tab”事件处理程序没有执行您想要的操作。

由于将选项卡初始化延迟到图表绘制之后对于 Bootstrap 来说并不是真正可行的选择,因此我建议替换此代码:

google.load("visualization", "1", {packages: ["corechart"]});

$("a[href='#engagement-graph']").on('shown.bs.tab', function (e) {
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawChart
});
});

用这个:

function init () {
if (/* boolean expression teting if chart tab is open */) {
drawChart();
}
else {
$("a[href='#engagement-graph']").one('shown.bs.tab', drawChart);
}
}

google.load("visualization", "1", {packages: ["corechart"], callback: init});

如果容器选项卡打开,这应该绘制图表,如果选项卡未打开,则创建一个一次性事件处理程序,在第一次打开选项卡时绘制图表。

您需要将此代码放在 setGraphData 函数中以避免数据加载时出现竞争条件,因此 drawChart 函数将在范围内。此外,删除这些行:

if (google) {
drawChart()
} else {
google.setOnLoadCallback(drawChart)
}

google 对象在 jsapi 的脚本标签加载后就存在,这将是在执行此代码之前,因此您将始终触发 drawChart 函数在这里。然而,google 对象可用并不意味着可视化 API 已加载。

关于javascript - 在隐藏的 Bootstrap 选项卡 Pane 上重绘谷歌图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23932363/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com