web-dev-qa-db-fra.com

La largeur des highcharts dépasse le div du conteneur lors du premier chargement

J'utilise HighCharts avec jQuery Mobile.

J'ai un graphique en aires dessiné dans un conteneur jQM data-role="content" et dans ce conteneur, j'ai les div suivants:

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

Mon graphique Highcharts est un graphique de base tiré de l'un de leurs exemples où je n'ai pas défini la propriété chart width.

Lors du premier chargement, le graphique dépasse la largeur des divs qui le contiennent, mais lorsque je redimensionne le navigateur, il s'aligne sur la largeur appropriée.

Comment puis-je faire en sorte que sa largeur soit exacte lors du chargement de la première page et pas uniquement lors du redimensionnement?

J'ai examiné des publications similaires sur le dépassement de capacité de la pile et aucune des solutions ne semble fonctionner.

MISES &AGRAVE; JOUR

  1. J'ai identifié le problème est que la balise <rect> générée dynamiquement par Highcharts occupe toute la largeur de la fenêtre du navigateur au chargement de la page et ne la prend pas du tout de la largeur de conteneur Voici le code HTML généré lors de l'inspection:

    <rect rx="5" ry="5" fill="#FFFFFF" x="0" y="0" **width="1920"** height="200"></rect>

  2. J'ai essayé de reproduire en JSFiddle, mais cela semble bien fonctionner là-bas, ce qui m'a vraiment sidérée. Voici mon code JSFiddle: http://jsfiddle.net/meandnotyou/rMXnY

27
activelogic

Appeler chart.reflow() m'a aidé. Docs: http://api.highcharts.com/highcharts#Chart.reflow

34
Lyudmyla

cela fonctionne comme par magie

mettre dans votre fichier css suivant

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

J'ai le même problème, dans mon cas avait un graphique de HighChart qu'il est affiché après un clic sur un bouton Je mets $(window).resize(); après spectacle et cela résout le problème correctement. J'espère que tu sers.

13
CMM

Définir la largeur du graphique. C'est la seule option qui a fonctionné pour moi. 

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

J'ai eu un problème similaire avec le centrage du graphe de graphiques en haut qu'il a donné. Il serait centré et dimensionné correctement pour certaines résolutions mais pas toutes. Quand ce n'était pas le cas, j'avais exactement les mêmes symptômes que ceux que vous décrivez ici.

Je l'ai corrigé en attachant/surchargeant des CSS supplémentaires à la valeur par défaut de Highcharts.

donc dans un fichier css personnalisé, en ajoutant

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

devrait résoudre votre problème. En supposant que votre div "hg = graph" n’ait que des graphiques en hauteur.

4
Tim Z.

Pour ceux qui utilisent des composants angulaires et personnalisés, n'oubliez pas de définir une variable display dimensionnée dans css (telle que block ou flex) pour l'élément Host.

Et lorsque le conteneur de graphique a un remplissage, vous pouvez trouver cela indispensable:

html

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

ts

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

Sinon, la carte passera au-delà du conteneur lors du chargement et obtiendra sa largeur correcte uniquement à la prochaine redistribution du navigateur (par exemple, lorsque vous commencerez à redimensionner la fenêtre).

3
user776686

Définissez les tableaux dans le document prêts:

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

et le script:

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

Esperons que ça marche ;)

1
Juan Carlos Quispe

J'ai résolu ce problème (dans mon cas) en veillant à ce que les éléments de l'interface utilisateur contenant le rendu avant le graphique permettent à Highcharts de calculer la largeur correcte.

Par exemple:

Avant:

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

Après:

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

Le meilleur moyen est d'appeler chart.reflow dans la fonction d'événement de rendu documentation ;

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

et n'oubliez pas de définir min-width sur zéro et overflow sur masqué dans le conteneur de graphique.

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

