在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最大值是星期六的底部边缘,因此是天6 + 1(底部边缘)* 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.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章