d3.js datetime:小时未在y轴上正确显示 [英] d3.js datetime: hour not displaying correctly on y-axis

查看:69
本文介绍了d3.js datetime:小时未在y轴上正确显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用d3.js v4,我试图在y轴上绘制时间. y轴表示一天中的24小时.

Using d3.js v4 I am trying to graph a time on the y-axis. The y-axis represents 24 hours of the clock.

数据很简单

[{
    "start": "2016-11-14 20:00",
    "end": "2016-11-14 23:59"
  },
  {
    "start": "2016-11-16 01:00",
    "end": "2016-11-16 03:00"
  },
  {
    "start": "2016-11-15 00:00",
    "end": "2016-11-15 04:00"
  }
]

第一个对象的图形应该从20到24,但是它将从19到23.这将提示诸如基于零的计数之类的问题.

The first object should graph from 20 to 24 but it is going from 19 to 23. This would suggest a problem such as zero based counting.

有人对我如何解决这个问题有建议吗?

Does anyone have an suggestions on how i might solve this?

这是完整的代码段,

<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>d3 datetime graph</title>
  <script src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <svg width="800" height="400"></svg>
  </div>
  <div id="json">
  </div>
  <!-- <script type="text/javascript" src="script.js"></script> -->
  <script type="text/javascript">
    var svg = d3.select("svg"),
      margin = {
        top: 20,
        right: 60,
        bottom: 60,
        left: 40
      },
      width = +svg.attr("width") - margin.left - margin.right,
      height = +svg.attr("height") - margin.top - margin.bottom;
    var color = ["#2C93E8", "#838690", "#F56C4E", "#A60F2B", "#648C85", "#B3F2C9", "#528C18", "#C3F25C"];


    var data = [{
        "start": "2016-11-14 20:00",
        "end": "2016-11-14 23:59"
      },
      {
        "start": "2016-11-16 01:00",
        "end": "2016-11-16 03:00"
      },
      {
        "start": "2016-11-15 00:00",
        "end": "2016-11-15 04:00"
      }
    ]

    var parseTime = d3.timeParse("%Y-%m-%d %H:%M");
    var parseDay = d3.timeParse("%e %b %Y");
    var formatDay = d3.timeFormat("%e %b %Y");
    // data.forEach(function(d) {
    //   commence = parseTime(d.start);
    //   conclude = parseTime(d.end);
    //   if (commence.getDay() != conclude.getDay()) {
    //     // a check here in case they are more than a day apart
    //     // 2016-11-04 12:00
    //
    //     morning = conclude.getFullYear() + "-" + (conclude.getMonth() + 1) + "-" + conclude.getDate() + " 00:00";
    //     console.log("morning is " + morning);
    //     data.push({
    //       "start": morning,
    //       "end": d.end
    //     })
    //     midnight = commence.getFullYear() + "-" + (commence.getMonth() + 1) + "-" + commence.getDate() + " 23:59";
    //     console.log("midnight is " + midnight);
    //     d.end = midnight;
    //     //we need to remove current object
    //     //what element in the array is it, read the 'i'
    //     //use slice to remove that element data.slice(i,1) or soemthing like that
    //   }
    // });
    console.log(JSON.stringify(data, null, 2));

    data.forEach(function(d) {
        d.start = parseTime(d.start);
        d.end = parseTime(d.end);
        d.duration = ((d.end - d.start) / (60 * 1000) / 60); // session duration in hours
        d.starttime = d.start.getHours();
        d.endtime = d.end.getHours();
        d.daily = formatDay(d.start);
        d.day = parseDay(d.daily);

        return d;
      },
      function(error, data) {
        if (error) throw error;
      });

    document.getElementById("json").innerHTML = "<h5>data.json</h5>" + "<pre>" + JSON.stringify(data, null, 2) + "</pre>";

    var x = d3.scaleTime()
      .domain(d3.extent(data, function(d) {
        return d.day; //need to round to day
      }))
      .range([0, width]);

    var y = d3.scaleLinear()
      .domain([0, 24])
      .range([height, 0]);

    var group = svg.append("g");

    group.selectAll(".bar")
      .data(data)
      .enter()
      .append("rect")
      .style("fill", "blue")
      .attr("class", "bar")
      .attr("transform", "translate(80,0)")
      .attr("x", function(d) {
        return x(d.day) + 10;
      })
      .attr("y", function(d) {
        //if ((d.endtime + d.duration) > 24) {
        // console.log("oh no:")
        // console.log("d.starttime: " + d.starttime); //2
        // console.log("y(d.starttime): " + y(d.starttime)); //293.3333
        // console.log("d.endtime: " + d.endtime); //18
        // console.log("y(d.endtime): " + y(d.endtime)); //80
        // console.log("d.duration: " + d.duration); //16
        // console.log("y(d.duration): " + y(d.duration)); //106.6666
        // console.log("height: " + height); //320
        // console.log("y(16): " + y(16)); //106.6666
        // console.log("y(24): " + y(24)); //0
        // console.log("y(0): " + y(0)); //320
        // console.log("height - y(d.duration): " + (height - y(d.duration))); //320-106.666=213.333
        //  }
        return y(d.endtime);
      })
      .attr("width", 20)
      .attr("height", function(d) {
        return height - y(d.duration);
        // return y(d.starttime);
      })
      .style("fill", function(d, i) {
        return color[i];
      });

    svg.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(100," + (height + 2) + ")")
      .call(d3.axisBottom(x).ticks(d3.timeDay.every(1)).tickFormat(d3.timeFormat("%e %b %Y")))
      // axis.ticks(d3.timeMinute.every(15));
      // .call(d3.axisBottom(x))
      .selectAll("text")
      .style("text-anchor", "end")
      .attr("dx", "-.8em")
      .attr("dy", ".15em")
      .attr("transform", "rotate(-35)");

    svg.append("g")
      .attr("class", "axis axis--y")
      .attr("transform", "translate(80,0)")
      .call(d3.axisLeft(y).ticks(24))
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0)
      .attr("x", 0)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("duration (hours)");
  </script>
</body>

</html>

谢谢

推荐答案

因此,第一个柱(您遇到问题的柱)基于此数据:

So the first bar, the one that you're having issues with, is based on this data:

{
  "start": "2016-11-14 20:00",
  "end": "2016-11-14 23:59"
},

然后根据它的endtime对其进行定位,而endtime的推导方式为

And you're positioning it based on its endtime, which is derived like

d.endtime = d.end.getHours();

所以,这就是问题所在:如果您得到的时间是23:59,则是23,而不是24:JavaScript不能四舍五入到最接近的小时数,而只是小时数.如果您想要更精确的y轴,则可以:

So, that's the issue: if you get the hour of 23:59, it's 23, not 24: JavaScript doesn't round to the nearest hour, it just takes the hour part. If you want a more accurate y-axis, you can:

  • 使用非小时的内容,例如分钟或秒.
  • 为每个条形图创建一个时间刻度,其域设置为该条形图时间范围之前/之后的午夜.

这篇关于d3.js datetime:小时未在y轴上正确显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