Je viens de rencontrer le même problème aujourd'hui - pas sur mobile, mais avec une fenêtre de petite taille lors du chargement de la première page. Lorsque la page est chargée, le graphique est masqué, puis après quelques sélections sur la page, nous créons le graphique. Nous avons défini une largeur min et une largeur max pour le conteneur en css, mais pas une largeur. 

Lors de la création du graphique, il doit déterminer les dimensions pour créer le fichier SVG. Le graphique étant masqué, il ne peut pas obtenir les dimensions correctement. Le code clone le conteneur de graphique, le positionne à l'écran et l'ajoute au corps afin qu'il puisse déterminer la hauteur/largeur.

Puisque la largeur n'est pas définie, la division clonée essaie de prendre le plus d'espace possible - jusqu'à la largeur maximale que j'avais définie. Les éléments SVG sont créés en utilisant cette largeur, mais ils sont ajoutés à la div du conteneur de graphique, qui est actuellement plus petite (en fonction de la taille de l'écran). Le résultat est que le graphique s'étend au-delà des limites de la division de conteneur. 

Après le premier rendu du graphique, les dimensions à l'écran sont connues et la fonction de clonage n'est pas appelée. Cela signifie que toute fenêtre redimensionnant ou rechargeant les données du graphique entraîne sa taille correcte.

J'ai contourné ce problème de chargement initial en surchargeant la fonction Highcharts cloneRenderTo qui clone la div pour obtenir des dimensions:

(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);

J'ai enregistré cette fonction dans un fichier de script séparé, chargé après le chargement du script Highchart.js.

0
Stephen

Voici une solution qui a fonctionné pour moi! Les graphiques fonctionnaient bien pendant un moment, puis après une fonctionnalité, ils ont commencé à dépasser leur conteneur. Il s’est avéré que c’était l’attribut de report du script situé en tête de mon application.

Essayez de supprimer différer vos balises javascript:

<script defer src="script.js"></script> à <script src="script.js"></script>

Ou déplacer mon lien de feuille de style plus haut dans la tête a également semblé le réparer, mais c'est une solution moins fiable.

0
Alex - SK

J'ai également le même problème dans mon application où j'utilise angular Et j'utilise aussi la directive ngCloak que j'ai supprimée car je n'en ai pas besoin

après cela, mon problème est résolu.

0

Je viens de constater que, parfois, plusieurs problèmes se posent en même temps. 

Si cela se produit, la hauteur dépasse la hauteur attendue:

Style SCSS:

.parent_container{

    position:relative;

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

Si la largeur dépasse le conteneur (plus gros que ce qui est supposé) ou ne redimensionne pas correctement en un plus petit :

    let element = $("#"+id);
    element.highcharts({...});

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

Le dernier m’est arrivé lors de la destruction de la carte et de la création d’une nouvelle ... La nouvelle figurait avec une largeur supplémentaire.

0
kitimenpolku

Je me suis aussi heurté à ce problème. tous les deux affectés dans la vue de bureau et mobile de la carte.

Dans mon cas, j’ai un qui met à jour la couleur de la série en fonction de min ou de max .

Pour résoudre ce problème, j'ai ajoutéchart.reflow ();après la mise à jour des points.

CODE:

//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();

J'espère que cela aide ceux qui ont le même problème que moi. :)

0
Jefsama

Je rencontre également ce problème et la solution CSS de .highcharts-container ne fonctionnait pas pour moi. J'ai réussi à le résoudre pour mon cas en scindant une condition de classe ng (qui définissait des largeurs différentes pour le div de conteneur) en divs séparés.

par exemple, ceci

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

dans

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

Je ne saurais vraiment vous dire pourquoi cela a fonctionné. J'imagine que la classe ng prend plus de temps pour calculer la largeur du conteneur et qu'ainsi, le rendu des tableaux élevés par une largeur indéfinie? Espérons que cela aide quand même quelqu'un.

0
Romesh Panditha

essayer d'encapsuler la génération highchart dans un événement pageshow

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