Cool Interactive Map

I added a new interactive map out on NBNW and I think it’s pretty cool. That’s one person!

If you check it out and like it, you can use it too (I’ll give you everything below). Everything is free including the source where I got started (RaphaelJS check it out, very powerful).

Hover your mouse over a country and if available, the average net worth results will appear for all users in that country.

Hover your mouse over a country and if available, the average net worth results will appear for all users in that country.

To play with the map, the only real requirement is that you have a fairly modern browser.  I use HTML5 features that might not work properly in older browsers. Oh, sorry, one more thing, it’s a pretty large map, like 1000 pixels wide, so you might do some scrolling on a small screen.

For you techies, here’s the guts you’ll need (feel free to right-click and View source on my site and take any of that you need). In short, I load my custom database data (just a country name with an average net worth) into a two dimensional Javascript array by parsing the results of an Ajax call. Then when I hover over a country on the map, I pass the country name into my custom array looking for the average net worth.

First, download this from github:

https://raw.github.com/DmitryBaranovskiy/raphael/master/raphael-min.js

Then, download this from Raphael:

http://raphaeljs.com/world/world.js

Ok, so now it’s going to look like I threw up on the page and I sort of did. However, keep following past this main block and the rest will make sense. After that, back into this main block and it too will make sense.

<script src="/js/vendor/raphael-min.js"></script>
<script src="/js/vendor/world.js"></script>
<script>
Raphael("forworldmap", 1000, 400, function () {
var r = this;
r.rect(0, 0, 1000, 400, 10).attr({
    stroke: "none",
    fill: "0-#9bb7cb-#adc8da"
});
var over = function () {
    this.c = this.c || this.attr("fill");
    this.stop().animate({fill: "#bacabd"}, 500);
},
    out = function () {
	this.stop().animate({fill: this.c}, 500);
    };
r.setStart();
var hue = Math.random();
var myCountryArray = new Array();
for (var country in worldmap.shapes) {
    // var c = Raphael.hsb(Math.random(), .5, .75);
    // var c = Raphael.hsb(.11, .5, Math.random() * .25 - .25 + .75);
     var myRPath = r.path(worldmap.shapes[country]).attr({stroke: "#ccc6ae", fill: "#f0efeb", "stroke-opacity": 0.25});
     myCountryArray[myRPath.id] = worldmap.names[country];
     myRPath.hover(function() {
	showNetWorthTooltip(myCountryArray[this.id]);
     });
}
var world = r.setFinish();
world.hover(over, out);
// world.animate({fill: "#666", stroke: "#666"}, 2000);
world.getXY = function (lat, lon) {
    return {
	cx: lon * 2.6938 + 465.4,
	cy: lat * -2.6938 + 227.066
    };
};
world.getLatLon = function (x, y) {
    return {
	lat: (y - 227.066) / -2.6938,
	lon: (x - 465.4) / 2.6938
    };
};
var latlonrg = /(\d+(?:\.\d+)?)[\xb0\s]?\s*(?:(\d+(?:\.\d+)?)['\u2019\u2032\s])?\s*(?:(\d+(?:\.\d+)?)["\u201d\u2033\s])?\s*([SNEW])?/i;
world.parseLatLon = function (latlon) {
    var m = String(latlon).split(latlonrg),
	lat = m && +m[1] + (m[2] || 0) / 60 + (m[3] || 0) / 3600;
    if (m[4].toUpperCase() == "S") {
	lat = -lat;
    }
    var lon = m && +m[6] + (m[7] || 0) / 60 + (m[8] || 0) / 3600;
    if (m[9].toUpperCase() == "W") {
	lon = -lon;
    }
    return this.getXY(lat, lon);
};

try {
    navigator.geolocation && navigator.geolocation.getCurrentPosition(function (pos) {
	r.circle().attr({fill: "none", stroke: "#f00", r: 5}).attr(world.getXY(pos.coords.latitude, pos.coords.longitude));
    });
} catch (e) {}
var frm = document.getElementById("latlon-form"),
    dot = r.circle().attr({fill: "r#FE7727:50-#F57124:100", stroke: "#fff", "stroke-width": 2, r: 0}),
    // dot2 = r.circle().attr({stroke: "#000", r: 0}),
    ll = document.getElementById("latlon"),
    cities = document.getElementById("cities");
});
</script>

In that code above, it’s all right off Raphael. I only changed a few lines to create a new array for myself and call my own Javascript function on a mouse hover event.

var myRPath = r.path(worldmap.shapes[country]).attr({stroke: "#ccc6ae", fill: "#f0efeb", "stroke-opacity": 0.25});
myCountryArray[myRPath.id] = worldmap.names[country];
myRPath.hover(function() {
    showNetWorthTooltip(myCountryArray[this.id]);
});

And of course, here’s my custom code

//this var will hold all country data from initial ajax call
var mycountryarray = new Array();

$(document).ready(function(){
doLoadCountriesData();
});
function doLoadCountriesData()
{
	var sessionKey = "countriesInSession";
	//if browser supports session storage, try to use it
	if (sessionStorage) {
		var sessionValue = sessionStorage.getItem(sessionKey);
		if (sessionValue) {
			mycountryarray = $.parseJSON(sessionValue);
			return true; // We just avoided one ajax request
		}
	}
	//browser doesn't support session storage or the session var is empty, go get posts
	$.ajax({
		url: 'GetCountryAvgNetWorth.php',
		type: 'GET',
		cache: 'false',
		success: function(jsonresponse) {
			//if sessionStorage supported, save response in session
			if (sessionStorage) {
				mycountryarray = $.parseJSON(jsonresponse);
				sessionStorage.setItem(sessionKey, jsonresponse);
			}
		},
		error: function(xhr) {
			// handle errors
		},
	});
	return true;
}
function showNetWorthTooltip(country) {
	if (!(mycountryarray)) {
		doLoadCountriesData();
	}
	if (mycountryarray[country]) {
		$("#forworldmapcomment").html("Average net worth for " + country + " is $" + ReplaceNumberWithCommas(mycountryarray[country]));
	} else {
		$("#forworldmapcomment").html("Average net worth for " + country + " is unavailable");
	}
}
function ReplaceNumberWithCommas(yourNumber) {
	//Seperates the components of the number
	var n= yourNumber.toString().split(".");
	//Comma-fies the first part
	n[0] = n[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
	//Combines the two sections
	return n.join(".");
}
Advertisements

With That Much Cash

This guy has some money stuffed under the mattress, that’s for sure.

Here’s the deets:  43 year old male, residing in the US, positive net worth, large short term liquidity and no debt. Whoohoo (if that’s how you spell that)!

He’d also like some feedback on how he’s doing. Kudos to you sir.

NothingButNetWorth.com

NothingButNetWorth.com

And The Drum Roll Please

It’s not every day you see a 31 year old with a house nearly paid off.

But that’s exactly what this anonymous Suzie Q has done so it seems.  Tip of the hat to you.

NothingButNetWorth.com

NothingButNetWorth.com