【问题标题】:counting filter results in d3在 d3 中计算过滤器结果
【发布时间】:2018-08-06 04:43:12
【问题描述】:

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

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";
        };
    }

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

谢谢!

【问题讨论】:

  • 您的函数当前返回一种颜色。你是说你想让它返回一个计数吗?此外,这个函数看起来不像是在过滤 data 它是在将月份与一个神秘变量 inputValue 进行比较并返回一个颜色字符串。

标签: javascript d3.js


【解决方案1】:

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

var counter = 0;

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";
        };
    }

【讨论】:

    【解决方案2】:

    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 月)的时间滑块结束时求和,如果用户反过来,计数将再次开始减少。

    【讨论】:

    • 我有点困惑。你在哪里调用 dateMatch 函数?另外,如果你能创建一个 jsfiddle 那就太好了。
    【解决方案3】:

    摆脱这些全局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) )
          ;
    }
    

    我已将更新方法中的geopath 调用注释掉,因为它与示例 sn-p 无关。

    <!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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-26
      • 2021-07-22
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      • 2016-04-27
      • 2012-10-03
      • 2019-06-19
      相关资源
      最近更新 更多