Skip to content

Instantly share code, notes, and snippets.

@mariohmol
Created September 1, 2020 17:26
Show Gist options
  • Save mariohmol/6179e71a834df367c44185af558ed070 to your computer and use it in GitHub Desktop.
Save mariohmol/6179e71a834df367c44185af558ed070 to your computer and use it in GitHub Desktop.
D3 Geo Maps WIth Brazil
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="me"
href="https://twitter.com/twitterdev"
>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body class="mat-typography">
<div id="container"></div>
<div id="container2"></div>
<script src="/test/d3.min.js"></script>
<script src="/test/d3plus-geomap.v0.7.full.min.js"></script>
<script src="https://d3js.org/d3-array.v2.min.js"></script>
<script src="https://d3js.org/d3-geo.v2.min.js"></script>
<script src="/test/topojson.v1.min.js"></script>
<!-- <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> -->
<script src="/test/index.js"></script>
</body>
</html>
function main() {
// https://bl.ocks.org/almccon/410b4eb5cad61402c354afba67a878b8
// https://github.com/d3plus/d3plus-geomap/blob/8724bfa93f91fb44f7f0fc827e02cfbee63a5757/src/Geomap.js#L41
// https://github.com/d3plus/d3plus-geomap/blob/master/src/Geomap.js
// https://github.com/Irio/br-atlas/blob/master/geo/to-municipalities.json
// const url = `http://localhost:8080/api/geo/state/states`;
// const state = '11'
// const url = `/test/states/${state}.json`;
// d3.json(url, function (error, topology) {
// console.log(url)
// if (error) throw error;
// makeChart6('#container', topology, topology.objects[state]);
// })
const url3 = `/test/states/to-municipalities.json`;
d3.json(url3, function (error, topology) {
console.log(url3)
if (error) throw error;
makeChart8('#container', topology);
})
const url2 = '/test/us.json'
// d3.json(url2, function (error, topology) {
// console.log(url2)
// if (error) throw error;
// makeChart3('#container2', topology, topology.objects.states);
// })
}
main();
var width = 960,
height = 500;
function makeChart8(div, json){
var vis = d3.select(div).append("svg")
.attr("width", width).attr("height", height)
// create a first guess for the projection
var center = d3.geo.centroid(json)
var scale = 150;
var offset = [width/2, height/2];
var projection = d3.geo.mercator().scale(scale).center(center)
.translate(offset);
// create the path
var path = d3.geo.path().projection(projection);
// using the path determine the bounds of the current map and use
// these to determine better values for the scale and translation
var bounds = path.bounds(json);
var hscale = scale*width / (bounds[1][0] - bounds[0][0]);
var vscale = scale*height / (bounds[1][1] - bounds[0][1]);
var scale = (hscale < vscale) ? hscale : vscale;
var offset = [width - (bounds[0][0] + bounds[1][0])/2,
height - (bounds[0][1] + bounds[1][1])/2];
// new projection
projection = d3.geo.mercator().center(center)
.scale(scale).translate(offset);
path = path.projection(projection);
// add a rectangle to see the bound of the svg
vis.append("rect").attr('width', width).attr('height', height)
.style('stroke', 'black').style('fill', 'none');
vis.selectAll("path").data(json.features).enter().append("path")
.attr("d", path)
.style("fill", "red")
.style("stroke-width", "1")
.style("stroke", "black")
}
function makeChart7(div, features) {
// Create a unit projection.
var projection = d3.geo.albers()
.scale(1)
.translate([0, 0]);
// Create a path generator.
var path = d3.geo.path()
.projection(projection);
// Compute the bounds of a feature of interest, then derive scale & translate.
var b = path.bounds(features[0]),
s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];
// Update the projection to use computed scale & translate.
projection
.scale(s)
.translate(t);
// let path = d3.geoPath().projection(projection)
// const pathData = features.map(feature => path(feature));
const svg = d3.select(div).append('svg')
.attr('width', width)
.attr('height', height);
svg.append("path")
.datum({ type: "FeatureCollection", features: features })
// .enter().append("path")
// .attr("id", "landmass")
// .attr("transform", "scale(2)")
.attr('fill', '#000')
// .attr('stroke', '#000')
.attr("d", path);
}
function makeChart6(div, features) {
console.log(features)
// var projection = d3.geoEqualEarth();
const projection = d3.geoMercator();
// projection.scale(projection.scale() * (2 * Math.PI) * 2)
let path = d3.geoPath().projection(projection)
const pathData = features.map(feature => path(feature));
const svg = d3.select(div).append('svg')
.attr('width', width)
.attr('height', height);
svg.append("path")
.datum({ type: "FeatureCollection", features: features })
// .enter().append("path")
// .attr("id", "landmass")
// .attr("transform", "scale(2)")
.attr('fill', '#000')
// .attr('stroke', '#000')
.attr("d", path);
}
function makeChart5() {
const coordData = this._coordData = this._topojson
? topo2feature(this._topojson, this._topojsonKey)
: { type: "FeatureCollection", features: [] };
const topoData = coordData.features.reduce((arr, feature) => {
const id = this._topojsonId(feature);
arr.push({
__d3plus__: true,
data: pathData[id],
feature,
id
});
return arr;
}, []);
this._shapes.push(new Path()
.data(topoData)
.d(d => path(d.feature))
.select(pathGroup.node())
.x(0).y(0)
.config(configPrep.bind(this)(this._shapeConfig, "shape", "Path"))
.render());
}
function makeChart4(div, map, objs) {
console.log(map, features)
// objs = map.objects.world
var features = objs.geometries
.map( //.map: create a new array by applying the function below to each element of the orignal array
function (g) { //take the geometry
return topojson.feature(map, g) //and return the corresponding feature.
}
);
var width = 960,
height = 500;
const path = d3.geo.path();
const svg = d3.select(container).append('svg')
.attr('width', width)
.attr('height', height);
svg.selectAll(div)
.data(features)
.enter()
.append("path")
.attr("class", "state")
.attr("d", path);
}
function makeChart3(container, topology, geojsonTopo) {
var width = 960,
height = 500;
const path = d3.geo.path();
const svg = d3.select(container).append('svg')
.attr('width', width)
.attr('height', height);
console.log('topojson', topology)
var geojson = topojson.feature(topology, geojsonTopo);
console.log('geojson', geojson)
svg.selectAll('path')
.data(geojson.features)
.enter().append('path')
.attr('fill', '#088')
.attr('stroke', '#000')
.attr('d', path);
const states_contour = topojson.mesh(topology, geojsonTopo);
svg.append("path")
.datum(states_contour)
.attr("d", path)
.attr("class", "state_contour");
}
function makeChart2(div, bb) {
let width = 200, height = 200;
let projection = d3.geoEqualEarth();
projection.fitSize([width, height], bb);
let geoGenerator = d3.geoPath()
.projection(projection);
let svg = d3.select(div).append('svg')
.style("width", width).style("height", height);
svg.append('g').selectAll('path')
.data(bb.features)
.join('path')
.attr('d', geoGenerator)
.attr('fill', '#088')
.attr('stroke', '#000');
}
function makeChart(url, values) {
// https://developer.aliyun.com/mirror/npm/package/d3plus-geomap
if (!this.chart) {
this.chart = new d3plus.Geomap()
.colorScale('value')
.topojson(url)
.select('#container')
.label((d) => {
return `<p>${d.label}</p>`;
})
.colorScaleConfig({ scale: 'jenks' });
// const path = d3.geo.path();
// const width = 960,
// height = 500;
// const svg = d3.select('#container').append('svg')
// .attr('width', width)
// .attr('height', height);
// d3.json(url, function (error, map) {
// console.log(map);
// const features = map.objects.geojson.geometries
// .map( // .map: create a new array by applying the function below to each element of the orignal array
// function (g) { // take the geometry
// return topojson.feature(map, g); // and return the corresponding feature.
// }
// );
// svg.selectAll('.state')
// .data(features)
// .enter()
// .append('path')
// .attr('class', 'state')
// .attr('d', path);
// });
}
this.chart.config({
data: values,
tiles: false,
zoom: false,
ocean: 'transparent'
})
.render(() => {
document.querySelectorAll('.d3plus-Path').forEach(d => {
d.addEventListener('click', (e) => {
const target = e.target;
const id = target.className.baseVal.split('-id-')[1];
const state = this.states[id];
this.openDialog(state);
});
});
});
}
function topo2feature(topo, key) {
const k = key && topo.objects[key] ? key : Object.keys(topo.objects)[0];
return feature(topo, k);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment