在D3中定位文字

时间:2019-06-10 20:41:40

标签: d3.js svg

我正在尝试D3中的第一个条形图,但我一直无法将标签放置在条形中的正确位置。无论我做什么,我都无法将标签居中放置在栏上。是否有任何技巧和提示可以轻松做到这一点?我的代码如下。我尝试使用宽度和高度来定位,但仍然无法使其完美。我尝试使用栏的宽度,但无济于事。 大多数帖子都给出了公式,但在我的情况下却没有用。我只希望标签位于顶部的栏内。我濒临放弃D3。按原样学习一种新语言是不堪重负的,而文本定位使它变得更难上百万倍。

function makeBarChart()
  {
    d3.select("#barsvg").remove();
    var filtered_values = justFilter(data_for_bar);
    console.log("length",filtered_values.length)
    var barsvg = d3.select("#barchartdiv")
                 .append('svg')
                 .attr("id",'barsvg')
                 .attr("class","barclass")
                 .attr('width',960)
                 .attr('height',160);

    margin = {top: 20, right: 20, bottom: 30, left: 40}
    width = +barsvg.attr("width") - margin.left - margin.right
    height = +barsvg.attr("height") - margin.top - margin.bottom

    var x = d3.scaleBand().rangeRound([0, width]).padding(0.1)
    var y = d3.scaleLinear().rangeRound([height, 0])

    var g = barsvg.append("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    x.domain(filtered_values.map(function(d) { return d.year; }));
    //y.domain([0, d3.max(filtered_values, function(d) { return d.female_lfpr; })]);
    y.domain([0, 100]);

    console.log(x.domain())
    console.log(y.domain())

    g.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));

    g.append("g")
    .attr("class", "axis axis--y")
    .call(d3.axisLeft(y).ticks(11, ".0f"))
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", "0.9em")
    .attr("text-anchor", "end")
    .text("Female LFPR");  

    function select_axis_label(datum) {
    return d3.select('.axis--x')
        .selectAll('text')
        .filter(function(x) { return x == datum.year; });
    }

    g.selectAll(".bar")
    .data(filtered_values)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.year); })
      .attr("y", function(d) { return y(d.female_lfpr); })
      .attr("width", x.bandwidth())
      .attr("height", function(d) {
        return height - y(d.female_lfpr); })
      //.text(function(d) { return d.female_lfpr; })
        .on('mouseover', function(d) {
          select_axis_label(d).attr('style', "font-weight: bold;");
        })
        .on('mouseout', function(d) {
            select_axis_label(d).attr('style', "font-weight: regular;");
      });

    g.selectAll(".text")
    .data(filtered_values)
    .enter()
    .append("text")
    .attr("class","barlabel")
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
      return i * (width / filtered_values.length) + (width / filtered_values.length) / 2;
    })
    .attr("y", function(d) {
      return +height - (+d.female_lfpr + 4);
    })
    .text(function(d) {
        return d.female_lfpr.toFixed(1);
      })
    //.attr("transform", "rotate(-90)")  
    .attr("font-family", "sans-serif")
    .attr("font-size", "11px")
    .attr("fill", "black");
  }

1 个答案:

答案 0 :(得分:0)

不要弄乱索引(第二个参数)。为了将文本放置在条形图的中间,您只需要使用与放置矩形相同的比例,一半的带宽并将text-anchor设置为middle(您已经拥有) :

.attr("x", function(d) {
    return x(d.year) + x.bandwidth()/2
})

对于垂直位置,请使用与矩形相同的y值,并使用填充或为dominant-baseline设置text-before-edge

.attr("y", function(d) {
    return y(d.female_lfpr) + padding;//your padding here 
})