D3JS:无法仅添加一次文本元素

时间:2018-09-05 20:08:09

标签: d3.js

我有这段代码可生成9个甜甜圈图。事实是,SVG画布被附加到DOM的次数很多,绘制的甜甜圈图也是如此,并且当我尝试在屏幕顶部放置一个text元素时(如一个大标题来解释图形),它也会被附加9次(在每个容纳每个甜甜圈的SVG画布中)。我只需要一个SVG画布,并在其中包含9个甜甜圈,但是我很难做到这一点。

这是我到目前为止的摘要。

$("#chartdiv").empty()

var dataObj = {
  data1: [19, 81],
  data2: [15, 85],
  data3: [13, 91],
  data4: [8, 92],
  data5: [7, 93],
  data7: [6, 94],
  data8: [5, 95],
  data9: [4, 96],
  data10: [3, 97],
  data11: [2, 98],
  data11: [1, 99],
  data12: [0, 100],
};

var newarr = ["Manufacturing", "Technology", "Other", "Engineering", "Automotive", "Consulting/professiona services", "Entertaiment and media", "Financial services", "Apparel and textile", "Construction", "Academic and educational", "Legal services"]

var width = 140,
  height = 140,
  radius = (Math.min(width, height) / 2.8);

function drawDonut(data, divchart, index, chartName) {

  var color = ["#00338D", "#dedede"];

  var pie = d3.pie()
    .sortValues(null)
    .value(function(d) {
      return d
    })(data);

  var arc = d3.arc()
    .outerRadius(radius - 10)
    .innerRadius(radius - (radius / 1.9));

  var labelArc = d3.arc()
    .outerRadius(radius - 31)
    .innerRadius(radius - 31);

  var svg = d3.select("#chartdiv")
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + 75 + "," + 50 + ")");

  var g = svg.selectAll("arc")
    .data(pie)
    .enter().append("g")
    .attr("class", "arc");

  function easeInverse(ease) {
    return function(e) {
      var min = 0,
        max = 1;
      while (max - min > 1e-3) {
        var mid = (max + min) * 0.5;
        emid = ease(mid);
        if (emid > e) {
          max = mid;
        } else {
          min = mid;
        }
      }
      return max;
    }
  }
  var inverseCubic = easeInverse(d3.easeCubic);
  var oneOver2Pi = 1.0 / (2 * Math.PI);
  var total_msec = 900;

  g.append("path")
    .style("fill", function(d, i) {
      return color[i];
    })
    .transition()
    .ease(d3.easeLinear)
    .delay(function(d) {
      return total_msec * inverseCubic(d.startAngle * oneOver2Pi);
    })
    .duration(function(d) {
      return total_msec * (inverseCubic(d.endAngle * oneOver2Pi) - inverseCubic(d.startAngle * oneOver2Pi));
    })
    .attrTween("d", arcTween);

  function arcTween(d) {
    var i = d3.interpolate(inverseCubic(d.startAngle * oneOver2Pi), inverseCubic(d.endAngle * oneOver2Pi));
    return function(t) {
      d.endAngle = 2 * Math.PI * d3.easeCubic(i(t));
      return arc(d);
    }
  }

  g.append("text")
    .attr("transform", "translate(0,5) scale(1.4)")
    .attr("font-weight", "bold")

    .attr("class", "st0 donutsTextElemnt")
    .attr("font-size", "11px")

    .attr("text-anchor", "middle")

    .html(data[0] + "%");

  svg.append("foreignObject")
    .attr("transform", "translate(-30,50) scale(.75)")
    .attr("width", 120)
    .attr("height", 80)
    .attr("class", "caption 3rForeignObj")
    .append("xhtml:body")
    .html(newarr[index])
    .style("background", "white");

  var lastDonut = $("#donutdiv").children().eq(6)

  lastDonut.css({
    'transform': 'translate(0 , 20px)'
  });
}

Object.keys(dataObj).forEach(function(d, i) {
  drawDonut(dataObj[d], '#pie' + (i + 1), i, 'chart' + (i + 1));
});
body {
  background: rgb(92, 29, 186);
  height: 100vh;
}

* {
  box-sizing: border-box;
}

