D3.JS — Линейный график — отзывчивый — не могу найти способ обновить x-значения строки

#javascript #svg #d3.js #responsive

#javascript #svg #d3.js #отзывчивый

Вопрос:

Я пытаюсь сделать D3.JS Линейная диаграмма, реагирующая по горизонтали — мою работу можно увидеть в этом CodePen

Моя проблема заключается в обновлении положения значения x для точки данных Lines при изменении ширины диаграммы. Ось x изменяется нормально.

В моем Javascript у меня есть функция с именем resizeChart, которая вызывается при изменении ширины окна браузера:

   function resizeChart() {

currentWidth = parseInt(d3.select('#div_basicResize').style('width'), 10)
Svg.attr("width", currentWidth - 60)

x.range([20, currentWidth - 100]);
xAxis.call(d3.axisBottom(x));

var self = this;

Svg.selectAll("path")
  .data(data)
  .attr("x", function (d) {
    return self.x(d.period);
  });
  

}

Проблема заключается в Svg.selectAll, поскольку, похоже, он не обновляет значения x строки.

Ответ №1:

Ну, элементы пути SVG не имеют x атрибута (просто d атрибут, который вы используете в нескольких строках выше, чтобы добавить путь).

Тем не менее, просто назовите свой выбор…

 var path = Svg.append("path")
    //etc...
  

… и, внутри resizeChart , d снова установите атрибут, после изменения диапазона масштаба x:

 path.attr("d", line);
  

Вот код с этими изменениями:

 var Svg = d3.select("#div_basicResize")
  .append("svg")
  .attr("height", 0)

var data = [{
    "period": 2010,
    "count": 166
  },
  {
    "period": 2011,
    "count": 192
  },
  {
    "period": 2012,
    "count": 158
  },
  {
    "period": 2013,
    "count": 183
  },
  {
    "period": 2014,
    "count": 174
  },
  {
    "period": 2015,
    "count": 197
  },
  {
    "period": 2016,
    "count": 201
  },
  {
    "period": 2017,
    "count": 195
  },
  {
    "period": 2018,
    "count": 203
  },
  {
    "period": 2019,
    "count": 209
  },
  {
    "period": 2020,
    "count": 208
  }
]

var Svg = d3.select("#div_basicResize")
  .append("svg")
  .attr("height", 400);

var x = d3.scalePoint()
  .domain(
    data.map(function(d) {
      return d.period;
    })
  )
  .range([20, 20]);

var xAxis = Svg.append("g").attr(
  "transform",
  "translate("   20   ","   360   ")"
);

var max =
  d3.max(data, function(d) {
    return  d.count;
  })   10;

var min =
  d3.min(data, function(d) {
    return  d.count;
  }) - 10;

var y = d3.scaleLinear()
  .domain([min, max])
  .range([360, 0]);

Svg.append("g")
  .attr("transform", "translate("   40   ",0)")
  .call(d3.axisLeft(y));

var self = this;

var line = d3.line()
  .x(function(d) {
    return x(d.period)   20;
  })
  .y(function(d) {
    return y( d.count);
  });

var path = Svg.append("path")
  .datum(data)
  .attr("fill", "none")
  .attr("stroke", "black")
  .attr("stroke-width", 1)
  .attr("d", line);

function resizeChart() {

  currentWidth = parseInt(d3.select('#div_basicResize').style('width'), 10)
  Svg.attr("width", currentWidth - 60)

  x.range([20, currentWidth - 100]);
  xAxis.call(d3.axisBottom(x));

  //This is where I'm trying to update x value
  path.attr("d", line);
}

resizeChart()
window.addEventListener('resize', resizeChart);  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id="div_basicResize"></div>  

Комментарии:

1. Привет, Херардо — большое спасибо — это работает как шарм. Я все еще пытаюсь лучше понять D3 и то, как он работает.