Perché le tabs Bootstrap mostrano i div del riquadro delle tabs con larghezze errate quando si utilizzano i diagrammi elevati?

Quindi sto creando una pagina con contenuti a tabs usando il Bootstrap di Twitter, tuttavia il contenuto del mio div di avvio è sempre diverso da quello delle altre mie tabs. Ad esempio, inserisco i grafici utilizzando highcharts.js nelle mie diverse tabs, tuttavia quello attivo viene sempre visualizzato correttamente mentre gli altri hanno una larghezza errata.

Guarda l’esempio qui sotto:

Test

One

$(function () { $('#container1').highcharts({ chart: { }, xAxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] }, series: [{ data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4] }] }); });

Two

$(function () { $('#container2').highcharts({ chart: { }, xAxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] }, series: [{ data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4] }] }); });

Three

$(function () { $('#container3').highcharts({ chart: { }, xAxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] }, series: [{ data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4] }] }); });

Here is the content on my sidebar

In questo caso, il passaggio dalla scheda triggers al caricamento della pagina fa sì che il grafico sia corretto per me, ma il resto si estende sempre fino al bordo (Nel caso dei miei dati, che voglio riempire solo lo spazio della spanna9 div. Ho usato solo grafici fittizi in questo caso, ma è la stessa idea.

Ecco un JSFiddle: http://jsfiddle.net/dw9tn/

Le mie domande per tutti voi sono:

1.) Sono solo io?

2.) Che cosa sta succedendo esattamente quando le tabs sono rese attive? Guardando il css di bootstrap, questo sembra riguardare la visualizzazione: none e display: block, ma non ho una buona comprensione di come funzioni in questo caso.

3.) Si tratta di un problema di highcharts o di un problema di bootstrap? Ho notato che questo mi è successo con elementi non grafici (come mostrare i tweet nella barra laterale), quindi mi sto appoggiando al bootstrap.

4.) C’è qualche soluzione che puoi trovare per rendere tutto coerente?

Grazie ragazzi!

Il problema è che Highcharts non può calcolare la larghezza del contenitore che ha CSS: display:none , quindi applicato è la larghezza predefinita (600px). In realtà, il browser non è in grado di calcolare la larghezza per tali elementi.

Ad esempio, quando utilizzerai il separatore per ridimensionare la finestra dei risultati, il grafico verrà ridimensionato e funzionerà. Quindi hai tre opzioni:

  • rendering grafico dopo il primo clic su quella scheda
  • renderizza il grafico all’inizio, ma dopo ogni clic e ridimensionamento della finestra usa chart.setSize(w,h) con nuova larghezza e altezza
  • rendering grafico all’inizio, ma dopo aver cliccato su una scheda, fare clic su chart.reflow()

La causa

Questo non è un problema di Highcharts, almeno non da solo, il problema è causato dal fatto che Bootstrap usa display: none per hide le tabs inattive:

 .tab-content > .tab-pane, .pill-content > .pill-pane { display: none; /* this is the problem */ } 

Ciò causa che Highcharts non è in grado di ottenere la larghezza prevista per inizializzare il grafico, pertanto il valore predefinito è 600px . Ciò accadrebbe ad altri strumenti che usano lo stesso approccio per hide i contenuti.

Una soluzione CSS pura

Invece di aggirare il problema con un ulteriore ridisegno o inizializzazione ritardata, possiamo ottenere l’effetto nascosto usando height: 0; overflow-y: hidden height: 0; overflow-y: hidden , in questo modo i riquadri nascosti delle tabs sono ancora al loro posto e hanno una width valida:

 /* bootstrap hack: fix content width inside hidden tabs */ .tab-content > .tab-pane:not(.active), .pill-content > .pill-pane:not(.active) { display: block; height: 0; overflow-y: hidden; } /* bootstrap hack end */ 

Aggiornamento : la precedente soluzione in due passaggi nasconde tutte le tabs, quindi rende nuovamente visibile la scheda triggers. In confronto, ora abbiamo una soluzione in 1 fase, che si rivolge direttamente alle tabs inattive.

Questa soluzione è perfetta, quindi non devi più preoccuparti se il grafico si trova all’interno di un pannello a tabs o no. Ed è efficiente in quanto risolve il problema della larghezza in primo luogo, quindi non c’è bisogno di risolvere il problema di larghezza dopo ridimensionare / ridisegnare / ridisporre usando javascript.

Nota sull’ordine a cascata

Questa patch deve essere caricata dopo il bootstrap css, a causa delle regole di ordine CSS CSS , in breve, vince l’ultima regola .

dimostrazione

Prima vs Dopo

Suggerimento: passa alla scheda Profilo per vedere la differenza.

Sulla base della risposta di Paweł ho fatto un esempio funzionante:

http://codepen.io/colinsteinmann/pen/BlGfE

Fondamentalmente la funzione .reflow () viene chiamata su ogni grafico quando si fa clic su una scheda. In questo modo il grafico viene ridisegnato in base alle nuove dimensioni che vengono applicate al contenitore quando diventa visibile.

Questo è lo snippet di codice più importante:

 // fix dimensions of chart that was in a hidden element jQuery(document).on( 'shown.bs.tab', 'a[data-toggle="tab"]', function (e) { // on tab selection event jQuery( ".contains-chart" ).each(function() { // target each element with the .contains-chart class var chart = jQuery(this).highcharts(); // target the chart itself chart.reflow() // reflow that chart }); }) 

In base alla risposta di Pawel, renderò il grafico all’inizio e quindi ridimensiono il grafico.

Il codice utilizzato (con bootstrap 3.0.3 e HighCharts 3.0.7)

 $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { $('#container').highcharts().setSize($('#container').width(),$('#container').height()); }) 

Fonte: http://getbootstrap.com/javascript/#tabs-usage

Ho trovato una soluzione più semplice in un altro post. Fondamentalmente, il problema si presenta perché Highcharts non può eseguire il rendering su un div con “display: none” impostato. La soluzione è solo scrivere una correzione nel tuo foglio di stile CSS.

 .tab-content > .tab-pane, .pill-content > .pill-pane { display: inline; visibility: hidden; position: absolute; width: 930px; } .tab-content > .active, .pill-content > .active { display: inline; visibility: visible; position: absolute; width: 930px; } 

Questo farà in modo che le tabs funzionino con attributo di visibility anziché display . I grafici renderanno bene.

Lo stile “larghezza” in linea è diverso per i grafici. Non sono sicuro di quando e come vengono calcolati, ma puoi sovrascrivere quelli in css, ad esempio.