Подтвердить что ты не робот

Highcharts - Скрытые диаграммы не получают правильного размера

В настоящее время у меня есть 3 вкладки. Каждая вкладка представляет собой div, который установлен на display: hidden, когда он не выбран. В этих вкладках у меня есть грид-система, созданная с помощью Susy (плагин компаса). Также на каждой закладке есть набор Highcharts. Когда я загружаю страницу, в зависимости от того, какая вкладка находится в URl, загружается одна из вкладок. Все диаграммы выглядят отлично, однако, когда я переключаюсь на другую вкладку, некоторые из диаграмм не правильно установлены в своем div. Если я просто изменил размер окна, графики пересчитываются, а затем они идеально подходят. Или, если я перезагружаю ту же вкладку, графики тоже подходят. Можно ли вызвать функцию, которая изменит размеры всех диаграмм на странице, когда я сделаю свой переключатель вкладок?

Он выглядит так: How it looks

когда он должен выглядеть следующим образом: How it should look

EDIT: Похоже, что это не проблема, связанная напрямую с highcharts, например, мои карты google выглядят следующим образом: How Google Maps looks

но когда я изменяю размер окна, он настраивается правильно: How Google Maps looks after resize

Можно ли обновить/настроить CSS в сетках через вызов функции в JS при переключении вкладки?

4b9b3361

Ответ 1

Что сработало для меня, вызывает:

$(window).resize();

Когда я загружаю новую вкладку. По-прежнему возникают проблемы с API Карт Google, но он отлично работает с Highcharts.

Ответ 2

Вы обнаружите много проблем, когда пытаетесь воспроизвести вещи, которые начинаются с "display: none". В то время как $(window).resize() может работать во многих случаях, я бы предложил попробовать сначала отобразить вашу страницу перед отображением: ни один не вступает в силу. Возможным решением было бы установить непрозрачность: 0 или видимость: скрытый.

Атрибут display - это то, что контролирует, как будет отображаться ваш элемент, например, блок (100% ширина) или встроенный (соответствие содержимому). Когда элемент имеет отображение: none, он отменяет это, в конечном счете удаляя его эффективную ширину и высоту, пока этот элемент не получит тип блока.

Вот пример, демонстрирующий: http://jsfiddle.net/m2f3scmm/3/

<div id="log1" style="display: none;">
</div>
<div id="log2" style="visibility: hidden;">
</div>
<div id="log3" style="opacity: 0">
</div>

При использовании взлома "resize" вы предполагаете, что плагин или script, который вы используете, привязывают к событию изменения размера окна, что не всегда так. Запуск window.resize также может замедлить рендеринг или вызвать нежелательные эффекты (например, маленькие анимационные диаграммы выполняются при первом рендеринге - который выглядит хромым, когда он происходит каждый раз, когда изменяется вкладка).

Ответ 3

/**
 * Adjust size for hidden charts
 * @param chart highcharts
 */
function adjustGraph(chart) {
    try {
        if (typeof (chart === 'undefined' || chart === null) && this instanceof jQuery) { // if no obj chart and the context is set
            this.find('.chart-container:visible').each(function () { // for only visible charts container in the curent context
                $container = $(this); // context container
                $container.find('div[id^="chart-"]').each(function () { // for only chart
                    $chart = $(this).highcharts(); // cast from JQuery to highcharts obj
                    $chart.setSize($container.width(), $chart.chartHeight, doAnimation = true); // adjust chart size with animation transition
                });
            });
        } else {
            chart.setSize($('.chart-container:visible').width(), chart.chartHeight, doAnimation = true); // if chart is set, adjust
        }
    }
    catch (err) {
        // do nothing
    }
}

Использование

$(window).resize(function () {
        if (this.resizeTO) clearTimeout(this.resizeTO);
        this.resizeTO = setTimeout(function () {
            // resizeEnd call function with pass context body
            adjustGraph.call($('body'));

        }, 500);
    });

для вкладки начальной загрузки

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
            var isChart = $(this).attr('data-chart');
            var target = $(this).attr('href');
            if (isChart) {
                // call functio inside context target
                adjustGraph.call($(target));
            }
        });



  <ul id="tabs" class="nav nav-tabs" data-tabs="tabs">
        <li class="active">
            <a href="#anagrafica" data-toggle="tab"><h5>Anagrafica</h5></a>
        </li>
        <li>
            <a href="#consumi" data-toggle="tab" data-chart="1"><h5>Consumi</h5></a>
        </li>
    </ul>

на графике

new Highcharts.Chart({
            chart: {
                renderTo: 'chart-bar',
                defaultSeriesType: 'column',
                zoomType: 'xy',
                backgroundColor: null,
                events: {
                    load: function (event) {
                        adjustGraph(this);
                    }
                }
            },

html-код

div class="tab-pane" id="charts">
    <div class="row-fluid">
        <div class="span6 offset3">
            <div id="myCarousel" class="carousel slide">
                <!-- Carousel items -->
                <div class="carousel-inner chart-container">
                    <div class="active item">
                        <h3>Chart 1/h3>
                        <div id="bar-pod-annuale">
                           <div id="chart-bar" style="width:100%;margin: 0 auto"></div>
                        </div>
                    </div>
                    <div class="item">
                        <h3>Char 2</h3>
                        /** chart **/
                    </div>
                    <div class="item">
                        <h3>Char 3</h3>
                        /** chart **/
                    </div>
                </div>
                <!-- Carousel nav -->
                <a class="carousel-control left" href="#myCarousel" data-slide="prev">‹</a>
                <a class="carousel-control right" href="#myCarousel" data-slide="next">›</a>
            </div>
        </div>
    </div>

См. jsfiddle http://jsfiddle.net/davide_vallicella/LuxFd/2/