Last active
August 29, 2015 13:56
-
-
Save wboykinm/9144571 to your computer and use it in GitHub Desktop.
map.js, still perched between angular and jquery dependencies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var mapModule = angular.module('mapModule', []); | |
mapModule.controller('mapCtrl', ['$scope', function($scope){ | |
//do nothing | |
}]); | |
mapModule.directive('map', function(){ | |
var mobile = (window.devicePixelRatio > 1); | |
var desktopMapId = "faraday2.hb90naie"; | |
var mobileMapId = "landplanner.hajfpk7a"; | |
var desktopRefId = "faraday2.hb927i5h"; | |
var mobileRefId = "faraday2.hb92k1l3"; | |
var currentMapId = (mobile) ? mobileMapId : desktopMapId; | |
var currentRefId = (mobile) ? mobileRefId : desktopRefId; | |
return { | |
restrict: 'E', | |
link: function(scope, element, attrs){ | |
// Build map, set baselayers | |
var map = L.mapbox.map(element[0], currentMapId, { | |
detectRetina: true, | |
zoomControl: false //take away the zoom controls on the top left | |
}); | |
map.setView([43.073, -89.401], 11); | |
if (!mobile) { | |
//add zoom controls on the top right if we're not on mobile | |
new L.Control.Zoom({ position: 'topright' }).addTo(map); | |
} | |
// Adding choropleth tiles here, visible to zoom 14 | |
cartodb.createLayer(map, { | |
user_name: 'faraday', | |
type: 'cartodb', | |
cartodb_logo: false, | |
sublayers: [{ | |
sql: "SELECT * FROM dane_county_tracts", | |
cartocss: "#table_name [zoom<14][aland>0]{polygon-opacity: 0.8;line-color: #FFF;line-width: 0;line-opacity: 0;[mean_hh_inc <= 86839]{polygon-fill: #333333;}[mean_hh_inc <= 77010]{polygon-fill: #3c4745;}[mean_hh_inc <= 66569]{polygon-fill: #465b56;}[mean_hh_inc <= 53669]{polygon-fill: #537165;}[mean_hh_inc <= 45069]{polygon-fill: #658672;}[mean_hh_inc <= 38652]{polygon-fill: #7d9b7a;}[mean_hh_inc <= 34652]{polygon-fill: #99af7d;}[mean_hh_inc <= 29881]{polygon-fill: #bdc277;}[mean_hh_inc <= 11409]{polygon-fill: #e9d362;}}" | |
}] | |
}).addTo(map) | |
// ADD THE REFERENCE OVERLAY (THE TOP OF THE SANDWICH) HERE: | |
var topPane = map._createPane('leaflet-top-pane', map.getPanes().mapPane); | |
var topLayer = new L.mapbox.tileLayer(currentRefId).addTo(map); | |
topPane.appendChild(topLayer.getContainer()); | |
topLayer.setZIndex(7); | |
////////Playing with d3 fire ////////// | |
function addMask(svg, prefix, x, y, offset) { | |
var gradient = svg.append('defs') | |
.append('linearGradient') | |
.attr('id', prefix + 'Gradient') | |
.attr('gradientUnits', 'objectBoundingBox') | |
.attr('x2', x) | |
.attr('y2', y) | |
gradient.append('stop') | |
.attr('offset', offset) | |
.attr('stop-color', 'white') | |
.attr('stop-opacity', 1) | |
gradient.append('stop') | |
.attr('offset', offset + 0.1) | |
.attr('stop-color', 'white') | |
.attr('stop-opacity', 0) | |
var mask = svg.select('defs') | |
.append('mask') | |
.attr('id', prefix + 'Mask') | |
.attr('maskUnits', 'objectBoundingBox') | |
.attr('maskContentUnits', 'objectBoundingBox') | |
.append('rect') | |
.attr('x', 0) | |
.attr('y', 0) | |
.attr('width', 1) | |
.attr('height', 1) | |
.attr('fill', 'url(#' + prefix + 'Gradient)') | |
} | |
function timeStampSort(a, b) { | |
var a = new Date(a.timestamp), | |
b = new Date(b.timestamp) | |
return (a < b) ? -1 : (a > b) ? 1 : 0; | |
} | |
// feed | |
(function() { | |
var radius = 20; | |
var margin = {top: 0 + radius, right: 0, bottom: 50, left: 0}, | |
width = radius * 2 - margin.left - margin.right, | |
height = 1000 - margin.top - margin.bottom; | |
d3.csv("../data/responses.csv", null, function(error, data) { | |
var responseData = data.slice(0,numResponses).sort(timeStampSort).reverse(); | |
var y = d3.time.scale() | |
.domain(d3.extent(responseData, function(response) { return new Date(response.timestamp); })) | |
.range([height, 0]); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.tickPadding(50) | |
.tickFormat(d3.time.format('%B %Y')) | |
.orient("left"); | |
var svg = d3.select("#feed") | |
.attr('width', radius * 2) | |
.attr('viewBox', '0 0 ' + width + ' ' + height) | |
.attr('preserveAspectRatio', "xMidYMin") | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") | |
addMask(svg, 'feed', 0, 1, 0.7) | |
svg.attr('mask', 'url(#feedMask)') | |
svg.append("g") | |
.attr("class", "y axis") | |
.attr("transform", "translate(" + (width - radius) + ", 0)") | |
.call(yAxis) | |
var responses = svg.selectAll("g.response") | |
.data(responseData) | |
var response = responses.enter().append('g').attr('class', 'response') | |
response.append("circle") | |
.attr("class", "dot") | |
.attr("r", radius) | |
.attr("cx", width - radius - margin.right) | |
.attr("cy", function(d,i) { | |
var prev = $(this).parent().prev('.response'); | |
if (prev.length > 0) { | |
var prevBottom = prev[0].getBBox().y + prev[0].getBBox().height; | |
return d3.max([prevBottom + radius, y(new Date(d.timestamp))]) | |
} else { | |
return y(new Date(d.timestamp)); | |
} | |
}) | |
.on("mouseover", function(d) { | |
var bubble = document.querySelector('#feedBubble'); | |
bubble.find('.person').text(d.name); | |
bubble.find('.channel').text(d.channel); | |
bubble.find('.time').attr('title', d.timestamp).timeago('updateFromDOM'); | |
var box = this.getBoundingClientRect(); | |
var top = Math.round(box.top + box.height / 2 - bubble.outerHeight() / 2); | |
var left = Math.round(box.left - bubble.outerWidth() - 8); | |
bubble.css({top: top + 'px', left: left + 'px'}); | |
bubble.show(); | |
}) | |
.on("mouseout", function() { | |
document.querySelector('#feedBubble').hide(); | |
}) | |
response.append("text") | |
.attr("class", "icon") | |
.text(function(d) { return channelData.filter(function(channel) { return channel.nickname == d.channel })[0].icon }) | |
.attr("x", width - radius) | |
.attr("y", function(d) { return $(this).prev('.dot').first().attr('cy'); }) | |
.attr('dy', radius / 4) | |
}); | |
})(); | |
// campaigns | |
(function() { | |
var radius = 20; | |
var margin = {top: radius, right: 10, bottom: radius, left: 10}, | |
width = 1000 - margin.right - margin.left, | |
height = radius * 4 - margin.top - margin.bottom; | |
d3.csv("../data/campaigns.csv", null, function(error, data) { | |
var campaignData = data.slice(0,numCampaigns).sort(timeStampSort); | |
var x = d3.time.scale() | |
.domain(d3.extent(campaignData, function(campaign) { return new Date(campaign.timestamp); })) | |
.range([0, width]); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.tickPadding(50) | |
.tickFormat(d3.time.format('%B %Y')) | |
.orient("top"); | |
var svg = d3.select("#timeline") | |
.attr('height', radius * 2 + 10) | |
.attr('viewBox', '0 0 ' + width + ' ' + height) | |
.attr('preserveAspectRatio', "xMinYMid") | |
.append("g") | |
.attr("transform", "translate(" + (margin.left + radius) + "," + margin.top + ")"); | |
addMask(svg, 'timeline', 1, 0, 0.75) | |
svg.attr('mask', 'url(#timelineMask)') | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0, " + (height - margin.bottom - radius) + ")") | |
.call(xAxis) | |
var campaigns = svg.selectAll("g.campaign") | |
.data(campaignData) | |
var campaign = campaigns.enter().append('g').attr('class', 'campaign') | |
campaign.append("circle") | |
.attr("class", "dot") | |
.attr("r", radius) | |
.attr("cy", height - radius - margin.bottom) | |
.attr("cx", function(d,i) { | |
var prev = $(this).parent().prev('.campaign'); | |
if (prev.length > 0) { | |
var prevRight = prev[0].getBBox().x + prev[0].getBBox().width; | |
return d3.max([prevRight + radius, x(new Date(d.timestamp))]) | |
} else { | |
return x(new Date(d.timestamp)); | |
} | |
}) | |
.on("mouseover", function(d) { | |
var bubble = document.querySelector('#campaignBubble'); | |
bubble.find('.name').text(d.name); | |
bubble.find('.size').text(d.size); | |
bubble.find('.channel').text(d.channel); | |
bubble.find('.time').attr('title', d.timestamp).timeago('updateFromDOM'); | |
var box = this.getBoundingClientRect(); | |
var top = Math.round(box.top - bubble.outerHeight() - 12); | |
var left = Math.round(box.left + box.width / 2 - bubble.outerWidth() / 2); | |
bubble.css({top: top + 'px', left: left + 'px'}); | |
bubble.removeClass("left center right") | |
if (left < 0) { | |
bubble.css({ left: Math.round(box.left + box.width / 2 - 12.5) + 'px' }) | |
bubble.addClass("left"); | |
} else if (left + bubble.outerWidth() > $(window).width()) { | |
bubble.addClass("right"); | |
bubble.css({ left: Math.round(box.left + box.width / 2 - bubble.outerWidth() + 12.5) + 'px' }) | |
} else | |
bubble.addClass("center"); | |
bubble.show(); | |
}) | |
.on("mouseout", function() { | |
document.querySelector('#campaignBubble').hide(); | |
}) | |
campaign.append("text") | |
.attr("class", "icon") | |
.text(function(d) { return channelData.filter(function(channel) { return channel.nickname == d.channel })[0].icon }) | |
.attr("y", height - margin.bottom - radius) | |
.attr("x", function(d) { return $(this).prev('.dot').first().attr('cx'); }) | |
.attr('dx', 1) | |
.attr('dy', radius / 4) | |
}); | |
})(); | |
}); | |
} | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment