简体   繁体   English

具有10,000个节点的d3.js树图

[英]d3.js treemap with 10,000 nodes

js treemap that updates and re-renders when I receive new data. 接收新数据时更新并重新渲染的js树图。 I have built on a data set of 50 elements and it works great. 我建立了包含50个元素的数据集,并且效果很好。 However, I am trying to run the same code on a much larger dataset 10,000 elements. 但是,我试图在更大的数据集10,000个元素上运行相同的代码。 And it seems to be unable to render the graphic, does anybody know of any examples of d3.js working on large data sets, or does anybody have any suggestions? 而且它似乎无法渲染图形,有人知道在大型数据集上使用d3.js的任何示例吗,或者有人有任何建议吗?

Also, when I do graph the maps, sometimes they shift position, and it seems like the orientation of the elements is messed up because they move outside the chart or overlap with another element, leaving whitespace in the throughout the graph, but after re-rendering the graph usually corrects itself, and then messes up again. 另外,当我绘制地图时,有时它们会移动位置,并且元素的方向似乎被弄乱了,因为它们移到了图表之外或与另一个元素重叠,从而在整个图表中都留有空白,但是在重新绘制之后渲染图形通常会自行纠正,然后再次混乱。 I think the problem comes about because the graph is resizing itself with regards to absolute positions, but rects in certain positions from the previous render are messing things up. 我认为问题之所以出现,是因为图形会根据绝对位置调整自身大小,但是前一渲染中某些位置的矩形会使事情变得混乱。 Any clue how to stop this intermediate phase of having a messed up graph before being able to re-render? 有什么线索可以在重新渲染之前停止图表混乱的中间阶段吗? Thanks. 谢谢。

This is the code I use to initially draw the d3 regraph. 这是我最初用来绘制d3笔迹的代码。

function drawTreeMap(array1,array2, colorArray)
{
  console.log("got to drawing"); 
  var cellMargin=5;
  this.marginTree = {top:20, right:20, bottom:20, left:20};
  var coloring = d3.scale.linear()
          .range(['lightblue', 'green']) // or use hex values
          .domain([this.getMinOfThisArray(colorArray), this.getMaxOfThisArray(colorArray)]);
  this.nestedJson = this.createObj(array1, array2, colorArray);
      this.w = 1700 - 80,
      this.h = 980 - 180,
      this.x = d3.scale.linear().range([0, this.w]),
      this.y = d3.scale.linear().range([0, this.h]),

      this.root,
      this.node;


      this.treemap = d3.layout.treemap()
          .round(false)
          .size([this.w, this.h])
          .sticky(true)
          .padding([this.marginTree.bottom, this.marginTree.right, this.marginTree.top, this.marginTree.left])
          .sort(function(a,b) {
                return a.value - b.value;
            })
          .value(function(d) { return d.size; });

      this.svg = d3.select("#body").append("div")

          .attr("class", "chart")
          .style("position", "relative")
          .style("width", (this.w) + "px")
          .style("height", (this.h ) + "px")
          .style("left", this.marginTree.left +"px")
          .style("top", this.marginTree.top + "px")
        .append("svg:svg")
          .attr("width", this.w)
          .attr("height", this.h)
        .append("svg:g")
          .attr("transform", "translate(.5,.5)");


        this.node = this.root = this.nestedJson;



        var nodes = this.treemap.nodes(this.root)
            .filter(function(d) { return !d.children; });

        this.tip = d3.tip()
              .attr('class', 'd3-tip')
              .html(function(d) {
                return "<span style='color:white'>" + (d.name+",\n "+d.size) + "</span>";
              })
        this.svg.call(this.tip);

        var cell = this.svg.selectAll("g")
            .data(nodes)
            .enter().append("svg:g")
            .attr("class", "cell")
            .call(this.position)
            .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
            .on("click", function(d) { return this.zoom(this.node == d.parent ? this.root : d.parent); });

        var borderPath = this.svg.append("rect")
            .attr("class", "border")
            .attr("x", this.marginTree.left)
            .attr("y", this.marginTree.top)
            .attr("height", this.h - this.marginTree.top - this.marginTree.bottom )
            .attr("width", this.w - this.marginTree.left - this.marginTree.right)
            .style("stroke", 'darkgrey')
            .style("fill", "none")
            .style("stroke-width", '3px');


        cell.append("svg:rect")
            .attr("id", function(d,i) { return "rect-" + (i+1); })
            .attr("class","highlighting2 cell-rects")
                .attr("title", function(d) {return (d.name+", "+d.size);})
                .attr("data-original-title", function(d) {return (d.name+",\n "+d.size);})
          .attr("width", function(d) { return d.dx ; })
          .attr("height", function(d) { return d.dy ; })
          .on('mouseover', this.tip.show)
                .on('mouseout', this.tip.hide)
          .style("fill", function(d) {return coloring(d.color);});


        cell.append("svg:text")
            .attr("class", "treemap-text nameTexts") 
            .attr("id", function(d,i) { return "name-" + (i+1); })
            .attr("x", cellMargin)  
            .attr("y", function(d) {  return parseInt($('.treemap-text').css('font-size'))+cellMargin; })
          .text(function(d) {return (d.name);});

       cell.append("svg:text")
            .attr("class", "treemap-text sizeTexts") 
            .attr("id", function(d,i) { return "size-" + (i+1); })  
            .attr("x", cellMargin)  
            .attr("y", function(d) {  return 2*parseInt($('.treemap-text').css('font-size'))+2*cellMargin; })
            .text(function(d) {return (d.size);});

       // d3.selectAll("svg:rect")
       //    .style("stroke-width", 2)
       //    .style("stroke", function(d){ return this.LightenDarkenColor(coloring(d.color), -5);});



          this.treeMapping = true;
        $(document).ready(function(){

            for (var i =1 ; i<graphObj.rc.positions[graphObj.currentVpName].SetSize; i++){
                var obj = "rect-"+i;
                var size = "size-"+i;
                var name = "name-"+i;
                graphObj.formatNumbers(size);
                graphObj.placeTextWithEllipsis(obj, size);
                graphObj.placeTextWithEllipsis(obj, name);

                }
          d3.selectAll(".nameTexts")
          .style("fill", "#333333");
         d3.selectAll(".sizeTexts")
          .style("fill","#383838");

         });
}

