计数d3中的过滤器结果

时间:2018-08-06 04:43:13

标签: javascript d3.js

我正在按月过滤数据集。我想从以下函数返回“匹配”记录的数量:

function dateMatch(data, value) {
        var d = new Date(data.properties.Date);
        var m = month[d.getMonth()];
        if (inputValue == m) {
            this.parentElement.appendChild(this);
            return "red";
        } else {
            return "#808080";
        };
    }

基本上,要计算此函数中附加子项的数量。我该怎么办?

谢谢!

3 个答案:

答案 0 :(得分:0)

您可以在函数外部定义一个变量,并在条件匹配时将其递增。每次要重新启动计数器时,请确保将计数器初始化为0。

responsive:{
0:{
    items:1,
    loop:true
},
600:{
    items:3,
    loop:true
},
1000:{
    items:4,
    loop:true
}

答案 1 :(得分:-1)

cdoshi,谢谢。这可行:

var counter = 55
function dateMatch(data, value) {
        var d = new Date(data.properties.Date);
        var m = month[d.getMonth()];
        if (inputValue == m) {
            this.parentElement.appendChild(this);
            counter++;
            return "red";
        } else {
            return "#808080";
        };


        return counter
    }

然后,我输出计数器变量,以便在启动时间滑块时它会更改:

 <div id="sliderContainer">
        <input id="timeslide" type="range" min="0" max="11" value="0" step="1" /><br>
        <span id="range" style="font-family:optima"; >January</span>
    </div>

var inputValue = null;
    var month = ["January","February","March","April","May","June","July","August","September","October","November","December"];

d3.select("#timeslide").on("input", function() {
        update(+this.value);
        document.getElementById("count").innerHTML = counter
    });

这可以按预期工作,但是唯一的问题是,如果时间滑块按相反顺序运行,则计数将继续递增更新。我只希望将其总计到时间滑块末尾的最后一个月12月,如果用户倒转,计数将再次开始减少。

答案 2 :(得分:-1)

摆脱这些全局counterinputVariable变量,让d3计数selected个项目,这样会更清洁。

不是在selected项上设置颜色,而是给它们提供类selected

document.getElementById("count").innerHTML = d3.selectAll(".incident.selected").size();

将所需的月份作为参数传递给选择器函数。

function dateMatch(monthIdx) {
    return function (d) {
        return (new Date(d.properties.Date).getMonth() === monthIdx);
    }
}

在更新功能中

function update(monthIdx) {
    document.getElementById("range").innerHTML = month[monthIdx];
    d3.selectAll(".incident")
      .classed("selected", dateMatch(monthIdx))
      //.attr( "d", geoPath.pointRadius(dateMatchRadius) )
      ;
}

我已将update方法中的geopath调用注释掉,因为它与示例代码段无关。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
.incident {fill:#808080;}
.incident.selected {fill:red;}
</style>
</head>
<body>
<div id="sliderContainer">
<input id="timeslide" type="range" min="0" max="11" value="0" step="1" /><br>
<div>Month: <span id="range" style="font-family:optima;">January</span></div>
<div>Count: <span id="count"></span></div>
<svg id="chart" width="500" height="500"></svg>
<script>
var month = ["January","February","March","April","May","June","July","August","September","October","November","December"];

var data = d3.range(200)
             .map(d => { return {properties: {Date: new Date(Math.floor(Math.random() * 21)+1990, Math.floor(Math.random() * 12), 1).toString()} }; });

d3.select("#chart")
  .selectAll(".incident")
  .data(data)
  .enter()
  .append("circle")
  .attr("class", "incident")
  .attr("cx", d => (Math.random() * 400)+50)
  .attr("cy", d => (Math.random() * 400)+50)
  .attr("r",  d => (Math.random() * 10)+5);

function dateMatch(monthIdx) {
    return function (d) {
        return (new Date(d.properties.Date).getMonth() === monthIdx);
    }
}

function update(monthIdx) {
    document.getElementById("range").innerHTML = month[monthIdx];
    d3.selectAll(".incident")
      .classed("selected", dateMatch(monthIdx))
      //.attr( "d", geoPath.pointRadius(dateMatchRadius) )
      ;
}

d3.select("#timeslide").on("input", function() {
    update(+this.value);
    document.getElementById("count").innerHTML = d3.selectAll(".incident.selected").size();
});
</script>
</div>
</body>
</html>