【问题标题】:Direct Force Layout customization - d3.js直接强制布局自定义 - d3.js
【发布时间】:2015-06-25 17:34:01
【问题描述】:

关于 Stack Overflow 的第一个问题,请耐心等待!我是 d3.js 的新手,但一直对其他人能够用它完成的事情感到惊讶......几乎同样对我自己能够取得的进展感到惊讶!显然我不是在摸索什么,所以我希望这里的好心人能给我带来光明。

我的目的是根据 CSV 数据制作一个连接图。我的 CSV 数据有不同的信息,其中一些需要表示为节点,其中一些需要用作 ltool-tip 的信息。我可以使用以下 sn-p 代码从 CSV 读取数据:

d3.csv("data/project.csv", function(links) {
  var nodesByName = {};

  // Create nodes for each unique source and target.
  links.forEach(function(link) {
    link.source = nodeByName(link.Project);
    link.target = nodeByName(link.Problem);
  });

这会将节点 P1 连接到三个节点问题 (URL)。 问题来了,我看不到所选节点上的标签,如何使用 CSV 文件中的提取信息,例如“日期、摘要、URL”。有什么方法可以使用鼠标单击,当我单击节点时,我需要它的信息出现在 SVG 板上以用于进一步分析,例如显示 URL,摘要的短文本,以及当用户单击板时应该显示完整的信息。

这是我从this link使用的代码

    var width = 800,
    height = 600;

var svg = d3.select("#visualization")
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("svg:g");

var force = d3.layout.force()
    .gravity(0.2)
    .distance(200)
    .charge(-1500)
    .size([width, height]);

var container = svg.append("g")
    .attr("id", "container");

d3.csv("data/project.csv", function(links) {
  var nodesByName = {};

  // Create nodes for each unique source and target.
  links.forEach(function(link) {
    link.source = nodeByName(link.Project);
    link.target = nodeByName(link.Problem);
  });

  // Extract the array of nodes from the map by name.
  var nodes = d3.values(nodesByName);

  //define a scale for color mapping
  var colormapping = d3.scale.ordinal()
      .domain([0,nodes.length])
      .range(['#A700E6','#D95B96','#F4DA88','#22C1BE','#F24957','#DBEF91','#CF8EE8','#FF9B58','#B8FFC4','#91AEFF','#E873D3','#CCB298']);

  //create label node tooltip
  var labeltooltip = d3.select("body").append("div")
    .attr("class", "labeltooltip")
    .style("opacity", 1e-6);
  var zoom = d3.behavior.zoom()
     .scaleExtent([1, 10])
     .on("zoom", function() {
         container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
     });

     svg.call(zoom);
  //links
  var link = container.selectAll(".line")
      .data(links)
      .enter()
      .append("line")
      .attr("stroke-width",4)
    //  .attr("stroke-width",function (d) { return linethickness(d.value); })
      .style("stroke", "gray");

  // Create the node circles.
  var node = container.selectAll(".node")
      .data(nodes)
      .enter()
      .append("circle")
      .attr("class", "node")
      .attr("r", 20)
      .attr("fill", function (d,i) {return d3.rgb(colormapping(i)); })
      .call(force.drag);


  // Start the force layout.
  force
      .nodes(nodes)
      .links(links)
      .on("tick", tick)
      .start();

 node.on("mousemove", function(d) {
    labeltooltip.selectAll("p").remove();
    labeltooltip.style("left", (d3.event.pageX+15) + "px").style("top", (d3.event.pageY-10) + "px");
    labeltooltip.append("p").attr("class", "tooltiptext").html("<span>Id: </span>" + d.Score );
        labeltooltip.append("p").attr("class", "tooltiptext").html("<span>Score: </span>" + d.Score);
  }); 


 node.on("mouseover", function(d) {
        labeltooltip.transition()
          .duration(500)
          .style("opacity", 1);
        link.style('stroke', function(l) {
            if (d === l.source || d === l.target)
              return d3.rgb('#C20606');
            else
              return 'gray';
            });
        link.style('opacity', function(o) {
            return o.source === d || o.target === d ? 1 : 0;
        });
        node.style("opacity", function(o) {
            if (o.id != d.id)
                return neighboring(d.id, o.id) ? 1 : 0;
        });
    }); 

 node.on("mouseout", function(d) {
        labeltooltip.transition()
          .duration(500)
          .style("opacity", 1e-6);
    link.style('stroke', 'gray');
    link.style('opacity', 1);
    node.style("opacity", 1);  
    });

var circletext = node.append("svg:text")
    .text(function(d) {return d.name;})
    .attr("class","labelText");
  function tick() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
    circletext.attr("x", function(d) { return d.x-25; });
    circletext.attr("y", function(d) { return d.y-25;});
  }

  function nodeByName(name) {
    return nodesByName[name] || (nodesByName[name] = {name: name});
  }
    addZoomMoveIcon("#labelgraph");
});

更新 我的 CSV 数据

Project,Problem, Score,Data,Summary,id
p1,Problem1,10,2014-09-04T13:55:05.623-04:00, text text text text, 1
p1,Problem2,5,2014-09-04T13:55:05.623-04:00, text text text text,2
p1,Problem3,11,2014-09-04T13:55:05.623-04:00, text text text text,3

我想要的最终结果如下图:

单击“问题”节点时黄色框应出现在 SVG 上的位置。

【问题讨论】:

    标签: java javascript csv svg d3.js


    【解决方案1】:

    您需要解决的第一个问题是 where 以正确添加节点文本。现在您将文本嵌套在圆圈内,但文本标签必须是圆圈的兄弟(它们甚至不需要紧挨着每个圆圈)。你可以替换这个:

    var circletext = node.append("svg:text")
    .text(function(d) {return d.name;})
    .attr("class","labelText");
    

    与:

    var circletext = container.selectAll("g")
    .data(nodes)
    .enter()
    .append("text").text(function(d) {return d.name})
    .attr("class", "labelText");
    

    (参考:https://www.dashingd3js.com/svg-text-element)

    接下来,如果您想显示分数/数据/摘要,请注意这些附加到链接,而不是节点(只有三个,而不是四个)。但是,在创建节点时,您可以将此信息从链接传递到节点。修改 nodeByName 函数为节点添加新属性:

    function nodeByName(name,score,data,summary) {
        return nodesByName[name] || (nodesByName[name] = {name: name, score: score, data: data, summary: summary});
    }
    

    然后在创建链接时修改对这个函数的调用:

    links.forEach(function(link) {
        link.source = nodeByName(link.Project);
        link.target = nodeByName(link.Problem,link.Score,link.Data,link.Summary);
    });
    

    要让 labeltooltip 显示在固定位置,而不是在节点旁边,您需要删除节点 mouseover 和 mouseout 事件中移动 div 的位,并且可能只需将 div 添加到html而不是动态添加它。

    【讨论】:

    • 任何帮助,如何获取节点值
    • 嗨,很抱歉这么久才回来 - 我病了。你想让 labeltooltip 是静止的吗?由于当前设置了代码,当您将鼠标悬停在节点旁边时,它会浮动 - 尽管您必须将位置样式设置为绝对样式才能看到这一点。看看我能做些什么来让实际数据显示在 labeltooltip 中。
    • 很抱歉,当鼠标悬停在节点上时,我需要查看 csv 的内容,如上图所述。
    • 上面的解决方案,但是注意由于你的数据是链接而不是节点,所以p1节点不会有任何数据。您可以手动更改。
    猜你喜欢
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 2013-07-15
    • 1970-01-01
    • 2013-06-25
    • 2013-02-12
    • 2013-04-19
    相关资源
    最近更新 更多