D3 过滤数据点 [英] D3 filtering data points

查看:27
本文介绍了D3 过滤数据点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实施经典的墨卡托示例 (https://github.com/mbostock/d3/blob/master/examples/mercator/mercator.html),我已将其更改为放大阿富汗并仅使用一个自定义滑块.我正在阅读发生爆炸的地方的 GeoJSON 数据,并且图表在加载时将它们全部映射出来.我想使用滑块一次仅查看一个月的爆炸点,但无法过滤结果.我已经根据 Google 群组中的帖子尝试了几项操作,但无法理解如何过滤之前从explosions.json"读取的数据.感谢您的帮助!

I'm implementing the classic mercator example (https://github.com/mbostock/d3/blob/master/examples/mercator/mercator.html), which I've changed to zoom into Afghanistan and to use only one custom slider. I'm reading in GeoJSON data of places where explosions have happened and the graph maps them all at load. I want to use the slider to view only a month of explosion points at a time but am having trouble filtering the results. I've tried several things based on posts in the Google group but fail to understand how to filter the data read in previously from 'explosions.json'. Thanks for the help!

    <!DOCTYPE html>
    <html>
    <head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>IED Attacks in Afghanistan (2004-2009)</title>
<script type="text/javascript" src="../d3.v2.js"></script>
<script type="text/javascript" src="../lib/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../lib/jquery-ui/jquery-ui.min.js"></script>
<style type="text/css">

    @import url("../lib/jquery-ui/jquery-ui.css");

    body, .ui-widget {
    font: 14px Helvetica Neue;
    }

    svg {
    width: 960px;
    height: 600px;
    border: solid 1px #ccc;
    background: #eee;
    }

    line {
    stroke: brown;
    stroke-dasharray: 4,2;
    }

    path {
    fill: #ccc;
    stroke: #fff;
    }

    div {
    width: 960px;
    }

</style>
</head>
<body>
<h3>IED Attacks in Afghanistan (2004-2009)</h3>
<script type="text/javascript">

        // Create the Mercator Projection (Map)
        var xy = d3.geo.mercator(),
            path = d3.geo.path().projection(xy);


        // Create the states variable
        var states = d3.select("body")
        .append("svg")
        .append("g")
            .attr("id", "states");
        // Create the equator variable
        var equator = d3.select("svg")
        .append("line")
            .attr("x1", "0%")
            .attr("x2", "100%");
        // Create the explosions variable
        var explosions = d3.select("svg")
        .append("g")
            .attr("id","explosions");

        // Load in the states & equator data from the file 'world-countries.json'
        d3.json("world-countries.json", function(collection) {
            states
                .selectAll("path")
                .data(collection.features)
                .enter().append("path")
                .attr("d", path)
                .append("title")
                .text(function(d) { return d.properties.name; });
            equator
                .attr("y1", xy([0, 0])[1])
                .attr("y2", xy([0, 0])[1]);
        });

        // the variable that holds our translate, center on Afghanistan
        var translate = xy.translate(); //create translation to center gride in different area
        translate[0] = -1741;
        translate[1] = 1487;
        xy.translate(translate); // center

        xy.scale(12000); //zoom in

        // Load in the explosions data from the file 'explosions.json'
        d3.json("explosions.json", function(collection) {
            explosions
                .selectAll("path") //make a path and attach data
                .data(collection.features)
                .enter().append("path")
                .attr("d", path)
                .style("stroke","red") //color the path points
                .style("stroke-width",2) //size of point stroke
                .attr("class","explosionpoint")
                .append("title") //title is the 'name' field in the json file
                .text(function(d) { return d.properties.name; });
        });



    </script>

    <p></p>
    <!-- Slider -->
    <div id="scale"></div><p></p>
    <script type="text/javascript">

        $("#scale").slider({
        min: 20040101, //min : 1/1/04
        max: 20100101, //max: 1/1/10
        value: 20060601, //default slider value
        step: 100, // step is the allow increments the slider can move. 100 = one month
        slide: function(event, ui) {


            /* REMOVE ALL EXPLOSION PATHS EXCEPT FOR A PARTICULAR MONTH OR RELOAD WITH FILTERED RESULTS */
        }
        });

</script>

推荐答案

您需要张贴部分或全部 Explosions.json 对象以获得具体答案.但是,如果 JSON 的结构类似于 {explosion1:{data1:true, data2:true},blast2:{data1:true, data2:false}}:

You'll need to post part or all of your explosions.json object for a concrete answer. However, something like this will filter a JSON if it's structured like {explosion1:{data1:true, data2:true}, explosion2:{data1:true, data2:false}}:

function filterJSON(json, key, value) {
  var result = {};
  for (var explosionIndex in json) {
    if (json[explosionIndex][key] === value) {
      result[explosionIndex] = json[explosionIndex];
    }
  }
  return result;
}

(e.g. filterJSON(myjson, "data1", true) 将使用 data1:true 给出所有爆炸)

(e.g. filterJSON(myjson, "data1", true) will give all explosions with data1:true)

这不是特定于 d3.

然后你可以在 d3 方面使用这样的东西:

Then you could use something like this for the d3-side of things:

explosions.data(myFilteredData).exit().remove(); // remove ones you don't want
explosions.enter().append("path")... // add back ones you do want

<小时>

如果我了解您的应用程序,实际上只切换 SVG 元素的 visiblity 属性会更好.

var sliderrange = [20040101, 20040201]; //replace with code based on your slider
explosions.selectAll(".explosionpoint").attr("visibility", function(d) {
  //Replace with the correct date comparison logic
  return d.date < sliderrange[1] && d.date > sliderrange[0] ? "visible" : "hidden";
});

这篇关于D3 过滤数据点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