D3.js 如何在函数内的图像上使用D3剪辑路径

D3.js 如何在函数内的图像上使用D3剪辑路径,d3.js,D3.js,我希望能够用一个圆圈遮罩图像。我可以用D3做到这一点,但是我在更新循环中遇到了麻烦。以下是我最好的尝试: 我已经用id“#ellipse clip”定义了剪辑路径,但当我将其设置为图像的属性时,剪辑不会生效。我做错了什么 var w = 300, h = 200; var barHeight = 20; var data = championsleague = [{ "name": "Hart", "saves": "9", "tota

我希望能够用一个圆圈遮罩图像。我可以用D3做到这一点,但是我在更新循环中遇到了麻烦。以下是我最好的尝试:

我已经用id“#ellipse clip”定义了剪辑路径,但当我将其设置为图像的属性时,剪辑不会生效。我做错了什么

  var w = 300,
      h = 200;
  var barHeight = 20;

  var data = 

  championsleague = [{
    "name": "Hart",
    "saves": "9",
    "total": "15",
    "image": "https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"
  }, {
    "name": "Subasic",
    "saves": "6",
    "total": "10",
    "image": "https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"
  },];

  premierleague = [{
    "name": "Neuer",
    "saves": "12",
    "total": "27",
    "image": "https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"
  }, {
    "name": "Forster",
    "saves": "13",
    "total": "22",
    "image": "https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"
   }];


// config, add svg
  var canvas = d3.select('#chart')
    .append('svg')
    .attr('width', w)
    .attr('height', h)
    .append('g')
    .attr("transform", "translate(0,70)");

// config, add groups

  var name_g = canvas.append('g')
      .attr("transform", "translate(80,0)");

  var image_g = canvas.append('g');

  var clip = image_g.append("clipPath");

  var Scale = d3.scale.linear().domain([0, 39]).range([0, w]);

 // function that wraps around the d3 pattern (bind, add, update, remove)
  function updateLegend(data) {

 // bind data

  var clip = image_g
      .selectAll('ellipse')
      .data(data);

  var image = image_g
      .selectAll('image')
      .data(data);

    var name = name_g
        .selectAll('text')
        .data(data);

    // add new elements

    name.enter().append('text');
    clip.enter().append('ellipse').attr("id", "ellipse-clip");
    image.enter().append('image');

    // update existing elements

    name.transition()
    .duration(200)
    .text(function(d) {return d.name;
    })
    .attr('x', 0)
     .attr('y', function(d, i) {return i * (h / data.length) -10
     });

    clip.transition()
    .duration(200) 
    .attr("cx", 25)        
    .attr("cy", function(d, i) {return i * (h / data.length) - 25
    })        
    .attr("rx", 30)        
    .attr("ry", 30);  

    image.transition()
    .duration(200)
    .attr('xlink:href', function(d) {return d.image;
         })
    .attr('x', 0)
    .attr('y', function(d, i) {return i * (h / data.length) -50
    })
    .attr('width', 80)
    .attr('height', 80)
    .attr("clip-path", "url(#ellipse-clip)"); 

    // remove old elements

    name.exit().remove();
    clip.exit().remove();
    image.exit().remove();

    };

    // generate initial legend
    updateLegend(data);

    // handle on click event
    d3.selectAll('.opts')
     .on('click', function() {
     var data = eval(d3.select(this).property('value'));
        updateLegend(data);
     })

首先,您的代码有点混乱,多个
g
都绑定到相同的数据,并且文本与剪裁的imag分开。我可能会重新构造一点,为每个玩家创建一个
g
,其中包含一个clippath(具有唯一id)、图像和文本

但是要回答您真正的问题,您的SVG是不正确的。最后你需要这样的东西:

<g>
   <clipPath id="ellipse-clip"> <!-- id on clipPath with ellipse as child -->
     <ellipse ry="30" rx="30" cy="-25" cx="25"></ellipse>
     <ellipse ry="30" rx="30" cy="75" cx="25"></ellipse>
   </clipPath>
   <image clip-path="url(#ellipse-clip)" height="80" width="80" y="-50" x="0" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"></image>
   <image clip-path="url(#ellipse-clip)" height="80" width="80" y="50" x="0" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"></image>
</g>

冠军联赛
英超联赛

首先,您的代码有点混乱,多个
g
都绑定到相同的数据,并且文本与剪裁的IMAG分开。我可能会重新构造一点,为每个玩家创建一个
g
,其中包含一个clippath(具有唯一id)、图像和文本

但是要回答您真正的问题,您的SVG是不正确的。最后你需要这样的东西:

<g>
   <clipPath id="ellipse-clip"> <!-- id on clipPath with ellipse as child -->
     <ellipse ry="30" rx="30" cy="-25" cx="25"></ellipse>
     <ellipse ry="30" rx="30" cy="75" cx="25"></ellipse>
   </clipPath>
   <image clip-path="url(#ellipse-clip)" height="80" width="80" y="-50" x="0" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"></image>
   <image clip-path="url(#ellipse-clip)" height="80" width="80" y="50" x="0" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://upload.wikimedia.org/wikipedia/commons/4/41/Joe_Hart_69775.jpg"></image>
</g>

冠军联赛
英超联赛

这是一个非常好的答案,这样分组是有意义的。非常感谢你能再帮我一件事吗?我已经重新构造了我的代码,使每个玩家都有一个单独的组(接下来将添加剪辑路径)。然而,我这样做的方式完全阻止了我的数据更新。你能告诉我我做错了什么吗?非常感谢你!我也非常感谢你的评论,非常有帮助。如果你不介意的话,你知道我应该在哪里使用转换来使它们工作吗?例如,它用于('.saves')类,我也尝试过('.player'),但没有luck@user3821345,这是非常非常奇怪的(对不起,我以前没有注意到)。如果将转换写出长格式,它将起作用:。另一个版本也可以,不过,我有点困惑。谢谢你的帮助!这太棒了。虽然对于转换,我希望它在不同的值之间工作,而不是每次都从0开始。这让我很困惑,因为我在一个老例子上做得很好。我将发布一个新问题。再次感谢这是一个非常好的答案,这样分组是有意义的。非常感谢你能再帮我一件事吗?我已经重新构造了我的代码,使每个玩家都有一个单独的组(接下来将添加剪辑路径)。然而,我这样做的方式完全阻止了我的数据更新。你能告诉我我做错了什么吗?非常感谢你!我也非常感谢你的评论,非常有帮助。如果你不介意的话,你知道我应该在哪里使用转换来使它们工作吗?例如,它用于('.saves')类,我也尝试过('.player'),但没有luck@user3821345,这是非常非常奇怪的(对不起,我以前没有注意到)。如果将转换写出长格式,它将起作用:。另一个版本也可以,不过,我有点困惑。谢谢你的帮助!这太棒了。虽然对于转换,我希望它在不同的值之间工作,而不是每次都从0开始。这让我很困惑,因为我在一个老例子上做得很好。我将发布一个新问题。再次感谢