I'm struggling getting my choropleth map to work. I have a CSV file of values and district names I want to match to my TopoJSON map. The data on the CSV map looks like this:
id, values
NAIROBI,50
MOMBASA,10
KWALE,20
KILIFI,40
TANA RIVER,50
LAMU,10
The id column is for names of districts in Kenya, the values are arbitrary and are just meant to generate colors according to the domain set for the threshold scale I am using. For some reason the colors just won't generate. Here is the rest of my code. Please let me know where I am going wrong? I keep trying to fix it to no avail:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="d3.v3.js"></script>
<script type="text/javascript" src="js/topojson.js"></script>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" media="screen">
</head>
<body>
<div class="row">
<header class="span12">
<h1>Aphellion Activity 1 - Kenya Maps</h1>
<h3>The goal of this activity is generate two maps one drawn with D3.js using GeoJSON to generates the paths, the other drawn using TopoJSON to generate the paths.</h3>
</header>
</div>
</br>
<div class="row">
<div class="span6" id="Map1">
<p>This first map of Kenya was made using TopoJSON.</p>
</div>
<div class="span6" id="Map2">
<p>This second map of Kenya was made using GeoJSON.</p>
</div>
</div>
</body>
<script type="text/javascript">
var width = 460;
var height = 400;
//Setting the color domains for the choropleth maps
var color = d3.scale.threshold()
.domain([10, 20, 30, 40, 50])
.range(["#9e9ac8", "756bb1", "dadaeb", "bcbddc", "#E82D0C"]);
//TopoJSON Map
//new projection
var projection = d3.geo.mercator()
.center([36.8000, 1.2667])
.scale([1000])
.translate([width/2, height/2]);
var path = d3.geo.path().projection(projection);
//Drawing Choropleth
var svg = d3.select("div#Map1")
.append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.append("g")
.call(d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", zoom));
d3.json("js/output.json", function(error, topology) {
d3.csv("js/Schools.csv", function(error, Schools) {
var rateById = {};
Schools.forEach(function (d) {
rateById[d.id] = +d.values;
});
g.append("g")
.attr("class", "districts")
.selectAll("path")
.data(topojson.feature(topology, topology.objects.kenya).features)
.enter()
.append("path")
.attr("d", path)
.style("fill", function(d) {
return color(rateById[d.id]);
});
});
});
//Draw a rect around the map
svg.append("rect").attr("width", width).attr("height", height).style("stroke", "black").style("fill", "none")
;
function zoom() {
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")")};
</script>
</html>
You were very, very close. You were returning an empty hash, return rateById = {}; instead of declaring it for use in your code, var rateById = {};.
I have updated the PLUNK with the correct references to libraries and added CSS styling to it.
The only other change is that I used more contrasting colors for demo purposes, but you can uncomment your original colors and it will work just fine.
Related
The given code bellow produces a simple region vice world map and render some data on mouse hover. API document shows a click even can be added but unfortunatly I dint find any document on it how can I add a url link for another web page to a particular region (country).
I short when I clicked on a region/country it should render associated page that holds detailed information provide by my data base application.
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
'packages':['geochart'],
// Note: you will need to get a mapsApiKey for your project.
// See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings
'mapsApiKey': 'AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY'
});
google.charts.setOnLoadCallback(drawRegionsMap);
var j = "{{ind}}".replace(/"/g,"\"")
function drawRegionsMap() {
var data = google.visualization.arrayToDataTable([
['Country', 'Popularity'],
['Germany', 200],
['United States', 300],
['Brazil', 400],
['Pakistan', 500],
['France', 600],
['RU', 700],
]);
var options = {};
var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="regions_div" style="width: 1400px; height: 1200px;"></div>
</body>
</html>
I'm using my Ubuntu server to run automated speed tests and am recording the data in a csv file. I'd like to now plot all this data in a graph. The csv file is called data.csv in the same directory as index.html and it contains the following:
time,ping,down,up
1454190169992.8655,25.40,61.1,18.2
1454196940589.804,24.57,65.8,18.2
1454200093536.6118,26.39,66.8,18.2
1454235805528.2244,25.21,59.3,18.1
1454235966417.7297,25.01,59.4,18.2
1454236051628.0317,24.68,59.8,18.2
1454239827546.229,26.63,64.6,18.2
index.html currently looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="nv.d3.css" />
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="nv.d3.min.js"></script>
</head>
<body>
<svg id="chart" style="width:500; height:500;"></svg>
</body>
<script type="text/javascript">
d3.csv("data.csv", function(error, data){
console.log(data)
// create an empty object that nv is expecting
var exampleData = [
{
key: "totals",
values: []
}
];
// populate the empty object with your data
data.forEach(function (d){
d.value = +d.value
exampleData[0].values.push(d)
})
nv.addGraph(function() {
var chart = nv.models.lineChart()
.margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
.x(function (d) { console.log(d); return d.time })
.y(function (d) { return d.ping })
d3.select('#chart')
.datum(exampleData)
.attr("id", function (d) { console.log(d); })
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
</script>
</html>
I am trying to plot circles on a map based on data from csv files. I want the latitude and longitude from the csv file and plot a circle.
I am unable to long the two fields. I get an object undefined error. Here's my code so far:
Here's the link for the CSV file -
http://slate-interactives-prod.elasticbeanstalk.com/gun-deaths/getCSV.php
<html>
<head>
<meta charset="utf-8">
<link href="d3-geomap/css/d3.geomap.css" rel="stylesheet">
<script src="d3-geomap/vendor/d3.geomap.dependencies.min.js"></script>
<script src="d3-geomap/js/d3.geomap.min.js"></script>
</head>
<style>
path.unit:hover{
fill:#99d8c9;
}
</style>
<body>
<div id="map"></div>
</body>
</html>
<script>
var map = d3.geomap.choropleth()
.geofile('d3-geomap/topojson/countries/USA.json')
.projection(d3.geo.albersUsa)
.column('2012')
.unitId('fips')
.scale(1000)
.legend(true);
var width = 950,
height = 550;
// set projection
var projection = d3.geo.albersUsa();
// create path variable
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.csv("data.csv", function(data) {
var coordinates = projection([data.lat,data.lng]);
svg.append("circle")
.attr("cx", coordinates[0])
.attr("cy", coordinates[1])
.attr("r", 5)
.style("fill", "red");
});
d3.select('#map')
.call(map.draw, map);
</script>
There are at least a couple of problems in your code. First the data object that d3.csv retrieves is an array. It's the elements of that array that will have properties such as .lat and .lng. So data.lat and data.lng are not defined.
I'm guessing that you want to create circles for each element in the array. You could do that by iterating through the array, e.g.
data.forEach(function(d) {
var coordinates = projection([d.lat, d.lng]);
// ...
});
That's not the normal D3 idiom (it's not using selections and .enter()) but it would work.
Secondly, CSV files are always read as text strings, even when the values are actually numbers. You'll want to convert from strings to numbers, so the code above really should be
var coordinates = projection([parseFloat(d.lat), parseFloat(d.lng)]);
As I said, there may be other problems with your code, but fixing those two should at least get you further along.
I am trying to create a custom Google street view of a buildings interior. I have looked many places and I have seen the basic idea of how to do it.
I have been using this link
http://googlemaps.googlermania.com/google_maps_api_v3/en/custom_streetview/index.html
as well as other examples.
They seem to have very similar code but what they all seem to lack is how to set up the files.
If someone knows where I can find a working example I should be able to work my way backwards of if someone can offer me some detailed instructions, I would be very appreciative.
I have a VirtualBox running an Ubuntu server.
On the server I have an html file named street.html(code below).
I also have a folder named "lab_tiles," which contains "lab_test," which contains several jpegs with the naming pattern XX-YY_s1.jpg(i.e. 00-00_s1.jpg, 00-01_s1.jpg, 00-02_s1.jpg)
I have the following code for the html file.
<!DOCTYPE html>
<html>
<head>
<title>Custom Street View panorama tiles</title>
<meta charset="utf-8">
<link href="/maps/documentation/javascript/examples/default.css" rel="stylesheet">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type='text/javascript'>
function code3_2() {
// Set StreetView provider.
var streetViewOptions = {
zoom: 1,
pano : "lab_test",
panoProvider: getCustomPanorama
};
// Create a StreetView object.
var streetViewDiv = document.getElementById('streetview_canvas1');
streetViewDiv.style.fontSize = "15px";
var streetView = new google.maps.StreetViewPanorama(streetViewDiv, streetViewOptions);
}
function getCustomPanoramaTileUrl(panoID, zoom, tileX, tileY) {
// Return a pano image given the panoID.
return "lab_tiles/" + panoID + '/' + tileX + '-' +tileY + '_s1.jpg';
}
function getCustomPanorama(panoID) {
var streetViewPanoramaData = {
links: [],
copyright: 'People at my job',
tiles: {
tileSize: new google.maps.Size(256, 256),
worldSize: new google.maps.Size(2048, 1024),
centerHeading: 0,
getTileUrl: getCustomPanoramaTileUrl
}
};
switch(panoID) {
case "lab_test":
streetViewPanoramaData["location"] = {
pano: 'lab_test',
description: "lab test",
latLng: new google.maps.LatLng(37.556429,-122.050745)
};
return streetViewPanoramaData;
}
}
google.maps.event.addDomListener(window, 'load', code3_2);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
Looking at the link you supplied it seems you can put your (tile)images anywhere you want. The function below is used to specify the location when retrieving them.
function getCustomPanoramaTileUrl(panoID, zoom, tileX, tileY) {
// Return a pano image given the panoID.
return "ardenwood_tiles/" + panoID + '/' + tileX + '-' +tileY + '_s1.jpg';
}
In this case the images will be in the folder named ardenwood_tiles/visitor_center/
How can one get the coordinates of a particular point on a map in OpenLayers?
Handle click event on map Click handler. Here is one of many sample codes you can find in OpenLayers mailing list archives:
map.events.register('click', map, handleMapClick);
function handleMapClick(e)
{
var lonlat = map.getLonLatFromViewPortPx(e.xy);
// use lonlat
// If you are using OpenStreetMap (etc) tiles and want to convert back
// to gps coords add the following line :-
// lonlat.transform( map.projection,map.displayProjection);
// Longitude = lonlat.lon
// Latitude = lonlat.lat
}
<html>
<head>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
function init(){
map = new OpenLayers.Map('map');
base_layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
map.addLayer(base_layer);
map.zoomToMaxExtent();
map.events.register('click', map, handleMapClick);
}
function handleMapClick(evt)
{
var lonlat = map.getLonLatFromViewPortPx(evt.xy);
// use lonlat
alert(lonlat);
}
</script>
</head>
<body onload="init()">
Hello Map.<br />
<div id="map"></div>
</body>
</html>
#mloskot Your answer is great you had a mistake with the evt variable.
Just added the html markup to make it a working page.