【问题标题】:ChartJS charts not generating within tabsChartJS 图表未在选项卡中生成
【发布时间】:2015-03-24 17:06:37
【问题描述】:

我正在尝试在选项卡系统中使用 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技术不是很好。

【问题讨论】:

  • 在您的代码中,您在这一行中使用了newChart 变量new Chart(newChart).Line(newData, newOptions);,但我在您的代码中没有找到它,也许您可​​以使用chartjs 文档中的update() 方法@987654322 @

标签: javascript jquery tabs chart.js


【解决方案1】:

如果您使用 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; }

【讨论】:

    【解决方案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);
    
        }); 
    

    【讨论】:

      【解决方案3】:

      在使用仅在下拉列表中的某些选择时显示的隐藏 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();
          }); 
      

      【讨论】:

        【解决方案4】:

        以bootstrap的tab为例,我的解决方案是在使用chart.js渲染之前将.loading-data类添加到.tab-content,渲染完成后移除类。

        .tab-content.loading-data .tab-pane {
          display: block;
        }
        

        这样.tab-panes就会在chartjs渲染的瞬间显示出来。

        【讨论】:

          【解决方案5】:

          试试这个,我尝试了所有其他方法,但最终完成了这段代码。

          $("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()
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-08-22
            • 2020-11-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-03-17
            相关资源
            最近更新 更多