如何在D3js中动态添加图像到圈子

问题描述:

我很难解决如何使用数据集中的链接将图像放置在圆内的问题.我知道需要一种将图像添加到节点的模式-相关在引入节点和数据之前,有关此主题的问题会附加def,pattern和image元素.

I'm having a tough time figuring out how to place images inside a circle using links in my data set. I know a pattern is required to add images to nodes - related SO questions on this topic append the def, pattern and image elements before the introduction of nodes and data.

对于我来说,我找不到在选择器函数内附加标签的方法,因为数据是动态添加到每个节点的.这是项目的代码,每个黑点都应该包含一个不同的昆虫图像(URL在tsv文件中): https://plnkr.co/edit/Ydrxogbfm9JvqrgeQaQ6?p=preview

In my case, I couldn't find a way out of appending the tags inside the selector function because data is added dynamically to each node. Here's the code to the project, each black dot is supposed to contain a different image of an insect (url is in the tsv file): https://plnkr.co/edit/Ydrxogbfm9JvqrgeQaQ6?p=preview

我尝试使用以下代码更改body标签中的xlink:href:

I tried changing xlink:href in the body tags with the code below:

<body>
<svg width="1000" height="600">
    <defs id="mdef">
    <pattern id="image" x="0" y="0" height="40" width="40">
      <image x="0" y="0" width="40" height="40" ></image>
    </pattern>
  </defs>
</svg>

</body>

以及此代码段中的JS代码段,用于添加节点. :

and this snippet of JS within the code block adding the nodes. :

.attr('"xlink:href", function(d){return d[1];}) //d is an array and the d[1] is the link

但是,图像没有出现.然后,我尝试使用js添加模式:

However, the images didn't appear. I then tried adding the pattern using js:

for (i=0;i<insects.length;i++){
  g.selectAll("circle")
      .data(insects[i],function(d) {console.log(d); return d }) //each insect
    .enter().append("circle")
      .attr('cx', function(d,index) {return x(insects[i].length)/insects[i].length*index; })
      .attr("r", 20)
      .attr("cy", function(d,index){return y.bandwidth()*i})
    .append('svg:defs') //adding pattern
    .append('svg:pattern')
      .attr('id','pattern')
        .attr("x",0)
        .attr("y",0)
        .attr("width",40)
        .attr("height",40)
      .append("svg:image")
        .attr("x",0)
        .attr("y",0)
        .attr("width",40)
        .attr("height",40)
        .attr("xlink:href", function(d){console.log(d[1]); return d[1];})
    .style("fill", "url(#pattern)");
  }
})

但是我得到相同的结果.我真的很感谢任何指针,因为我是d3的初学者.节日快乐

But I get the same result. Would really appreciate any pointers as I'm a beginner in d3. Happy holidays

您不能将<defs><pattern><image>附加到圆上.那行不通.

You cannot append a <defs>, a <pattern> and a <image> to a circle. That won't work.

相反,您必须创建<defs>,添加图案和图像,并根据其唯一ID填充圆圈:

Instead of that, you have to create the <defs>, append the patterns and images, and fill the circles according to their unique IDs:

var defs = g.append("defs");

defs.selectAll(".patterns")
    .data(insects[i], function(d) {
        return d
    })
    .enter().append("pattern")
    .attr("id", function(d) {
        return "insect" + (d[0].split(" ").join(""))
    })
    .attr("width", 1)
    .attr("height", 1)
    .append("svg:image")
    .attr("xlink:href", function(d) {
        return d[1]
    })
    .attr("width", 40)
    .attr("height", 40);


g.selectAll("circle")
    .data(insects[i], function(d) {
        return d
    })
    .enter().append("circle")
    .attr('cx', function(d, index) {
        return x(insects[i].length) / insects[i].length * index;
    })
    .attr("r", 20)
    .attr("cy", function(d, index) {
        return y.bandwidth() * i
    })
    .style("fill", function(d) {
        return "url(#insect" + (d[0].split(" ").join("")) + ")"
    });
}

这是您更新的监听器: http://plnkr.co/edit/WLC2ihpzsjDUgcuu910O?p =预览

Here is your updated plunker: http://plnkr.co/edit/WLC2ihpzsjDUgcuu910O?p=preview

PS :您的代码正在运行,但是我不得不说,在D3 dataviz中,您的for循环是不必要的(甚至很尴尬).这不是访问数据的 D3方法.因此,我建议您完全重构该块中的代码.

PS: Your code is working, but I have to say that your for loop is unnecessary (and even awkward) in a D3 dataviz. This is not the D3 way of accessing the data. Thus, I suggest you completely refactor your code in that block.