D3文字元素的样式

时间:2018-08-16 15:58:50

标签: d3.js

由于某种原因,我无法向我的文本元素添加样式。特殊性:

svg.append("text")
.attr("class", function (d) { return "role-title-" + d.place; } ) 
.text(function (d) {return d.role;});

.role-title-1 {
position: absolute;
left: 40px;
}

var data = [{
  "site": "75%",
  "filled": 75,
  "capacity": 100,
  "role": "Business Intelligence Analyst",
  "place": 1
}, {
  "site": "72%",
  "filled": 72,
  "capacity": 100,
  "role": "Computer and Information Research Scientist",
  "place": 2
}, {
  "site": "70%",
  "filled": 70,
  "capacity": 100,
  "role": "Computer Systems Analyst",
  "place": 3
}, {
  "site": "68%",
  "filled": 68,
  "capacity": 100,
  "role": "Computer Programmer",
  "place": 4
}, {
  "site": "65%",
  "filled": 65,
  "capacity": 100,
  "role": "Software Developers, Applications",
  "place": 5
}, {
  "site": "57%",
  "filled": 57,
  "capacity": 100,
  "role": "Software Developers, Systems Software",
  "place": 6
}, {
  "site": "46%",
  "filled": 46,
  "capacity": 100,
  "role": "Software Quality Assurance Engineers",
  "place": 7
}, {
  "site": "25%",
  "filled": 25,
  "capacity": 100,
  "role": "Computer Systems Engineers",
  "place": 8
}];

var width = 700,
  height = 230,
  twoPi = 2 * Math.PI;

var arc = d3.arc()
  .innerRadius(52.5)
  .outerRadius(65)
  .startAngle(0);

var svg = d3.select("#chart").selectAll("svg")
  .data(data)
  .enter()
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .attr("class", function(d) {
    return "donut-" + d.place;
  })
  //.attr("class", function (d, i) { return "donut" + " svg_" + i; } )
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

svg.append("path")
  .style("fill", "#e6e6e6")
  .attr("d", arc({
    endAngle: twoPi
  }));

svg.append("path")
  .attr("d", arc.endAngle(function(d) {
    return (twoPi * (1 - ((d.capacity - d.filled) / d.capacity)));
  }))
  .style("fill", "orange");

svg.append("text")
  .attr("dy", ".35em")
  .style("text-anchor", "middle")
  .style("font-size", "40px")
  .text(function(d) {
    return d.site;
  });

svg.append("text")
  .attr("class", function(d) {
    return "role-title-" + d.place;
  })
  .text(function(d) {
    return d.role;
  })
  .attr('transform', 'translate(70, 0)');
.total {
  font: 14px sans-serif;
  font-weight: bold;
}

.label {
  font: 18px sans-serif;
  font-weight: bold;
  fill: #c5c5c5;
}

.role-alternatives-wrapper {
  position: relative;
  width: 960px;
  height: 600px;
  margin-top: 20px;
  margin-left: 50px;
}

.role-alternatives-wrapper .donut .pct {
  font-weight: 500;
  font-size: 40px;
  color: #2C3D65;
}

.role-alternatives-wrapper .donut .title {
  font-size: 16px;
  font-weight: 400;
  color: #2C3D65;
}

.role-alternatives-wrapper .donut-1 {
  position: absolute;
  top: -53px;
  left: 200px;
}

.role-alternatives-wrapper .donut-1 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-1 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-1 .title {
  position: absolute;
  top: -14px;
  left: 128px;
  width: 300px;
}

.role-alternatives-wrapper .donut-2 {
  position: absolute;
  top: 23px;
  left: 384px;
}

.role-alternatives-wrapper .donut-2 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-2 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-2 .title {
  position: absolute;
  top: 35px;
  left: 153px;
  width: 300px;
}

.role-alternatives-wrapper .donut-3 {
  position: absolute;
  top: 201px;
  left: 463px;
}

