2016-03-30 4 views
0

Я пытаюсь реализовать вложенную пузырьковую диаграмму для моего проекта, где я должен показывать, что происходит в разных клиентах в сети. Я использовал этот пример показал, по адресу: https://bl.ocks.org/mbostock/7607535Обновление вложенной пузырьковой диаграммы d3 с потоковыми данными

Вот код, я использую:

/// <reference path="../bower_components/dt-d3/d3.d.ts" /> 
    var margin = 20, diameter = 960; 
    var color = d3.scale.linear() 
     .domain([-1, 4]) 
     .range(["#ff8080", "#b30000"]) 
     .interpolate(d3.interpolateHcl); 
    var pack = d3.layout.pack() 
     .padding(2) 
     .size([diameter - margin, diameter - margin]) 
     .value(function (d) { return d.size; }); 
    var svg = d3.select("body").select("#parent").select("#svg1").append("svg") 
    .attr("width", diameter) 
    .attr("height", diameter) 
    .append("g") 
    .attr("transform", "translate(" + diameter/2 + "," + diameter/2 + ")"); 
    var svg2 = d3.select("body").select("#parent").select("#svg2").append("svg") 
     .attr("width", 100) 
     .attr("height", 100) 
     .append("g") 
     .attr("transform", "translate(" + margin + "," + margin + ")"); 
    function draw(fileToRead){ 
     console.log(fileToRead); 
     d3.json(fileToRead, function (error, root) { 
      if (error) 
       throw error; 
     var focus = root, nodes = pack.nodes(root), view; 
     var circle = svg.selectAll("circle").data(nodes); 
     circle.attr("class","update"); 
     circle.enter().append("circle") 
      .attr("class", function (d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })  .style("fill", function (d) { return d.children ? d.children.length > 3 ? color(d.depth) : "white" : d.size > 0.02 ? "#660000" : "#003366"; }) 
      .style("fill", function (d) { return d.children ? "white" : d.size > 0.02 ? "#660000" : "#003366"; }) 
      .on("click", function (d) { if (focus !== d) 
      zoom(d), d3.event.stopPropagation(); }); 
     circle.exit().remove(); 
     var text = svg.selectAll("text").data(nodes); 
     text.attr("class","update"); 
     text.enter().append("text") 
      .attr("class", "label") 
      .style("fill-opacity", function (d) { return d.parent === root ? 1 : 0; }) 
      .style("display", function (d) { return d.parent === root ? "inline" : "none"; }) 
      .style("fill", "black") 
      .text(function (d) { return d.name; }); 
     text.exit().remove(); 
     var node = svg.selectAll("circle,text"); 
     d3.select("body") 
      .style("background", color(-1)) 
      .on("click", function() { zoom(root); }); 
     zoomTo([root.x, root.y, root.r * 2 + margin]); 
     function zoom(d) { 
      var focus0 = focus; 
      focus = d; 
      if (focus.depth == 2) { 
       circle2.style("fill", "white"); 
      } else { 
       circle2.style("fill", "black"); 
      } 
      var transition = d3.transition() 
       .duration(d3.event.altKey ? 7500 : 750) 
       .tween("zoom", function (d) { 
       var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]); 
       return function (t) { zoomTo(i(t)); }; 
      }); 
      transition.selectAll("text") 
       .filter(function (d) { return d.parent === focus || this.style.display === "inline"; }) 
       .style("fill-opacity", function (d) { return d.parent === focus ? 1 : 0; }) 
       .each("start", function (d) { if (d.parent === focus) 
       this.style.display = "inline"; }) 
       .each("end", function (d) { if (d.parent !== focus) 
       this.style.display = "none"; }); 
     } 
     function zoomTo(v) { 
      var k = diameter/v[2]; 
      view = v; 
      node.attr("transform", function (d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; }); 
      circle.attr("r", function (d) { return d.r * k; }); 
     } 
     }); 
    } 
    d3.select(self.frameElement).style("height", diameter + "px"); 

Проблема я встречая, когда я постоянно поток новых данных в пользовательском интерфейсе. Каждый раз я вызываю «Draw» с полным json-файлом со всеми данными, которые у меня есть в базе данных. Я прочитал, что функции ввода(), exit(), remove() несут ответственность за обновление элементов DOM, но, похоже, я что-то упускаю. Когда вызывается функция draw(), кажется, что она нарисовала пузырьки над существующими, и исчезают такие вещи, как цвет рамки границы или цвет границы текста. Мне интересно, правильно ли я использую команды enter() и exit(). Я хотел бы, чтобы функция draw() возвращала json-файл и обновляла информацию только в новом графическом элементе, и для него не существует никаких элементов DOM, но, похоже, он снова воссоздает все элементы DOM.

