сортировка баров в d3. js не меняет положение баров - PullRequest
0 голосов
/ 26 января 2020

У меня есть скрипт для сортировки баров в d3, но почему-то бары не двигаются. Кто-нибудь может посоветовать мне, чего не хватает?

<!DOCTYPE html>
<meta charset='utf-8'>

<head>
  <title>Simple Bar Chart</title>
</head>

<body>
  <div id="buttons">
    <p>Sort by</p>
    <div class="button current" data-val="A">value</div>
    <div class="button" data-val="B">week</div>
    <div class="clr"></div>
  </div>
  <div class='container'>
    <div id='viz'></div>
  </div>
  <script src='https://d3js.org/d3.v4.min.js'></script>
  <script>

    var sdata = d3.range(10).map(function (d) {
      return {
        id: d,
        week: 1 + Math.floor(Math.random() * 9),
        value: Math.floor(Math.random() * 20)
      };
    });


    // Setting the margin and dimensions of the work area
    var margin = {
        top: 50,
        right: 20,
        bottom: 30,
        left: 30
      },
      width = 760 - margin.left - margin.right,
      height = 280 - margin.top - margin.bottom;

    // Creating the scale variables and setting the ranges
    var xScale = d3.scaleBand().rangeRound([0, width]).padding(0.1),
      yScale = d3.scaleLinear().rangeRound([height, 0]);

    // Adjusting data by assigning domain to the range of the scale

    var xscale = d3.scaleBand()
      .domain(sdata.map(function (d) {
        return d.week;
      }))
      .range([margin.left, width])
      .padding(0.1);

    // Appending the svg object to the div on the page
    var svg = d3.select('#viz').append('svg')
      .attr('width', width + margin.left + margin.right)
      .attr('height', height + margin.top + margin.bottom);

    // Appending the 'group' element to the svg
    // Moving the 'group' element to the top left margin
    var g = svg.append('g')
      .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');


    // Creating chart
    g.selectAll('bar')
      .data(sdata)
      .enter().append('rect')
      .attr('class', 'bar')
      .attr('x', function (d, i) {
        return 50 * i
      })
      .attr('height', function (d) {
        return height - d.value;
      })
      .attr('y', function (d) {
        return d.value;
      })
      .attr('width', 30);


    g.selectAll(".bar-label")
      .data(sdata)
      .enter()
      .append("text")
      .classed("bar-label", true)
      .attr("transform", function (d, i) {
        return "translate(" + (i * 50) + "," + (height + 15) + ")" +
          " rotate(45)"
      })
      .attr("text-anchor", "left")
      .text(function (d) {
        return 'wk' + d.week
      })

    g.selectAll(".bar-label2")
      .data(sdata)
      .enter()
      .append("text")
      .classed("bar-label", true)
      .attr("transform", function (d, i) {
        return "translate(" + (i * 50) + "," + (height - 15) + ")" +
          " rotate(45)"
      })
      .attr("text-anchor", "left")
      .text(function (d) {
        return 'id: ' + d.id
      })

    //update 
    d3.selectAll(".button").on("click", function () {
      selected = d3.select(this).attr("data-val");
      console.log(selected)
      update(sdata, selected)
    })

    function update(data, selected) {
      data
        .sort((a, b) =>
          selected === "A" ?
          d3.descending(a.value, b.value) :
          d3.descending(a.week, b.week)
        );
      console.log(data)
      d3.selectAll('bar')
        .transition()
        .attr('x', function (d, i) {
          return 50 * i
        })
    }
  </script>
</body>

1 Ответ

2 голосов
/ 27 января 2020

Проблема в том, что при сортировке массива вы не изменяете данные, которые были присоединены к вашим объектам панели d3. И обратите внимание, что в вашем примере важно использовать параметр key в .data() (по умолчанию d3 использует индексы массивов в качестве ключей). Вам необходимо сделать следующее:

Сначала , изменить сопоставление клавиш в коде создания диаграммы (и заменить селектор bar на селектор .bar):

из

// Creating chart
g.selectAll('bar').data(sdata)

до

// Creating chart
g.selectAll('.bar').data(sdata, function(d){return d.id})

Секунда , добавьте отображение данных в свою функцию обновления (и замените селектор bar селектором .bar):

от

d3.selectAll('bar')
        .transition()

до

d3.selectAll('.bar').data(data, function(d){return d.id})
        .transition()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...