.role-alternatives-wrapper .donut-3 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-3 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-3 .title {
  position: absolute;
  top: 35px;
  left: 153px;
  width: 200px;
}

.role-alternatives-wrapper .donut-4 {
  position: absolute;
  bottom: -11px;
  left: 388px;
}

.role-alternatives-wrapper .donut-4 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-4 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-4 .title {
  position: absolute;
  top: 35px;
  left: 153px;
  width: 250px;
}

.role-alternatives-wrapper .donut-5 {
  position: absolute;
  top: 460px;
  left: 202px;
}

.role-alternatives-wrapper .donut-5 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-5 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-5 .title {
  position: absolute;
  top: 79px;
  left: 144px;
  width: 250px;
}

.role-alternatives-wrapper .donut-6 {
  position: absolute;
  top: 390px;
  left: 18px;
}

.role-alternatives-wrapper .donut-6 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-6 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-6 .title {
  position: absolute;
  top: 79px;
  left: -267px;
  width: 250px;
  text-align: right;
}

.role-alternatives-wrapper .donut-7 {
  position: absolute;
  top: 200px;
  left: -62px;
}

.role-alternatives-wrapper .donut-7 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-7 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-7 .title {
  position: absolute;
  top: 79px;
  left: -199px;
  width: 200px;
  text-align: right;
}

.role-alternatives-wrapper .donut-8 {
  position: absolute;
  top: 34px;
  left: 17px;
}

.role-alternatives-wrapper .donut-8 .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-8 .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-8 .title {
  position: absolute;
  top: 36px;
  left: -270px;
  width: 250px;
  text-align: right;
}

.role-alternatives-wrapper .donut-center {
  position: absolute;
  top: 222px;
  left: 356px;
}

.role-alternatives-wrapper .donut-center .donut-wrapper {
  position: relative;
}

.role-alternatives-wrapper .donut-center .pct {
  position: absolute;
  top: 40px;
  left: 34px;
}

.role-alternatives-wrapper .donut-center .title {
  position: absolute;
  top: 104px;
  left: 41px;
  width: 150px;
  font-weight: 600;
  font-size: 18px;
  text-align: center;
}

.role-title-1 {
  transform: translate(70px, 0);
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="role-alternatives-wrapper">
  <div id="chart"></div>
</div>

codepen

1 个答案:

答案 0 :(得分:0)

使用standard SVG text attributestextxy)定位SVG transform

但是,如果要使用CSS定位它们,则标准绝对/相对定位将不适用于SVG元素,但您始终可以应用transform样式。例如(仅将CSS应用于第一张图表):

.role-title-1 {
  transform: translate(70px, 0);
}

代码段:

var data = [{
    "site": "75%",
        "filled": 75,
        "capacity": 100,
        "role": "Business Intelligence Analyst",
        "place": 1
}, {
    "site": "72%",
        "filled": 72,
        "capacity": 100,
        "role": "Computer and Information Research Scientist",
        "place": 2
}, {
    "site": "70%",
        "filled": 70,
        "capacity": 100,
        "role": "Computer Systems Analyst",
        "place": 3
}, {
    "site": "68%",
        "filled": 68,
        "capacity": 100,
        "role": "Computer Programmer",
        "place": 4
}, {
    "site": "65%",
        "filled": 65,
        "capacity": 100,
        "role": "Software Developers, Applications",
        "place": 5
}, {
    "site": "57%",
        "filled": 57,
        "capacity": 100,
        "role": "Software Developers, Systems Software",
        "place": 6
}, {
    "site": "46%",
        "filled": 46,
        "capacity": 100,
        "role": "Software Quality Assurance Engineers",
        "place": 7
}, {
    "site": "25%",
        "filled": 25,
        "capacity": 100,
        "role": "Computer Systems Engineers",
        "place": 8
}];

    var width = 700,
    height = 230,
    twoPi = 2 * Math.PI;

    var arc = d3.arc()
    .innerRadius(52.5)
    .outerRadius(65)
    .startAngle(0);

    var svg = d3.select("#chart").selectAll("svg")
    .data(data)
    .enter()
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", function (d) { return "donut-" + d.place; } ) 
    //.attr("class", function (d, i) { return "donut" + " svg_" + i; } )
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

