Добавить текст после столбцов на горизонтальной гистограмме - PullRequest
1 голос
/ 17 апреля 2019

Я работаю над горизонтальной гистограммой и хочу переместить Y-метки после гистограммы.

d3.csv("mydata.csv", function(data) {

    // Add X axis
    var x = d3.scaleLinear()
        .domain([0, 100])
        .range([ 0, width])

    svg.append("g")
        .attr("transform", "translate(0,0)")
        .call(d3.axisTop(x).ticks(10).tickFormat(function(d){return d+ "%"}))
        .selectAll("text")
        .attr("transform", "translate(10,-12)rotate(-45)")
        .style("text-anchor", "end");

    // Y axis
    var y = d3.scaleBand()
        .range([ 0, height ])
        .domain(data.map(function(d) { return d.type; }))
        .padding(.5);

    svg.append("g")
        .call(d3.axisRight(y))
        .selectAll('text')
        .attr("x", function(d) { return d.number; } )

    //Bars
    svg.selectAll("myRect")
        .data(data)
        .enter()
        .append("rect")
        .attr("x", x(0.5) )
        .attr("y", function(d) { return y(d.type); })
        .attr("width", function(d) { return x(d.number); })
        .attr("height", y.bandwidth() )
        .attr("fill", "#69b3a2")

})

CSV-файл имеет два столбца

  • type
  • число

В этой части кода

  svg.append("g")
        .call(d3.axisRight(y))
        .selectAll('text')
        .attr("x", function(d) { return d.number; } )

Если я заменим строку .attr("x", function(d) { return d.number; } ) на .attr("x", 100 ), то она сместит метки вправо.Но когда я пытаюсь сохранить его динамическим по ширине полосы, текст остается началом оси Y.

1 Ответ

2 голосов
/ 17 апреля 2019

В своем коде вместо создания нового выделения с метками в качестве элементов <text> вы пытаетесь переместить отметки оси! Это довольно необычный подход, но, безусловно, выполнимый.

Основная проблема - только данные: в этой строке ...

.attr("x", function(d) { return d.number; })

... данные (d) - это не те данные, которые есть у прямоугольников, которые исходят из ваших данных. Исходные данные здесь - это только строки в тиках оси.

Следовательно, мы должны получить реальное значение, чтобы мы могли получить значение number. Как это:

.attr("x", function(d) {
    const datum = data.find(function(e){return e.type === d})
    return x(datum.number);
})

Вот ваш код с этим изменением (и некоторые поддельные данные):

var width = 500,
  height = 300,
  padding = 20;

var data = [{
    type: "foo",
    number: 42
  },
  {
    type: "bar",
    number: 12
  },
  {
    type: "baz",
    number: 79
  },
  {
    type: "foobar",
    number: 17
  },
  {
    type: "foobaz",
    number: 36
  }
];

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var x = d3.scaleLinear()
  .domain([0, 100])
  .range([padding, width - padding])

svg.append("g")
  .attr("transform", "translate(0,20)")
  .call(d3.axisTop(x).ticks(10).tickFormat(function(d) {
    return d + "%"
  }))
  .selectAll("text")
  .attr("transform", "translate(10,-12)rotate(-45)")
  .style("text-anchor", "end");

// Y axis
var y = d3.scaleBand()
  .range([padding, height - padding])
  .domain(data.map(function(d) {
    return d.type;
  }))
  .padding(0.5);

svg.append("g")
  .attr("transform", "translate(20,0)")
  .call(d3.axisRight(y))
  .selectAll('text')
  .attr("x", function(d) {
    const datum = data.find(function(e) {
      return e.type === d
    })
    return x(datum.number) + 6;
  })

//Bars
svg.selectAll("myRect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", x(0.5))
  .attr("y", function(d) {
    return y(d.type);
  })
  .attr("width", function(d) {
    return x(d.number);
  })
  .attr("height", y.bandwidth())
  .attr("fill", "#69b3a2")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...