简体   繁体   English

如何在d3.js中填写我的svg圈内的图像

[英]How to fill an image inside my svg circles in d3.js

This is my piece of code filling circles in my svg. 这是我在svg中填充圈子的代码片段。

   var svgContainer = d3.select("body").append("svg")
                                 .attr("width", 1000)
                             .attr("height", 1000);
    var circles = svgContainer.selectAll("circle")
                      .data(nodes)
                      .enter()
                      .append("circle");

     var circleAttributes = circles
                   .attr("cx", function (d) { return d.x_axis; })
                   .attr("cy", function (d) { return d.y_axis; })
                   .attr("r", function (d) { return d.radius; })
                   .attr('fill', 'green')

But instead of filling green color inside my circles, I want to fill different image inside each circles where the url is in my json data. 但是我不想在我的圈子里填充绿色,而是想在每个圈子里面填充不同的图像,其中url在我的json数据中。 I've been trying to use .attr('fill', url(function(d) {return d.url})) but it does not work. 我一直在尝试使用.attr('fill',url(function(d){return d.url}))但它不起作用。 I am new to d3 and can anyone help me solving this task? 我是d3的新手,任何人都可以帮我解决这个问题吗?

Imagine you have a dataset like this: 想象一下,你有一个像这样的数据集:

data = [{
  posx: 100,
  posy: 100,
  img: "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png",

}, {
  posx: 200,
  posy: 200,

  img: "https://cdn1.iconfinder.com/data/icons/social-media-set/24/Reverbnation-128.png"
}, {
  posx: 300,
  posy: 300,

  img: "https://cdn1.iconfinder.com/data/icons/user-pictures/100/male3-128.png"
}]

Make defs like this in svg like this: 在svg中像这样制作defs:

var defs = svg.append('svg:defs');

Iterate over all the data and make as many defs with image and circle. 迭代所有数据,并使用图像和圆圈进行尽可能多的defs。 Inside circles's fill pass the def's id like this .style("fill", "url(#grump_avatar" + i + ")"); .style("fill", "url(#grump_avatar" + i + ")");的填充传递了def的id,就像这样.style("fill", "url(#grump_avatar" + i + ")");

data.forEach(function(d, i) {
  defs.append("svg:pattern")
    .attr("id", "grump_avatar" + i)
    .attr("width", config.avatar_size) 
    .attr("height", config.avatar_size)
    .attr("patternUnits", "userSpaceOnUse")
    .append("svg:image")
    .attr("xlink:href", d.img)
    .attr("width", config.avatar_size)
    .attr("height", config.avatar_size)
    .attr("x", 0)
    .attr("y", 0);

  var circle = svg.append("circle")
    .attr("transform", "translate(" + d.posx + "," + d.posy + ")")
    .attr("cx", config.avatar_size / 2)
    .attr("cy", config.avatar_size / 2)
    .attr("r", config.avatar_size / 2)
    .style("fill", "#fff")
    .style("fill", "url(#grump_avatar" + i + ")");

})

working code here 这里工作代码

Inspired from this SO answer 灵感来自这个SO答案

Creating pattern from image uses too much of memory and using multiple images will create a serious performance issue. 从图像创建模式使用太多内存并使用多个图像将产生严重的性能问题。 So to avoid that we can use clip-path over image. 所以为了避免这种情况,我们可以在图像上使用剪辑路径。

Like this: 像这样:

var config = {
  "avatar_size": 100
}

var body = d3.select("body");
var svg = body.append("svg")
  .attr("width", 500)
  .attr("height", 500);

var defs = svg.append('svg:defs');

data = [{
  posx: 100,
  posy: 100,
  img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/pencil-gear-128.png",
}, {
  posx: 200,
  posy: 200,
  img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/gear-clock-128.png"
}, {
  posx: 300,
  posy: 300,
  img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/magnifier-data-128.png"
}];


svg .append('clipPath')
   .attr('id','clipObj')  
        .append('circle')
         .attr('cx',config.avatar_size/2)
          .attr('cy',config.avatar_size/2)
         .attr('r',config.avatar_size/2);

data.forEach(function(d,i){
  svg.append('image')
     .attr('xlink:href',d.img)
     .attr('width',config.avatar_size)
     .attr('height',config.avatar_size)
 .attr('transform','translate('+parseInt(d.posx+config.avatar_size/2)+','+parseInt(d.posy+config.avatar_size/2)+')')
     .attr('clip-path','url(#clipObj)');
});

Also we can easily replace the clipping area with new one as we want. 我们也可以根据需要轻松地用新的剪切区域替换剪裁区域。 Here is the link of Code pen : http://codepen.io/anon/pen/VagxKp?editors=0010 这是Code pen的链接: http//codepen.io/anon/pen/VagxKp?editors = 0010

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM