2016-08-12 5 views
2

Я создаю div контейнер, который я затем заполнить с svgЗаменить старое содержание D3

var someContainer = d3.select("#abc") 
     .append("div") 
     .classed("svg-container", true) 
     .append("svg") 
     .attr("preserveAspectRatio", "xMinYMin meet") 
     .attr("viewBox","0 0 400 100") 
     .classed("svg-content-responsive", true) 
     .selectAll("circle") 
     .data(someScale.range()); 

Я затем добавить мои данные к нему

someContainer.remove(); 

someContainer.enter() 
     .append("circle") 
     .attr("x", function (d, i) { 
      return i * 2; 
     }) 
     .attr("y", 5) 
     .attr("height", 15) 
     ....; 

Однако всякий раз, когда я обновить содержание svg, т. Е. Добавлять новые круги, создается совершенно новое div-container и svg-container. Это оставляет меня со старыми данными, визуально остающимися на своем месте и прямо внизу (что на 100 пикселей ниже) появляются новые данные. Его в основном визуальная копия, но с новыми данными ... Всякий раз, когда я обманываю свои данные, новый coy заменяется под старым, оставляя меня с n графикой.

Вот css, который стирает относительный контейнер и гарантирует, что он масштабируется при изменении размера окна. Источник: Resize svg when window is resized in d3.js */

.svg-container { 
    display: inline-block; 
    position: relative; 
    width: 100%; 
    padding-bottom: 50%; /* aspect ratio */ 
    vertical-align: top; 
    overflow: hidden; 
} 

.svg-content-responsive { 
    display: inline-block; 
    position: absolute; 
    top: 10px; 
    left: 0; 
} 

Любые идеи, что я делаю неправильно?

ответ

0

Проблема заключается в том, что каждый раз, когда данные обновляется, создается новый div.

var someContainer = d3.select("#abc") 
    .append("div") 
    .classed("svg-container", true) 
    ... 

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

d3.select(".svg-container").remove(); 

над var someContainer = d3.select...

2

Если вам просто нужно удалить все старые круги, которые вы можете сделать это следующим образом:

someContainer.selectAll("circle").remove() 

А потом добавлять новые круги по данным -> введите -> добавить последовательность.

someContainer.selectAll("circle") 
     .data(new_circle_data) 
     .enter() 
     .append("circle") 
     .attr("x", function (d, i) { 
      return i * 2; 
     }) 
     .attr("y", 5) 
     .attr("height", 15) 
     ....; 

Если вы хотите удалить только некоторые из существующих кругов и держать остальных вы можете использовать general update pattern. Вам нужно сделать что-то вроде этого:

var circleUpdate = someContainer.selectAll("circle") 
    .data(new_circle_data) 

circleUpdate.enter().append("circle") 
    .attr("x", function (d, i) { 
      return i * 2; 
     }) 
    .attr("y", 5) 
    .attr("height", 15) 
    ....; 

circleUpdate.exit().remove() 
+0

Нет, это не делает трюк. Материал все еще дублируется. Я думаю, проблема в том, что каждый раз, когда создается новый ** div ** ... Когда я использую элемент Inspector, я вижу, что каждый раз, когда я обновляю данные, появляется новый контейнер div. – Stophface

+0

Создайте SVG только один раз, когда вы инициализируете сюжет. Вызовите функцию обновления при взаимодействии с графиком, чтобы изменить ее. Эта функция обновления может содержать только кодовые блоки, которые я предоставил, для обновления кругов должно быть достаточно. –