Позиционирование текста в D3 - PullRequest
1 голос
/ 10 июня 2019

Я пробую свою первую гистограмму в 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 голосов
/ 11 июня 2019

Не связывайтесь с индексами (второй аргумент).Для позиционирования текстов прямо в середине столбца вам нужен тот же масштаб, который вы используете для позиционирования каналов, половина полосы пропускания и 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 
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...