简体   繁体   English

设置D3力导向图

[英]Setting up D3 force directed graph

To the esteemed readers. 致尊敬的读者。 I'm reasonably new in javascript and I have come across this problem. 我在javascript中相当新,我遇到过这个问题。 I'm trying to implement a modified version of this force directed graph: 我正在尝试实现此强制有向图的修改版本:

http://mbostock.github.com/d3/ex/force.html http://mbostock.github.com/d3/ex/force.html

The json data is generated on the fly from a php script. json数据是从PHP脚本动态生成的。 The idea is to color all lines connecting to one specific node ( defined in a php script) in one color and all the others in shades of gray. 我们的想法是将所有连接到一个特定节点(在PHP脚本中定义)的线条用一种颜色着色,而所有其他线条用灰色阴影着色。 I'm attempting to do it by matching the source variable in the json file to the variable from the php script and changing color when that is true like this: 我试图通过将json文件中的源变量与php脚本中的变量进行匹配来改变颜色,如下所示:

  var link = svg.selectAll("line.link")
  .data(json.links)
  .enter().append("line")
  .attr("class", "link")
  .style("stroke-width", function(d) { return Math.sqrt(d.value);})
  .style("stroke-opacity", function(d) { return d.value/10;})
  .style("stroke", function(d) { 
  x = (tested == d.source) ?  return '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true.
  })

however this does not work. 但这不起作用。 The script works fine but without the color change if I just do this 如果我这样做,脚本工作正常但没有颜色变化

  var link = svg.selectAll("line.link")
  .data(json.links)
  .enter().append("line")
  .attr("class", "link")
  .style("stroke-width", function(d) { return Math.sqrt(d.value);})
  .style("stroke-opacity", function(d) { return d.value/10;})
  .style("stroke", function(d) { 
  return '#707070';
  })

I've been staring at this for days trying to figure out to get this done and I'm stuck. 我一直在盯着这几天试图弄清楚这一点,我被卡住了。 Any help would be greatly appreciated!! 任何帮助将不胜感激!!

Here is my complete script 这是我的完整脚本

<script type="text/javascript">

var width = 1200,
    height = 1200;

var color = d3.scale.category20();

var tested=<?php echo $tested_source;?>; //<-- the variable from php

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

d3.json("data.json", function(json) {

var force = d3.layout.force()
    .charge(-130)
    .linkDistance(function(d) { return 500-(50*d.value);})
    .size([width, height]);

  force
      .nodes(json.nodes)
      .links(json.links)
      .start();

  var link = svg.selectAll("line.link")
      .data(json.links)
      .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value);})
      .style("stroke-opacity", function(d) { return d.value/10;})
      .style("stroke", function(d) { 
      x = (tested == d.source) ?  return '#1f77b4' : '#707070'; //<-- Attempt to change the color of the link when this is true. But is is not working...  :(
      })


  var node = svg.selectAll("circle.node")
      .data(json.nodes)
    .enter().append("circle")
      .attr("class", "node")
      .attr("r", 12)
      .style("fill", function(d) { return color(d.group); })
      .call(force.drag);

  node.append("title")
      .text(function(d) { return d.name; });

  force.on("tick", function() {
    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; });
  });
});

</script>

d.source is an object, you can't use == to determine if tested is a similar object. d.source是一个对象,你不能使用==来确定tested是否是一个类似的对象。 Have a look at this answer for more details on object equality. 有关对象平等的更多详细信息,请查看此答案。

If you want to test for a specific value of the d.source object described below, which I assume you want, you need to specify it. 如果要测试下面描述的d.source对象的特定值(我假设您需要),则需要指定它。

Here is the source object architecture : (I'm using the example you pointed so the data comes from the miserables.json ) 这是源对象架构:(我正在使用您指向的示例,因此数据来自miserables.json

source: Object
    group: 4
    index: 75
    name: "Brujon"
    px: 865.6440689638284
    py: 751.3426708796574
    weight: 7
    x: 865.9584580575608
    y: 751.2658636251376

Now, here is the broken part in your code : 现在,这是代码中破碎的部分:

x = (tested == d.source) ?  return '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true.

It doesn't work because the return is misplaced. 它不起作用,因为返回是错误的。 You're mixing ternary and return statements but you don't put them in the right order : 您正在混合使用三元语句和return语句,但不要将它们按正确的顺序排列:

return test ? value_if_true : value_if_false;

if you want to assign the value to x anyway, you can do 如果你想将值分配给x,你可以这样做

x = test ? value_if_true : value_if_false;
return x;

You should do something like this : 你应该做这样的事情:

return (tested == d.source) ? '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true.

That's for the general syntax, but this won't work as is You need to pick one of the value for your test for example : 这是一般语法,但这不会起作用你需要选择一个测试值,例如:

return (tested === d.source.name) ? '#1f77b4' : '#707070';

Also, if the variable from PHP is a string you should do 此外,如果PHP中的变量是一个字符串,你应该这样做

var tested="<?php echo $tested_source;?>"; //<-- the variable from php

and in most cases you should use json_encode to map PHP variables into javascript ones. 在大多数情况下,您应该使用json_encode将PHP变量映射到javascript变量。

As a final note, I would recommend using console functions coupled with Firebug 's console panel if you're using Firefox, or the Chrome Developer Tool 's console panel if you're using a Chromium based browser. 最后请注意,如果您使用的是Firefox,我建议使用console功能和Firebug的控制台面板,如果您使用的是基于Chromium的浏览器,我建议使用Chrome Developer Tool的控制台面板。 It would allow you to debug your code more easily. 它可以让您更轻松地调试代码。


Working code 工作代码

var width = 960,
  height = 500;

var color = d3.scale.category20();

var force = d3.layout.force().charge(-120).linkDistance(30).size([width, height]);

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

var tested = 20;

d3.json("miserables.json", function (json) {
  force.nodes(json.nodes).links(json.links).start();

  var link = svg.selectAll("line.link")
  .data(json.links)
  .enter()
  .append("line")
  .attr("class", "link")
  .style("stroke-width", function (d) {
    return Math.sqrt(d.value);
  }).style("stroke-opacity", function (d) {
    return d.value / 10;
  }).style("stroke", function (d) {
    return (tested == d.source.index) ? '#ee3322' : '#707070'; //'#1f77b4'
  });

  var node = svg.selectAll("circle.node")
  .data(json.nodes)
  .enter()
  .append("circle")
  .attr("class", "node")
  .attr("r", 5)
  .style("fill", function (d) {
    return color(d.group);
  }).call(force.drag);

  node.append("title").text(function (d) {
    return d.name;
  });

  force.on("tick", function () {
    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;
    });
  });
});

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

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