D3线图 - 按日计算的线x轴,x轴标签按月计算

时间:2018-03-06 16:39:41

标签: d3.js

我有一个D3线图,目前按月计算线x轴和x轴标签。在下面的屏幕截图中,我在同一个月有两个不同的日期。目前,它们显示的x轴值相同:

enter image description here

我希望x轴行按天计算,而标签保持数月。请参阅以下相关代码:

<script>
              $(document).ready(function() {
                  let eventSourceArr = [];
                  $.ajax({
                    url: '/diary',
                    type: 'GET',
                    dataType: 'json',
                    success: function(data) {
                      console.log('Diary GET success');
                      console.log('data: ',data);

                      //Need to show days, not just months, in the graph
                      for (let i in data.data) {

                        //Convert UNIX time to date
                        let a = new Date(data.data[i].created_at*1000);
                        let year = a.getFullYear();
                        year = year.toString();
                        year = year.slice(2);
                        let month = a.getMonth();
                        month = month.toString();
                        if (month.length === 1) {
                          month = '0' + month;
                        }
                        let date = a.getDate();
                        date = date.toString();
                        if (date.length === 1) {
                          date = '0' + date;
                        }
                        let formattedTime = month + '/' + year;

                        eventSourceArr.push({"feeling": data.data[i].feeling, "month": formattedTime});
                        console.log('eventSourceArr: ',eventSourceArr);
                      }

                      let sixMonthsAgo;
                      let yearSixMonthsAgo;

                      if ((parseInt(moment().format('MM')) - 6) > 0) {
                        sixMonthsAgo = parseInt(moment().format('M') - 6);
                        yearSixMonthsAgo = parseInt(moment().format('YYYY'));
                      }
                       else if ((parseInt(moment().format('MM')) - 6) <= 0) {
                        sixMonthsAgo = parseInt(moment().format('M')) + 6;
                        yearSixMonthsAgo = parseInt(moment().format('YYYY')) - 1;
                      };

                      let vis = d3.select("#visualisation"),
                          WIDTH = 1000,
                          HEIGHT = 475,
                          MARGINS = {
                              top: 20,
                              right: 20,
                              bottom: 20,
                              left: 50
                          },
                          xScale = d3.time.scale()
                            .domain([new Date(yearSixMonthsAgo, sixMonthsAgo, 1), new Date()])
                            .range([MARGINS.left, WIDTH - MARGINS.right]),
                          yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([1, 10]),
                          xAxis = d3.svg.axis()
                            .scale(xScale)
                            .orient("bottom")
                            .ticks(d3.time.months)
                            .tickFormat(d3.time.format("%B")),
                          yAxis = d3.svg.axis()
                            .scale(yScale)
                            .orient("left");

                      vis.append("svg:g")
                          .attr("class", "x axis")
                          .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
                          .call(xAxis);
                      vis.append("svg:g")
                          .attr("class", "y axis")
                          .attr("transform", "translate(" + (MARGINS.left) + ",0)")
                          .call(yAxis);


                      let lineGen = d3.svg.line()
                          .x(function(d) {
                              // let formatDate = d3.time.format("%-m/%y");
                              let formatDate = d3.time.format("%-j");
                              let monthData = formatDate.parse(d.month);
                              console.log('formatDate: ',formatDate);
                              console.log('monthData: ',monthData);
                              return xScale(monthData);
                              // return xScale(d.created_at);
                          })
                          .y(function(d) {
                              return yScale(parseInt(d.feeling));
                          })
                          .interpolate("basis");
                      vis.append('svg:path')
                          .attr('d', lineGen(eventSourceArr))
                          .attr('stroke', 'blue')
                          .attr('stroke-width', 2)
                          .attr('fill', 'none');

                      },
                      error: function() {
                        console.log('Diary GET failure');
                      }
                  });
              });
            </script>

原始data.data对象如下所示:

{"id": 2, "feeling": 3, "notes": "Had a bad day", "updated_at": 1520273147, "created_at": 1520273147}

x轴线可视化"created_at"。屏幕截图中有两个数据项,两个日期都不同。

如何更改此内容?

编辑:添加了整个脚本而不是部分。

1 个答案:

答案 0 :(得分:1)

我将您的代码更新为v4并且没有解析时间,为了显示目的创建了一个虚假的第二个数据点。轴是不完美的,因为我只有2个数据点,但这应该让你朝着正确的方向前进。

&#13;
&#13;
var data = [{
    "id": 2,
    "feeling": 3,
    "notes": "Had a bad day",
    "updated_at": 1520273147000,
    "created_at": 1520273147000
  },
  {
    "id": 3,
    "feeling": 5,
    "notes": "Had a bad day",
    "updated_at": 1520273287000,
    "created_at": 1520273287000
  }
];

let vis = d3.select("#visualization"),
  WIDTH = 1000,
  HEIGHT = 475,
  MARGINS = {
    top: 20,
    right: 20,
    bottom: 20,
    left: 50
  },
  xScale = d3.scaleTime()
  .domain([1520273146000, 1520273288000])
  .range([MARGINS.left, WIDTH - MARGINS.right]),
  yScale = d3.scaleLinear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([1, 10]);
vis.attr("height", HEIGHT).attr('width', WIDTH)
vis.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
  .call(d3.axisBottom(xScale).tickFormat(d3.timeFormat("%b")));
vis.append("g")
  .attr("class", "y axis")
  .attr("transform", "translate(" + (MARGINS.left) + ",0)")
  .call(d3.axisLeft(yScale));

let lineGen = d3.line()
  .x(function(d) {
    return xScale(+d.created_at);
  })
  .y(function(d) {
    return yScale(+d.feeling);
  });

vis.datum(data).append('path')
  .attr("class", "genLine")
  .attr('d', lineGen)
  .attr('stroke', 'blue')
  .attr('stroke-width', 2)
  .attr('fill', 'none');
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<svg id='visualization'></svg>
</body>
&#13;
&#13;
&#13;