Спасибо заранее, Георгий

PS: У меня есть два SVG-х Becase Я пытаюсь разделить экран на две части с левой стороны, занимаемых пузырьковой диаграмме и правой стороны с дополнительной информацией, полученной после мы увеличить его на внутренний пузырь

edit1: Вот пример данных я передаю в функцию Жеребьевка():

{"name": "", 
    "children": 
     [{"name": "10.0.0.64", "children": 
      [{"name": "unidentified", "children": 
       [{"name": "datasource", "size": 0.002551020408163265}, {"name": "datasource", "size": 0.0031746031746031746}, {"name": "datasource", "size": 0.0017123779389460522}, {"name": "average", "size": 0.008550406895439414}, {"name": "datasource", "size": 0.019020266320109332}]}, 
      {"name": "www.quefaire.be", "children":     
       [{"name": "average", "size": 0.002270490544565449}, {"name": "datasource", "size": 0.023243328100470965}]}, {"name": "tnsinternet.be", "children": [{"name": "average", "size": 0.002199967070440535}, {"name": "datasource", "size": 0.022009167303284966}]}, 
      {"name": "hy.sachinese.com", "children":      
       [{"name": "average", "size": 0.0022121416372369493}, {"name": "datasource", "size": 0.022222222222222223}]}, {"name": "pagesdor.be", "children": [{"name": "average", "size": 0.0030411250824668935}, {"name": "datasource", "size": 0.03672943251374624}]}, 
      {"name": "r.254a.com", "children": 
       [{"name": "average", "size": 0.0018942905665264935}, {"name": "datasource", "size": 0.015873015873015872}]}, 
      {"name": "i.ctnsnet.com", "children": 
       [{"name": "average", "size": 0.0018942905665264935}, {"name": "datasource", "size": 0.015873015873015872}]}, 
      {"name": "link.carrefour.eu", "children": 
       [{"name": "average", "size": 0.0019793245801319357}, {"name": "datasource", "size": 0.017857142857142856}]}, 
      {"name": "goudengids.be", "children": 
       [{"name": "average", "size": 0.00457041828122788}, {"name": "datasource", "size": 0.06349206349206349}]}, {"name": "www.inmemoriam.be", "children": [{"name": "average", "size": 0.0018443560093702978}, {"name": "datasource", "size": 0.014707876206037973}]}, 
      {"name": "www1.gfk-wi.com", "children": 
       [{"name": "datasource", "size": 0.011986645572622365}, {"name": "average", "size": 0.0017277318393667718}]}, {"name": "bootstrapcdn.com", "children": [{"name": "average", "size": 0.008550406895439414}, {"name": "datasource", "size": 0.13314186424076532}]}, 
      {"name": "maxcdn.bootstrapcdn.com", "children": 
       [{"name": "datasource", "size": 0.031746031746031744}, {"name": "average", "size": 0.0027563593243117796}]}]}]} 

Вот и мой CSS:

+0

вы можете также предоставить образец данных, которые вы получаете от 'fileToRead' – Cyril

+0

Это также выглядит, как вы не вызывая' обновление) 'функции (, которая, вероятно, вызывая (потенциально связанные) проблемы. – JSBob

+0

@ Кирилл Я обновил сообщение с образцом данных и CSS для веб-сайта –

ответ

2

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

Решение ниже будет работать только в том случае, если есть уникальное имя.

Вместо

var circle = svg.selectAll("circle").data(nodes);

сделать

var circle = svg.selectAll("circle").data(nodes, function(d){return d.name}); 

и вместо этого

var text = svg.selectAll("text").data(nodes); 

сделать

var text = svg.selectAll("text").data(nodes, function(d){return d.name}); 

функция exit() не может работать должным образом из-за выше.

Читайте о ключевой функции here

+0

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

+0

да! он должен работать в этом случае. – Cyril

+0

Итак, после некоторой работы с уникальными идентификаторами мне удалось заставить ее работать частично. Я все еще сталкиваюсь с проблемами при обновлении, что границы или блики (стиль attr, определенный через d3 или SCC) не перерисовываются. Знаете ли вы, в чем причина? –

Смежные вопросы