NVD3 добавляет старый график в SVG, когда вызывается событие изменения размера

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

Это все работает отлично, проблема возникает, когда я изменяю размер окна и звоню chart.update через nv.utils.windowResize, По какой-то странной причине во время этого процесса старые диаграммы снова добавляются в DOM, и отображаются 2 диаграммы.

Вот картина эффекта:

Вот пример плунжера с поведением: Плункер. Просто нажмите кнопку, чтобы изменить тип диаграммы со строки на линейку, и измените размер окна предварительного просмотра.

Кто-нибудь имел эту проблему раньше или знает что-нибудь, что я могу попытаться решить это поведение?

Большое спасибо за любую помощь!

1 ответ

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

    var removeChart = function(element) {
        d3.select(element).selectAll('*').remove();
        d3.selectAll('.nvtooltip').style('opacity', '0');
    };

    nv.utils.windowResize(function() {
        // chartElement is a reference to the chart's <svg> element
        removeChart(chartElement);
        chart.update();
    });

Мне кажется, что есть проблема с тем, как вы объявляете график. Оператор let использует область видимости, поэтому ваш оригинальный код:

 if(that.useLine) {
   let chart = nv.models.lineChart();
 } else {
   let chart = nv.models.discreteBarChart();
 }

не сработает Диаграмма будет определена только в блоке if. Вы можете сделать это вместо этого (обратите внимание, что диаграмма объявлена ​​вне замыкания):

private addGraph(): void {

  let that = this;
  let chart;

  nv.addGraph(() {

    d3.selectAll(`svg > *`).remove();

    if(that.useLine) {
      chart = nv.models.lineChart();
    } else {
      chart = nv.models.discreteBarChart();
    }

    let myData = that.testData();

    d3.select('#chart svg')   
      .datum(myData) 
      .call(chart);

    //Update the chart when window resizes.
    nv.utils.windowResize(function() { chart.update() });
    return chart;
  });
}

https://plnkr.co/edit/pwiO8FCpGyd2JLG4hllW?p=preview

Другие вопросы по тегам