D3:用 d3.svg.line() 替换 d3.svg.diagonal() [英] D3: Substituting d3.svg.diagonal() with d3.svg.line()

查看:53
本文介绍了D3:用 d3.svg.line() 替换 d3.svg.diagonal()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用 d3.svg.diagonal() 渲染了边来实现了下图.但是,当我尝试用 d3.svg.line() 替换对角线时,它似乎没有提取目标和源数据.我错过了什么?我对 d3.svg.line 有什么不明白的地方吗?

I have implemented the following graph with the edges rendered with d3.svg.diagonal(). However, when I try substituting the diagonal with d3.svg.line(), it doesn't appear to pull the target and source data. What am I missing? Is there something I don't understand about d3.svg.line?

以下是我所指的代码,后面是完整的代码:

The following is the code I am referring to, followed by the full code:

var line = d3.svg.line()
    .x(function(d) { return d.lx; })
    .y(function(d) { return d.ly; });

...

var link= svg.selectAll("path")
    .data(links)
  .enter().append("path")
    .attr("d",d3.svg.diagonal())
    .attr("class", ".link")
    .attr("stroke", "black")
    .attr("stroke-width", "2px")
    .attr("shape-rendering", "auto")
    .attr("fill", "none"); 

完整代码:

var margin = {top: 20, right: 20, bottom: 20, left: 20},
    width =1500, 
    height = 1500, 
    diameter = Math.min(width, height),
    radius = diameter / 2;


var balloon = d3.layout.balloon()
  .size([width, height])
  .value(function(d) { return d.size; })
  .gap(50)                  

var line = d3.svg.line()
    .x(function(d) { return d.lx; })
    .y(function(d) { return d.ly; });


var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + (margin.left + radius) + "," + (margin.top + radius) + ")")

    root = "flare.json";
    root.y0 = height / 2;
    root.x0 = width / 2;

d3.json("flare.json", function(root) {
  var nodes = balloon.nodes(root),
      links = balloon.links(nodes);


var link= svg.selectAll("path")
    .data(links)
  .enter().append("path")
    .attr("d",d3.svg.diagonal())
    .attr("class", ".link")
    .attr("stroke", "black")
    .attr("stroke-width", "2px")
    .attr("shape-rendering", "auto")
    .attr("fill", "none");   

  var node = svg.selectAll("g.node")
    .data(nodes)
    .enter()
    .append("g")
    .attr("class", "node");

  node.append("circle")
      .attr("r", function(d) { return d.r; })
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });

  node.append("text")
      .attr("dx", function(d) { return d.x })
      .attr("dy", function(d) { return d.y })
      .attr("font-size", "5px")
      .attr("fill", "white")
      .style("text-anchor", function(d) { return d.children ? "middle" : "middle"; })
      .text(function(d) { return d.name; })
});

svg 的 d 属性在使用line"时如何消失的比较.

A comparison of how the d attribute of the svg disappears when using "line."

推荐答案

问题已经过时了,但由于我没有看到答案,而且有人可能会遇到同样的问题,所以在这里.

Question is quite dated, but since I don't see an answer and someone might face the same problem, here it is.

line 简单替换 diagonal 不起作用的原因是因为 d3.svg.lined3.svg.diagonal 返回不同的结果:

The reason why simple replacement of diagonal with line is not working is because d3.svg.line and d3.svg.diagonal return different results:

  • d3.svg.diagonal 返回接受数据及其索引并使用投影将其转换为路径的函数.换句话说,diagonal.projection 决定了函数如何从提供的数据中获取点的坐标.
  • d3.svg.line 返回接受线的点数组并将其转换为路径的函数.方法 line.xline.y 确定如何从提供的数组的单个元素中检索点的坐标
  • d3.svg.diagonal returns function that accepts datum and its index and transforms it to path using projection. In other words diagonal.projection determines how the function will get points' coordinates from supplied datum.
  • d3.svg.line returns function that accepts an array of points of the line and transforms it to path. Methods line.x and line.y determine how coordinates of the point retreived from the single element of supplied array

D3 SVG-Shapes 参考

SVG 路径和 D3.js

所以你不能直接在 d3 选择中使用 d3.svg.line 的结果(至少当你想画多条线时).

So you can not use result of the d3.svg.line directly in d3 selections (at least when you want to draw multiple lines).

你需要把它包装在另一个像这样的函数中:

You need to wrap it in another function like this:

var line = d3.svg.line()
                 .x( function(point) { return point.lx; })
                 .y( function(point) { return point.ly; });

function lineData(d){
    // i'm assuming here that supplied datum 
    // is a link between 'source' and 'target'
    var points = [
        {lx: d.source.x, ly: d.source.y},
        {lx: d.target.x, ly: d.target.y}
    ];
    return line(points);
}

// usage:
var link= svg.selectAll("path")
    .data(links)
    .enter().append("path")
    .attr("d",lineData)
    .attr("class", ".link")
    .attr("stroke", "black")
    .attr("stroke-width", "2px")
    .attr("shape-rendering", "auto")
    .attr("fill", "none");   

这是 jsFiddle mobeets 的工作版本:jsFiddle

Here's working version of jsFiddle mobeets posted: jsFiddle

这篇关于D3:用 d3.svg.line() 替换 d3.svg.diagonal()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