svg.append("path")
    .style("fill", "#e6e6e6")
    .attr("d", arc({endAngle: twoPi}));

svg.append("path")
    .attr("d", arc.endAngle(function (d) {return (twoPi * (1 - ((d.capacity - d.filled) / d.capacity)));}))
    .style("fill", "orange");

    svg.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .style("font-size", "40px")
    .text(function (d) {return d.site;});

    svg.append("text")
    .attr("class", function (d) { return "role-title-" + d.place; } ) 
    .text(function (d) {return d.role;});
.total {
    font: 14px sans-serif;
    font-weight: bold;
}
.label {
    font: 18px sans-serif;
    font-weight: bold;
    fill: #c5c5c5;
}

.role-alternatives-wrapper {
    position: relative;
    width: 960px;
    height: 600px;
    margin-top: 20px;
    margin-left: 50px;
}
.role-alternatives-wrapper .donut .pct {
    font-weight: 500;
    font-size: 40px;
    color: #2C3D65;
}
.role-alternatives-wrapper .donut .title {
    font-size: 16px;
    font-weight: 400;
    color: #2C3D65;
}
.role-alternatives-wrapper .donut-1 {
    position: absolute;
    top: -53px;
    left: 200px;
}
.role-alternatives-wrapper .donut-1 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-1 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-1 .title {
    position: absolute;
    top: -14px;
    left: 128px;
    width: 300px;
}
.role-alternatives-wrapper .donut-2 {
    position: absolute;
    top: 23px;
    left: 384px;
}
.role-alternatives-wrapper .donut-2 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-2 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-2 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 300px;
}
.role-alternatives-wrapper .donut-3 {
    position: absolute;
    top: 201px;
    left: 463px;
}
.role-alternatives-wrapper .donut-3 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-3 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-3 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 200px;
}
.role-alternatives-wrapper .donut-4 {
    position: absolute;
    bottom: -11px;
    left: 388px;
}
.role-alternatives-wrapper .donut-4 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-4 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-4 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 250px;
}
.role-alternatives-wrapper .donut-5 {
    position: absolute;
    top: 460px;
    left: 202px;
}
.role-alternatives-wrapper .donut-5 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-5 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-5 .title {
    position: absolute;
    top: 79px;
    left: 144px;
    width: 250px;
}
.role-alternatives-wrapper .donut-6 {
    position: absolute;
    top: 390px;
    left: 18px;
}
.role-alternatives-wrapper .donut-6 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-6 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-6 .title {
    position: absolute;
    top: 79px;
    left: -267px;
    width: 250px;
    text-align: right;
}
.role-alternatives-wrapper .donut-7 {
    position: absolute;
    top: 200px;
    left: -62px;
}
.role-alternatives-wrapper .donut-7 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-7 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-7 .title {
    position: absolute;
    top: 79px;
    left: -199px;
    width: 200px;
    text-align: right;
}
.role-alternatives-wrapper .donut-8 {
    position: absolute;
    top: 34px;
    left: 17px;
}
.role-alternatives-wrapper .donut-8 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-8 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-8 .title {
    position: absolute;
    top: 36px;
    left: -270px;
    width: 250px;
    text-align: right;
}
.role-alternatives-wrapper .donut-center {
    position: absolute;
    top: 222px;
    left: 356px;
}
.role-alternatives-wrapper .donut-center .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-center .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-center .title {
    position: absolute;
    top: 104px;
    left: 41px;
    width: 150px;
    font-weight: 600;
    font-size: 18px;
    text-align: center;
}
.role-title-1 {
  transform: translate(70px, 0);
}
<script src="https://d3js.org/d3.v4.min.js"></script>


