Choropleth Not Displaying - javascript

I'm working on a project in d3.js, and I can't seem to make my map work. Every time I run it there are no syntax errors, but there's only a blank screen. Here's the code:
<svg id="my_dataviz" width="1000" height="1000"></svg>
<script>
// The svg
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
// Map and projection
var path = d3.geoPath();
var projection = d3.geoMercator()
.scale(10000)
.center([30, -85])
.translate([width / 2, height / 2]);
// Data and color scale
var data = d3.map();
var colorScale = d3.scaleThreshold()
.domain([-5000, -3000, -1000, 1000, 3000, 5000])
.range(d3.schemeReds[7]);
// Load external data and boot
d3.queue()
.defer(d3.json, "G2.geojson")
.defer(d3.csv, "ps.csv", function(d) { data.set(d.GEOID20, +d.PRE_SC); })
.await(ready);
function ready(error, topo) {
// Draw the map
svg.append("g")
.selectAll("path")
.data(topo.features)
.enter()
.append("path")
// draw each country
.attr("d", d3.geoPath()
.projection(projection)
)
// set the color of each country
.attr("fill", function (d) {
d.total = data.get(d.id) || 0;
return colorScale(d.total);
});
}
</script>
</body>
</html>
I made sure that my projection was WGS 84. If I have any errors in the code please let me know! Thank you all!

Related

Choropleth map using D3.js and CSV file

I am using d3.js in a project for university where I have to visualize the world Choropleth world MAP passing the data to color the country form a file csv internally built this way:
nationality,victims
Austria,4500
France,1345
China,16000000
Italy,452345
Hungary,70000
and so on.
Until I create only the world map it works and a map will show on the web.
When I add the d3.csv part to read data it shows nothing.
I attached the code below:
function mapRender(){
var width = 900;
var height = 550;
//Select the div to show the maps
var svg = d3.select("#map")
.append("svg")
.attr("width", width)
.attr("height", height)
.append('g')
//Setting the color domains for the choropleth maps
var color = d3.scaleThreshold()
.domain([0, 50000, 100000, 150000, 200000, 500000, 1000000, 5000000, 10000000, 20000000])
.range(["#ffff00", "#FFF933", "#DCFF33", "#97FF33", "#40FF33", "#33FFA7", "#33FFFB", "#33AAFF", "#336EFF"]);
var projection = d3.geoMercator()
.scale(125)
.translate([width / 2, height / 1.4]);
var path = d3.geoPath().projection(projection);
d3.json("https://unpkg.com/world-atlas#1/world/110m.json", function (error, world) {
if (error) throw error;
//Load data from CSV file
d3.csv("../datasets/csv/choropleth.csv", function (data) {
var dataByName = {};
data.forEach(function (d) {
dataByName[d.nationality] = +d.victims;
});
svg.append("path")
.datum(topojson.feature(world, world.objects.land))
.append("path")
.attr("d", path)
.attr("fill", function(d) {
return color(dataByName[d.nationality]);
});
// .attr("fill", "#000000")
// .attr("d", path);
})
})
}
Anyone that can help me to understand why it doesn't work?

D3.js svg does not draw Map

