【问题标题】:d3.js center image in bubble chartd3.js 气泡图中的中心图像
【发布时间】:2019-03-25 16:42:02
【问题描述】:

我正在尝试将center 我的images 附加到circle 但我无法弄清楚如何设置我的xy,因为圆的大小是动态的并且随着宽度而变化svg.

在给定圆的当前半径的情况下,找到xy 坐标的公式是什么?

  vis
    .enter()
    .append("svg:image")
    .attr("transform", d => "translate(" + d.x + "," + d.y + ")")
    .attr("xlink:href", function(d) {
      return d.img;
    })
    .attr("x", 0)
    .attr("y", 0)
    .attr("width", d => d.r / 1.5);

(function() {
  var json = {
    call_data: [
      [
        "Lifestyle",
        1,
        "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/5bb3ce2f801fbc657f83dd57_pp-lifestyle(white).svg"
      ],
      [
        "Sports",
        10,
        "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/5c9131911ad86f445cb5abc7_pp-sport(white).svg"
      ],
      [
        "Environment",
        8,
        "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/59f2a4bef42fff000159ba7a_pp-environ(white).svg"
      ],
      [
        "Medical",
        6,
        "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/59f2a4dc831e8500015fda53_pp-health(white).svg"
      ],
      [
        "Food",
        4,
        "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/59f8c2cc78cc2d0001fd4a7e_pp-food(white).svg"
      ]
    ]
  };

  var svg = d3
    .select(".bubble_chart")
    .append("svg")
    /*
    .attr("width", diameter)
    .attr("height", diameter);
*/
    .attr("preserveAspectRatio", "xMinYMin meet")
    .attr("viewBox", "0 0 600 400")
    //class to make it responsive
    .classed("svg-content-responsive", true);

  var bubble = d3.layout
    .pack()
    .size([600, 400])
    .value(function(d) {
      return d.size;
    })
    .padding(2);

  // generate data with calculated layout values
  var nodes = bubble.nodes(processData(json)).filter(function(d) {
    return !d.children;
  }); // filter out the outer bubble

  var vis = svg.selectAll("circle").data(nodes, function(d, i) {
    return d.name + i;
  });

  vis
    .enter()
    .append("circle")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    })
    .attr("class", function(d) {
      return d.className;
    })
    .attr("r", 0)
    .transition()
    .duration(1000)
    .attr("r", function(d) {
      return d.r;
    });

  vis
    .enter()
    .append("svg:image")
    .attr("transform", d => "translate(" + d.x + "," + d.y + ")")
    .attr("xlink:href", function(d) {
      return d.img;
    })
    .attr("x", 0)
    .attr("y", 0)
    .attr("width", d => d.r / 1.5);

  function processData(data) {
    var obj = data.call_data;

    var newDataSet = [];

    for (var prop in obj) {
      newDataSet.push({
        name: obj[prop][0],
        className: obj[prop][0].toLowerCase(),
        size: obj[prop][1],
        img: obj[prop][2]
      });
    }
    return {
      children: newDataSet
    };
  }
})();
.lifestyle {
  fill: #89BED3;
}

.sports {
  fill: #2A83D4;
}

.environment {
  fill: #6CC070;
}

.food {
  fill: #665C9E;
}

.medical {
  fill: #C13E40;
}

.bubble_chart {
  border: 2px solid red;
  display: inline-block;
  position: absolute;
  width: 100%;
  padding-bottom: 100%;
  /* aspect ratio */
  vertical-align: top;
  overflow: hidden;
}

.svg-content-responsive {
  border: 3px solid green;
  display: inline-block;
  position: absolute;
  top: 0;
  left: 0;
}
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.5/d3.js"></script>
<div class="container">
  <div class="bubble_chart"></div>
</div>

