2016-05-08 7 views
2

これは私のSVGのサークルを塗りつぶすコードです。d3.jsで私の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') 

しかし、その代わりに、私の円の内側に緑色の充填、私はURLは私のJSONデータである場合、それぞれの円内の異なる画像を記入します。私は.attr( 'fill'、url(function(d){return d.url}))を使用しようとしていますが、動作しません。私はd3の新人です。誰もこの仕事を解決するのを助けることができますか?

答えて

2

あなたは、このようなデータセットを持っている想像:すべてのデータの上に

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

反復処理し、画像やサークルのように多くのDEFSを作る:

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" 
}] 

このようなSVGでこのようなDEFSを行います。画像は、メモリのあまり使用し、複数の画像を使用すると、深刻なを作成しますから 内側の円の塗りつぶしがこのSO answer

1

作成パターンからインスピレーションを受け、この.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 + ")"); 

}) 

作業コードhere

ようにDEFのIDを渡しますパフォーマンスの問題。だから、それを避けるために、画像上にクリップパスを使うことができます。このよう

:私たちが望むよう

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)'); 
}); 

はまた、我々は簡単に新しいものとクリッピングエリアを置き換えることができます。 コードペンのリンクです:http://codepen.io/anon/pen/VagxKp?editors=0010

関連する問題