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