Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- uboat.taxonomy.countyModule = function(){
- //internal module variables
- var thisObj = {
- //deals with map-centric elements and state variables
- _mapElement : {
- id : "#us_map",
- width : 954,
- height : 500,
- projection : null,
- path : null,
- svg : null,
- clicked : false,
- centered : null,
- scale : 1100,
- loaded : false,
- zoom : 4,
- },
- _currentCounty : {
- id : null,
- color : null,
- name : null,
- },
- _previousCounty : {
- color : null,
- id : null
- },
- _fillColors : {
- market : "#0000ff",
- prospect : "#ff0000",
- neutral : "#c0c0c0",
- hover : "#4CD550"
- },
- //deals with tooltip data and variables
- _tooltip : {
- tooltip : null,
- county : null,
- open : false,
- buttonTemplate : "<div id = 'tooltip_template'>" +
- "<div class = 'county_data'></div>" +
- "<img src = '/static/images/delete.png' width = '28' height = '28' class = " +
- "'delete_logo' id = 'close_tooltip' />" +
- "<div id = 'no_client_message'></div>" +
- "<button id = 'add_prospective_market' class = 'tooltip_button'>" +
- "Prospective Market</button>" +
- "<button id = 'add_market' class = 'tooltip_button'>Market County</button>" +
- "<button id = 'remove_market' class = 'tooltip_button'>Remove Market</button></div>",
- hoverTemplate : "<div id = 'tooltip_template'><div class = 'county_data'></div>"
- },
- _clientSelect : $("#county_client_select"),
- _countySearch : $("#county_search_autocomplete"),
- _countySearchArray : [],
- _currentClient : {
- id : null,
- name : null
- },
- _cachedCounties : false,
- }
- //Need to initialize JS bindings and events
- var initializeElements = function(){
- $("#county_search_autocomplete").autocomplete({
- minLength : 3,
- //source : thisObj._countySearchArray
- source : function(request, response){
- var results = $.ui.autocomplete.filter(thisObj._countySearchArray, request.term);
- response(results.slice(0, 10));
- }
- });
- thisObj._countySearch.keyup(countySearchHandler);
- thisObj._clientSelect.change(countyClientHandler);
- //bind the tooltip event handlers to the body to avoid the event listener creation/destruction cycle
- $("body")
- .on("click", "#add_market", function(){
- if (thisObj._currentCounty.color != thisObj._fillColors.market)
- marketHandler(0);
- else
- $("#no_client_message").text("Market button has been disabled");
- })
- .on("click", "#add_prospective_market", function(){
- if (thisObj._currentCounty.color != thisObj._fillColors.prospect)
- marketHandler(1);
- else
- $("#no_client_message").text("Prospective market button has been disabled");
- })
- .on("click", "#remove_market", function(){
- marketHandler(2);
- })
- .on("click", "#close_tooltip", closeTooltipHandler)
- .on("mouseover", "#close_tooltip", function(){
- $(this).css({"border-color" : "black", "opacity" : 1});
- })
- .on("mouseout", "#close_tooltip", function(){
- $(this).css({"border-color" : "black", "opacity" : 0.5});
- });
- }
- //initialize the county search array, uses "label" and "value" to execute autocomplete searches
- var initializeCountyArray = function(json){
- for (var i = 0; i < json.length; i++) {
- thisObj._countySearchArray.push({
- "id" : json[i].id,
- "name" : json[i].name,
- "state" : json[i].properties.StateCode,
- "label" : json[i].name + " "+ json[i].properties.StateCode, //used for jquery autocomplete
- "value" : json[i].name + " "+ json[i].properties.StateCode
- });
- }
- }
- //Get all current clients in the db, initialize dropdown select list
- var loadClientSelection = function(){
- $.ajax({
- url : "getClientorgList/",
- type : "GET",
- dataType : "json",
- success : function(results){
- var appendString = "";
- for (var i = 0; i < results.length; i++){
- appendString += "<option value = '" + results[i].id + "' " +
- "id = 'county_client" + results[i].id +
- "' data-parentorg = '" + results[i].parentorg + "'>" +
- results[i].name + "</option>";
- }
- thisObj._clientSelect
- .empty()
- .append(appendString);
- }
- })
- }
- //autocomplete search handler, returns results only after 3 letters input
- //An arrow up or down, or enter press highlights the selected county on the map
- var countySearchHandler = function(e){
- if (thisObj._tooltip.open)
- closeTooltipHandler();
- if (thisObj._currentCounty.id != null)
- mapMouseOut({id : thisObj._currentCounty.id});
- if ($(this).val().length > 3){
- var key = $(this).val();
- for (var i = 0; i < thisObj._countySearchArray.length; i++){
- if ((thisObj._countySearchArray[i].name + " " +
- thisObj._countySearchArray[i].state) == key){
- //store previous county's id and fill color
- thisObj._previousCounty.id = thisObj._currentCounty.id;
- thisObj._previousCounty.color = rgb2hex($("#" +
- thisObj._previousCounty.id).css("fill"));
- //get the current id
- thisObj._currentCounty.id = thisObj._countySearchArray[i].id;
- thisObj._currentCounty.color = rgb2hex($("#" +
- thisObj._currentCounty.id).css("fill"));
- break;
- }
- }
- //highlight on enter, up and down key presses
- if (e.which == 13 || e.which == 38 || e.which == 40) {
- if (thisObj._previousCounty.color != "#00000") {
- d3.selectAll($("#" + thisObj._previousCounty.id))
- .style("fill", thisObj._previousCounty.color);
- }
- d3.selectAll($("#" + thisObj._currentCounty.id))
- .style("fill", thisObj._fillColors.hover);
- }
- }
- }
- //Handles the client selection from the client dropdown list. A valid result
- //populates the map in red and green counties for market/prospective layout
- var countyClientHandler = function(){
- if ($(this).children(":selected").val() != "-" ){
- if (thisObj._tooltip.open)
- closeTooltipHandler();
- var client = thisObj._clientSelect.children(":selected");
- thisObj._currentClient.id = parseInt(client.val());
- thisObj._currentClient.name = client.text()
- $.ajax({
- url : "getClientCounties/",
- type : "POST",
- data : {"data" :
- JSON.stringify({
- "id" : thisObj._currentClient.id
- })
- },
- success : function(results){
- if (results.success == "true"){
- showClientMarkets(results.results);
- } else
- alert(results.message);
- }
- })
- }
- }
- //executes ajax post request to add a new client-county relationship. Type is 0 for
- //new market, 1 for new prospective market and 2 for remove this client-county relationship
- var marketHandler = function(type){
- $.ajax({
- url : "marketHandler/",
- type : "POST",
- data : {"data" : JSON.stringify({
- "client" : thisObj._currentClient.id,
- "county" : thisObj._currentCounty.id,
- "type" : type
- })
- },
- dataType : "json",
- success : function(results){
- if (results.success == "true"){
- /*
- console.log("Market handler type: " + type);
- var fillColor = "";
- if (type == 0)
- fillColor = thisObj._fillColors.market;
- else if (type == 1)
- fillColor = thisObj._fillColors.prospect;
- else
- fillColor = thisObj._fillColors.neutral;
- d3.selectAll($("#" + thisObj._currentCounty.id))
- .style("fill", fillColor);
- closeTooltipHandler();
- */
- //hack to get the fill color change to apply. There is some conflict going
- //on between the jquery and d3 event handlers. While the function executes,
- //the change of the fill is not applied on success.
- thisObj._clientSelect.trigger("change");
- } else
- alert(results.message);
- }
- })
- }
- //alters the selected client county mappings fill color in regard to their market status
- var showClientMarkets = function(results){
- d3.selectAll("path")
- .style("fill", "gray");
- for (var i = 0; i < results.length; i++){
- if (results[i].market == 1) {
- d3.selectAll($("#" + results[i].fips))
- .style("fill", thisObj._fillColors.market);
- }
- if (results[i].prospect == 1){
- d3.selectAll($("#" + results[i].fips))
- .style("fill", thisObj._fillColors.prospect);
- }
- }
- }
- var closeTooltipHandler = function(){
- d3.selectAll($("#" + thisObj._tooltip.county))
- .style("fill", thisObj._currentCounty.color);
- closeTooltip();
- d3.select(thisObj._mapElement.id).on("click", mapClick);
- thisObj._tooltip.open = false;
- }
- //handles the zoom effect of a double click event.
- var mapZoom = function(d){
- var x, y, k;
- closeTooltipHandler();
- d3.event.stopPropagation()
- if (d && thisObj._mapElement.centered !== d && !thisObj._mapElement.clicked){
- thisObj._tooltip.tooltip.transition()
- .duration(500)
- .style("opacity", 0)
- .style("pointer-events", "none");
- var centroid = thisObj._mapElement.path.centroid(d);
- x = centroid[0];
- y = centroid[1];
- k = thisObj._mapElement.zoom;
- thisObj._mapElement.centered = d;
- thisObj._mapElement.clicked = true;
- } else {
- x = thisObj._mapElement.width / 2;
- y = thisObj._mapElement.height / 2;
- k = 1;
- thisObj._mapElement.centered = null;
- thisObj._mapElement.clicked = false;
- closeTooltip();
- }
- thisObj._mapElement.svg.selectAll("path")
- .classed("active", thisObj._mapElement.centered && function(d){
- return d === thisObj._mapElement.centered;
- });
- thisObj._mapElement.svg.transition()
- .duration(1000)
- .attr("transform", "translate(" + thisObj._mapElement.width / 2 + ", " +
- thisObj._mapElement.height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
- .style("stroke-width", 5/k + "px");
- }
- //handles the click event on the map, which brings a button-filled tooltip into view
- var mapClick = function(d){
- if (!thisObj._tooltip.open && d != undefined){
- d3.event.stopPropagation();
- //add tooltip HTML and styles to this element
- thisObj._tooltip.tooltip.html(thisObj._tooltip.template)
- .style("left", (d3.event.pageX + 10) + "px")
- .style("top", (d3.event.pageY - 50) + "px")
- .style("pointer-events" , "auto")
- .style("width", "400px")
- .style("height", "150px");
- //generate jQuery UI button overlays for the tooltip buttons, and enable
- //or disable as neccessary
- $(".tooltip_button").button();
- if (thisObj._currentClient.id == null) {
- $("#no_client_message").text("No client has been selected");
- $(".tooltip_button").button("disable");
- }
- else {
- var countyFillColor = rgb2hex($("#" + d.id).css("fill"));
- if (countyFillColor == thisObj._fillColors.market)
- $("#add_market").button("disable");
- if (countyFillColor == thisObj._fillColors.prospect)
- $("#add_prospective_market").button("disable");
- }
- //fade tooltip into view
- thisObj._tooltip.tooltip
- .transition()
- .delay(300)
- .duration(500)
- .style("opacity", 1);
- //get county name and state for future use
- thisObj._currentCounty.name = d.name + ", " + d.properties.StateCode
- //add in county name and state text
- $(".county_data").text(thisObj._currentCounty.name);
- //disable all single click events on this map
- d3.select(thisObj._mapElement.id).on("click", null);
- //update state variables.
- thisObj._tooltip.open = true;
- thisObj._tooltip.county = d.id;
- }
- }
- //Changes the fill of the current county to highlight its location
- var mapMouseOver = function(d){
- if (!thisObj._tooltip.open) {
- thisObj._currentCounty.id = d.id;
- thisObj._currentCounty.color = rgb2hex($("#" + d.id).css("fill"));
- d3.selectAll($("#" + d.id))
- .style("fill", thisObj._fillColors.hover);
- thisObj._tooltip.tooltip.html(thisObj._tooltip.hoverTemplate)
- .style("left", (d3.event.pageX + 10) + "px")
- .style("top", (d3.event.pageY - 50) + "px")
- .style("pointer-events", "none")
- .style("width", "150px")
- .style("height", "50px");
- $(".county_data").text(d.name + ", " d.properties.StateCode);
- thisObj._tooltip.tooltip.transition()
- .duration(200)
- .style("opacity", 1)
- }
- }
- //Changes the fill of the county to its previous coloration
- var mapMouseOut = function(d){
- if (!thisObj._tooltip.open){
- d3.selectAll($("#" + d.id))
- .style("fill", thisObj._currentCounty.color);
- closeTooltip();
- }
- }
- //utility function to close the tooltip
- var closeTooltip = function(){
- thisObj._tooltip.tooltip.transition()
- .duration(200)
- .style("opacity", 0);
- thisObj._tooltip.open = false;
- }
- //utility function to convert 'rgb(1, 2, 3)' color codes to hexadecimal
- var rgb2hex = function (rgb) {
- if (rgb != undefined) {
- rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
- function hex(x) {
- return ("0" + parseInt(x).toString(16)).slice(-2);
- }
- return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
- }
- return "#00000";
- }
- //module initialization and event binder
- var init = function(){
- if (!thisObj._mapElement.loaded){
- //initialize client dropdown selection list
- loadClientSelection();
- thisObj._mapElement.loaded = true;
- thisObj._mapElement.projection = d3.geo.albersUsa()
- .scale(thisObj._mapElement.scale)
- .translate([thisObj._mapElement.width / 2, thisObj._mapElement.height / 2]);
- thisObj._mapElement.path = d3.geo.path()
- .projection(thisObj._mapElement.projection);
- thisObj._mapElement.svg = d3.select(thisObj._mapElement.id).append("svg")
- .attr("width", thisObj._mapElement.width)
- .attr("height", thisObj._mapElement.height);
- thisObj._mapElement.svg.append("rect")
- .attr("class", "county_background")
- .attr("width", thisObj._mapElement.width)
- .attr("height", thisObj._mapElement.height)
- .on("mouseover", closeTooltip);
- thisObj._mapElement.svg.append("g");
- thisObj._tooltip.tooltip = d3.select("body")
- .append("div")
- .attr("class", "tooltip")
- .style("opacity", 0);
- d3.json("/static/js/json/us-counties.json", function(json){
- //inititalize array for autocomplete search
- initializeCountyArray(json.features);
- thisObj._mapElement.svg.selectAll("path")
- .data(json.features)
- .enter().append("path")
- .attr("d", thisObj._mapElement.path)
- .attr("class", "states")
- .attr("id", function(d){
- return d.id;
- })
- .style("fill", thisObj._fillColors.neutral)
- .style("stroke", "black")
- .style("stroke-width", "0.5px")
- .on("click", mapClick)
- .on("dblclick", mapZoom)
- .on("mouseover", mapMouseOver)
- .on("mouseout", mapMouseOut);
- });
- }
- initializeElements();
- return thisObj;
- }
- return {
- init : init
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement