【问题标题】:How to fill D3 SVG with image instead of colour with fill? [closed]如何用图像而不是用填充颜色填充 D3 SVG? [关闭]
【发布时间】:2015-03-02 18:11:01
【问题描述】:

我想创建如下图所示的东西,但我想使用表情符号的图像(whatsapp 表情符号等)而不是圆圈

我想从 JSON 中提取的数据应该是这样的:

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

表情符号应随机出现在画布上,“点击次数”最多的应显示最大,点击次数最少的应显示为最小。它应该尽可能简单,并在我更改值或向 JSON 添加一些内容时自动更新。

有谁知道我如何做到这一点?

我找到了一个非常棒的示例,但我不知道如何使用代码来获取图像而不是颜色? http://codepen.io/girliemac/pen/cDfmb

【问题讨论】:

  • 您在哪里寻找数据?如果你知道 - 去看看 API - 如果不知道然后找一个来源。我们不是来为您工作的——我们是来解决问题的。
  • @BLewis 我不需要像真实的实时数据。问题是我想知道如何制作这样的东西?我将在 JSON 文件中组成一些数据。
  • @BLewis 另外,我在这里找到了一个很好的例子:codepen.io/girliemac/pen/cDfmb 但问题是我不知道如何编辑它,所以它只显示图像而不是颜色。
  • 好的,所以您可能应该重新表述您的问题 - 您正在寻找的是一种使用 D3 嵌入自定义图像的方法 - 您可以简单地使用动态 CSS 来设置您喜欢的元素的样式'已经发送,但是对于许多表情符号来说效率很低 - 所以你可能希望网络浏览器对输出进行光栅化 - 我没有这样做 - 所以我无法真正提供解决方案。对不起!
  • 如果你只是想让它工作,但不关心性能/构建时间 - 修改 CSS 以使用 background-image 而不是 background-colour 并引用表情符号 - 另一个小时间节省同时构建是使用 JS 从 JSON 中添加 CSS。

标签: javascript json svg d3.js circle-pack


【解决方案1】:

d3 是一个很好的库。

在您的示例中,尝试替换此代码:

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

使用此代码:

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

请注意,您将不得不稍微调整图像的大小,因为图像将是方形的,而您正在尝试处理圆形。尝试找到表情符号与图像边缘接触的图像。

希望这会有所帮助!告诉我进展如何。

编辑:解决方案第 2 部分基于 cmets 中的讨论

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

})();

【讨论】:

  • 感谢您的调整!它的工作原理和结果是这样的i.imgur.com/FywzJQ5.png。附加在所有对象上。因此,如果我希望每个对象都使用它,我很可能必须在 JSON 数据集中添加表情符号的每个 url,对吗?编辑 - 等一下,这是一个假的 json 数据集。有没有办法可以为每个不同的对象分配一张图片?
  • 是的,你是对的,这只是改变数据的问题。这是一个完整的示例,但您需要添加更多 JSON 数据才能看到任何不错的结果。
  • 一秒钟,我不能评论它太大了
  • 好的,我在原始答案中更新了更完整的解决方案。您可以在 JSON 数据中看到现在如何添加更多元素。干杯!
猜你喜欢
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
相关资源
最近更新 更多