D3.js树形图中的圆形图像

时间:2015-10-20 14:22:15

标签: d3.js

我花了一天时间试图让我的方形轮廓图像在树形图中创建圆形。这是一个演示我的问题的小提琴。我已经评论了应该允许我做我想做的代码。

http://jsfiddle.net/ssvuxb0k/4/

WebServiceTransportException

我有两个问题,其中一个问题由以下答案修正。另一方面,确保clippath的URL位置正确无误。

我的图表假设显示在/ graph / 1上,因此代码应为

var data = [
      {
        "name": "Jules",
        "parent": "null",
        "facebookId": 100003252256072,
        "children": [
          {
            "name": "Shawn Spencer",
            "parent": "Jules",
            "facebookId": 104088302962435,
            "children": [
              {
                "name": "Carlton Lassiter",
                "parent": "Shawn Spencer",
                "facebookId": 126495827393151
              }
            ]
          },
          {
            "name": "Burton Guster",
            "parent": "Jules",
            "facebookId": 100002858896488
          }
        ]
      }
    ];
var svg, root, margin;
var width = 750;
var height = 500;
var margin = 50;
var count = 0;
var duration = 750;
var tree = d3.layout.tree().size([height, width])
var diagonal = d3.svg.diagonal().projection(function(d) {
    return [d.y, d.x];
});

var svg = d3.select('svg')
    .attr('width', width + margin + margin)
    .attr('height', height + margin + margin)
    .append('g')
    .attr('transform', 'translate(' + margin + ',' + margin + ')');
var defs = svg.append("defs").attr("id", "imgdefs");

var root = data[0];
root.x0 = height / 2;
root.y0 = 0;

var update = function(source) {
            // Compute the new tree layout.
        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        // Normalize for fixed Depth
        nodes.forEach(function(d) {
            d.y = d.depth * 180;
        });

        // Update the nodes...
        var node = svg.selectAll('g.node')
            .data(nodes, function(d) {
                return d.id || (d.id = ++count);
            });

        var nodeEnter = node.enter().append('g')
            .attr('class', 'node')
            .attr('transform', function() {
                return 'translate(' + source.y0 + ',' + source.x0 + ')';
            })
            .on('click', this.nodeClicked);

    //PART THATS NOT WORKING
    nodes.forEach(function(d, i) {
        defs
            .data(nodes)
            .append('clipPath')
            .attr('id',  function(d) {
            return 'clip-circle-' + i;
        })
            .append("circle")
            .attr('id', function(d) {
            return 'test-id-' + i;
        })
            .attr('transform', function(d) {
            return 'translate(' + d.y + ',' + d.x + ')';
        })
            .attr("r", 20)
            .attr("cy", 0)
            .attr("cx", 0);
    });
    // END

        nodeEnter.append('image')
            .attr('x', -20)
            .attr('y', -20)
            .attr('width', 40)
            .attr('height', 40)
            .attr("xlink:href", function(d) {
                return "https://graph.facebook.com/" + d.facebookId + "/picture";
            })
            .attr("clip-path", function(d, i) {
                return "url(#clip-circle-" + i + ")";
            });

        nodeEnter.append('text')
            .attr('x', function(d) {
                return d.children || d._children ? -25 : 25;
            })
            .attr('dy', '.35em')
            .attr('text-anchor', function(d) {
                return d.children || d._children ? 'end' : 'start';
            })
            .text(function(d) {
                return d.name;
            })
            .style('fill-opacity', 1e-6);

        // Transition nodes to their new position
        var nodeUpdate = node.transition()
            .duration(duration)
            .attr('transform', function(d) {
                return 'translate(' + d.y + "," + d.x + ')';
            });

        nodeUpdate.select('circle')
            .attr('r', 10);

        nodeUpdate.select('text')
            .style('fill-opacity', 1);

        //Transition exiting nodes to the parents new position
        var nodeExit = node.exit().transition()
            .duration(duration)
            .attr('transform', function() {
                return 'translate(' + source.y + ',' + source.x + ')';
            })
            .remove();

        nodeExit.select('image')
            .style('opacity', 1e-6);

        nodeExit.select('text')
            .style('fill-opacity', 1e-6);

        // Update the links...
        var link = svg.selectAll('path.link')
            .data(links, function(d) {
                return d.target.id;
            });

        // Enter any new links at the parents previous position
        link.enter().insert('path', 'g')
            .attr('class', 'link')
            .attr('d', function() {
                var o = {
                    x: source.x0,
                    y: source.y0
                };
                return diagonal({
                    source: o,
                    target: o
                });
            }.bind(this));

        //Transition links to their new position.
        link.transition()
            .duration(duration)
            .attr('d', diagonal);

        // Transition exiting nodes to the parents new position.
        link.exit().transition()
            .duration(duration)
            .attr('d', function() {
                var o = {
                    x: source.x,
                    y: source.y
                };
                return diagonal({
                    source: o,
                    target: o
                });
            }.bind(this))
            .remove();

        // Stash the old positions for transition
        nodes.forEach(function(d) {
            d.x0 = d.x;
            d.y0 = d.y;
        });
};
update(root);

1 个答案:

答案 0 :(得分:2)

您无需为所有图像添加单独的剪辑路径。

定义一个剪辑路径,如下所示:

<svg>
     <defs>
      <clipPath id="clip">
          <circle cx="0" cy="0" r="20"/>
      </clipPath>
  </defs>

将URL添加到节点,圆圈将应用于每个图像:

  nodeEnter.append('image')
        .attr('x', -20)
        .attr('y', -20)
        .attr('width', 40)
        .attr('height', 40)
        .attr("xlink:href", function(d) {
            return "https://graph.facebook.com/" + d.facebookId + "/picture";
        })
       .attr("clip-path", "url(#clip)");

更新代码:shown here in fiddle