.list-group-item {
  font-size: 24px;
  background: inherit;
  border: none;
  color: #fff!important;
}


/* .action{
                font-size: 14px!important;
                background: inherit;
                border: none;
                color:#fff!important;
            } */

.list-group-item:hover {
  color: black!important;
}

.firstPage {
  background: #470a68;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%)
}

.secondPage {
  background: #00A3A1;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  ;
  -o-transform: translate(-50%, -50%);
  ;
  transform: translate(-50%, -50%);
  ;
}

.thirdPage {
  background: #00A3A1;
}

.fourthPage {
  background: #f45f42;
}

.submenuTitle p {
  font-size: 30px;
  color: #fff;
}

.sectionsTitle {
  font-size: 52px!important;
}

.inactive {
  display: none;
}

.active {
  display: block;
}

#chartdiv {
  background: #fff;
}

.chart {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.heightZero {
  height: 0;
  overflow: hidden
}

@keyframes slideUp {
  to {
    height: 100%
  }
}

.slideUp {
  animation: slideUp .6s ease-in forwards;
}

.thirdDonutsDiv {
  display: inline
}

a {
  font-size: 16px!important;
}

.back {
  transform: scale(.7)
}

.container-fluid {
  width: 512px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%)
}

.sectionsTitle {
  font-family: KPMG Extralight;
  color: white;
  font-weight: bold;
}

p.mainTitle {
  color: #fff;
  font-size: 115px;
  font-family: KPMG Extralight;
  margin-top: 5px;
}

p.standardP {
  color: #fff;
  font-family: univers;
  font-size: 1.666rem;
  line-height: 1.2;
  margin: 1rem 1;
  margin-top: 30px;
}

h3.mainTitle {
  color: #fff;
  font-family: KPMG;
  margin-top: 14px;
  margin-bottom: 14px;
  font-size: 3.8rem;
  font-weight: bolder;
}

p.standardP {
  color: #fff;
  font-family: univers;
  font-size: 1.666rem;
  line-height: 1.2;
  margin: 1rem 1;
  margin-top: 30px;
}

ul {
  list-style-type: none;
  padding: 0;
  margin-right: 10px;
  margin-left: 10px;
}

label {
  width: 100%;
  height: 100%;
  padding: 0.85rem 1rem;
  background-color: hsla(0, 0%, 100%, 0);
  color: #fff;
  cursor: pointer;
  border-radius: 4px;
  margin-bottom: 11px;
  transition: all .4s;
  font-size: 16px;
  font-weight: normal;
}

label:hover {
  background-color: white;
  color: #000;
  transition: background-color .2s
}

.labelUnselected {
  background-color: hsla(0, 0%, 100%, .6);
  color: #fff;
}

div.mainDiv p {
  word-wrap: break-word;
  line-height: 100%;
}

input {
  display: none;
}

.backSubMenu1 {
  text-align: center;
}


/* donut chart 4*/

.st0 {
  fill: #00338D;
}

#fourtySeven {
  transform: translate(50px, 0px)
}

#twentyEight {
  transform: translate(-63.104974985120286px, 86.28081103480314px)
}

.icon2 {
  opacity: 0;
  animation: fadeIn 1s linear 1.5s forwards;
  transform: translate(-50px, -45px)
}

@keyframes fadeIn {
  to {
    opacity: 1;
  }
}

.rect {
  opacity: 0;
  animation: fadeIn 1.3s linear 1.5s forwards;
}

@keyframes fadeIn {
  to {
    opacity: 1;
  }
}

.ifram {
  width: 512px;
}

