Форматирование оси X на d3 js v5 не работает - PullRequest
0 голосов
/ 08 марта 2020

Я перепробовал все из https://observablehq.com/@d3 / styled-axes и других уроков, но нет никаких шансов: форматирование оси x не работает, например, с .call(d3.axisBottom(x).ticks(10)). Мой график всегда показывает каждый тик (> 100), поэтому он перекрывается. На оси абсцисс отображаются даты, например 2020-03-06. Вот мой код:

<script>

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 80, left: 80},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

var x = d3.scaleBand().rangeRound([0, width]).paddingInner(0.15),
    y = d3.scaleLinear().rangeRound([height, 0]);

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

d3.json("10.json").then(function (data) {
    x.domain(data.map(function (d) { return d.TIMESTAMP; }));
    y.domain([0, d3.max(data, function (d) { return Number(d.TURNOVER); })]);

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

        g.append("g")
            .attr("class", "axis axis--y")
            .call(d3.axisLeft(y).ticks(10));

        g.selectAll(".bar")
          .data(data)
          .enter().append("rect")
            .attr("class", "bar")
            .attr("x", function(d) { return x(d.TIMESTAMP); })
            .attr("y", function(d) { return y(d.TURNOVER); })
            .attr("width", x.bandwidth())
            .attr("height", function(d) { return height - y(d.TURNOVER); });
    })
    .catch((error) => {
            throw error;
    });

</script>

1 Ответ

0 голосов
/ 08 марта 2020
  • Вам следует использовать шкалу даты и времени для вашей шкалы x, которая равна x = d3.scaleTime().
  • В ticks(10). Возможно, вы захотите нарезать ее по месяцам или дням. Например .ticks(d3.timeDay.every(4)). Это будет каждые 4 дня.
  • Вы также хотите изменить формат даты. Вы можете использовать d3.timeFormat("%m/%d"), что даст вам «02/06».
  • Вот несколько примеров. Надеюсь, это поможет.

// Let create some json dataset
var data = [];

for (var i = 0; i < 1000; ++i) {
  let date = parseInt(Math.random() * 30) + 1;
  let dateStr = (date < 10) ? '0' + date : date
  
  data.push({
    TIMESTAMP: '2020-02-' + dateStr.toString(),
    TURNOVER: Math.random() * 100
  });
}

// Create svg
var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 80, left: 80},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

var x = d3.scaleTime().range([0, width]),
    y = d3.scaleLinear().rangeRound([height, 0]);

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

// Find min and max date
var minDate = d3.min(data.map(function(d) { return new Date(d.TIMESTAMP); }));
var maxDate = d3.max(data.map(function(d) { return new Date(d.TIMESTAMP); }));

// Set x and y data domains
x.domain([minDate, maxDate]);
y.domain([0, d3.max(data, function(d) { return d.TURNOVER; })]);

// Create x axis
var xAxis = d3.axisBottom(x)
  .ticks(d3.timeDay.every(4)) // Slice time every 4 days
  .tickFormat(d3.timeFormat("%m/%d")); // Change time format as m/d

// Add x axis
g.append('g')
  .attr('class', 'axis axis--x')
  .attr('transform', 'translate(0, 10)')
  .call(xAxis);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="100"></svg>
...