我试图在标签系统中使用ChartsJS。渲染第一个选项卡中的第一个图表,但后续图表不会。
我认为这是因为标签有display:none
,所以当首次生成图表时,它们是在零维度的div中创建的。
这解决了问题,但打破了标签:
.vertical-nav>div.tab-content {
display: block !important;
}
考虑到这一点,我在选项卡打开后尝试了各种方法来重新生成图表,或者在生成图表之前强制display:block
。什么都行不通。
我尝试重新生成图表:
jQuery(document).ready(function() {
jQuery('.vertical-nav ul li span').click(function(){
// Target the canvas within the correct tab
var tabIndex = jQuery(this).parent().index();
var canvasID = jQuery('.vertical-nav .tab-content:eq( ' + tabIndex + ' ) canvas').attr('id');
theChart = charts[canvasID].chart;
builtChart = charts[canvasID].builtChart;
// Destroy all of the charts so that we can rebuild them
for (var key in charts) {
if (charts.hasOwnProperty(key)) {
charts[key].builtChart.destroy();
}
}
// get the chart data and options from the charts object
newData = charts[canvasID].data;
newOptions = charts[canvasID].options;
// create the new chart
newChart = document.getElementById(canvasID).getContext("2d");
new Chart(newChart).Line(newData, newOptions);
});
})
暂存网站为:http://telcomplusplc.uberleaf.com/company/?tab=our-growth
我甚至尝试设置超时来延迟图表生成,直到显示标签,但没有运气。
您可以在上面的URL中看到第一个图表生成并重新生成。它只是其他人的不足(大概是因为他们第一代有display:none
div。)
非常感谢任何帮助。如果需要,很乐意提供更多信息。
更新
调整窗口大小时,将重绘图表。这是代码(在chart.js中):
// Attach global event to resize each chart instance when the browser resizes
helpers.addEvent(window, "resize", (function(){
// Basic debounce of resize function so it doesn't hurt performance when resizing browser.
var timeout;
return function(){
clearTimeout(timeout);
timeout = setTimeout(function(){
each(Chart.instances,function(instance){
// If the responsive flag is set in the chart instance config
// Cascade the resize event down to the chart.
if (instance.options.responsive){
instance.resize(instance.render, true);
}
});
}, 50);
};
})());
我认为我需要的是能够通过点击功能触发它。我尝试过失败了,我的JS技能并不好。
答案 0 :(得分:4)
如果你使用display:none,那么chartjs不知道制作图表的大小,然后就不知道了。如果切换到jquery.hide()/ show(),它将起作用。这是jsfiddle
*没有它的小提琴工作,但如果你有很多内容,那么你可能还需要暂时隐藏该区域。
的Javascript
var data1 = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{ data: [65, 59, 80, 81, 56, 55, 40] }]
};
var data2 = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{ data: [65, 59, 80, 81, 56, 55, 40] }]
};
// Load each chart and hide() the tab immediately.
var ctx = document.getElementById('chart1').getContext('2d');
var chart1 = new Chart(ctx).Bar(data1);
$('#tab1').hide();
var ctx = document.getElementById('chart2').getContext('2d');
var chart2 = new Chart(ctx).Line(data2);
$('#tab2').hide();
/*
// will not work because chart is not rendered
$('#tab1_btn').on('click',function(){
$('#tab1').css('display','block');
$('#tab2').css('display','none') })
$('#tab2_btn').on('click',function(){
$('#tab1').css('display','none');
$('#tab2').css('display','block') })
*/
$('#tab1_btn').on('click',function(){
$('#tab1').show();
$('#tab2').hide()
})
$('#tab2_btn').on('click',function(){
$('#tab1').hide();
$('#tab2').show()
})
// if you have a lot of content in multiple tabs
// it may be necessary to temporarily cover the content
$('#tab_cover').hide();
HTML
<button id="tab1_btn">tab1</button>
<button id="tab2_btn">tab2</button>
<div id="tab_cover"> </div>
<div id="tabs">
<div id="tab1" class="tab">
<canvas id="chart1" class="chart" width="400" height="300"></canvas>
</div>
<div id="tab2" class="tab">
<canvas id="chart2" class="chart" width="400" height="300"></canvas>
</div>
</div>
CSS
/* will not work because chart is not rendered
.tab { display:none } */
.chart { width:50% }
.float { float:right; width:50%; }
#tab_cover { background:#9ff; height: 100% !important; width:100%; position: absolute; z-index: 300; }
答案 1 :(得分:2)
我找到了解决方案。我接近我在问题中的代码。我似乎需要销毁和调整图表的大小。
我还必须手动更改标签的display
状态。
这对我有用:
function createNewChart(canvasID) {
// get the chart data and options from the charts object
newData = charts[canvasID].data;
newOptions = charts[canvasID].options;
// create the new chart
theChart = document.getElementById(canvasID).getContext("2d"); console.dir(theChart);
new Chart(theChart).Line(newData, newOptions);
}
jQuery('.vertical-nav ul li').click(function(){
// Target the canvas within the correct tab
var tabIndex = jQuery(this).index();
var canvasID = jQuery('.vertical-nav .tab-content:eq( ' + tabIndex + ' ) canvas').attr('id');
theChart = charts[canvasID].chart;
builtChart = charts[canvasID].builtChart;
// Destroy all of the charts so that we can rebuild them
for (var key in charts) {
if (charts.hasOwnProperty(key)) {
jQuery('.vertical-nav .tab-content:eq( ' + tabIndex + ' )').css('display', 'block');
jQuery('.vertical-nav .tab-content:eq( ' + tabIndex + ' ) .tab-content-chart').css('display', 'block');
charts[key].builtChart.destroy();
charts[key].builtChart.resize();
}
}
createNewChart(canvasID);
});
答案 2 :(得分:0)
当使用隐藏的div时,我遇到了同样的问题,这些div只显示在下拉菜单中的某些选项上。我发现的工作方式类似于ow3n所做的。我创建了图表,然后只有在选择完成后才生成它们。
HTML:
<div>
<select>
<option value="option-1">Option 1</option>
<option value="option-2">Option 2</option>
<option value="option-3">Option 3</option>
</select>
</div>
<div class="chart1">
<canvas id="chart1"></canvas>
</div>
<div class="chart2">
<canvas id="chart2"></canvas>
</div>
<div class="chart3">
<canvas id="chart3"></canvas>
</div>
使用Javascript:
//example of chart variables (I only included 1 example)
var chart1 = {
labels : ["2009","2010","2011","2012","2013","2014"],
labelAlign: 'center',
datasets : [
{
label: "Visitor Average",
fillColor : "rgba(255,255,255,0)",
strokeColor : "rgba(0,34,221,1)",
pointColor : "rgba(0,34,221,1)",
pointStrokeColor : "#fff",
pointHighlightFill : "#fff",
pointHighlightStroke : "rgba(0,34,221,1)",
data: [28, 48, 40, 19, 86, 27]
},
{
label: "Baseline Average",
fillColor : "rgba(255,255,255,0)",
strokeColor : "rgba(255,0,0,1)",
pointColor : "rgba(255,0,0,1)",
pointStrokeColor : "#fff",
pointHighlightFill : "#fff",
pointHighlightStroke : "rgba(255,0,0,1)",
data: [65, 59, 80, 81, 56, 55]
}
]
}
window.onload = function(){
var ctx1 = document.getElementById("chart1").getContext("2d");
window.myLine1 = new Chart(ctx1).Line(chart1, {
responsive: true,
});
}
//change graph per drop-down selection
$(document).ready(function(){
$("select").change(function(){
$( "select option:selected").each(function(){
if($(this).attr("value")=="option-1"){
$(".chart2").hide();
$(".chart3").hide();
$(".chart1").show();
var ctx1 = document.getElementById("chart1").getContext("2d");
window.myLine1 = new Chart(ctx1).Line(chart1, {
responsive: true,
});
}
if($(this).attr("value")=="option-2"){
$(".chart2").show();
$(".chart1").hide();
$(".chart3").hide();
var ctx2 = document.getElementById("chart2").getContext("2d");
window.myLine2 = new Chart(ctx2).Line(chart2, {
responsive: true,
});
}
if($(this).attr("value")=="option-3"){
$(".chart3").show();
$(".chart1").hide();
$(".chart2").hide();
var ctx3 = document.getElementById("chart3").getContext("2d");
window.myLine3 = new Chart(ctx3).Line(chart3, {
responsive: true,
});
}
});
}).change();
});
答案 3 :(得分:0)
以bootstrap的选项卡为例,我的解决方案是在使用chart.js渲染之前将.loading-data
添加到.tab-content
,并在渲染完成后删除该类。
.tab-content.loading-data .tab-pane {
display: block;
}
通过这种方式,.tab-pane
将显示在chartjs渲染的瞬间。
答案 4 :(得分:0)
试试这个,我尝试了所有其他方法,但最终还是用了这段代码。
$("a").click(function(e){
let val = '#'+ e.target.href.split("#")[1]
localStorage.setItem('tab', val)
window.location.reload();
})
$(document).ready(function()
{
$('a[href="' + localStorage.getItem('tab') + '"]').parent().addClass('active')
$(document.getElementById(localStorage.getItem('tab').slice(1))).addClass('active')
});
另外,试试这些方法
window.dispatchEvent(new Event('resize'))
Chartkick.charts["<id of chart element like chart-1>"].redraw()