Графики NVD3 не отображаются корректно на скрытой вкладке

Я создаю страницу, которая содержит много диаграмм, которые отображаются по одному в зависимости от того, на какой вкладке вы смотрите.

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

Предположительно, это связано с тем, что скрытое поле не имеет размеров, пока оно не станет видимым. Фактически, если я изменил размер окна, график будет корректировать его пропорции и отобразить так, чтобы он заполнил доступную ширину.

Я могу исправить эту проблему, явно определяя размер диаграммы через css, но это побеждает отзывчивый аспект диаграмм.

Может ли кто-нибудь сказать мне, как запускать одно и то же событие NVD3, которое активируется при изменении размера окна? Таким образом, я могу привязать его к выбору новой вкладки и, надеюсь, устранить проблему с рендерингом.

Ответы

Ответ 1

Я понял, как вызвать событие изменения размера, которое мне нужно. В моем случае вкладки управляются бутстрапом. Поэтому я просто изменил событие вкладки show bootstrap, чтобы вызвать событие изменения размера страницы. Это немного косвенно, но он выполняет свою работу:

jQuery('#myTab a').click(function (e) {
    e.preventDefault()
    jQuery(this).tab('show')
    jQuery(window).trigger('resize'); // Added this line to force NVD3 to redraw the chart
})

Ответ 2

У меня была такая же проблема (диаграммы на нескольких вкладках), и это единственное, что я мог бы сделать.

$(function () {
    $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
        window.dispatchEvent(new Event('resize'));
    });
});

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

Кто-нибудь знает, как обеспечить ТОЛЬКО активную диаграмму, которая будет изменена/перерисована?

Ответ 3

Просто добавьте этот JavaScript:

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  window.dispatchEvent(new Event('resize'));
})

hidden.bs.tab - событие, которое запускается после того, как новая вкладка отображается в соответствии с документами Bootstrap. Этот код запускает событие изменения размера после изменения каждой вкладки.

Ответ 4

Я столкнулся с такой же проблемой. Я использовал ng-show, чтобы сделать div скрытым. Когда я заменяю ng-show на ng-if, я могу видеть график в ожидаемом поведении. Объяснение: 1. Когда мы используем ng-show или ng-hide, чтобы скрывать div, он меняет его отображаемое свойство, но div будет в dom. 2. Когда мы используем ng-if, div удаляется из dom и снова добавляется в dom, поэтому он выполняет внутреннюю операцию redraw на графике nvd3. Следовательно, вместо правильного графика мы видим правильный граф.

Ответ 5

Событием, которое обычно запускает перерисовку, является событие window resize - для этого NVD3 не использует для этого настраиваемое событие. Вы можете контролировать это самостоятельно; обычное определение

nv.utils.windowResize(function() { d3.select('#chart svg').call(chart); });

(где "#chart" - это элемент, содержащий граф). Там ничего не мешает вам запускать код на другом событии или даже просто запускать код перерисовывания явно при изменении вкладки.

Ответ 6

более эффективным подходом было бы использовать метод chart.update()

var chart_x = nv.models.somechart()
var chart_y = nv.models.somechart()

..... показать графики

jQuery('#myTab a').click(function (e) {
    e.preventDefault()
    jQuery(this).tab('show')
    if(jQuery(this)...something === '..x..')
      chart_x.update(); //CALL THE UPDATE
    else ...  

})