Skip to content

Commit

Permalink
Merge pull request #88 from cmgiven/enhanced-school-view
Browse files Browse the repository at this point in the history
Enhanced school view
  • Loading branch information
HarlanH committed Oct 19, 2013
2 parents 7db09fa + 3899bbc commit d53490e
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 37 deletions.
69 changes: 46 additions & 23 deletions public/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ var data,
// A Leaflet geoJSON layer containing all of the neighborhood clusters.
//
// map.edges
// A layergroup for the edge polylines. Clear with map.edges.clearLayers().
// A featuregroup for the edge polylines. Clear with map.edges.clearLayers().
//
// map.boundaries
// A layergroup for school boundary polygons. Clear with map.boundaries.clearLayers().
// A featuregroup for school boundary polygons. Clear with map.boundaries.clearLayers().
//
// map.infobox
// A Leaflet control for tooltip info. Update with map.infobox.update(string).
Expand All @@ -79,6 +79,10 @@ var data,
//
// utils.lineOpacity(number)
// Returns the corresponding opacity for a given value.
//
// utils.zeroPad(number, length)
// Returns a string, adding leading zeros to achieve length if necessary.
// h/t http://stackoverflow.com/a/1268377

onHashChange,
currentPage,
Expand Down Expand Up @@ -122,7 +126,6 @@ var data,
delete globalFilter.school_code;
globalFilter.cluster = id;
}
map.displayEdges(globalFilter);
}

templates[page].update(globalFilter);
Expand Down Expand Up @@ -251,17 +254,23 @@ var data,
return (_.keys(filter).length > 0) ? _.where(edges, filter) : edges;
},
boundary: function (schoolCode) {
var level,
llOrder = ["lng", "lat"],
var level, matches,
school = data.schools({"school_code": schoolCode})[0];
if (!school.charter_status) {
level = school.elementary ? "es" : school.middle ? "ms" : "shs";
if (!boundaries[level]) { getBoundaries(level); }
return _(_.where(boundaries[level].features,
{"properties": {"BLDG_NUM": schoolCode}})[0].geometry.coordinates[0])
.initial()
.map(function (coords) { return _.zipObject(llOrder, coords); })
.value();
matches = _.where(boundaries[level].features, {
"properties": {"BLDG_NUM": schoolCode}
});
if (matches.length === 1) {
return _(matches[0].geometry.coordinates[0])
// Leaflet doesn't like polygons to repeat the first coordinate, so we drop it.
.initial()
// Now we need to reverse the ordering of each latitude/longitude pair.
.map(function (coords) { return [coords[1], coords[0]]; })
// And now let's get our value back from Lo-dash.
.value();
}
}
return [];
}
Expand Down Expand Up @@ -311,8 +320,8 @@ var data,
}
}).addTo(this);

this.edges = L.layerGroup().addTo(this);
this.boundaries = L.layerGroup().addTo(this);
this.edges = L.featureGroup().addTo(this);
this.boundaries = L.featureGroup().addTo(this);

this.infobox = L.control();
this.infobox.onAdd = function () {
Expand Down Expand Up @@ -349,19 +358,19 @@ var data,
Map.prototype.displayEdges = function (filter, animation) {
var highlight, reset, click,
map = this,
layerGroup = this.edges,
featureGroup = this.edges,
edges = _.sortBy(data.edges(filter), "count");

if (!animation) { this.edges.clearLayers(); }

highlight = function (e) {
var layer = e.target;
var layer = e.layer;
layer.setStyle({ weight: layer.options.weight + 3, opacity: 1 });
map.infobox.update(layer.options.text);
};

reset = function (e) {
var layer = e.target;
var layer = e.layer;
layer.setStyle({
weight: layer.options.orig_weight,
opacity: layer.options.orig_opacity
Expand All @@ -371,9 +380,9 @@ var data,

click = function (e) {
if (currentPage !== "school") {
window.location.hash = "#!/school/" + e.target.options.school_code;
window.location.hash = "#!/school/" + e.layer.options.school_code;
} else {
window.location.hash = "#!/neighborhood/" + e.target.options.cluster_id;
window.location.hash = "#!/neighborhood/" + e.layer.options.cluster_id;
}
};

Expand Down Expand Up @@ -402,26 +411,31 @@ var data,
text: text
});

lineseg.addTo(layerGroup);
lineseg.addTo(featureGroup);

if (!animation) {
lineseg.on({ mouseover: highlight, mouseout: reset, click: click });
}
}
});

if (!animation) { this.legend.show(); }
if (!animation) {
this.fitBounds(featureGroup.getBounds());
this.legend.show();
}
};

Map.prototype.displayBoundary = function (schoolCode) {
var boundary,
map = this,
layerGroup = this.edges,
featureGroup = this.boundaries,
geometry = data.boundary(schoolCode);

boundary = L.polygon(geometry);
boundary = L.polygon(geometry, { color: "#BD0026" });

boundary.addTo(layerGroup);
featureGroup.clearLayers();
boundary.addTo(featureGroup);

this.fitBounds(featureGroup.getBounds());
};

Map.prototype.animate = function () {
Expand Down Expand Up @@ -509,6 +523,15 @@ var data,

lineOpacity: function (d) {
return d < 2 ? 0.4 : d < 100 ? 0.4 + (d / 200.0) * 0.5 : 0.9;
},

zeroPad: function (num, numZeros) {
var n = Math.abs(num),
zeros = Math.max(0, numZeros - Math.floor(n).toString().length ),
zeroString = Math.pow(10,zeros).toString().substr(1);
if (num < 0) { zeroString = '-' + zeroString; }

return zeroString+n;
}
};

Expand Down
4 changes: 4 additions & 0 deletions public/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@

#map.static {
cursor: default;
}

.nav-pills a:not(.disabled) {
cursor: pointer;
}
88 changes: 74 additions & 14 deletions public/templates.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*jslint browser: true*/
/*jslint nomen: true*/
/*global $, _, map, data, globalFilter*/
/*global $, _, map, data, utils, globalFilter*/

var templates;

Expand Down Expand Up @@ -74,18 +74,18 @@ var templates;
t: ["<b>Select a school from the dropdown menu to see where its students commute from.</b>",
"<div><b>Choose which schools are available through the dropdown menu using the buttons.</b></div>",
"<p>",
"<div id='systembuttons' class='btn-group' data-toggle='buttons-checkbox'>",
"<div id='systembuttons' class='btn-group filters' data-toggle='buttons-checkbox'>",
"<button value='charter' id='charter' type='button' class='btn btn-primary active'>Charter</button>",
"<button value='dcps' id='dcps' type='button' class='btn btn-primary active'>DCPS</button>",
"</div>",
"<div id='levelsbuttons' class='btn-group' data-toggle='buttons-checkbox'>",
"<div id='levelsbuttons' class='btn-group filters' data-toggle='buttons-checkbox'>",
"<button value='elementary' id='elementary' type='button' class='btn btn-primary active'>Elementary</button>",
"<button value='middle' id='middle' type='button' class='btn btn-primary active'>Middle</button>",
"<button value='high' id='high' type='button' class='btn btn-primary active'>High</button>",
"</div>",
"</p>",
"<p>",
"<div id='wardsbuttons' class='btn-group' data-toggle='buttons-radio'>",
"<div id='wardsbuttons' class='btn-group filters' data-toggle='buttons-radio'>",
"<button name='ward' value='allwards' id='allwards' type='button' class='btn active'> All Wards</button>",
"<button name='ward' value='w1' id='w1' type='button' class='btn'> 1</button>",
"<button name='ward' value='w2' id='w2' type='button' class='btn'> 2</button>",
Expand All @@ -97,14 +97,46 @@ var templates;
"<button name='ward' value='w8' id='w8' type='button' class='btn'> 8</button>",
"</div>",
"</p>",
"<select id='schoolsList' name='schoolsList'></select>"].join("\n"),
"<select id='schoolsList' name='schoolsList'></select>",
"<div id='school-info'></div>",
"<div id='map-views-toggle' style='display: none; margin-top: 20px;'>",
"<h4>View map data on&hellip;</h4>",
"<ul class='nav nav-pills nav-stacked'>",
"<li id='map-views-commutes' class='active'><a>Where this schools' students live</a></li>",
"<li id='map-views-zones' class='disabled'><a>What areas are zoned for this school</a></li>",
"</ul>",
"</div>"].join("\n"),
schoolInfo: _.template([
"<h1><%= school.school_name %></h1>",
"<p><%= school.school_address %></p>",
"<p>",
"<a href='http://www.learndc.org/schoolprofiles/view#<%= utils.zeroPad(school.school_code, 4) %>/overview' target='_blank'>",
"Explore information about <%= school.school_name %> on LearnDC",
"</a>",
"</p>"
].join("\n"), null, { 'variable': 'school' }),
init: function () {
updateButtonStatus();
$(".btn-group").on("click.school", "button", function (e) { updateFilters(e); templates.school.update(); });
$(".filters").on("click.school", "button", function (e) { updateFilters(e); templates.school.update(); });
$("#map-views-commutes").on("click.school", "a", function (e) {
if (!$(e.delegateTarget).hasClass("disabled")) {
$(e.delegateTarget).addClass("active");
$("#map-views-zones").removeClass("active");
map.boundaries.clearLayers();
map.displayEdges(globalFilter);
}
});
$("#map-views-zones").on("click.school", "a", function (e) {
if (!$(e.delegateTarget).hasClass("disabled")) {
$(e.delegateTarget).addClass("active");
$("#map-views-commutes").removeClass("active");
map.edges.clearLayers();
map.displayBoundary(globalFilter.school_code);
}
});
$('#schoolsList').on("change.school", function () {
window.location.hash = "#!/school/" + parseInt($('#schoolsList').find(":selected").attr("id"), 10);
});
templates.school.update();
},
update: function () {
var $select = $('#schoolsList');
Expand All @@ -116,10 +148,31 @@ var templates;
$("#schoolsList option[id='" + globalFilter.school_code + "']").prop('selected', true);
}
});
if (globalFilter.school_code) {
var boundary = data.boundary(globalFilter.school_code);
$("#school-info").html(this.schoolInfo(data.schools({ "school_code": globalFilter.school_code })[0]));
$("#map-views-toggle").show();
if (boundary.length > 0) {
$("#map-views-zones").removeClass("disabled");
} else {
$("#map-views-zones").addClass("disabled");
$("#map-views-zones").removeClass("active");
$("#map-views-commutes").addClass("active");
map.boundaries.clearLayers();
}
if ($("#map-views-zones").hasClass("active")) {
map.displayBoundary(globalFilter.school_code);
} else {
map.displayEdges({ "school_code": globalFilter.school_code });
}
} else {
$("#map-views-toggle").hide();
}
},
strike: function () {
$(".btn-group").off(".school");
$(".filters").off(".school");
map.edges.clearLayers();
map.boundaries.clearLayers();
delete globalFilter.school_code;
delete globalFilter.ward;
}
Expand All @@ -128,25 +181,32 @@ var templates;
t: ["<b>Click a neighborhood to see where its students attend school.</b>",
"<div><b>Use the buttons to hide various school types.</b></div>",
"<p>",
"<div id='systembuttons' class='btn-group' data-toggle='buttons-checkbox'>",
"<div id='systembuttons' class='btn-group filters' data-toggle='buttons-checkbox'>",
"<button value='charter' id='charter' type='button' class='btn btn-primary active'>Charter</button>",
"<button value='dcps' id='dcps' type='button' class='btn btn-primary active'>DCPS</button>",
"</div>",
"<div id='levelsbuttons' class='btn-group' data-toggle='buttons-checkbox'>",
"<div id='levelsbuttons' class='btn-group filters' data-toggle='buttons-checkbox'>",
"<button value='elementary' id='elementary' type='button' class='btn btn-primary active'>Elementary</button>",
"<button value='middle' id='middle' type='button' class='btn btn-primary active'>Middle</button>",
"<button value='high' id='high' type='button' class='btn btn-primary active'>High</button>",
"</div>",
"</p>"].join("\n"),
"</p>",
"<div id='neighborhood-info'></div>"].join("\n"),
neighborhoodInfo: _.template([
"<h1><%= neighborhood.NBH_NAMES %></h1>"
].join("\n"), null, { 'variable': 'neighborhood' }),
init: function () {
updateButtonStatus();
$(".btn-group").on("click.neighborhood", "button", function (e) { updateFilters(e); templates.neighborhood.update(); });
$(".filters").on("click.neighborhood", "button", function (e) { updateFilters(e); this.update(); });
},
update: function () {
if (globalFilter.cluster) { map.displayEdges(globalFilter); }
if (globalFilter.cluster) {
$("#neighborhood-info").html(this.neighborhoodInfo(_.where(data.clusters().features, {"id": globalFilter.cluster})[0].properties));
map.displayEdges(globalFilter);
}
},
strike: function () {
$(".btn-group").off(".neighborhood");
$(".filters").off(".neighborhood");
map.edges.clearLayers();
delete globalFilter.cluster;
}
Expand Down

0 comments on commit d53490e

Please sign in to comment.