.iconXY {
  opacity: 0;
  animation: fadeIn 1.5s linear 1.8s forwards;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<div class="row">
  <div class="col-sm-12" id="chartdiv"></div>

  <div class="text-left backSubMenu1">
    <i class="fas fa-chevron-left back" style="font-size: 40px;color:aliceblue" targetX="secondPage">
        <a href="#firstPage"></a>
      </i>
  </div>

  <div id="pie1" class="thirdDonutsDiv"></div>
  <div id="pie2" class="thirdDonutsDiv"></div>
  <div id="pie3" class="thirdDonutsDiv"></div>
  <div id="pie4" class="thirdDonutsDiv"></div>
  <div id="pie5" class="thirdDonutsDiv"></div>
  <div id="pie6" class="thirdDonutsDiv"></div>
  <div id="pie7" class="thirdDonutsDiv"></div>
  <div id="pie8" class="thirdDonutsDiv"></div>
  <div id="pie9" class="thirdDonutsDiv"></div>
</div>

1 个答案:

答案 0 :(得分:2)

这里有一个 d3ish 重构,可以实现一个包含所有饼图的SVG的目标:

<!DOCTYPE html>
<html>

<body>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <div class="row">
    <div class="col-sm-12" id="chartdiv">
    </div>
  </div>

  <script>

    var dataObj = {
      data1: [19, 81],
      data2: [15, 85],
      data3: [13, 91],
      data4: [8, 92],
      data5: [7, 93],
      data7: [6, 94],
      data8: [5, 95],
      data9: [4, 96],
      data10: [3, 97],
      data11: [2, 98],
      data11: [1, 99],
      data12: [0, 100],
    };

    var newarr = ["Manufacturing", "Technology", "Other", "Engineering", "Automotive", "Consulting/professiona services", "Entertaiment and media", "Financial services", "Apparel and textile", "Construction", "Academic and educational", "Legal services"]

    var width = 140,
      height = 140,
      radius = (Math.min(width, height) / 2.8),
      numCol = 4;

    var svg = d3.select("#chartdiv")
      .append("svg")
      .attr("width", width * numCol)
      .attr("height", height * (newarr.length / numCol));

    svg.selectAll(".donut")
      .data(d3.values(dataObj))
      .enter()
      .append("g")
      .attr("class", "donut")
      .each(drawDonut);

    function drawDonut(data, index) {

      var color = ["#00338D", "#dedede"];

      var pie = d3.pie()
        .sortValues(null)
        .value(function(d) {
          return d
        })(data);

      var arc = d3.arc()
        .outerRadius(radius - 10)
        .innerRadius(radius - (radius / 1.9));

      var labelArc = d3.arc()
        .outerRadius(radius - 31)
        .innerRadius(radius - 31);

      var xPos = 75 + ((index % numCol) * width),
        yPos = 50 + (Math.floor(index / numCol) * height);

      var group = svg
        .append("g")
        .attr("transform", "translate(" + xPos + "," + yPos + ")");

      var g = group.selectAll("arc")
        .data(pie)
        .enter().append("g")
        .attr("class", "arc");

      function easeInverse(ease) {
        return function(e) {
          var min = 0,
            max = 1;
          while (max - min > 1e-3) {
            var mid = (max + min) * 0.5;
            emid = ease(mid);
            if (emid > e) {
              max = mid;
            } else {
              min = mid;
            }
          }
          return max;
        }
      }
      var inverseCubic = easeInverse(d3.easeCubic);
      var oneOver2Pi = 1.0 / (2 * Math.PI);
      var total_msec = 900;

      g.append("path")
        .style("fill", function(d, i) {
          return color[i];
        })
        .transition()
        .ease(d3.easeLinear)
        .delay(function(d) {
          return total_msec * inverseCubic(d.startAngle * oneOver2Pi);
        })
        .duration(function(d) {
          return total_msec * (inverseCubic(d.endAngle * oneOver2Pi) - inverseCubic(d.startAngle * oneOver2Pi));
        })
        .attrTween("d", arcTween);

      function arcTween(d) {
        var i = d3.interpolate(inverseCubic(d.startAngle * oneOver2Pi), inverseCubic(d.endAngle * oneOver2Pi));
        return function(t) {
          d.endAngle = 2 * Math.PI * d3.easeCubic(i(t));
          return arc(d);
        }
      }

      g.append("text")
        .attr("transform", "translate(0,5) scale(1.4)")
        .attr("font-weight", "bold")

      .attr("class", "st0 donutsTextElemnt")
        .attr("font-size", "11px")

      .attr("text-anchor", "middle")

      .html(data[0] + "%");

      svg.append("text")
        .attr("transform", "translate(" + (xPos) + "," + (yPos + height / 2.4) + ") scale(.75)")
        .attr("text-anchor", "middle")
        .text(newarr[index]);

    }
  </script>
</body>

</html>