This is the file I use to re-render the treemap when I receive new data. 这是我收到新数据时用于重新渲染树形图的文件。

function redrawGraph(array1, array2, colorArray)
{   

   this.nestedJson = this.createObj(array1, array2, colorArray);
  var coloring = d3.scale.linear()
          .range(['lightblue', 'green']) // or use hex values
          .domain([this.getMinOfThisArray(colorArray), this.getMaxOfThisArray(colorArray)]);
   var cellMargin = 5;

  this.svg = d3.select("#body").append("div")

  this.treemap
    .mode("squarify")
    .round(false)
    .size([this.w,this.h])
    .sticky(true)
    .value(function(d) { return d.size; });


  // Draw the graph


  this.node = this.root = this.nestedJson;

  var nodes = this.treemap.nodes(this.root)
              .filter(function(d) { return !d.children; });



  var rect = d3.select("#body").selectAll(".cell-rects")
        .data(nodes);

  rect.exit().remove();

  rect.enter().append("rect");

  rect
    .transition()
    .attr("width", function(d) { return d.dx ; })
    .attr("height", function(d) { return d.dy ; })
        .attr("title", function(d) {return (d.name+", "+d.size);})
        .attr("data-original-title", function(d) {return (d.name+",\n "+d.size);})
    .style("fill", function(d) { return coloring(d.color)})
    .call(this.position);

  var text = d3.select("#body").selectAll(".nameTexts")
        .data(nodes);


  text.exit().remove();

  text.enter().append("text");

  text
    .attr("class", "treemap-text nameTexts")
    .attr("x", cellMargin)  
    .attr("y", function(d) {  return parseInt($('.treemap-text').css('font-size'))+cellMargin; })
    .text(function(d) { return (d.name); });


  var text2 = d3.select("#body").selectAll(".sizeTexts")
        .data(nodes);

  text2.exit().remove();

  text2.enter().append("text");

  text2
    .attr("class", "treemap-text sizeTexts")
    .attr("x", cellMargin)  
    .attr("y", function(d) {  return 2*parseInt($('.treemap-text').css('font-size'))+2*cellMargin; })
    .text(function(d) { return (d.size); });

  var cell = this.svg.selectAll("g")
    cell.append("svg:rect")
    cell.append("svg:text");

  // var border = this.svg.append("rect")
  //   .attr("x", this.marginTree.left)
  //   .attr("y", this.marginTree.top)
  //   .attr("height", this.h - this.marginTree.top - this.marginTree.bottom )
  //   .attr("width", this.w - this.marginTree.left - this.marginTree.right)
  //   .style("stroke", 'darkgrey')
  //   .style("fill", "none")
  //   .style("stroke-width", '3px');


    // d3.select(window).on("click", function() { 
    //   this.zoom(this.root); });

    // d3.select("select").on("change", function() 
    // {
    //   this.treemap.value(this.value == "size" ? this.size : this.count).nodes(this.root);
    //   this.zoom(this.node);
    // });
    d3.selectAll(".nameTexts")
      .style("fill", "#333333");
   d3.selectAll(".sizeTexts")
    .style("fill","#383838");

    $(document).ready(function(){

      for (var i =1 ; i<graphObj.rc.positions[graphObj.currentVpName].SetSize; i++){
          var obj = "rect-"+i;
          var size = "size-"+i;
          var name = "name-"+i;
          graphObj.formatNumbers(size);
          graphObj.placeTextWithEllipsis(obj, size);
          graphObj.placeTextWithEllipsis(obj, name); 
          }
     });

} }

 rdaGraph.prototype.position = function()
 {
    this.style("left", function(d) { return d.x + "px"; })
      .style("top", function(d) { return d.y + "px"; })
      .style("width", function(d) { return Math.max(0, d.dx - 1) + "px"; })
      .style("height", function(d) { return Math.max(0, d.dy - 1) + "px"; });
 }

Also by white space I mean this. 同样,空白是指这个。

Image is linked here. 图片链接在这里。 [ http://i.stack.imgur.com/LTLk6.png][1] [ http://i.stack.imgur.com/LTLk6.png][1]

您可以将数据流传输到D3,请查看这篇文章,其中显示了将数据实时流传输到图形。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM