javascript - 删除 d3js 日历中的周末
问题描述
在下面的片段中,我有一个常规的年历,我现在尝试做的是使用以下代码排除周末。
var day = function(d) {
if (d.getDay() == 0 || d.getDay() == 6) return null;
return d.getDay();
}
但它并没有像我希望的那样工作。
如果这需要对函数进行太大的重构,monthPath
那么我将研究另一种类型的日历。
这是代码:
var width = 960,
height = 136,
cellSize = 17,
trans_1 = ((width - cellSize * 53) / 2),
trans_2 = (height - cellSize * 7 - 1);
var day = function(d) {
// filter out weekends
if (d.getDay() == 0 || d.getDay() == 6) return null;
return d.getDay();
},
week = d3.timeFormat("%U"),
date = d3.timeFormat("%Y-%m-%d");
var svg = d3.select("body").selectAll("svg")
.data([2018])
.enter().append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform",
"translate(" + trans_1 + "," + trans_2 + ")");
var rect = svg.selectAll(".day")
.data(function(d) {
return d3.timeDays(
new Date(d, 0, 1), new Date(d + 1, 0, 1));
})
.enter().append("rect")
.attr("class", "day")
.attr("width", cellSize)
.attr("height", cellSize)
.attr("x", d => week(d) * cellSize)
.attr("y", d => day(d) * cellSize)
.datum(date);
svg.selectAll(".month")
.data(function(d) {
return d3.timeMonths(
new Date(d, 0, 1), new Date(d + 1, 0, 1));
})
.enter().append("path")
.attr("class", "month")
.attr("d", monthPath);
function monthPath(t0) {
var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
d0 = +day(t0), w0 = +week(t0),
d1 = +day(t1), w1 = +week(t1);
return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize
+ "H" + w0 * cellSize + "V" + 7 * cellSize
+ "H" + w1 * cellSize + "V" + (d1 + 1) * cellSize
+ "H" + (w1 + 1) * cellSize + "V" + 0
+ "H" + (w0 + 1) * cellSize + "Z";
}
body {
padding-top: 25px;
width: 1000px;
margin: auto;
}
.day {
fill: #fff;
stroke: #ccc;
}
.month {
fill: none;
stroke: #000;
stroke-width: 2px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<meta charset="utf-8">
解决方案
要从您的月份路径中删除周末,首先更改顶部和底部垂直点。之前的最小值是0
(对于第 0 天的顶部边缘,星期日),但由于我们正在消除它,它现在将是1
(对于第 1 天,星期一)* cellSize
。最大值是周六的底边,所以 day 6 + 1
(for the bottom edge) * cellSize
,但由于周六被淘汰,新的底边是周五(第 5 天),即5+1 * cellSize
。这给出了:
return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize
+ "H" + w0 * cellSize + "V" + 6 * cellSize // note change
+ "H" + w1 * cellSize + "V" + (d1 + 1) * cellSize
+ "H" + (w1 + 1) * cellSize + "V" + cellSize // note change
+ "H" + (w0 + 1) * cellSize + "Z";
我们还需要更改该月的第一天和最后一天。如果第一天是星期日,则“向上取整”到星期一:
d0 = +day(t0) === 0 ? 1 : +day(t0)
同样,如果最后一天是星期六,则将其“四舍五入”为星期五:
d1 = +day(t1) === 6 ? 5 : +day(t1)
把所有这些放在一起,我们得到:
var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
d0 = +day(t0) === 0 ? 1 : +day(t0),
w0 = +week(t0),
d1 = +day(t1) === 6 ? 5 : +day(t1),
w1 = +week(t1);
return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize
+ "H" + w0 * cellSize + "V" + 6 * cellSize // note change
+ "H" + w1 * cellSize + "V" + (d1 + 1) * cellSize
+ "H" + (w1 + 1) * cellSize + "V" + cellSize // note change
+ "H" + (w0 + 1) * cellSize + "Z";
var width = 960,
height = 150,
cellSize = 17,
trans_1 = ((width - cellSize * 53) / 2),
trans_2 = (height - cellSize * 7 - 1);
var day = function(d) {
// filter out weekends
// if (d.getDay() == 0 || d.getDay() == 6) return null;
return d.getDay();
},
week = d3.timeFormat("%U"),
date = d3.timeFormat("%Y-%m-%d");
var svg = d3.select("body").selectAll("svg")
.data([2018])
.enter().append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform",
"translate(" + trans_1 + "," + trans_2 + ")");
var rect = svg.selectAll(".day")
.data(function(d) {
return d3.timeDays(new Date(d, 0, 1), new Date(d + 1, 0, 1))
})
.enter().append("rect")
.attr("class", function(d) {
return "day _" + d.getDay()
})
.attr("width", cellSize)
.attr("height", cellSize)
.attr("x", d => week(d) * cellSize)
.attr("y", d => day(d) * cellSize)
.datum(date);
svg.selectAll(".month")
.data(function(d) {
return d3.timeMonths(
new Date(d, 0, 1), new Date(d + 1, 0, 1));
})
.enter().append("path")
.attr("class", "month")
.attr("d", monthPath);
function monthPath(t0) {
var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
d0 = +day(t0) === 0 ? 1 : +day(t0),
w0 = +week(t0),
d1 = +day(t1) === 6 ? 5 : +day(t1),
w1 = +week(t1);
return "M" + (w0 + 1) * cellSize + "," + d0 * cellSize +
"H" + w0 * cellSize + "V" + 6 * cellSize // note change
+
"H" + w1 * cellSize + "V" + (d1 + 1) * cellSize +
"H" + (w1 + 1) * cellSize + "V" + cellSize // note change
+
"H" + (w0 + 1) * cellSize + "Z";
}
body {
padding-top: 25px;
width: 1000px;
margin: auto;
}
.day {
fill: #fff;
stroke: #ccc;
}
.month {
fill: none;
stroke: #000;
stroke-width: 2px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<meta charset="utf-8">
顺便说一句,您过滤掉周末的策略会(有点)删除代表一周中的几天的网格单元:
var rect = svg.selectAll(".day")
.data(function(d) {
return d3.timeDays(new Date(d, 0, 1), new Date(d + 1, 0, 1))
.filter( function(x){
return (x.getDay() !== 6 && x.getDay() !== 0) // filter out day 0 and 6
})
})
.enter().append("rect")
// etc.
推荐阅读
- javascript - 覆盖打开后如何防止正文滚动?
- javascript - 使用 gulp 支持旧版浏览器
- react-native - 使用 Wix React Native Navigation (RNN) 时将属性从本机传递到 React Native
- excel - 为什么 CountA 会产生额外的行
- javascript - 如何使用备用值对 JavaScript DataTable 进行排序?
- tensorflow - TensorFlow1.13 无法使用 slice_input_producer
- arrays - 解析 JSON 字符串 Pyspark 数据框列,其中一列中有数组字符串
- google-chrome - 如何在谷歌浏览器中启用开发者模式(在 Mac 中)
- django-models - 如何使用选择选项输入字段(从下拉菜单中选择)根据其分类属性过滤模型实例
- c++ - 使用命名空间 std 的 C++“对重载函数的引用”错误