Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/topojson@3"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<div id="mapa" style="position: relative;left: 0; top: 0;">
<canvas id='mapa_base'
style="position: absolute; left: 0; top: 0; z-index: 0;border: 2px solid green"></canvas>
<canvas id='mapa_bolhas'
style="position: absolute; left: 0; top: 0; z-index: 1;border: 1px solid red"></canvas>
</div>
<script>
const width = 800;
const height = 800;
const canvas_bolhas = d3.select("#mapa_bolhas")
.attr("width", width)
.attr("height", height);
const canvasBase = d3.select("#mapa_base")
.attr("width", width)
.attr("height", height);
const baseMapa = canvasBase.node().getContext("2d")
const context = canvas_bolhas.node().getContext("2d");
/*var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height) */
const promises =
[d3.json('municipios.json'),
d3.json('estados.json')];
Promise.all(promises).then((values) => {
const municipios = values[0];
const estados = values[1];
//const rio = municipios.filter(d => d.uf === "RJ")
const rio = municipios.filter(d => d)
const rio_base = topojson.feature(estados, estados.objects.BRUFE250GC_SIR);
const rio_filtro = rio_base.features.filter(d=> d.properties.CD_GEOCUF == 33)[0]
const extent = d3.extent(municipios, d=> d.pop2017)
const maximo = extent[1]
const escalaCor = d3.scaleLinear()
const projecao = d3.geoMercator().fitSize([width, height], rio_base)
const path = d3.geoPath().projection(projecao).context(baseMapa) //IMPORTANTE
const tamanho = d3.scaleSqrt().domain(extent).range([1,20])
const cor = d3.scaleOrdinal().domain([1,2,3,4]).range(d3.schemeSet1)
const simulacao = d3.forceSimulation()
.force('center', d3.forceCenter(width / 2, height / 2))
.force('collision', d3.forceCollide(d => tamanho(d.pop2017)).iterations(2))
.force('x', d3.forceX(d => projecao([d.lon,d.lat])[0]).strength(0.3))
.force('y', d3.forceY(d => projecao([d.lon,d.lat])[1]).strength(0.3))
.nodes(rio)
/*const base = canvas.selectAll('.base_UF')
.data([null])
.enter()
.append('path')
.attr('class', 'base_UF')
.attr('d', path(rio_base))
.style('fill', '#f2f2f2')
*/
function drawBase(ctx){
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.fillStyle = '#f2f2f2';
path(rio_base);
ctx.fill();
ctx.closePath();
}
/*const circulos = canvas.selectAll("circle.node")
.data(municipios)
.enter()
.append("circle")
.attr("class", "node")
.attr('r', d => tamanho(d.pop2017))
.style('fill', d => cor(d.venc))
.style('stroke', 'red')
.style("stroke-width", 0)
circulos.append('title')
.text(d => d.municipio)
*/
drawBase(baseMapa);
simulacao.on("tick", ticked)
function ticked(){
context.clearRect(0, 0, width, height);
// draw nodes
context.strokeStyle = "#fff";
context.lineWidth = 0.5;
municipios.forEach(function(d, i) {
context.beginPath();
context.fillStyle = cor(d.venc);
context.moveTo(d.x, d.y);
context.arc(d.x, d.y, tamanho(d.pop2017), 0, 2 * Math.PI);
context.stroke();
context.fill();
context.closePath();
});
/*d3.selectAll("circle.node")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
*/
}
})
</script>
</body>
https://d3js.org/d3.v5.min.js
https://unpkg.com/topojson@3