【问题标题】:d3.js Fill area between to diagonalsd3.js 填充到对角线之间的区域
【发布时间】:2014-10-25 20:49:08
【问题描述】:

我会模仿图像中的粉红色填充元素。我认为这是两条对角线。但我不知道如何填充它们之间的区域。

任何帮助,我将不胜感激! 这是我的代码:

<!DOCTYPE html>
  <meta charset="utf-8">
  <body>
    <script src="d3.min.js"></script>
    <style>
      .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 1.5px;
        }
    </style>

  <div class="container">
    <h1 class="page-header">Chart</h1>
    <div class="chart"></div>
  </div>

  <script>
  var links = [{source: {x:0,y:0}, target: {x:200,y:200},x:0,y:0},
               {source: {x:0,y:0}, target: {x:170,y:200},x:0,y:0}
              ]

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


        var linksContainer = canvas.append("g").attr("class","linksContainer")
        var diagonal = d3.svg.diagonal()
                .source(function(d) { return {"x":d.source.x, "y":d.source.y}; })
                .target(function(d) { return {"x":d.target.x, "y":d.target.y};})
                .projection(function(d) { return [d.x, d.y]; });


        var link = linksContainer.selectAll(".link")
                .data(links)
                .enter()
                  .append("path")
                  .attr("class", "link")
                  .attr("d", diagonal);

                  var line = linksContainer.append("line")
                          .attr("x1", 170)
                          .attr("y1", 200)
                          .attr("x2", 200)
                          .attr("y2", 200)
                          .attr("stroke-width", 1)
                          .attr("stroke", "black");
  </script>
</body>

【问题讨论】:

  • 嗨@meetamit 恐怕你误解了这个问题。我附上了一些 html/js 代码,让您更好地了解我在寻找什么。我想填充对角线之间的区域。

标签: d3.js area diagonal


【解决方案1】:

d3.svg.diagonal() 生成一个表示 SVG 路径描述的字符串。在您的情况下,两个路径字符串是

var path1 = diagonal(links[0]);// "M0,0C0,100 200,100 200,200"

var path2 = diagonal(links[1]);// "M0,0C0,100 170,100 170,200"

您的代码当前将它们中的每一个分配给&lt;path class=".link" d="..."&gt;d 属性。

相反,您只需要创建一个 &lt;path&gt; 和一个填充的(因此是封闭的)路径字符串,它是这两个字符串的组合。

var shape = path1 + path2;// But not quite...

事实证明,您不能简单地连接这两个字符串。你需要做的一件事是用L 替换M——它会拿起笔并将笔移动到一个新点(从而中断形状的封闭性)——它会在那个新点上画一条线:

var path2 = diagonal(links[1]).replace(/^M/, 'L');// "L0,0C0,100 170,100 170,200"

这给了你这个:

var shape = path1 + path2;// "M0,0C0,100 170,100 170,200 L0,0C0,100 170,100 170,200"

但是,子路径...170,200 L0,0... 错误地将path1 的结尾连接到path2 的开头。要更正此问题,您需要通过在链接的起点和终点之间交换来反转 path2

var links = [ {source: {x:0,y:0}, target: {x:200,y:200},x:0,y:0},
// instead of {source: {x:0,y:0}, target: {x:170,y:200},x:0,y:0}]
              {source: {x:170,y:200}, target: {x:0,y:0},x:0,y:0}]

最后,这可能不会在视觉上产生影响,但为了正确起见,您应该使用 Z 指令关闭路径:

var shape = path1 + path2 + 'Z';

// Apply `shape` to a single path element:
var path = linksContainer.append('path')
  .attr("class", "link")
  .attr("d", shape);

Here's a working fiddle.

【讨论】:

    【解决方案2】:

    显示的图片实际上是一个和弦图布局。

    你可以在这里学习如何使用它 https://github.com/mbostock/d3/wiki/Chord-Layout

    对角线是用于树形图的不同形状

    【讨论】:

    • 对不起安德烈斯,和弦图布局对我不起作用。因为你只需要它的一部分。并且chrod图作为一个单一的东西给出。 @meetamit 的答案正是我想要的。