D3 JS - GeoJson (US Map) - not loading - d3.js

I have used the code from github (https://github.com/alignedleft/d3-book/blob/master/chapter_12/04_fill.html).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Setting path fills</title>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 300;
//Define map projection
var projection = d3.geo.albersUsa()
.translate([w/2, h/2])
.scale([500]);
//Define path generator
var path = d3.geo.path()
.projection(projection);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Load in GeoJSON data
d3.json("us-states.json", function(json) {
//Bind data and create one path per GeoJSON feature
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "steelblue");
});
</script>
</body>
</html>
JSON file is from ( https://github.com/alignedleft/d3-book/edit/master/chapter_12/us-states.json).
Sample:
{"type":"FeatureCollection","features":[
{"type":"Feature","id":"01","properties":{"name":"Alabama"},"geometry":{"type":"Polygon","coordinates":[[[-87.359296,35.00118],[-85.606675,34.984749],[-85.431413,34.124869],[-85.184951,32.859696],[-85.069935,32.580372],[-84.960397,32.421541],[-85.004212,32.322956],[-84.889196,32.262709],[-85.058981,32.13674],[-85.053504,32.01077],[-85.141136,31.840985],[-85.042551,31.539753],[-85.113751,31.27686],[-85.004212,31.003013],[-85.497137,30.997536],[-87.600282,30.997536],[-87.633143,30.86609],[-87.408589,30.674397],[-87.446927,30.510088],[-87.37025,30.427934],[-87.518128,30.280057],[-87.655051,30.247195],[-87.90699,30.411504],[-87.934375,30.657966],[-88.011052,30.685351],[-88.10416,30.499135],[-88.137022,30.318396],[-88.394438,30.367688],[-88.471115,31.895754],[-88.241084,33.796253],[-88.098683,34.891641],[-88.202745,34.995703],[-87.359296,35.00118]]]}},...
But i'm getting an empty HTML page as output. What am i missing?

No i don't see any issues with the code except may be us-states.json be not available in the root folder, where your code is looking for.
You can also access the us-states.json directly from github like this:
d3.json("https://raw.githubusercontent.com/alignedleft/d3-book/master/chapter_12/us-states.json", function(json) {
//Bind data and create one path per GeoJSON feature
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "steelblue");
});
Working code here

Related

How do I minimize mercator projection using D3

I would like to minimize greenland and antartica on my D3 geojson map. How do I do this. I've tried scale and translate methods but they simply move the map around on the page not providing the minimized y coordinates.
image of map
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="d3.v3.js"></script>
<script src="topojson.min.js"></script>
<style>
</style>
<script type="text/javascript">
function draw(geo_data) {
"use strict";
var margin = 75,
width = 1920 - margin,
height = 1080 - margin;
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin)
.attr("height", height + margin)
.append('g')
.attr('class', 'map');
var projection = d3.geo.mercator();
var path = d3.geo.path().projection(projection);
var map = svg.selectAll('path')
.data(geo_data.features)
.enter()
.append('path')
.attr('d', path)
.style('fill', 'rgb(9, 157, 217)')
.style('stroke', 'black')
.style('stroke-width', 0.5);
};
</script>
</head>
<body>
<script type="text/javascript">
/*
Use D3 to load the GeoJSON file
*/
//d3.json("world-topo-min.json", draw);
d3.json("world_countries.json", draw);
</script>
</body>
</html>
If you want to remove the areas for Greenland and Antarctica on the fly, you can simply filter your GeoJSON FeatureCollection, i.e. geo_data.features. In this array you will find features for both Greenland ("id": "GRL") as well as Antarctica ("id": "ATA"). Hence, you can make use of the array's .filter() method to get rid of these two features leaving the rest untouched:
var map = svg.selectAll('path')
.data(geo_data.features.filter(d => d.id !== "GRL" && d.id !== "ATA))

TopoJSON rendering issues using D3

I have rendered the world map using world-110m topojson. I directly used the code provided by Jakob on D3 mapping tutorial - http://www.digital-geography.com/d3-js-mapping-tutorial-1-set-initial-webmap/#.V4iGN9J97IV
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Set a style for our worldshape-data -->
<style>
path {
stroke: red;
stroke-width: 0.5px;
fill: grey;
}
</style>
<body>
<!-- implementation of the hosted D3- and TopoJson js-libraries -->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
<!-- map creation -->
<script>
// canvas resolution
var width = 1000,
height = 600;
// projection-settings for mercator
var projection = d3.geo.mercator()
// where to center the map in degrees
.center([0, 50 ])
// zoomlevel
.scale(100)
// map-rotation
.rotate([0,0]);
// defines "svg" as data type and "make canvas" command
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// defines "path" as return of geographic features
var path = d3.geo.path()
.projection(projection);
// group the svg layers
var g = svg.append("g");
// load data and display the map on the canvas with country geometries
d3.json("world-110m.json", function(error, topology) {
g.selectAll("path")
.data(topojson.object(topology, topology.objects.countries)
.geometries)
.enter()
.append("path")
.attr("d", path)
});
// zoom and pan functionality
/*var zoom = d3.behavior.zoom()
.on("zoom",function() {
g.attr("transform","translate("+
d3.event.translate.join(",")+")scale("+d3.event.scale+")");
g.selectAll("path")
.attr("d", path.projection(projection));
});
svg.call(zoom)*/
</script>
</body>
</html>
Now i want to reuse this code to render the map of India. But when I link it to India topoJSON file, only a blank SVG is created. The js console gives an error - topojson.v0.min.js:1 Uncaught TypeError: Cannot read property 'type' of undefined
I have placed world-110m.json and india.json on dropbox -
https://www.dropbox.com/sh/wrxyngyq4jdie9c/AACG2-dTzC79rRvlxlOC5poBa?dl=0
Its just a small error.
topojson.object(topology, topology.objects.countries //wrong
topojson.object(topology, topology.objects.collection // right
Next time check the data, by printing it to console and check its contents.

how to define data structure of D3 to draw pie ring

I am a D3 newer and wrote a program to draw a pie ring.
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>pie ring</title>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript">
var dataset=[{name:A,value:5},{name:C,value:10},{name:F,value:13}];
var pie=d3.layout.pie(dataset);
var h=600;
var w=600;
var outerRadius=w/2;
var innerRadius=w/3;
var arc=d3.svg.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
var svg=d3.select("body")
.append("svg")
.attr("width",w)
.attr("height",h);
var color=d3.scale.category10();
var arcs=svg.selectAll("g.arc")
.data(pie(dataset))
.enter()
.append("g")
.attr("class","arc")
.attr("transform","translate("+outerRadius+","+outerRadius+")");//translate(a,b)
arcs.append("path")
.attr("fill",function(d,i){
return color(i);
})
.attr("d",arc);
arcs.append("text")
.attr("transform",function(d){
return "translate("+arc.centroid(d)+")";
})
.attr("text-anchor","middle")
.text(function(d){
return d.name + ":" + d.value;
});
</script>
</body>
</html>
But failed, I don't know that how to define data structure and don't know how to pie dataset. pie(dataset) or pie(function(d){return d.value} ); could you help me to correct it
the javascript console told me that A is not defined. This A is the value of the name of the dataset. I don't know if the only request is digital value or digital array for pie ring.
Few problems here. It's telling you A isn't defined because it's not. You're using plain text instead of a string, so it thinks A is a variable, not a label. Even if you resolved that, there would be some other issues with the structure.
Copied almost straight from the d3 pie chart example here, I put in your data and it works a charm.
Here's the code, but I also strongly recommend going over the tutorial so you can see how it's supposed to work.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>pie ring</title>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript">
var w = 600;
var h = 600;
var outerRadius=w/2;
var innerRadius=w/3;
color = d3.scale.category20c();
data = [{"label":"A", "value":5},
{"label":"C", "value":10},
{"label":"F", "value":13}];
var vis = d3.select("body")
.append("svg:svg")
.data([data])
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")")
var arc = d3.svg.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
var pie = d3.layout.pie()
.value(function(d) { return d.value; });
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("svg:g")
.attr("class", "slice");
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); } )
.attr("d", arc);
arcs.append("svg:text")
.attr("transform", function(d) {
d.innerRadius = innerRadius;
d.outerRadius = outerRadius;
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.text(function(d, i) { return data[i].label; });
</script>
</body>
</html>

Drawing D3 Rectangles

I am a beginner with D3 and JS in general.
I am trying to do a simple rectangle visualisation with a small csv file as a source.
price, units
80.67, 100
80.87, 99
79.34, 47
File, csv are in the same folder.
I am using Python's SimpleHTTPServer to serve locally in this folder.
This is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Data</title>
<script type="text/javascript" src="../d3/d3.v3.js"></script>
</head>
<body>
<script type="text/javascript">
// load csv from the same directory
d3.csv("test.csv", function (data){
return {
price: +data.price, // convert to number with +
units: +data.units, // convert to number with +
};
var canvas = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 500)
canvas.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", function (d) { return d.price; })
.attr("height", 48)
.attr("y", function (d) { return d.units; })
.attr("fill", "blue");
canvas.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("fill", "white")
.attr("y", function (d) { return d.units + 24; })
.text( function (d) { return d.units;})
});
</script>
</body>
I am getting no errors, just a blank page.
What is wrong with this code?
The first thing you do in your callback is to return. None of the code after that is being executed. I'm referring to
return {
price: +data.price, // convert to number with +
units: +data.units, // convert to number with +
};
which should probably be
data.forEach(function(d) {
d.price = +d.price;
d.units = +d.units;
});
The signature of the callback should also be function(error, data) instead of function(data).

Issues with d3 zoomable map

I'm having an issue with a d3 zoomable map.
I'm loading the map from a previously built topojson file with a departmentsobject (the areas in the map) and a maternidadesobject (a few points in the map, initially rendered with crosses).
I'm using d3.behavior.zoom to implement the zoom behaviour, and I want it to be able to zoom using the mouse wheel and pan with drag. It works just fine with the map itself (the areas). However, the points in the map get shifted instantly to a wrong location at any zoom event. Also, the points' path is changed from crosses to circles somehow!
You can reproduce the issue and view the code here: http://bl.ocks.org/monsieurBelbo/5033491
Here is code:
<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.js"></script>
<script src="topojson.v0.min.js"></script>
<html>
<style>
.background {
fill: none;
pointer-events: all;
}
.department {
fill: #aaa;
stroke: #fff;
stroke-width: 1.5px;
}
</style>
<body>
<script>
d3.json("santafe.json", function(error, theProvince) {
var width= 960, height= 500;
var svg = d3.select("body").append("svg");
var departments = topojson.object(theProvince, theProvince.objects.departments);
// The projection
var projection = d3.geo.mercator()
.scale(14000)
.center([-60.951,-31.2])
.translate([width / 2, height / 2]);
// The path
var path = d3.geo.path()
.projection(projection);
// Zoom behavior
var zoom = d3.behavior.zoom()
.translate(projection.translate())
.scaleExtent([height, Infinity])
.scale(projection.scale())
.on("zoom", function() {
projection.translate(d3.event.translate).scale(d3.event.scale)
map.selectAll("path.zoomable").attr("d", path);
});
// The map
var map = svg.append("g")
.classed("provinceMap", true)
.call(zoom);
map.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);
// Departments
map.selectAll(".department")
.data(departments.geometries)
.enter().append("path")
.classed("department", true)
.classed("zoomable", true)
.attr("d", path);
// Places
map.selectAll(".place-label")
.data(topojson.object(theProvince, theProvince.objects.maternidades).geometries)
.enter().append("path")
.classed("place", true)
.classed("zoomable", true)
.attr("d", d3.svg.symbol().type("cross"))
.attr("transform", function(d) { return "translate(" + projection(d.coordinates.reverse()) + ")"; });
});
</script>
</body>
</html>
Any ideas?
Thanks!
UPDATE
Thanks to #enjalot 's suggestion, the issue was solved by re-translating the places on the zoom behaviour. Just add:
map.selectAll(".place").attr("transform", function(d) { return "translate(" + projection(d.coordinates) + ")"; });
to the zoom behavior. Check out a working version here: http://tributary.io/inlet/5095947

Resources