首页 > 解决方案 > 在 d3 条形图中在 x 轴上排列正确的日期

问题描述

我有一个条形图,它显示在 x 轴日期、y 轴 gdp 上,并且条形图本身具有每一年的值。我的问题是,在 x 轴上,日期应该从 0、1950 开始,之后的每个刻度都应该增加 +5 年。但相反,它看起来像这样:

条形图

即使我使用.tickFormat()which 应该返回条件d%5!=0 ? " " : years[d];正确(预期)的结果,但事实并非如此。

我想添加 y 轴很好,x 轴也排成一行,只有在 x 轴刻度上应该显示 dates 0 -> 1950 -> 1955 -> ...5+

这是我的代码:

let res = null;
$(document).ready(() => {
  let url =
    "https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json";
  $.ajax({
    url: url,
    success: (response) => {
      res = JSON.parse(response);

      let dataset = [];
      let values = [];
      let years = [];
      let yearsNoDuplicates = [];
      let quarters = [];

      for (let i = 0; i < res.data.length; i++) {
        let year = res.data[i][0];
        let month = res.data[i][0].substring(
          res.data[i][0].length - 5,
          res.data[i][0].length - 3
        );
        let q = null;

        if (parseInt(month) <= 3) {
          q = "Q1";
        }

        if (parseInt(month) <= 6 && parseInt(month) > 3) {
          q = "Q2";
        }

        if (
          parseInt(month) <= 9 &&
          parseInt(month) > 6 &&
          parseInt(month) > 3
        ) {
          q = "Q3";
        }

        if (
          parseInt(month) <= 12 &&
          parseInt(month) > 9 &&
          parseInt(month) > 6 &&
          parseInt(month) > 3
        ) {
          q = "Q4";
        }
        dataset.push([res.data[i][1], year, q]);

        values.push(res.data[i][1]);
        years.push(parseInt(year.substring(0, 4)));
        quarters.push(q);
      }
      yearsNoDuplicates = years.filter((item, i) => {
        return i === years.indexOf(item);
      });

      const w = 800;
      const h = 600;

      const m = { top: 40, right: 40, bottom: 40, left: 40 };

      const svg = d3
        .select("#demo")
        .append("svg")
        .attr("width", w + m.left + m.right)
        .attr("height", h + m.top + m.bottom);

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

      let xScale = d3
        .scaleLinear()
        .range([0, w])
        .domain([0, values.length - 1]);

      const xAxis = d3.axisBottom(xScale).tickFormat((d, i) => {
        return d % 5 != 0 ? " " : years[d]; //is equivalent to return years[d];
      });

      g.append("g")
        .attr("transform", "translate(0," + h + ")")
        .attr("class", "tick axis")
        .attr("id", "x-axis")
        .call(xAxis);

      let yScale = d3
        .scaleLinear()
        .range([h, 0])
        .domain([0, dataset[dataset.length - 1][0]]);

      const yAxis = d3.axisLeft(yScale);

      g.append("g")
        .attr("transform", "translate(0, 0)")
        .attr("class", "tick axis")
        .attr("id", "y-axis")
        .attr("fill", "red")
        .call(yAxis);

      g.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("id", (d, i) => {
          return "tipX" + i;
        })
        .attr("x", (d, i) => {
          return xScale(i);
        })
        .attr("y", (d) => {
          return yScale(d[0]);
        })
        .attr("height", (d) => {
          return h - yScale(d[0]);
        })
        .attr("width", (d, i) => {
          return w - xScale(i);
        })
        .attr("data-date", (d, i) => {
          return d[1];
        })
        .attr("data-gdp", (d, i) => {
          return d[0];
        })
        .attr("class", "bar")
        .append("title")
        .attr("data-date", (d, i) => {
          return d[1];
        })
        .attr("id", "tooltip")
        .text((item, i) => {
          return (
            item[1].substr(0, 4) + " " + item[2] + " \n$" + item[0] + " Billion"
          );
        });
    },
    error: (xhr, ajaxOptions, thrownError) => {
      console.log(xhr, ajaxOptions, thrownError);
    }
  });
});

这是我的条形图

标签: javascriptd3.js

解决方案


推荐阅读