【问题讨论】:

    标签: javascript jquery d3.js


    【解决方案1】:

    由于您已经使用translate(" + d.x + "," + d.y + ") 转换图像,从而导致图像的起点为相应圆圈的中心,因此您只需将图像偏移它们各自的高度和宽度。

    即应用以下 x, y 属性:

    .attr('x', d => -(d.r/1.5)/2)
    .attr('y', d => -(d.r/1.5)/2)
    

    将图像居中,其中(d.r/1.5) 是图像的宽度/高度。

    代码 sn-p:

    (function() {
      var json = {
        call_data: [
          [
            "Lifestyle",
            1,
            "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/5bb3ce2f801fbc657f83dd57_pp-lifestyle(white).svg"
          ],
          [
            "Sports",
            10,
            "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/5c9131911ad86f445cb5abc7_pp-sport(white).svg"
          ],
          [
            "Environment",
            8,
            "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/59f2a4bef42fff000159ba7a_pp-environ(white).svg"
          ],
          [
            "Medical",
            6,
            "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/59f2a4dc831e8500015fda53_pp-health(white).svg"
          ],
          [
            "Food",
            4,
            "https://uploads-ssl.webflow.com/59df9e77ad9420000140eafe/59f8c2cc78cc2d0001fd4a7e_pp-food(white).svg"
          ]
        ]
      };
    
      var svg = d3
        .select(".bubble_chart")
        .append("svg")
        /*
        .attr("width", diameter)
        .attr("height", diameter);
    */
        .attr("preserveAspectRatio", "xMinYMin meet")
        .attr("viewBox", "0 0 600 400")
        //class to make it responsive
        .classed("svg-content-responsive", true);
    
      var bubble = d3.layout
        .pack()
        .size([600, 400])
        .value(function(d) {
          return d.size;
        })
        .padding(2);
    
      // generate data with calculated layout values
      var nodes = bubble.nodes(processData(json)).filter(function(d) {
        return !d.children;
      }); // filter out the outer bubble
    
      var vis = svg.selectAll("circle").data(nodes, function(d, i) {
        return d.name + i;
      });
    
      vis
        .enter()
        .append("circle")
        .attr("transform", function(d) {
          return "translate(" + d.x + "," + d.y + ")";
        })
        .attr("class", function(d) {
          return d.className;
        })
        .attr("r", 0)
        .transition()
        .duration(1000)
        .attr("r", function(d) {
          return d.r;
        });
    
      vis
        .enter()
        .append("svg:image").style('opacity', 0)
        .attr("transform", d => "translate(" + d.x + "," + d.y + ")")
        .attr('x', d => -(d.r/1.5)/2)
        .attr('y', d => -(d.r/1.5)/2)
        .attr("xlink:href", function(d) {
          return d.img;
        })
        .attr("width", d => d.r / 1.5).transition().duration(1000).style('opacity', 1);
    
      function processData(data) {
        var obj = data.call_data;
    
        var newDataSet = [];
    
        for (var prop in obj) {
          newDataSet.push({
            name: obj[prop][0],
            className: obj[prop][0].toLowerCase(),
            size: obj[prop][1],
            img: obj[prop][2]
          });
        }
        return {
          children: newDataSet
        };
      }
    })();
    .lifestyle {
      fill: #89BED3;
    }
    
    .sports {
      fill: #2A83D4;
    }
    
    .environment {
      fill: #6CC070;
    }
    
    .food {
      fill: #665C9E;
    }
    
    .medical {
      fill: #C13E40;
    }
    
    .bubble_chart {
      border: 2px solid red;
      display: inline-block;
      position: absolute;
      width: 100%;
      padding-bottom: 100%;
      /* aspect ratio */
      vertical-align: top;
      overflow: hidden;
    }
    
    .svg-content-responsive {
      border: 3px solid green;
      display: inline-block;
      position: absolute;
      top: 0;
      left: 0;
    }
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.5/d3.js"></script>
    <div class="container">
      <div class="bubble_chart"></div>
    </div>

    此外,我还为图像的不透明度添加了一个额外的过渡,以匹配圆圈的可见性 - .transition().duration(1000).style('opacity', 1)。希望这可以帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 2016-03-01
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 2020-04-20
      • 1970-01-01
      相关资源
      最近更新 更多