如何在Arc的末尾添加图像

时间:2020-09-09 06:24:21

标签: d3.js automatic-ref-counting

我正在使用d3 js,我必须在圆弧的末端显示图像,下面是我的示例如何实现

enter image description here

var total_codes = 8;
var remaining_codes = 4;
var issued = total_codes - remaining_codes;
var coloursArray = ["#128ED2", "#dadada"];
var dataset = {
  privileges: [issued, remaining_codes]
};

var width = 160,
  height = 160,
  radius = Math.min(width, height) / 2;

var color = d3.scale.ordinal()
  .range(coloursArray);

var pie = d3.layout.pie()
  .sort(null);

var arc = d3.svg.arc()
  .innerRadius(radius - 30)
  .outerRadius(radius);

var svg = d3.select("#donut").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var path = svg.selectAll("path")
  .data(pie(dataset.privileges))
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", arc);
path.transition().duration(750);

var point = path.node().getPointAtLength(path.node().getTotalLength() / 2);

svg.append("image")
  .attr("cx", point.x)
  .attr("cy", point.y)
  .attr({
    "xlink:href": "http://run.plnkr.co/preview/ckf41wu0g00082c6g6bzer2cc/images/pacman_active_icon.png", //nothing visible
    width: 35,
    height: 36
  });

svg.append("text")
  .attr("dy", ".0em")
  .style("text-anchor", "middle")
  .attr("class", "inside")
  .html(function() {
    return "<tspan x='0' dy='0em'>External</tspan><tspan x='0' dy='1.2em'>Privileges</tspan>";
  }); // Add your code here
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="donut"></div>

1 个答案:

答案 0 :(得分:1)

这有点乏味,但以下方法可行。

采用pieData的第一个元素,它表示蓝色弧。然后使用三角学计算偏移量以将pacman放置在正确的位置。最后,首先平移它,使其绕其中心旋转,然后将其旋转所需的量。

我将其放置在距中心radius - 15处,因为那是30像素宽弧线的中间。

var total_codes = 8;
var remaining_codes = 5;
var issued = total_codes - remaining_codes;
var coloursArray = ["#128ED2", "#dadada"];
var dataset = {
  privileges: [issued, remaining_codes]
};

var width = 160,
  height = 160,
  radius = Math.min(width, height) / 2,
  iconSize = 48;

var color = d3.scale.ordinal()
  .range(coloursArray);

var pie = d3.layout.pie()
  .sort(null);

var arc = d3.svg.arc()
  .innerRadius(radius - 30)
  .outerRadius(radius);

var svg = d3.select("#donut").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var pieData = pie(dataset.privileges);
var path = svg.selectAll("path")
  .data(pieData)
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", arc);
path.transition().duration(750);

svg
  .append('g')
  .attr('class', 'pacmancontainer')
  .style('transform', function() {
    // the radius of the center of the arc, also the hypothenuse of a triangle
    var meanRadius = radius - 15;
    var angleRadians = pieData[0].endAngle - Math.PI / 2;
    var xOffset = Math.cos(angleRadians) * meanRadius;
    var yOffset = Math.sin(angleRadians) * meanRadius;
    return " translate(" + xOffset + "px, " + yOffset + "px)";
  })
  .append("image")
  .attr({
    "xlink:href": "http://run.plnkr.co/preview/ckf41wu0g00082c6g6bzer2cc/images/pacman_active_icon.png", //nothing visible
    width: iconSize,
    height: iconSize
  })
  // Make sure the Pacman rotates around its center
  .style('transform-origin', (iconSize / 2) + 'px ' + (iconSize / 2) + 'px')
  .style('transform', function() {
    var angleDegrees = pieData[0].endAngle / (2 * Math.PI) * 360;
    return "translate(-" + (iconSize / 2) + "px, -" + (iconSize / 2) + "px) rotate(" + angleDegrees + "deg)";
  });

svg.append("text")
  .attr("dy", ".0em")
  .style("text-anchor", "middle")
  .attr("class", "inside")
  .html(function() {
    return "<tspan x='0' dy='0em'>External</tspan><tspan x='0' dy='1.2em'>Privileges</tspan>";
  }); // Add your code here
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="donut"></div>