Skip to content

Commit 85173f8

Browse files
committed
added more examples
1 parent a579c9a commit 85173f8

File tree

6 files changed

+266
-65
lines changed

6 files changed

+266
-65
lines changed

public/data/cb_2014_us_county_20m.json

+1
Large diffs are not rendered by default.

public/javascripts/examples.js

+231-49
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,238 @@
1-
// to see this example, run mapquery and go to localhost:3000/examples
1+
/**
2+
* Three ways you can use Mapquery data
3+
*
4+
* The Mapquery search page allows you to output data in several ways.
5+
* You can save an SVG, save raw map data, or use the API call Mapquery
6+
* generates based on your search parameters. Here's how you might use
7+
* each of those output options together with real-world data to make a graphic.
8+
*
9+
* To provide a full demo of each method, each section below is independent
10+
* from the others, so you'll notice a lot of repition in each.
11+
*
12+
* Static files used:
13+
* data/cb_2014_us_county_20m.svg is topojson data exported from mapquery
14+
* data/cb_2014_us_county_20m.json is topojson data exported from mapquery
15+
* data/worker-gender.csv is data from the us census on worker gender by county
16+
*/
217

18+
// establish some globals
319
var color = d3.scale.threshold()
420
.domain([40,42,44,46,48,50])
5-
.range(['#a3d3f0','#8cbad8','#74a2bf','#5d8ba9','#467492','#2f5e7c','#154866']);
21+
.range(['#a3d3f0','#8cbad8','#74a2bf','#5d8ba9','#467492','#2f5e7c','#154866']),
22+
width = 940,
23+
height = 500;
624

