Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
File renamed without changes.
Binary file added apps/__init__.pyc
Binary file not shown.
Binary file added apps/data_storage/__init__.pyc
Binary file not shown.
File renamed without changes.
Binary file added apps/data_storage/admin.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added apps/data_storage/migrations/__init__.pyc
Binary file not shown.
Binary file added apps/data_storage/models.pyc
Binary file not shown.
File renamed without changes.
File renamed without changes.
Binary file added apps/mapvisuals/__init__.pyc
Binary file not shown.
File renamed without changes.
Binary file added apps/mapvisuals/admin.pyc
Binary file not shown.
Binary file added apps/mapvisuals/lib/__init__.pyc
Binary file not shown.
15,090 changes: 15,090 additions & 0 deletions apps/mapvisuals/lib/states.py

Large diffs are not rendered by default.

Binary file added apps/mapvisuals/lib/states.pyc
Binary file not shown.
Binary file added apps/mapvisuals/migrations/__init__.pyc
Binary file not shown.
File renamed without changes.
Binary file added apps/mapvisuals/models.pyc
Binary file not shown.
15,087 changes: 15,087 additions & 0 deletions apps/mapvisuals/states.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
16 changes: 16 additions & 0 deletions apps/mapvisuals/static/mapvisuals/css/lib/materialize.min.css

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 4 additions & 0 deletions apps/mapvisuals/static/mapvisuals/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.tasks-container{
margin-bottom: 40px;
padding: 20px;
}
74 changes: 74 additions & 0 deletions apps/mapvisuals/static/mapvisuals/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<head>
<title>Project</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/css/lib/bootstrap.css">
<link rel="stylesheet" type="text/css" href="/css/lib/bootstrap-theme.css">
<link rel="stylesheet" type="text/css" href="/css/lib/bootstrap-social.css">
<link rel="stylesheet" type="text/css" href="/css/lib/font-awesome.css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="js/lib/leaflet-1.0.0-b1/leaflet.css">

<script src="/js/lib/jquery-1.9.1.js"></script>
<script src="/js/lib/jquery-ui.js"></script>
<script type="text/javascript" src="/js/lib/bootstrap.js"></script>
<script type="text/javascript" src="/js/lib/d3/d3.js"></script>

<!-- <script type="text/javascript" src="/socket.io/socket.io.js"></script> -->
<script type="text/javascript" src="/js/lib/angular/angular.js"></script>
<script type="text/javascript" src="/js/lib/angular/angular-route.js"></script>

<script type="text/javascript" src="/js/lib/leaflet-1.0.0-b1/leaflet-src.js"></script>
<script type="text/javascript" src="/js/modules/angular-leaflet-directive.js"></script>


<script type="text/javascript" src="/js/lib/heatmap/heatmap.min.js"></script>
<script type="text/javascript" src="/js/lib/heatmap/leaflet-heatmap.js"></script>
<script type="text/javascript" src="/js/lib/Leaflet.D3SvgOverlay/L.D3SvgOverlay.js"></script>
<script type="text/javascript" src="/js/modules/modules.js"></script>
<script type="text/javascript" src="/js/factories/factories.js"></script>
<script type="text/javascript" src="/js/controllers/controllers.js"></script>
<script type="text/javascript" src="/js/directives/directives.js"></script>
<script type="text/javascript" src="/js/services/services.js"></script>
<script type="text/javascript" src="/js/partialRoutes.js"></script>
<style>
#map {
width: 960px;
height: 500px;
}

svg {
position: relative;
}

path {
fill: grey;
fill-opacity: .2;
stroke: #fff;
stroke-width: 1.5px;
}

path:hover {
fill: brown;
fill-opacity: .7;
}

.container{
margin-top: 20px;
}

/*.point{
fill: orange;
fill-opacity: .7;
}*/

