D3JS:无法在多个矩形上放置一组文本元素

时间:2018-09-04 22:41:42

标签: d3.js

我正在尝试创建一组text元素,并将其放置在各种rect元素上方,以使其看起来好像在它们内部。问题是我无法完成这项简单的任务。

text列中需要的rect元素是数组的元素:var dataDnt4 = [42,31,16,4,3,2,1];

我会留下一个正在运行的代码段,以便到目前为止您的进度。

非常感谢您的帮助。谢谢

var icon2 = '<g><path class="st0" d="M23.1,34.9c6.9,0,12.5-5.6,12.5-12.5c0-6.9-5.6-12.5-12.5-12.5c-6.9,0-12.5,5.6-12.5,12.5	C10.6,29.3,16.2,34.9,23.1,34.9L23.1,34.9z"/><path class="st0" d="M39.2,54.6c0.2,0,0.4,0,0.7,0c-3.7-3-6-7.5-6-12.6c0-1.2,0.1-2.4,0.4-3.6c-0.1,0-0.3,0-0.4,0H12.4	C5.5,38.5-0.1,44.1-0.1,51v17.9h23.3C24.1,60.8,30.9,54.6,39.2,54.6L39.2,54.6z"/><path class="st0" d="M76.8,34.9c6.9,0,12.5-5.6,12.5-12.5c0-6.9-5.6-12.5-12.5-12.5c-6.9,0-12.5,5.6-12.5,12.5	C64.2,29.3,69.9,34.9,76.8,34.9L76.8,34.9z"/><path class="st0" d="M87.5,38.5H66c-0.1,0-0.3,0-0.4,0c0.3,1.1,0.4,2.3,0.4,3.6c0,5.1-2.4,9.6-6,12.6c0.2,0,0.4,0,0.7,0	c8.3,0,15.1,6.3,16,14.3H100V51C100,44.1,94.4,38.5,87.5,38.5L87.5,38.5z"/><path class="st0" d="M49.9,54.6c6.9,0,12.5-5.6,12.5-12.5c0-6.9-5.6-12.5-12.5-12.5c-6.9,0-12.5,5.6-12.5,12.5	C37.4,49,43,54.6,49.9,54.6L49.9,54.6z"/><path class="st0" d="M60.7,58.1H39.2c-6.9,0-12.5,5.6-12.5,12.5v17.9h46.5V70.7C73.2,63.7,67.6,58.1,60.7,58.1L60.7,58.1z"/></g>'

var dataDnt4 = [42, 31, 16, 4, 3, 2, 1];

var distanciaRect = [25, 50, 75, 100, 125, 150, 175]

var width = 512,

  height = 600

radius = (Math.min(width, height) / 2.5) - 60;

var sym = "%"

var legendTextArr = ["alpha", "beta", "Gamma", "vvv", "www", "xxx", "yyy", "zzz"]


var color_rect = ["#00338D", "#BC204B", "#0091DA", "#eaaa00", "#005eb8", "#f68d2e", "#009444", "#470a68"]

var pie = d3.pie()
  .value(function(d) {
    return d
  })(dataDnt4);

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

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

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



var title = svg.append("text")
  .attr("font-weight", "bold")
  .attr("class", "title1")
  .html("title 1")
  .attr("transform", function() {
    return "translate(" + (-184) + "," + (-180) + ")"
  })

var title = svg.append("text")
  .attr("font-weight", "bold")
  .attr("class", "title2")
  .html("title 2")
  .attr("transform", function() {
    return "translate(" + (-184) + "," + (-160) + ")"
  })

var legendG = svg.append("g")
  .attr("class", "legendG")
  .attr("transform", function() {
    return "translate(" + (-60) + "," + (155) + ")"
  })

var legendG = svg.append("g")
  .attr("class", "legendG")
  .attr("transform", function() {
    return "translate(" + (-60) + "," + (155) + ")"
  })



var legendText = legendG.selectAll("text")
  .data(distanciaRect)
  .enter()
  .append("text")
  .attr("x", -80)
  .attr("y", function(d, i) {
    return d + 10
  })
  .data(legendTextArr)
  .html(function(d) {
    return d
  })


var legends = legendG.selectAll(".rect")
  .data(distanciaRect)
  .enter()
  .append("rect")
  .attr("x", -120)
  .attr("y", function(d, i) {
    return d
  })
  .attr("width", 25)
  .attr("height", 17)
  .attr("class", "icon1")
  .data(color_rect)
  .attr("fill", function(d, i) {
    return d
  })


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 = 2000;



g.append("path")
  .attr("d", arc)
  .attr("transform", function() {
    return "translate(" + (-16) + "," + (0) + ")"
  })
  .style("fill", function(d, i) {
    return color_rect[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);
  }
}

svg.append("g")
  .attr("class", "icon2")
  .html(icon2);
<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 id="chartdiv"></div>

1 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点,因此这是一种可能的方法。我将图例的三个部分(矩形,键文本和矩形上的文本)组合到一个g元素中,并将dataDnt4绑定到每个项目。矩形颜色和图例文本可以按位置进行检索,即第一个dataDnt4项对应于color_rect[0]legendTextArr[0],第二个项对应于color_rect[1]legendTextArr[1]

我已经删除了与图例项的位置无关的代码-您可以在脚本中将其恢复。

var width = 512,

height = 600,

radius = (Math.min(width, height) / 2.5) - 60;

var sym = "%"

var legendTextArr = ["alpha", "beta", "Gamma", "vvv", "www", "xxx", "yyy", "zzz"]
var dataDnt4 =      [42, 31, 16, 4, 3, 2, 1];

var color_rect =    ["#00338D", "#BC204B", "#0091DA", "#eaaa00", "#005eb8", "#f68d2e", "#009444", "#470a68"]

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

var title = svg.append("text")
  .attr("font-weight", "bold")
  .attr("class", "title1")
  .html("scroll down!")
  .attr("transform", function() {
    return "translate(" + -184 + "," + -180 + ")"
  })

var legendG = svg.append("g")
  .attr("class", "legendG")
  .attr("transform", function() {
  // this moves the whole legend box
  // you can change this to whatever transformation is appropriate for your chart
    return "translate(" + -((width / 2)-40) + "," + 120 + ")"
  })

// group each legend item in a `g` element
var legendText = legendG.selectAll("g")
  .data(dataDnt4)
  .enter()
  .append('g')
    .attr('transform', function(d, i) {
   // instead of having a hard-coded list of multiples of 25, you can multiply
   // the array index, `i`, by 25 to get the correct position
      return 'translate(0,' + (i*25) + ')';
    });

 legendText.append("rect")
  .attr("width", 25)
  .attr("height", 17)
  .attr("class", "icon1")
  .attr("fill", function(d, i) {
    return color_rect[i];
  })

 // the text "in" the rectangle
 // use 'text-anchor: middle' and an x offset of 12.5 (rectangle width / 2)
 // to centre the labels
 // change the `y` attribute to alter the vertical positioning
 legendText.append("text")
  .attr("x", 12.5)
  .attr("y", 13)
  .attr('text-anchor', 'middle')
  .attr('fill', 'white')
  // d is the items in dataDnt4
  .text(function(d) {
    return d;
  })

 // legend text items
 legendText.append("text")
  .attr("x", 40)
  .attr("y", 13)
  // take legendTextArr item in position i
  .text(function(d,i) {
    return legendTextArr[i];
  })
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="chartdiv"></div>

您的代码中有一些错误(例如,您两次声明了变量legendGtitle),这可能对您通过代码套子运行代码很有帮助,这样您就可以看到您可能不会注意到的问题。