7-
// add static svg to #map-1 div
8-
d3.xml("data/cb_2014_us_county_20m.svg", "image/svg+xml", function(xml){
9-
var mapContainer = d3.select("#map-1");
10-
mapContainer.node().appendChild(xml.documentElement);
11-
var svg = d3.select("svg").attr("id","map-svg");
25+
//
26+
// Example 1: Bind data to static SVG
27+
//
1228

13-
// then load mappable data
14-
d3.csv("data/worker-gender.csv",function(error,data){
29+
function staticSvg() {
30+
// add static svg to #map-1 div
31+
d3.xml("data/cb_2014_us_county_20m.svg", "image/svg+xml", function(xml){
32+
var mapContainer = d3.select("#map-1");
33+
mapContainer.node().appendChild(xml.documentElement);
34+
var svg = d3.select("svg").attr("id","map-svg");
1535

16-
d3.map(data, function(d) {
17-
d.fips = d3.format("05d")(d.fips);
18-
d.femalePct = (+d.female_total/+d.pop_total)*100;
36+
// load mappable data
37+
d3.csv("data/worker-gender.csv",function(error,data){
38+
39+
// format some fields in the census data
40+
data.forEach(function(d){
41+
d.fips = d3.format("05d")(d.fips);
42+
d.femalePct = (+d.female_total/+d.pop_total)*100;
43+
});
44+
45+
// create a selector by the fips field in the census data
46+
// fips is a five-digit unique ID for each county
47+
var dataByFips = d3.nest()
48+
.key(function(d){ return d.fips })
49+
.map(data);
50+
51+
// loop through SVG's path elements
52+
var countyPaths = svg.selectAll("path")
53+
.each(function(d){
54+
55+
// get the id from the path element,
56+
// which mapquery sets with a given dataset's
57+
// unique identifier. in this case, fips code.
58+
// note that mapquery prepends a letter to the id,
59+
// which you should remove to get the code
60+
var id = d3.select(this).attr("id").substr(1);
61+
62+
// then look for matches between the fips code from the id
63+
// and the fips code in the data we've loaded
64+
// bind that datum when a match is found
65+
var datum = (typeof dataByFips[id] !== "undefined") ? dataByFips[id][0] : {};
66+
d3.select(this).datum(datum);
67+
68+
})
69+
.style("fill",function(d){
70+
// then use the bound datum to set the fill of each path
71+
if (dataByFips[d.fips]) return color(+dataByFips[d.fips][0].femalePct);
72+
});
1973
});
74+
});
75+
}
76+
staticSvg();
2077

21-
var dataByFips = d3.nest()
22-
.key(function(d){ return d.fips })
23-
.map(data);
24-
25-
// loop through SVG's path elements
26-
var countyPaths = svg.selectAll("path")
27-
.each(function(d){
28-
29-
// get the id from the path element,
30-
// which mapquery sets with a given dataset's
31-
// unique identifier. in this case, fips code.
32-
// note that mapquery prepends a letter to the id,
33-
// which you should remove to get the code
34-
var id = d3.select(this).attr("id").substr(1);
35-
36-
// then look for matches between the fips code from the id
37-
// and the fips code in the data we've loaded
38-
// bind that datum when a match is found
39-
var datum = (typeof dataByFips[id] !== "undefined") ? dataByFips[id][0] : {};
40-
d3.select(this).datum(datum);
78+
//
79+
// Example 2: Load data from static topojson file
80+
//
4181

42-
})
43-
.style("fill",function(d){
44-
// then use the bound datum to set the fill of each path
45-
if (dataByFips[d.fips]) return color(+dataByFips[d.fips][0].femalePct);
46-
});
82+
// we're using queue to load our two static data files
83+
queue()
84+
.defer(d3.json, "data/cb_2014_us_county_20m.json")
85+
.defer(d3.csv, "data/worker-gender.csv")
86+
.await(loadStaticData);
87+
88+
function loadStaticData(err, mapData, workerData) {
89+
90+
// append an svg
91+
var svg = d3.select("#map-2").append("svg:svg")
92+
.attr("id","map-2-svg")
93+
.attr("width", width)
94+
.attr("height", height);
95+
96+
// format some fields in the census data
97+
workerData.forEach(function(d){
98+
d.fips = d3.format("05d")(d.fips);
99+
d.femalePct = (+d.female_total/+d.pop_total)*100;
47100
});
48-
});
49101

50-
instaScale(color,600);
102+
// create a selector by the fips field in the census data
103+
// fips is a five-digit unique ID for each county
104+
var dataByFips = d3.nest()
105+
.key(function(d){ return d.fips })
106+
.map(workerData);
107+
108+
// get the name of the field in our map data
109+
// that is denoted as a unique identifier
110+
// in the metadata table.
111+
// in this case, we know it's fips, but this
112+
// is how we can get the field dynamically
113+
var uniqueFld = (mapData.table_metadata.fld_identifier) ? mapData.table_metadata.fld_identifier : "name";
114+
115+
// setup the projection using the handy
116+
// metadata mapquery provided
117+
var projection = d3.geo[mapData.projection]()
118+
.scale(mapData.scale)
119+
.translate(mapData.translate);
120+
121+
var path = d3.geo.path()
122+
.projection(projection);
123+
124+
// explicitly select the toposon map units.
125+
// for geojson it would be in data.map.features
126+
var units = mapData.map.objects.features;
127+
128+
// append each county path
129+
svg.selectAll(".units-2")
130+
.data(units)
131+
.enter().append("path")
132+
.attr("class","units-2")
133+
.attr("id",function(d) { return "u"+d.properties[uniqueFld]; })
134+
.attr("d", path)
135+
.style("fill",function(d){
136+
// get the fips code, the unique id, from this path's properties
137+
var fips = d3.format("05d")(d.properties[uniqueFld]);
138+
// select the census data by the fips code
139+
// when there's a match, set a color based on
140+
// the percentage of female workers in that county
141+
if (dataByFips[fips]) return color(+dataByFips[fips][0].femalePct);
142+
});
143+
144+
}
145+
146+
//
147+
// Example 3: Load data directly from the API
148+
//
51149

52-
function instaScale(colorScale,w) {
150+
// we're using queue to load our two static data files.
151+
// cb_2014_us_county_20m.json is topojson data exported from mapquery
152+
// worker-gender.csv is data from the us census on worker gender by county
153+
queue()
154+
.defer(d3.json, "/api/feature-collection?table=cb_2014_us_county_20m&field_value=&proj=albersUsa&width=940&height=500&datatype=topojson")
155+
.defer(d3.csv, "data/worker-gender.csv")
156+
.await(loadApiData);
157+
158+
function loadApiData(err, result, workerData) {
159+
160+
// append an svg
161+
var svg = d3.select("#map-3").append("svg:svg")
162+
.attr("id","map-3-svg")
163+
.attr("width", width)
164+
.attr("height", height);
165+
166+
// format some fields in the census data
167+
workerData.forEach(function(d){
168+
d.fips = d3.format("05d")(d.fips);
169+
d.femalePct = (+d.female_total/+d.pop_total)*100;
170+
});
171+
172+
// create a selector by the fips field in the census data
173+
// fips is a five-digit unique ID for each county
174+
var dataByFips = d3.nest()
175+
.key(function(d){ return d.fips })
176+
.map(workerData);
177+
178+
// grap the map data from the API result
179+
var mapData = result.data;
180+
181+
// get the name of the field in our map data
182+
// that is denoted as a unique identifier
183+
// in the metadata table.
184+
// in this case, we know it's fips, but this
185+
// is how we can get the field dynamically
186+
var uniqueFld = (mapData.table_metadata.fld_identifier) ? mapData.table_metadata.fld_identifier : "name";
187+
188+
// setup the projection using the handy
189+
// metadata mapquery provided
190+
var projection = d3.geo[mapData.projection]()
191+
.scale(mapData.scale)
192+
.translate(mapData.translate);
193+
194+
var path = d3.geo.path()
195+
.projection(projection);
196+
197+
// explicitly select the topojson map units.
198+
// for geojson it would be in data.map.features
199+
var units = mapData.map.objects.features;
200+
201+
// append each county path
202+
svg.selectAll(".units-3")
203+
.data(units)
204+
.enter().append("path")
205+
.attr("class","units-3")
206+
.attr("id",function(d) { return "u"+d.properties[uniqueFld]; })
207+
.attr("d", path)
208+
.style("fill",function(d){
209+
// get the fips code, the unique id, from this path's properties
210+
var fips = d3.format("05d")(d.properties[uniqueFld]);
211+
// select the census data by the fips code
212+
// when there's a match, set a color based on
213+
// the percentage of female workers in that county
214+
if (dataByFips[fips]) return color(+dataByFips[fips][0].femalePct);
215+
});
216+
217+
}
218+
219+
//
220+
// Below we just call a nifty/weird little function
221+
// that dynamically creates and appends a key
222+
// to represent an arbitrary scale.
223+
//
224+
// This is not part of the demo, but feel free
225+
// to try it out and let us know if you make improvements to it!
226+
//
227+
228+
instaScale(color,600,"scale-1");
229+
instaScale(color,600,"scale-2");
230+
instaScale(color,600,"scale-3");
231+
232+
function instaScale(colorScale,w,div) {
53233
w = (w < 300) ? 300 : w;
54234

55-
var svgScale = d3.select("#scale-1").append("svg")
235+
var svgScale = d3.select("#"+div).append("svg")
56236
.attr("width", w)
57237
.attr("height", 100);
58238

@@ -62,7 +242,7 @@ function instaScale(colorScale,w) {
62242
.domain(scaleDomain)
63243
.range([10, w-10]);
64244

65-
svgScale.selectAll(".scale-rects")
245+
svgScale.selectAll("."+div+"-rects")
66246
.data(colorScale.range().map(function(d, i) {
67247
return {
68248
x0: i ? x(colorScale.domain()[i - 1]) : x.range()[0],
@@ -71,28 +251,28 @@ function instaScale(colorScale,w) {
71251
};
72252
}))
73253
.enter().append("rect")
74-
.attr("id",function(d,i){ return "scale-"+i; })
75-
.attr("class","scale-rects")
254+
.attr("id",function(d,i){ return div+"-"+i; })
255+
.attr("class",div+"-rects")
76256
.attr("width", function(d) { return d.x1 - d.x0-5; })
77257
.attr("height", 17.5)
78258
.attr("x", function(d) { return d.x0; })
79259
.attr("y",25)
80260
.style("fill", function(d) { return d.z; });
81261

82262
svgScale.append("text")
83-
.attr("class","arrow-labels")
84263
.attr("x",10)
85264
.attr("y",15)
86-
.text("Share of female workers");
265+
.text("Share of female workers")
266+
.style("font-family","'AdelleSans-Bold', Helvetica, Arial, sans-serif");
87267

88-
svgScale.selectAll(".scale-labels")
268+
svgScale.selectAll("."+div+"-labels")
89269
.data(colorScale.range().map(function(d, i) {
90270
return {
91271
x0: i ? x(colorScale.domain()[i - 1]) : x.range()[0],
92272
};
93273
}))
94274
.enter().append("text")
95-
.attr("class","scale-labels")
275+
.attr("class",div+"-labels")
96276
.attr("x", function(d,i) { if (i == 0) { return d.x0-5; } else { return d.x0-10; } })
97277
.attr("y",60)
98278
.text(function(d,i){
@@ -104,5 +284,7 @@ function instaScale(colorScale,w) {
104284
} else {
105285
return l;
106286
}
107-
});
287+
})
288+
.style("font-family","'AdelleSans-Regular', 'Helvetica Neue', Arial, Helvetica, sans-serif")
289+
.style("font-size","14px");
108290
}

public/javascripts/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
//
2+
// this is the js for the mapquery search page.
3+
// to see examples for using mapquery,
4+
// check out public/javascripts/examples.js instead
5+
//
6+
17
var projections = [
28
"kavrayskiy7",
39
"mercator",

public/stylesheets/index.css

+7-8
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,13 @@ select {
195195
width: 100%;
196196
text-align: center;
197197
}
198+
.examples-container {
199+
margin-top: 100px;
200+
width: 100%;
201+
}
202+
.example-scale {
203+
text-align: center;
204+
}
198205

199206
.radio-label {
200207
margin-left: 5px;
@@ -341,12 +348,4 @@ label.enabled span {
341348
.units {
342349
stroke: #999;
343350
fill: #ddd;
344-
}
345-
346-
.arrow-labels {
347-
font-family: 'AdelleSans-Bold', "Helvetica", Arial, sans-serif;
348-
}
349-
.scale-labels {
350-
font-family: 'AdelleSans-Regular', 'Helvetica Neue', Arial, Helvetica, sans-serif;
351-
font-size: 14px;
352351
}

0 commit comments

Comments
 (0)