</style>
</head>
<body>
<div ng-app="app" class="container" ng-controller="MapController as main">
<leaflet event-broadcast="events" defaults="defaults" center="center" height="600px" width="1200px"></leaflet>
</div>
</body>
</html>
280 changes: 280 additions & 0 deletions apps/mapvisuals/static/mapvisuals/js/controllers/mapController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
app.controller('MapController', ['$scope', 'leafletData',

function($scope, leafletData) {

// Start the map zoomed in on the center of the country
//and add custom event listenters for our leaflet directive
angular.extend($scope, {
center: {
lat: 39.8282,
lng: -98.5795,
zoom: 4,
},
events: {
map: {
enable: ['zoomstart', 'zoomend'],
logic: 'emit'
}
}
});

/*********************************************************
MAP INITIALIZATIONS
*********************************************************/
// Grabs our map objects as a promise and then adds a click handler and runs our
// d3Map function which generates our d3 overlay.
d3.json("/statedata", function(stateData) {
console.log(stateData);
d3.json("/mapdata", function(jobsData){
leafletData.getMap().then(function(map) {
// var popup = L.popup();

function onMapClick(e) {
popup.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}

// map.on('click', onMapClick);
d3Map(map);
});


/*********************************************************
MAP EVENT HANDLERS
*********************************************************/
// This uses the custom event handlers that we registered at the top
//of the document to clear out the old svg and redraw it when the map
//is zoomed in or out.

$scope.$on('leafletDirectiveMap.zoomstart', function(event){
d3.selectAll('svg').remove();
$scope.$on('leafletDirectiveMap.zoomend', function(event){
leafletData.getMap().then(function(map){
map.getPanes().overlayPane.innerHTML = "";
d3.select(".tooltip").innerHTML = "";
d3Map(map);
});
});
});


/*********************************************************
D3 STUFFS
*********************************************************/
// MAP DRAWING FUNCTION
function d3Map(map){

//-------------------D3 INITIALIZATION--------------------//

// Main SVG which sits in the leaflet overlay pane
var svg = d3.select(map.getPanes().overlayPane).append("svg");

// This is the group which will contain all of our svg elements for our map overlay
var g = svg.append("g").attr("class", "leaflet-zoom-hide");
var transform = d3.geo.transform({point: projectPoint});
var path = d3.geo.path().projection(transform);

// This is the functionality that allows our dots to be correctly projected onto the map
//The function in our point radius method will use what we pass in below in our radius key in our
//datum method to our projection to draw the dots.
var g2 = svg.append("g").attr("class", "leaflet-zoom-hide");
var feature2 = g2.selectAll("path.point");
var transform2 = d3.geo.transform({point: projectPoint});
var path2 = d3.geo.path().projection(transform2).pointRadius(function(d){
var zoom = map.getZoom();
if(zoom < 5){
return Math.min(((d.radius + zoom) * 0.08), 10);
}else if( zoom >= 5 && zoom < 7){
return Math.min(((d.radius + zoom) * 0.09), 36);
} else if(zoom >= 7 && zoom < 10){
return Math.max(((d.radius + zoom) * 0.038), 5);
} else{
return Math.max(((d.radius + zoom) * 0.028), 5);
}
});

// This sets up our color and range to map the various color to different points based
//on job availability per point
var colors = ["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB",
"#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63",
"#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"];

var heatmapColor = d3.scale.linear()
.domain(d3.range(0, 1, 1.0 / (colors.length-1)))
.range(colors);

var range = [];
for(var i=0; i<jobsData.features.length; i++){
console.log(jobsData.features[i].properties.numJobs);
range.push(jobsData.features[i].properties.numJobs);
}
var c = d3.scale.linear().domain(d3.extent(range)).range([0,9]);


function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}

// Helper function to create the tooltip **taken directly form Mike Bostock
d3.helper = {};
d3.helper.tooltip = function(accessor){
return function(selection){
var tooltipDiv;
var bodyNode = d3.select('body').node();
selection.on("mouseover", function(d, i){
// Clean up lost tooltips
d3.select('body').selectAll('div.tooltip').remove();
// Append tooltip
tooltipDiv = d3.select('body').append('div').attr('class', 'tooltip');
var absoluteMousePos = d3.mouse(bodyNode);
tooltipDiv.style('left', (absoluteMousePos[0] + 10)+'px')
.style('top', (absoluteMousePos[1] - 15)+'px')
.style('position', 'absolute')
.style('z-index', 1001);
// Add text using the accessor function
var tooltipText = accessor(d, i) || '';
// Crop text arbitrarily
//tooltipDiv.style('width', function(d, i){return (tooltipText.length > 80) ? '300px' : null;})
// .html(tooltipText);
})
.on('mousemove', function(d, i) {
// Move tooltip
var absoluteMousePos = d3.mouse(bodyNode);
tooltipDiv.style('left', (absoluteMousePos[0] + 10)+'px')
.style('top', (absoluteMousePos[1] - 15)+'px');
var tooltipText = accessor(d, i) || '';
tooltipDiv.html(tooltipText);
})
.on("mouseout", function(d, i){
// Remove tooltip
tooltipDiv.remove();
});

};
};

//^^^^^^^^^^^^^^^^^^^^^^^END INITIALIZATION^^^^^^^^^^^^^^^^^^^^^^^^^//


//----------------APPEND NEW SVG ELEMENTS TO DOM-------------------//
// This runs through our geo-JSON file containing the data for the state overlays
var stateColors = d3.scale.linear()
.domain(d3.range(0, 1, 1.0 / (colorbrewer.Accent['7'].length-1)))
.range(colorbrewer.Accent['7']);

var newRange = [100, 1200];

var colorRange = d3.scale.linear().domain(d3.extent(newRange)).range([0,1]);
colorRange.clamp(true);
var zoom = map.getZoom();

var feature = g.selectAll("path")
.data(stateData.features)
.enter()
.append("path")
.attr("class", "state")
.attr("fill-opacity", function(d){
if( zoom < 5){
return 0.8;
}else if( zoom <= 6){
return 0.6;
} else if(zoom >=6 && zoom < 7){
return 0.3;
} else if (zoom >= 7 && zoom < 8){
return 0.2;
} else if (zoom >= 8 && zoom < 9){
return 0.1;
} else {
return 0;
}
})
// .style("fill", function(d) {
// if(d.properties.numJobs < 2900){
// return stateColors(colorRange(d.properties.numJobs));
// } else if(!d.properties.numJobs){
// return "lightblue";
// } else{
// return "red";
// }
// })
.attr("fill", "#000")
.attr("stroke", function(d){
if(zoom >= 9){
return "#666";
} else {
return "#fff";
}
})
.attr("stroke-width", function(d){
if(zoom >= 9){
return "2";
}
});

// Where our job data is actually put into SVG form and appended to the DOM
feature2.data(jobsData.features)
.enter()
.append("path")
.call(d3.helper.tooltip(function(d, i){
return "<b>"+d.name + "</b><br/>Jobs: "+d.radius;
}))
.style("fill", function(d) {
return heatmapColor(c(d.properties.numJobs));
})
.datum(function(d){
return {type: "Point", coordinates: [d.geometry.coordinates[1], d.geometry.coordinates[0]], radius: d.properties.numJobs, name:d.properties.name};
})
.attr("class", "point")
.attr("d", path2);

//^^^^^^^^^^^^^^^^^^^^^^^END DATA/APPEND^^^^^^^^^^^^^^^^^^^^^^^//



//-------------------CLEAN UP-------------------//
//Reposition our SVG's on zoom in/out
map.on("viewreset", reset);
reset();

function reset() {
var bounds = path.bounds(stateData),
topLeft = bounds[0],
bottomRight = bounds[1];

svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");

g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
g2.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
feature.attr("d", path);
feature2.attr("d", path2);

} //End reset
} //End D3Map
}); // End D3.json for mapdata
}); // End D3.json for statedata
} // End main controller function
]); // End controller wrapper



















Loading