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>
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}}:(e.g.
filterJSON(myjson, "data1", true)will give all explosions with data1:true)This is not specific to d3.
Then you could use something like this for the d3-side of things:
If I understand your application, it would actually be better to just toggle the
visiblityattribute of the SVG elements.