20

Вопрос по rendering, javascript, svg – amCharts не отображает диаграмму для изначально скрытых div

я используюamCharts (который используетRapha & # xEB; л за кулисами) визуализировать некоторые диаграммы в виде SVG; и заметили, что если SVG визуализируется в изначально невидимом div, браузер не сразу отображает изображение, когда div становится видимым. Однако если я изменю отображение, например, изменяя размер браузера или масштабирование с помощью Ctrl-mousewheel, изображение SVG затем отображается, как и ожидалось, когда страница перерисовывается.

Точный метод переключения видимости div черезПанель навигации с вкладками.

Я признаю, что не очень разбираюсь в SVG - это проблема с браузерами & apos; рендеринг или amCharts & apos; Разметка SVG, или я должен явно вызывать какой-то метод перерисовки, когда я могу сказать, что видимость SVG изменилась?

Вот этоjsFiddle, который иллюстрирует проблему; если вы переключитесь на Раздел 2 (в Chrome, Firefox), диаграмма изначально не видна. Изменение размера дисплея вызывает его появление.

На эту тему есть учебник, составленный amCharts:blog.amcharts.com/2012/08/…

от zeroin

Добавить chart.invalidateSize (); во вкладке нажмите. Ref:amcharts.com/tutorials/…

от Raja

Highcharts / Highstock также имеет эту проблему.

от iman
10 ответов
1

Code:

<a href="#" class="show_charts">Show me charts</a>
<div class="charts_div" style="display:hidden;">
some charts here
</div>
<script>
    $(document).on('click', '.show_charts', function(){
        $('.charts_div').toggle();
        //just redraw all charts available on the page
        for(var i = 0; i < AmCharts.charts.length; i++) {
            AmCharts.charts[i].validateData();
        }
    });
</script>
1

Code:

var chart = null;
AmCharts.ready(function () {
    chart = AmCharts.makeChart('chart', .....);
});
$(document).ready(function(){
    $("#view_chart").click(function(){
        chart.validateSize();
    });
});


<button type="button" id="view_chart">View Chart</button>
<div style="display:none;" id="chart"></div>
0

я имею на разных вкладках.

я имеюtwo amcharts на разных вкладках. Биржевая диаграмма должна быть размещена в #chartdiv, а круговая диаграмма - в #chartdivpie. Вот как я решил свою проблему.

Мой кастом css - перезаписать бутстрап -

#chartdivpie { width: 1138px; height: 500px; }
.tab-content .tab-pane {
   position: absolute;
   top: -9999px;
   left: -9999px;
   display: inline;
}
.tab-content .tab-pane.active {
    position: inherit !important;
}

JQuery вызов

$('#myTab a').click(function (e) {
      e.preventDefault()
        $(this).tab('show');
        chart.invalidateSize();
        chart.write('chartdiv');
    })
1

Это может помочь вам решить проблему. У меня есть амхарт

показывающий в другой панели вкладок. Компонент SVG не позволяет им показывать этот div из-за изменения размера.

$(window).resize(function() {
    setTimeout(function() {
        chart.write("chartdiv1");
    }, 300);
});

измените размер своего окна, пока вы создаете свои графики ..

3

У меня была та же проблема, но мое решение - альтернатива отображению

нет, вы можете использовать этот класс в CSS

.hidden {
   position: absolute !important;
   top: -9999px !important;
   left: -9999px !important;
}

это исчезновение экрана, но видимое для amchart, поэтому разрешение диаграммы никогда не теряет размер !!!!

Нет проще, спасибо !!

от 
0

Другая работа будет

drawTransactionTypeChart();
setTimeout(function(){hidePieCharts();},1);

Первоначально установленоdisplay:inline div, который является контейнером диаграммы, он визуализируется.

Затем установитеdisplay:none с помощьюsetTimeout() после 1 мс.

Надеюсь это поможет...

4

* Edited *

Вот обновленныйиграть на скрипке, Холст будет отображаться только после отображения вкладки. Я сохраняю идентификаторы чартов в массиве и проверяю, есть ли в нем или нет.

* Edited *

Единственное решение, которое я нашел, - показать график после показа конкретной вкладки.

Как вы видите в этомjsFiddle.

var tabs = $('.tabbable').tab()

tabs.on('shown', function(e){
   id = $(e.target).attr('href');        
   chartdiv_id = $(id).find('.chartdiv').attr('id');                        
   doChart(chartdiv_id, true);
});

Я думаю, это не совсем то, что вы ищете, но я надеюсь, что на данный момент это поможет.

Спасибо за вашу работу и обновление. В настоящее время все еще есть ошибка в вашей последней версии (хотя и незначительной) - если вы переключаетесь между вкладками,then измените размер браузера, обе диаграммы запускаются, чтобы перерисовать себя, и мы возвращаемся к исходной точке. Вот почему мое первое предложенное решение включало написание диаграммыevery время, когда вкладка стала активной (примерforked fiddle), который преодолевает влияние любых промежуточных размеров.

от Andrzej Doyle

Нет проблем. Я пропустил это. Я считаю, что перерисовка графиков каждый раз, наверное, лучшее решение. Спасибо за ваш голос! Всегда искал здесь решения своих проблем, но никогда не участвовал, и я думал, что пытаюсь помочь другим с их проблемами для разнообразия.

от 

Я принял свой собственный ответ, поскольку он объясняет, с чем я на самом деле пошел, но еще раз благодарю вас за вашу помощь. В частности, ваша идея определения конкретной вкладки, которая стала активной, была важна для предотвращения растягивания полей области графика.

от Andrzej Doyle
1

Я также столкнулся с проблемой и исправил ее

сделав инициализатор функцией.Рабочая скрипка.

$("#button").click(function(){
    $("#chartdiv").toggle();
    makeChart();
});

function makeChart() {
     var chart = AmCharts.makeChart("chartdiv", {
         //all the stuff
     });
}
23

Я нашел причину как исходного поведения

так и обходного пути - и это все специфично для amCharts (не имеет ничего общего с SVG как таковым), поэтому я перефразирую название соответствующим образом.

Что происходит, так это то, что когда amCharts создает SVG, ему нужно (или, по крайней мере, решить) определить ширину и высоту в абсолютном выражении. Они основаны на размере целевого div, полученного черезoffsetWidth а такжеoffsetHeight свойства.

Неактивная вкладка имеетdisplay: none набор свойств, и в результате эта часть DOM даже не отображается, поэтому возвращает ноль для обоих свойств размера. В конечном итоге это приводит к тому, что amCharts создает диаграмму SVG 0x0, когдаchart.write вызывается для скрытого div.

Изменение размера исправляет вещи, потому что каждая диаграмма регистрирует слушателяonresize событие окна, которое вызывает диаграммуhandleResize метод. Это заставляет пересчитывать ширину и высоту на основе новых (текущих) размеров div.

Итак, в заключение я думаю, что есть два альтернативных способа справиться с этим:

Call chart.write for a chart when and only when its tab becomes visible. Call each chart's handleResize method when the tabs change.

(Первый вариант позволяет избежать начального попадания при рендеринге невидимой диаграммы, но затем выполняет полную перерисовку при каждой смене вкладок. Последний принимает удар вперед, но, вероятно, быстрее после этого. Для бонусных отметок лучшим решением будет визуализировать каждую диаграмму ровно один раз между каждым изменением размера, когда она становится видимой в первый раз, но это намного сложнее, поскольку, помимо всего прочего, может потребоваться вмешательство в прослушиватели событий по умолчанию.)

UpdateДальнейшие осложнения с отображением невидимой диаграммы; в частности, я обнаружил проблемы с вычислениями высоты, не учитывающими пространство, требуемое для оси домена, и поэтому растягивающими диаграмму из ее деления. Это не было исправлено путем вызоваhandleResize - звонитmeasureMargins заранее выглядело так, как будто это должно работать, но это не так. (Возможно, есть другой метод, который можно вызвать после этого, чтобы он работал, например:resetMargins но в этот момент это начало казаться очень облупленным ...)

Таким образом, я не думаю, что было бы целесообразно впервые отображать диаграмму на невидимом элементе div, поэтому я выбрал некоторую комбинацию вышеупомянутых маркеров. Я слушаю, когда вкладка графика становится видимой в первый раз, а затем вызываюchart.write для соответствующего объекта диаграммы - и всякий раз, когда вкладки меняются,all ранее отрисованные диаграммы должны обрабатывать изменения размера.

1

Я полностью согласен с Анджей Дойл.

Выдача handleizeize на графике при нажатии на выбранный div (tab) работает для меня на cs-cart с пользовательскими вкладками (не jquery).

Следующее работает, пока тележка определена глобально.

    function refreshchart(){
        chart.handleResize();
    };

Похожие вопросы