<div class="role-alternatives-wrapper">
    <div id="chart"></div>
  </div>

使用SVG(优雅且可能更方便)放置文本的方法是(应用于所有中心标签)

.text(function (d) {return d.role;})
.attr('transform', 'translate(70, 0)');

OR

.text(function (d) {return d.role;})
.attr('x', '70');

代码段:

var data = [{
    "site": "75%",
        "filled": 75,
        "capacity": 100,
        "role": "Business Intelligence Analyst",
        "place": 1
}, {
    "site": "72%",
        "filled": 72,
        "capacity": 100,
        "role": "Computer and Information Research Scientist",
        "place": 2
}, {
    "site": "70%",
        "filled": 70,
        "capacity": 100,
        "role": "Computer Systems Analyst",
        "place": 3
}, {
    "site": "68%",
        "filled": 68,
        "capacity": 100,
        "role": "Computer Programmer",
        "place": 4
}, {
    "site": "65%",
        "filled": 65,
        "capacity": 100,
        "role": "Software Developers, Applications",
        "place": 5
}, {
    "site": "57%",
        "filled": 57,
        "capacity": 100,
        "role": "Software Developers, Systems Software",
        "place": 6
}, {
    "site": "46%",
        "filled": 46,
        "capacity": 100,
        "role": "Software Quality Assurance Engineers",
        "place": 7
}, {
    "site": "25%",
        "filled": 25,
        "capacity": 100,
        "role": "Computer Systems Engineers",
        "place": 8
}];

    var width = 700,
    height = 230,
    twoPi = 2 * Math.PI;

    var arc = d3.arc()
    .innerRadius(52.5)
    .outerRadius(65)
    .startAngle(0);

    var svg = d3.select("#chart").selectAll("svg")
    .data(data)
    .enter()
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", function (d) { return "donut-" + d.place; } ) 
    //.attr("class", function (d, i) { return "donut" + " svg_" + i; } )
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

svg.append("path")
    .style("fill", "#e6e6e6")
    .attr("d", arc({endAngle: twoPi}));

svg.append("path")
    .attr("d", arc.endAngle(function (d) {return (twoPi * (1 - ((d.capacity - d.filled) / d.capacity)));}))
    .style("fill", "orange");

    svg.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .style("font-size", "40px")
    .text(function (d) {return d.site;});

    svg.append("text")
    .attr("class", function (d) { return "role-title-" + d.place; } ) 
    .text(function (d) {return d.role;})
    .attr('x', '70');
.total {
    font: 14px sans-serif;
    font-weight: bold;
}
.label {
    font: 18px sans-serif;
    font-weight: bold;
    fill: #c5c5c5;
}

.role-alternatives-wrapper {
    position: relative;
    width: 960px;
    height: 600px;
    margin-top: 20px;
    margin-left: 50px;
}
.role-alternatives-wrapper .donut .pct {
    font-weight: 500;
    font-size: 40px;
    color: #2C3D65;
}
.role-alternatives-wrapper .donut .title {
    font-size: 16px;
    font-weight: 400;
    color: #2C3D65;
}
.role-alternatives-wrapper .donut-1 {
    position: absolute;
    top: -53px;
    left: 200px;
}
.role-alternatives-wrapper .donut-1 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-1 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-1 .title {
    position: absolute;
    top: -14px;
    left: 128px;
    width: 300px;
}
.role-alternatives-wrapper .donut-2 {
    position: absolute;
    top: 23px;
    left: 384px;
}
.role-alternatives-wrapper .donut-2 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-2 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-2 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 300px;
}
.role-alternatives-wrapper .donut-3 {
    position: absolute;
    top: 201px;
    left: 463px;
}
.role-alternatives-wrapper .donut-3 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-3 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-3 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 200px;
}
.role-alternatives-wrapper .donut-4 {
    position: absolute;
    bottom: -11px;
    left: 388px;
}
.role-alternatives-wrapper .donut-4 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-4 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-4 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 250px;
}
.role-alternatives-wrapper .donut-5 {
    position: absolute;
    top: 460px;
    left: 202px;
}
.role-alternatives-wrapper .donut-5 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-5 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-5 .title {
    position: absolute;
    top: 79px;
    left: 144px;
    width: 250px;
}
.role-alternatives-wrapper .donut-6 {
    position: absolute;
    top: 390px;
    left: 18px;
}
.role-alternatives-wrapper .donut-6 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-6 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-6 .title {
    position: absolute;
    top: 79px;
    left: -267px;
    width: 250px;
    text-align: right;
}
.role-alternatives-wrapper .donut-7 {
    position: absolute;
    top: 200px;
    left: -62px;
}
.role-alternatives-wrapper .donut-7 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-7 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-7 .title {
    position: absolute;
    top: 79px;
    left: -199px;
    width: 200px;
    text-align: right;
}
.role-alternatives-wrapper .donut-8 {
    position: absolute;
    top: 34px;
    left: 17px;
}
.role-alternatives-wrapper .donut-8 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-8 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-8 .title {
    position: absolute;
    top: 36px;
    left: -270px;
    width: 250px;
    text-align: right;
}
.role-alternatives-wrapper .donut-center {
    position: absolute;
    top: 222px;
    left: 356px;
}
.role-alternatives-wrapper .donut-center .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-center .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-center .title {
    position: absolute;
    top: 104px;
    left: 41px;
    width: 150px;
    font-weight: 600;
    font-size: 18px;
    text-align: center;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="role-alternatives-wrapper">
    <div id="chart"></div>
  </div>

是否使用 70 作为x偏移量?

您现在可能已经猜到了:我正在使用outerRadius(65)​​的甜甜圈。

根据评论进行编辑: 寻找个人翻译,方法如下:

.attr('transform', function (d) {
  // here you can translate based on d.place (maybe add an if)
  return d.place === 1 ? 'translate(70,0)' : 'translate(0, 80)';
});

代码段:

var data = [{
    "site": "75%",
        "filled": 75,
        "capacity": 100,
        "role": "Business Intelligence Analyst",
        "place": 1
}, {
    "site": "72%",
        "filled": 72,
        "capacity": 100,
        "role": "Computer and Information Research Scientist",
        "place": 2
}, {
    "site": "70%",
        "filled": 70,
        "capacity": 100,
        "role": "Computer Systems Analyst",
        "place": 3
}, {
    "site": "68%",
        "filled": 68,
        "capacity": 100,
        "role": "Computer Programmer",
        "place": 4
}, {
    "site": "65%",
        "filled": 65,
        "capacity": 100,
        "role": "Software Developers, Applications",
        "place": 5
}, {
    "site": "57%",
        "filled": 57,
        "capacity": 100,
        "role": "Software Developers, Systems Software",
        "place": 6
}, {
    "site": "46%",
        "filled": 46,
        "capacity": 100,
        "role": "Software Quality Assurance Engineers",
        "place": 7
}, {
    "site": "25%",
        "filled": 25,
        "capacity": 100,
        "role": "Computer Systems Engineers",
        "place": 8
}];

    var width = 700,
    height = 230,
    twoPi = 2 * Math.PI;

    var arc = d3.arc()
    .innerRadius(52.5)
    .outerRadius(65)
    .startAngle(0);

    var svg = d3.select("#chart").selectAll("svg")
    .data(data)
    .enter()
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", function (d) { return "donut-" + d.place; } ) 
    //.attr("class", function (d, i) { return "donut" + " svg_" + i; } )
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

svg.append("path")
    .style("fill", "#e6e6e6")
    .attr("d", arc({endAngle: twoPi}));

svg.append("path")
    .attr("d", arc.endAngle(function (d) {return (twoPi * (1 - ((d.capacity - d.filled) / d.capacity)));}))
    .style("fill", "orange");

    svg.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .style("font-size", "40px")
    .text(function (d) {return d.site;});

    svg.append("text")
    .attr("class", function (d) { return "role-title-" + d.place; } ) 
    .text(function (d) {return d.role;})
    .attr('transform', function (d) {
      // here you can translate based on d.place
      return d.place === 1 ? 'translate(70,0)' : 'translate(0, 80)';
    });
.total {
    font: 14px sans-serif;
    font-weight: bold;
}
.label {
    font: 18px sans-serif;
    font-weight: bold;
    fill: #c5c5c5;
}

.role-alternatives-wrapper {
    position: relative;
    width: 960px;
    height: 600px;
    margin-top: 20px;
    margin-left: 50px;
}
.role-alternatives-wrapper .donut .pct {
    font-weight: 500;
    font-size: 40px;
    color: #2C3D65;
}
.role-alternatives-wrapper .donut .title {
    font-size: 16px;
    font-weight: 400;
    color: #2C3D65;
}
.role-alternatives-wrapper .donut-1 {
    position: absolute;
    top: -53px;
    left: 200px;
}
.role-alternatives-wrapper .donut-1 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-1 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-1 .title {
    position: absolute;
    top: -14px;
    left: 128px;
    width: 300px;
}
.role-alternatives-wrapper .donut-2 {
    position: absolute;
    top: 23px;
    left: 384px;
}
.role-alternatives-wrapper .donut-2 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-2 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-2 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 300px;
}
.role-alternatives-wrapper .donut-3 {
    position: absolute;
    top: 201px;
    left: 463px;
}
.role-alternatives-wrapper .donut-3 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-3 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-3 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 200px;
}
.role-alternatives-wrapper .donut-4 {
    position: absolute;
    bottom: -11px;
    left: 388px;
}
.role-alternatives-wrapper .donut-4 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-4 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-4 .title {
    position: absolute;
    top: 35px;
    left: 153px;
    width: 250px;
}
.role-alternatives-wrapper .donut-5 {
    position: absolute;
    top: 460px;
    left: 202px;
}
.role-alternatives-wrapper .donut-5 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-5 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-5 .title {
    position: absolute;
    top: 79px;
    left: 144px;
    width: 250px;
}
.role-alternatives-wrapper .donut-6 {
    position: absolute;
    top: 390px;
    left: 18px;
}
.role-alternatives-wrapper .donut-6 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-6 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-6 .title {
    position: absolute;
    top: 79px;
    left: -267px;
    width: 250px;
    text-align: right;
}
.role-alternatives-wrapper .donut-7 {
    position: absolute;
    top: 200px;
    left: -62px;
}
.role-alternatives-wrapper .donut-7 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-7 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-7 .title {
    position: absolute;
    top: 79px;
    left: -199px;
    width: 200px;
    text-align: right;
}
.role-alternatives-wrapper .donut-8 {
    position: absolute;
    top: 34px;
    left: 17px;
}
.role-alternatives-wrapper .donut-8 .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-8 .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-8 .title {
    position: absolute;
    top: 36px;
    left: -270px;
    width: 250px;
    text-align: right;
}
.role-alternatives-wrapper .donut-center {
    position: absolute;
    top: 222px;
    left: 356px;
}
.role-alternatives-wrapper .donut-center .donut-wrapper {
    position: relative;
}
.role-alternatives-wrapper .donut-center .pct {
    position: absolute;
    top: 40px;
    left: 34px;
}
.role-alternatives-wrapper .donut-center .title {
    position: absolute;
    top: 104px;
    left: 41px;
    width: 150px;
    font-weight: 600;
    font-size: 18px;
    text-align: center;
}
<script src="https://d3js.org/d3.v4.min.js"></script>


<div class="role-alternatives-wrapper">
    <div id="chart"></div>
  </div>

希望这会有所帮助。