I am trying to draw maps using D3.js. The GeoJson file is converted from shapefile and stored in the project folder.
The GeoJson data format:
{"type":"FeatureCollection", "features": [{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[31.287890625000017,-22.40205078125001],[31.429492187500017,-22.298828125],[31.57148437500001,-22.15351562500001],[31.737695312500023,-21.9833984375],[31.88593750000001,-21.83154296875],[32.01630859375001,-21.698046875000003],[32.19472656250002,-21.515429687500003],[32.37109375,-21.33486328125001],[32.41240234375002,-21.311816406250003],[32.429785156250006,-21.29707031250001],[32.353613281250006,-21.136523437500003],[32.476171875000006,-20.95009765625001],[32.48281250000002,-20.828906250000003],[32.477636718750006,-20.712988281250006],[32.49238281250001,-20.659765625000006],[32.529296875,-20.613085937500003],[32.67255859375001,-20.51611328125],[32.780859375000006,-20.36152343750001],[32.86962890625,-20.21718750000001],[32.992773437500006,-19.98486328125],[33.0048828125,-19.93017578125],[33.00673828125002,-19.873828125000003],[32.97265625,-19.79541015625],[32.89042968750002,-19.668066406250006],[32.83076171875001,-19.558203125000006],[32.77763671875002,-19.388769531250006],[32.83095703125002,-19.24140625000001],[32.85000000000002,-19.152441406250006],[32.84980468750001,-19.10439453125001],[32.826171875,-19.05878906250001],[32.766210937500006,-19.02431640625001],[32.71650390625001,-19.00185546875001],[32.69970703125,-18.94091796875],[32.69921875,-18.868457031250003],[32.72197265625002,-18.828417968750003],[32.8544921875,-18.763671875],[32.88457031250002,-18.728515625],[32.90029296875002,-18.689062500000006],[32.90166015625002,-18.632910156250006],[32.942480468750006,-18.49267578125],[32.99306640625002,-18.35957031250001],[32.99638671875002,-18.312597656250006],[32.978515625,-18.271484375],[32.96464843750002,-18.1962890625],[32.95556640625,-18.08291015625001],[32.954687500000006,-17.765429687500003],[32.98076171875002,-17.4375],[32.969335937500006,-17.251562500000006],[32.884375000000006,-17.03779296875001],[32.87626953125002,-16.883593750000003],[32.93789062500002,-16.775976562500006],[32.94804687500002,-16.71230468750001],[32.902929687500006,-16.704199218750006],[32.81025390625001,-16.69765625000001],[32.741796875000006,-16.67763671875001],[32.635839843750006,-16.589453125000006],[32.45195312500002,-16.515722656250006],[32.243261718750006,-16.44873046875],[31.939843750000023,-16.428808593750006],[31.687597656250006,-16.214160156250003],[31.489843750000006,-16.1796875],[31.426171875000023,-16.15234375],[31.236230468750023,-16.02363281250001],[30.938769531250017,-16.01171875],[30.630175781250017,-15.999218750000011],[30.437792968750017,-15.995312500000011],[30.40937500000001,-15.978222656250011],[30.39814453125001,-15.80078125],[30.396093750000006,-15.64306640625],[30.25068359375001,-15.643457031250009],[29.994921875000017,-15.64404296875],[29.729589843750006,-15.644628906250006],[29.4873046875,-15.69677734375],[29.287890625000017,-15.776464843750006],[29.050585937500017,-15.901171875000003],[28.973046875000023,-15.950097656250009],[28.9130859375,-15.98779296875],[28.875585937500006,-16.0361328125],[28.856738281250017,-16.14228515625001],[28.856738281250017,-16.30615234375],[28.83271484375001,-16.424121093750003],[28.760546875000017,-16.53212890625001],[28.760644531250023,-16.53193359375001],[28.399804687500023,-16.66279296875001],[28.16376953125001,-16.76972656250001],[27.932226562500006,-16.89619140625001],[27.75654296875001,-17.060351562500003],[27.63671875,-17.26210937500001],[27.437890625000023,-17.51191406250001],[27.235742187500023,-17.728320312500003],[27.020800781250017,-17.95839843750001],[26.779882812500006,-18.04150390625],[26.577539062500023,-18.022558593750006],[26.333398437500023,-17.929296875000006],[26.139550781250023,-17.911718750000006],[25.995898437500017,-17.969824218750006],[25.86328125,-17.951953125000003],[25.741601562500023,-17.858203125000003],[25.6396484375,-17.82412109375001],[25.55712890625,-17.84951171875001],[25.451757812500006,-17.84511718750001],[25.2587890625,-17.793554687500006],[25.239062500000017,-17.843066406250003],[25.224023437500023,-17.91523437500001],[25.242285156250006,-17.969042968750003],[25.28242187500001,-18.04121093750001],[25.340234375000023,-18.1044921875],[25.384375000000006,-18.14199218750001],[25.43671875000001,-18.234960937500006],[25.4892578125,-18.35126953125001],[25.55830078125001,-18.44179687500001],[25.76123046875,-18.649218750000003],[25.78369140625,-18.72353515625001],[25.811914062500023,-18.79707031250001],[25.939355468750023,-18.93867187500001],[25.95917968750001,-18.985644531250003],[25.95068359375,-19.08173828125001],[26.081933593750023,-19.369921875000003],[26.168066406250006,-19.53828125000001],[26.241015625000017,-19.5693359375],[26.474609375,-19.748632812500006],[26.67822265625,-19.89277343750001],[26.91669921875001,-19.99013671875001],[27.091796875,-20.05419921875],[27.17822265625,-20.10097656250001],[27.221484375000017,-20.145800781250003],[27.256738281250023,-20.232031250000006],[27.27460937500001,-20.3818359375],[27.28076171875,-20.47871093750001],[27.46894531250001,-20.47480468750001],[27.624609375000006,-20.48359375000001],[27.679296875000006,-20.503027343750006],[27.699609375000023,-20.53066406250001],[27.69482421875,-20.594531250000003],[27.69697265625001,-20.689746093750003],[27.70429687500001,-20.766406250000003],[27.688085937500006,-20.84833984375001],[27.67695312500001,-20.94482421875],[27.66943359375,-21.064257812500003],[27.693457031250006,-21.11103515625001],[27.844140625000023,-21.261523437500003],[27.90742187500001,-21.35908203125001],[27.974609375,-21.50673828125001],[28.014062500000023,-21.55419921875],[28.04560546875001,-21.573046875000003],[28.181640625,-21.58935546875],[28.532031250000017,-21.65126953125001],[28.74775390625001,-21.707617187500006],[28.919335937500023,-21.76601562500001],[28.99072265625,-21.78144531250001],[29.02558593750001,-21.796875],[29.03730468750001,-21.811328125000003],[29.01582031250001,-21.93994140625],[29.023339843750023,-21.981250000000003],[29.042382812500023,-22.018359375000003],[29.07148437500001,-22.047460937500006],[29.106835937500023,-22.065722656250003],[29.237207031250023,-22.07949218750001],[29.315234375000017,-22.15771484375],[29.364843750000006,-22.193945312500006],[29.37744140625,-22.19277343750001],[29.6630859375,-22.146289062500003],[29.90234375,-22.184179687500006],[30.1904296875,-22.291113281250006],[30.46015625000001,-22.32900390625001],[30.71162109375001,-22.2978515625],[30.916113281250006,-22.29072265625001],[31.07343750000001,-22.30781250000001],[31.197265625,-22.34492187500001],[31.287890625000017,-22.40205078125001]]]},"properties":{"featurecla":"Admin-0 country","scalerank":1,"LABELRANK":3,"SOVEREIGNT":"Zimbabwe","SOV_A3":"ZWE","ADM0_DIF":0,"LEVEL":2,"TYPE":"Sovereign country","ADMIN":"Zimbabwe","ADM0_A3":"ZWE","GEOU_DIF":0,"GEOUNIT":"Zimbabwe","GU_A3":"ZWE","SU_DIF":0,"SUBUNIT":"Zimbabwe","SU_A3":"ZWE","BRK_DIFF":0,"NAME":"Zimbabwe","NAME_LONG":"Zimbabwe","BRK_A3":"ZWE","BRK_NAME":"Zimbabwe","BRK_GROUP":"","ABBREV":"Zimb.","POSTAL":"ZW","FORMAL_EN":"Republic of Zimbabwe","FORMAL_FR":"","NAME_CIAWF":"Zimbabwe","NOTE_ADM0":"","NOTE_BRK":"","NAME_SORT":"Zimbabwe","NAME_ALT":"","MAPCOLOR7":1,"MAPCOLOR8":5,"MAPCOLOR9":3,"MAPCOLOR13":9,"POP_EST":13805084,"POP_RANK":14,"GDP_MD_EST":28330,"POP_YEAR":2017,"LASTCENSUS":2002,"GDP_YEAR":2016,"ECONOMY":"5. Emerging region: G20","INCOME_GRP":"5. Low income","WIKIPEDIA":-99,"FIPS_10_":"ZI","ISO_A2":"ZW","ISO_A3":"ZWE","ISO_A3_EH":"ZWE","ISO_N3":"716","UN_A3":"716","WB_A2":"ZW","WB_A3":"ZWE","WOE_ID":23425004,"WOE_ID_EH":23425004,"WOE_NOTE":"Exact WOE match as country","ADM0_A3_IS":"ZWE","ADM0_A3_US":"ZWE","ADM0_A3_UN":-99,"ADM0_A3_WB":-99,"CONTINENT":"Africa","REGION_UN":"Africa","SUBREGION":"Eastern Africa","REGION_WB":"Sub-Saharan Africa","NAME_LEN":8,"LONG_LEN":8,"ABBREV_LEN":5,"TINY":-99,"HOMEPART":1,"MIN_ZOOM":0,"MIN_LABEL":3,"MAX_LABEL":8,"NE_ID":1159321441,"WIKIDATAID":"Q954","NAME_AR":"زيمبابوي","NAME_BN":"জিম্বাবুয়ে","NAME_DE":"Simbabwe","NAME_EN":"Zimbabwe","NAME_ES":"Zimbabue","NAME_FR":"Zimbabwe","NAME_EL":"Ζιμπάμπουε","NAME_HI":"ज़िम्बाब्वे","NAME_HU":"Zimbabwe","NAME_ID":"Zimbabwe","NAME_IT":"Zimbabwe","NAME_JA":"ジンバブエ","NAME_KO":"짐바브웨","NAME_NL":"Zimbabwe","NAME_PL":"Zimbabwe","NAME_PT":"Zimbábue","NAME_RU":"Зимбабве","NAME_SV":"Zimbabwe","NAME_TR":"Zimbabve","NAME_VI":"Zimbabwe","NAME_ZH":"辛巴威"}},
My code:
<svg id="mapSVG" width="560"; height="350" style="border: solid 1px black;"></svg>
<script src="js/d3.js"></script>
<script src="js/d3.min.js"></script>
<script type="text/javascript">
//Setting svg width and attributes
var svg = d3.select("svg");
var width = +svg.attr("width");
var height = +svg.attr("height");
d3.json("Resources/countries.json").then(function (json) {
var projection = d3.geoMercator().fitSize([width, height], json);
//Projections
var geoPath = d3.geoPath().projection(projection);
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", geoPath)
.style("fill", "steelblue")
})
Problems: The SVG is completely empty. There is no error log in the console and I tried to output the json and it is actually getting the data.
When I inspect the svg, the size of the whole svg is 560x350, so I tried to play with the translate and center, but had no luck with it.
#AndrewReid was correct. It was a winding problem and fortunately there is a simple way to fix it using turf.js
d3.json(path).then(function (json) {
var projection = d3.geoMercator();
var features = json.features;
var fixed = features.map(function (feature) {
return turf.rewind(feature, { reverse: true });
})
//Projections
var geoPath = d3.geoPath().projection(projection);
projection.fitSize([width, height], { "type": "FeatureCollection", "features": fixed })
svg.selectAll("path")
.data(fixed)
.enter()
.append("path")
.attr("d", geoPath)

Why is my choropleth coming out all the same colour?

This is my first question on here so please bear with.
I'm trying to make a choropleth (a map where different sections are coloured in based on some value assigned to them) using d3.js. I'm using the example given at https://www.d3-graph-gallery.com/graph/choropleth_basic.html, but changing the map to one of Scotland and changing the values to population density.
When I run it, I get a map but it's all coloured in the same shade of blue. I've tried changing the domain of colorScale but to no avail.
This is what I've got at the minute:
// The svg
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
// Map and projection
var path = d3.geoPath();
var projection = d3.geoNaturalEarth()
.scale(20 * width / Math.PI)
.translate([width / 2 + 150, height / 2 + 2500]);
// Data and color scale
var data = d3.map();
var colorScale = d3.scaleThreshold()
.domain([0, 600])
.range(d3.schemeBlues[7]);
// Load external data and boot
d3.queue()
.defer(d3.json, "https://raw.githubusercontent.com/squirrel-star/scotland/main/geojsonscotlandladjson.geojson")
.defer(d3.csv, "https://raw.githubusercontent.com/squirrel-star/scotland/main/scotlanddensitywithid.csv", function(d) {
data.set(d.code, +d.density);
})
.await(ready);
function ready(error, topo) {
console.log(data);
// Draw the map
svg.append("g")
.selectAll("path")
.data(topo.features)
.enter()
.append("path")
// draw each country
.attr("d", d3.geoPath()
.projection(projection)
)
// set the color of each country
.attr("fill", function(d) {
d.total = data.get(d.id) || 0;
return colorScale(d.total);
});
}
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<svg id="my_dataviz" width="400" height="400"></svg>
Any suggestions for fixing it would be greatly appreciated. Thank you!
I think you may have misread the documentation for d3.scaleThreshold, because it says you need to have N values in your domain if you have N + 1 values in your range. In your case, that makes N = 6.
Also, d.id didn't exist. I used d.properties.LAD13NM instead, because that field contained the name of the relevant county.
Finally, there was no need to use a map, since you were only using it as an object of some sorts, so I just replaced it with a regular object.
// The svg
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
// Map and projection
var path = d3.geoPath();
var projection = d3.geoNaturalEarth()
.scale(20 * width / Math.PI)
.translate([width / 2 + 150, height / 2 + 2500]);
// Data and color scale
var data = {};
var colorScale = d3.scaleThreshold()
.domain([100, 200, 300, 400, 500, 600])
.range(d3.schemeBlues[7]);
// Load external data and boot
d3.queue()
.defer(d3.json, "https://raw.githubusercontent.com/squirrel-star/scotland/main/geojsonscotlandladjson.geojson")
.defer(d3.csv, "https://raw.githubusercontent.com/squirrel-star/scotland/main/scotlanddensitywithid.csv", function(d) {
data[d.code] = +d.density;
})
.await(ready);
function ready(error, topo) {
// Draw the map
svg.append("g")
.selectAll("path")
.data(topo.features)
.enter()
.append("path")
// draw each country
.attr("d", d3.geoPath()
.projection(projection)
)
// set the color of each country
.attr("fill", function(d) {
d.total = data[d.properties.LAD13NM] || 0;
return colorScale(d.total);
});
}
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<svg id="my_dataviz" width="400" height="400"></svg>

d3.js projection scale doesn't increase a size of a country

I'm trying to build something with d3.js and GeoJSON for the first time. I have managed to get a country - Estonia to be displayed but it is so small you can barely see it. I tried to play with projection geoMercator().scale but it doesn't work - no increase in size.
Please see a picture attached below(under bar chart):
Here is my js:
var projection = d3.geoMercator()
.translate([w/2, h/2])
.scale([100]);
var path = d3.geoPath()
.projection(projection)
var w3 = 2000;
var h3 = 1500;
var svg = d3.select("body")
.append("svg")
.attr("width", w3)
.attr("height", h3)
d3.json("estonia.json", function (json){
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "#2294AA");
})
What am I doing wrong?
I took your code and saw that when I increased the scale, Estonia disappeared. Had to center the projection like this:
var projection = d3.geoMercator()
.center([24.312863, 57.793424])
.scale([500])
.translate([w/2, h/2])
I took the coordinates [24.312863, 57.793424] from the .json file.

Why don't my TopoJSON lat and long points show on my US map?

I'm plotting points on a US Map with TopoJSON. I think my data is formatted correctly, everything is loading, the states are showing... but I have no points. The console has no errors. Here is my script:
var width = 800,
height = 500;
var projection = d3.geo.albersUsa()
.scale(1070)
.translate([420, height / 2]);
var path = d3.geo.path()
.projection(projection)
.pointRadius(1.5);
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height);
queue()
.defer(d3.json, "../us.json")
.defer(d3.json, "../users.json")
.await(ready);
function ready(error, us, users) {
svg.append("path")
.datum(topojson.feature(us, us.objects.land))
.attr("class", "land")
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("class", "states")
.attr("d", path);
svg.append("path")
.datum(topojson.feature(users, users.objects.users))
.attr("class", "points")
.attr("d", path);
};
And my data looks like:
{
"type": "Topology",
"transform": {
"scale": [
0.032229964456445645,
0.006392461796179619
],
"translate": [
-176.6460306,
7.367222
]
},
"objects": {
"users": {
"type": "MultiPoint",
"coordinates": [[-121.3806, 38.0213],
[-69.726226, 44.275051],
...long JSON file...
]
}
},
"arcs" : []
}
Again, I get no errors.. it just doesn't work.
I'd like to answer this question so that others like me can figure this out.
Per user1614080's suggestion, I was going about the problem wrong. Since I just wanted to plot lat and long coordinates on a map, I needed to use Geojson and overlay that over a TopoJSON map. Like, so:
var width = 900,
height = 500;
var projection = d3.geo.albersUsa()
.scale(1070)
.translate([460, height / 2]);
var path = d3.geo.path()
.projection(projection)
.pointRadius(2);
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height);
queue()
.defer(d3.json, "../us.json")
.defer(d3.tsv, "../long_lat.tsv")
.await(ready);
function ready(error, us, long_lat) {
if (error){
console.log(error);
}
svg.append("path")
.datum(topojson.feature(us, us.objects.land))
.attr("class", "land")
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("class", "states")
.attr("d", path);
svg.append("path")
.datum({type: "MultiPoint", coordinates: long_lat})
.attr("class", "points")
.attr("d", path)
.style('fill', 'rgb(247, 150, 29)');
};
Notice in the last block I append my lat long coordinates with geoJson, not TopoJson.
However, my graph still wouldn't work. And even more frustrating, it wasn't throwing me any errors. I looked and looked online, until I found this thread with Bostock:
https://groups.google.com/forum/#!topic/d3-js/rxs-g6ezPwY
He mentions something very important,
"...the points come from a CSV file with
columns 0 and 1 (longitude and latitude)..."
I hadn't realized that the 0 1 at the top of the tsv file mapped to long and lat. Once I realized I had my coordinates backwards, I fixed and prezto. It worked.

Categories

Resources