【问题标题】:Highcharts width exceeds container div on first load首次加载时,Highcharts 宽度超过容器 div
【发布时间】:2013-08-14 19:10:16
【问题描述】:

我正在使用带有 jQ​​uery Mobile 的 Highcharts。

我在 jQM data-role="content" 容器中绘制了一个面积图,在该容器中我有以下 div:

<div style="padding-top: 5px; padding-bottom: 10px; position: relative; width: 100%;">
    <div id="hg_graph" style="width: 100%"></div>
</div>

我的 highcharts 图表是一个基本图表,取自他们的一个示例,我没有设置图表 width 属性。

在第一次加载时,图表超出了包含 div 的宽度,但是当我调整浏览器大小时,它会捕捉到适当的宽度。

我怎样才能使它的宽度在第一页加载时正确,而不仅仅是在调整大小时?

我查看过有关堆栈溢出的类似帖子,但似乎没有一个解决方案有效。

更新

  1. 我发现问题在于 Highcharts 动态生成的 &lt;rect&gt; 标签在页面加载时占用了浏览器窗口的整个宽度,而根本没有从容器 div 宽度中获取它。这是我检查时生成的html:

    &lt;rect rx="5" ry="5" fill="#FFFFFF" x="0" y="0" **width="1920"** height="200"&gt;&lt;/rect&gt;

  2. 我试图在 JSFiddle 中重现,但它似乎在那里工作正常,这真的让我很难过。这是我的 JSFiddle 代码:http://jsfiddle.net/meandnotyou/rMXnY

【问题讨论】:

  • 问题解决了,对吗?
  • @SebastianBochan 不,没有解决。投票最多的答案只是切断了图表!
  • 仍未解决。此问题是否已在其 GitHub 存储库中发布为问题?
  • 我也被这个 sh** 困住了! :(

标签: jquery-mobile highcharts


【解决方案1】:

致电chart.reflow() 帮助了我。 文档:http://api.highcharts.com/highcharts#Chart.reflow

【讨论】:

  • 这是最好的答案。这是正确的方法。这是唯一对我有用的东西。谢谢!!!!解决了数小时的挫败感
  • 我为没有看到这个答案的人感到抱歉。支持这个答案!
  • 如何调用chart.reflow()?我似乎无法在文档中找到它。我看到了图表属性,但找不到可以调用的方法。
  • 这里是例子:jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/… this.chart = new Highcharts.Chart(this.opts); this.chart.reflow();
  • 对不起,但这至少在我并排放置 3 个图表的情况下不起作用,但是,上面的解决方案适用于宽度和高度设置为 100% 的情况
【解决方案2】:

这很神奇

把你的css文件放在下面

.highcharts-container {
    width:100% !important;
    height:100% !important;
}

【讨论】:

  • 这会隐藏部分图表
  • 你知道我花了多长时间试图让它为我工作。就这么简单。非常感谢!
  • 你知道为什么会这样吗?为什么它没有在 Highcharts 中修复?
  • 对我来说,它使用添加到 highcharts-container position: absolute 和 parent container position: relative 以及此响应来工作。
  • 这不会使图表适合,它只是强制它的容器不脱离它的父容器。这使得图表延伸到 highcharts-container,不再显示滚动条。这绝不是根本问题的解决方案。
【解决方案3】:

我有同样的问题,在我的例子中,点击按钮后会显示一个高图。我把$(window).resize(); 放在show event 之后,它正确地解决了问题。我希望你服务。

【讨论】:

  • 我也用过,似乎是这个页面上最优雅的解决方案。
  • 对于因 Highchart 开始于页面加载时不显示的容器而发布尺寸调整的任何人,这种方法将为您提供最一致的结果。
  • 这就是我正在做的,在升级到版本 6 之前工作得很好:(
【解决方案4】:

设置图表的宽度。这是对我有用的唯一选择。

chart: {
            type: 'line',
            width: 835
        },

【讨论】:

  • 如果我们使用响应式,它只能在大屏幕上动态工作。?
【解决方案5】:

在准备好的文档中定义highcharts:

<div style="width:50%" id="charts">

和脚本:

$(document).ready(function(){
    $(#chart).highcharts(){
    ...
    });
)};

希望它有效;)

【讨论】:

    【解决方案6】:

    我在将它给出的 highcharts 图表居中时遇到了类似的问题。对于某些分辨率,它会正确居中和调整大小,但不是全部。如果没有,我的症状与您在此处描述的完全相同。

    我通过附加/覆盖附加 css 到 highcharts 默认值来修复它。

    所以在自定义css文件中,添加

    .highcharts-container{
    /** Rules it should follow **/
    }
    

    应该可以解决您的问题。假设您的 div "hg=graph" 只有 highcharts。

    【讨论】:

    • 我尝试用各种属性覆盖包含 highchart 图表的 div,但似乎无法正确处理。您可以发布您使用的 CSS 规则的示例吗?另外,我已经更新了我的帖子,提供了更多信息。
    • 我使用的是 {margin: 0 auto;} 因为我想居中我的。您需要覆盖的类可能不是我提到的类。如果您在页面上查看源代码,请检查您的 hg_graph div 并找到 highcharts 使用的底层容器。
    • 嗨,蒂姆。我找到了这个类,它是 .highcharts-container。我尝试在 Chrome 的 DevTools 中指定 width: 100% !important 或编辑内联,这确实成功地将容器限制在适当的宽度,但图形仍然是 1920px 宽并且溢出,但隐藏在容器之外。问题似乎在于,在第一次加载时,Highcarts 生成的 &lt;SVG&gt; 元素具有以像素为单位的定义宽度,因此更改容器实际上并没有做任何事情,因为图形只会溢出。
    • 很抱歉,我无法为您提供更多帮助,因为我只是为 PC 而不是移动设备构建它。另一件事是我不确定您要整体完成什么。您是否尝试按比例限制图形的大小?因为 100% 的屏幕将是整个屏幕,而 100% 的 100% 仍然是整个屏幕......所以这可能是你的溢出?
    • 感谢您的尝试。我现在正在我的 PC 上测试 Chrome,所以它与手机无关。基本上我有一个具有填充的父容器:1%。在该容器中是宽度为 100% 的 hg_graph div。所以基本上,它的宽度应该是屏幕总尺寸的 98%。当 HighCharts 生成图表时,它得到的是整个页面宽度,而不是 hg_graph (98%) 的宽度。这仅在第一页加载时发生。如果我调整浏览器的大小,Highcharts 会自动将自身重新渲染为 98% 的适当宽度。
    【解决方案7】:

    对于那些使用角度和定制组件的人,请记住在 css 中为宿主元素定义尺寸 display(例如 blockflex)。

    当图表容器有填充时,您可能会发现这是必不可少的:

    html

    <chart (load)="saveInstance($event.context)">
    ...
    </chart>
    

    ts

      saveInstance(chartInstance: any) {
        this.chart = chartInstance;
        setTimeout(() => {
          this.chart.reflow();
        }, 0);
      }
    

    否则图表将在加载时流过容器并仅在下一次浏览器重排时(例如,当您开始调整窗口大小时)获得正确的宽度。

    【讨论】:

    • 您好,我试过了,但它给了我以下错误:[ts] 属性 'reflow' 在类型 'Chart' 上不存在。
    • 最近没关注Highcharts,可能是API变了,现在帮不上忙了,抱歉。
    【解决方案8】:

    我今天遇到了同样的问题 - 不是在移动设备上,而是在首页加载时窗口大小很小。当页面加载时,图表被隐藏,然后在页面上进行一些选择后,我们创建图表。我们在 css 中为容器设置了最小宽度和最大宽度,但没有设置宽度。

    创建图表时,需要确定创建 SVG 的尺寸。 由于图表被隐藏,它无法正确获取尺寸,因此代码克隆了图表容器,将其放置在屏幕外并将其附加到正文,以便确定高度/宽度。

    由于未设置宽度,克隆的 div 会尝试尽可能多地占用空间 - 直到我设置的最大宽度。 SVG 元素是使用该宽度创建的,但添加到当前较小的图表容器 div 中(基于屏幕大小)。结果是图表超出了容器 div 的边界。

    图表第一次渲染后,屏幕上的尺寸是已知的,并且不调用克隆函数。这意味着任何调整窗口大小或重新加载图表数据都会导致图表大小正确。

    我通过重写 Highcharts 函数 cloneRenderTo 解决了这个初始加载问题,该函数克隆了 div 以获取维度:

    (function (H) {
        // encapsulated variables
        var ABSOLUTE = 'absolute';
    
        /**
        * override cloneRenderTo to get the first chart display to fit in a smaller container based on the viewport size
        */
        H.Chart.prototype.cloneRenderTo = function (revert) {
            var clone = this.renderToClone,
                container = this.container;
    
            // Destroy the clone and bring the container back to the real renderTo div
            if (revert) {
                if (clone) {
                    this.renderTo.appendChild(container);
                    H.discardElement(clone);
                    delete this.renderToClone;
                }
    
                // Set up the clone
            } else {
                if (container && container.parentNode === this.renderTo) {
                    this.renderTo.removeChild(container); // do not clone this
                }
                this.renderToClone = clone = this.renderTo.cloneNode(0);
                H.css(clone, {
                    position: ABSOLUTE,
                    top: '-9999px',
                    display: 'block' // #833
                });
                if (clone.style.setProperty) { // #2631
                    clone.style.setProperty('display', 'block', 'important');
                }
                doc.body.appendChild(clone);
    
                //SA: constrain cloned element to width of parent element
                if (clone.clientWidth > this.renderTo.parentElement.clientWidth){
                    clone.style.width = '' + this.renderTo.parentElement.clientWidth + 'px';
                }
    
                if (container) {
                    clone.appendChild(container);
                }
            }
        }
    
    })(Highcharts);
    

    我将此函数保存在一个单独的脚本文件中,该文件在加载 Highchart.js 脚本后加载。

    【讨论】:

      【解决方案9】:

      最好的方法是在渲染事件函数documentation中调用chart.reflow;

       Highcharts.stockChart( 'chartContainer', {
       chart: {
        events: {
          render: function() {
            this.reflow();
          }
        },
        zoomType: 'x',
         ...
      },
      

      记得在图表容器中将 min-width 设置为零并溢出隐藏。

      #chartContainter {
        min-width: 0;
        overflow: hidden;
        }
      

      【讨论】:

        【解决方案10】:

        尝试将 highchart 生成封装在 pageshow 事件中

        $(document).on("pageshow", "#hg_graph", function() {...});
        

        【讨论】:

          【解决方案11】:

          我通过确保包含的 UI 元素在图表之前呈现 解决了这个问题(就我而言),从而允许 Highcharts 计算正确的宽度。

          例如:

          之前:

          var renderChart = function(){
          ...
          };
          renderChart();
          

          之后:

          var renderChart = function(){
          ...
          };
          setTimeout(renderChart, 0);
          

          【讨论】:

            【解决方案12】:

            我也遇到过这个问题,而 .highcharts-container css 解决方案对我不起作用。我设法通过将 ng 类条件(为容器 div 设置不同的宽度)拆分为单独的 div 来解决这个问题。

            例如,这个

            <div ng-class="condition?'col-12':'col-6'">
                <chart></chart>
            </div>
            

            进入

            <div ng-show="condition" class="col-12">
                <chart></chart>
            </div>
            <div ng-show="!condition" class="col-6">
                <chart></chart>
            </div>
            

            但我无法真正告诉你为什么它会起作用。我猜 ng-class 需要更长的时间来计算容器宽度,所以 highcharts 首先以未定义的宽度呈现?希望这对某人有所帮助。

            【讨论】:

              【解决方案13】:

              我在使用 Angular 的应用程序中也遇到了同样的问题 而且我还使用了 ngCloak 指令,因为我不需要它,所以我已经删除了它

              这样做之后,我的问题就解决了。

              【讨论】:

                【解决方案14】:

                我刚刚看到有时会同时出现多个问题。

                如果发生高度超过预期高度:

                SCSS 样式:

                .parent_container{
                
                    position:relative;
                
                    .highcharts-container{position: absolute; width:100% !important;height:100% !important;}
                }
                

                如果宽度超过了容器(比预期的大)或者没有正确调整到更小的宽度

                    let element = $("#"+id);
                    element.highcharts({...});
                
                    // For some reason it exceeds the div height.
                    // Trick done to reflow the graph. 
                    setTimeout(()=>{
                        element.highcharts().reflow();
                    }, 100 );
                

                我在销毁图表并创建新图表时发生了最后一个问题……新图表带有额外的宽度。

                【讨论】:

                  【解决方案15】:

                  我也遇到过这个问题。在图表的桌面和移动视图中都受到影响。

                  在我的例子中,我有一个 根据最小值或最大值更新系列颜色的图表。更新点后,highcharts 的宽度在第一次加载时超过了容器 div。

                  为了解决这个问题,我所做的是在积分更新后添加 chart.reflow();

                  代码:

                  //First declare the chart
                  var chart = $('#TopPlayer').highcharts();
                  //Set the min and max
                  var min = chart.series[0].dataMin; //Top Losser
                  var max = chart.series[0].dataMax; //Top Winner
                  
                  for (var i = 0; i < chart.series[0].points.length; i++) {
                      if (chart.series[0].points[i].y === max) {
                          chart.series[0].points[i].update({
                              color: 'GREEN',
                          });
                      }
                      if (chart.series[0].points[i].y === min) {
                          chart.series[0].points[i].update({
                              color: 'RED',
                          });
                      }
                  }
                  
                  // redraw the chart after updating the points
                  chart.reflow();
                  

                  希望这对像我一样有同样问题的人有所帮助。 :)

                  【讨论】:

                    【解决方案16】:

                    这是一个对我有用的解决方案!图表在一段时间内运行良好,然后在某个功能之后,它们开始超出其容器。原来它是我的应用程序头部脚本中的 defer 属性。

                    尝试删除您的 javascript 标签上的延迟:

                    &lt;script defer src="script.js"&gt;&lt;/script&gt;&lt;script src="script.js"&gt;&lt;/script&gt;

                    或者将我的样式表链接移到更高的位置似乎也可以解决它,但这是一个不太可靠的解决方案..

                    【讨论】:

                      【解决方案17】:

                      这可能是自 2013 年 OP 以来引入的,但您应该可以使用 chart.height (https://api.highcharts.com/highcharts/chart.height) 设置高度

                                      options: {
                                          chart: {
                                              type: 'bar',
                                              height: window.innerHeight + 'px',
                                          },
                                          title: {
                                              text: 'Top 10 Users',
                                          },
                                          subtitle: {
                                              text: 'by scores',
                                          },
                      
                      

                      这是一个基于 Web 的解决方案,但我希望您可以将其用于 jQuery.mobile

                      【讨论】:

                        【解决方案18】:

                        没有一个答案对我有帮助。我动态更改图表数据,最佳答案解决方案破坏了动画并导致图表位置跳跃。

                        我最终想出的解决方法是为图表包装元素设置一些填充(在我的情况下,左侧图表的某些部分被隐藏了,所以我给了一些左侧填充),然后设置图表主元素溢出属性可见。它可以工作,动画也很好。您可能需要对填充值进行一些试验才能使其完美显示。

                        <div class="chart-wrapper">
                           <!-- high charts main element here -->
                        </div>
                        

                        风格

                        .chart-wrapper{
                          padding-left: 20px;
                        }
                        
                        .chart-wrapper > div:first-child{
                          overflow: visible !important;
                        }
                        

                        【讨论】:

                          【解决方案19】:

                          对我来说,我设置了图表宽度:

                          $('#container').highcharts({
                              chart: {
                                  backgroundColor: 'white',
                                  **width:3000**,
                                  ..... }
                          

                          并在 html 中设置overflow:auto

                          <div id="container" style="**width:100%;overflow:auto**;" ></div>
                          

                          【讨论】:

                            【解决方案20】:

                            我为此苦苦挣扎了太久,找到了适合我的解决方案。关于我的设置的一点背景:

                            1. highcharts 图表加载到我网站上的一个选项卡上,登录该网站时看不到该选项卡。
                            2. 切换到该选项卡时,图表在 div 之外。

                            所以,我为该特定标签附加了一个唯一 ID,我们将其命名为 tab5,然后绑定一个强制点击功能 - 这是重要的部分 - &lt;svg&gt; 容器 div 中的元素使用 jQuery 100%:

                            $('#tab5').bind('click', function() {
                                $('#container_div svg').width('100%');
                            });
                            

                            ...我的理智已经恢复。暂时。

                            【讨论】:

                              【解决方案21】:

                              请在图表容器中添加width:100%
                              希望这能解决overflow:hidden 相关问题。

                              classname{min-height:450px;width: 100%;}
                              

                              【讨论】:

                                猜你喜欢
                                • 2012-07-16
                                • 2012-12-13
                                • 1970-01-01
                                • 2015-12-04
                                • 2021-06-13
                                • 2020-07-14
                                • 1970-01-01
                                • 1970-01-01
                                • 2012-05-21
                                相关资源
                                最近更新 更多