How to fill D3 SVG with image instead of colour with fill? [closed]

夙愿已清 提交于 2019-12-11 06:29:45

问题


I would like to create something like the image below but instead of the circles I would like to use images of emoji's (the whatsapp emoticons etc.)

The data I would like to extract from the JSON should look something like this:

{
    'url': 'see-no-evil.png',
    'hits': 456
  }, 
  {
    'url': 'speak-no-evil.png',
    'hits': 425
  },

The emoji's should appear on a canvas randomly and the one with the most "hits" should be displayed the biggest and the one with the least hits as the smallest. It should be as simple as possible and automatic update as soon as I change the values or add something to the JSON.

Does anyone know how I can achieve this?

I found a really great example but I don't know how to play with the code so that I can get images instead of colours? http://codepen.io/girliemac/pen/cDfmb


回答1:


d3 is a good library to use for this.

In your example, try replacing this code:

vis.enter().append('circle')
        .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; })
        .attr('r', function(d) { return d.r; })
        .attr('class', function(d) { return d.className; });

with this code:

vis.enter().append("image")
    .attr("xlink:href", "your-image-url.png")
    .attr("width", function(d) { return 2*d.r; })
    .attr("height", function(d) { return 2*d.r; })
    .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; })
    .attr('class', function(d) { return d.className; });

Note that you will have to play with the size of the images a bit because the image will be square and you are trying to deal with circles. Try to find an image where the emoji touches the edges of the image.

Hope this helps! Let me know how it goes.

EDIT: solution part 2 based on discussion in the comments

(function() {

var json = {"countries_msg_vol": [
    {"url":"emoji-1.png","hits":100},{"url":"emoji-2.png","hits":200}
  ]};

    // D3 Bubble Chart 

    var diameter = 600;

    var svg = d3.select('#graph').append('svg')
                    .attr('width', diameter)
                    .attr('height', diameter);

    var bubble = d3.layout.pack()
                .size([diameter, diameter])
                .value(function(d) {return d.size;})
         // .sort(function(a, b) {
                //  return -(a.value - b.value)
                // }) 
                .padding(3);

  // generate data with calculated layout values
  var nodes = bubble.nodes(processData(json)); // filter out the outer bubble

  var vis = svg.selectAll('circle')
                    .data(nodes);

  vis.enter().append("image")
    .attr("xlink:href", function(d){

    return  d.url;})
    .attr("width", function(d) { 
    console.log("d.r:"+d.r);
    return d.r; })
    .attr("height", function(d) { return d.r; })
    .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; })
    .attr('class', function(d) { return d.className; });

  function processData(data) {
    var objs = data.countries_msg_vol;

    var newDataSet = [];


    for(var i=0; i<objs.length; i++) {
        var obj = objs[i];
 console.log(obj.url+" "+obj.hits);
      newDataSet.push({url: obj.url, className: obj.url, size: obj.hits});
    }
    return {children: newDataSet};
  }

})();


来源:https://stackoverflow.com/questions/27775579/how-to-fill-d3-svg-with-image-instead-of-colour-with-fill

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!