使用d3.js v4我试图在y轴上绘制时间图。 y轴表示24小时的时钟。
数据很简单,
[{
"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进行。这表明存在一个问题,例如基于零的计数。
有没有人对我如何解决这个问题提出建议?
以下是完整的代码段
<!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>
由于
答案 0 :(得分:1)
因此,您遇到问题的第一个栏就是基于这些数据:
{
"start": "2016-11-14 20:00",
"end": "2016-11-14 23:59"
},
您根据其endtime
进行定位,其类似于
d.endtime = d.end.getHours();
所以,这就是问题:如果你得到23:59的小时,它是23,而不是24:JavaScript没有四舍五入到最近的小时,它只需要一小时部分。如果您想要更准确的y轴,您可以: