Public
Edited
Nov 12, 2020
1 star
Insert cell
Insert cell
map = {
const svg = d3
.create("svg")
.attr("width", w)
.attr("height", h)
.attr("viewBox", [0, 0, w, h])

let map = svg
.append('g')
const s = 6
map.selectAll('.point')
.data(weather_data)
.enter()
.append('rect')
.attr('width', s)
.attr('height', s)
.attr('class', 'point')
.attr('transform', d => {
let p = projection([d.X, d.Y])
return `translate(${p[0]-s/2} ${p[1]-s/2})`
})
.attr('fill', d => temp_color(d.Value))
let screen = map.append('g')
.attr('class', 'screen')
screen.append('rect')
.attr('width', w*1.2)
.attr('height', h*1.2)
.attr('x', -w*0.1)
.attr('y', -h*0.1)
.attr('class', 'screenrect')
screen
.selectAll(".subunit")
.data(provinces.features)
.enter()
.append("path")
.attr("class", "subunit")
.attr("d", path)
map
.append('path')
.datum(topojson.merge(italy, italy.objects.subunits.geometries))
.attr("d", path)
.attr("class", "italy")
map
.append('path')
.datum(topojson.mesh(italy, italy.objects.subunits, (a,b) => a !== b && usu.get(a.id).codice_regione == usu.get(b.id).codice_regione))
.attr("d", path)
.attr("class", "subunits_borders")
map
.append('path')
.datum(topojson.mesh(italy, italy.objects.subunits, (a,b) => a !== b && usu.get(a.id).codice_regione != usu.get(b.id).codice_regione))
.attr("d", path)
.attr("class", "units_borders")
/*
map
.selectAll('.bubble')
.data(provinces.features)
.enter()
.append('g')
.attr('transform', d => {
let point = projection([usu.get(d.id).long, usu.get(d.id).lat])
return `translate(${point[0]} ${point[1]})`
})
.append('circle')
.attr('r', d => Math.random()*5)
.attr("class", "bubble")
*/
// zoom
function zoomed() {
map.attr('transform', d3.event.transform)
map.selectAll('.bubble').attr('transform', `scale(${1/d3.event.transform.k})`)
}
svg.call(d3.zoom()
.scaleExtent([0, Infinity])
.on('zoom', zoomed))
return svg.node()
}
Insert cell
Insert cell
Insert cell
Insert cell
html`
<style>
.italy {
fill: none;
stroke: #222;
stroke-width: 0.5;
vector-effect: non-scaling-stroke;
}
.subunit {
fill: #777;
}
.subunits_borders {
fill: none;
stroke: #999;
stroke-width: 0.5;
vector-effect: non-scaling-stroke;
mix-blend-mode: multiply;
}
.screen {
mix-blend-mode: screen;
}
.screenrect {
fill: white;
}
.units_borders {
fill: none;
stroke: #222;
stroke-width: 0.5;
vector-effect: non-scaling-stroke;
mix-blend-mode: multiply;
}
.bubble {
fill: black;
fill-opacity: 0.2;
stroke: black;
stroke-width: 0.75;
vector-effect: non-scaling-stroke;
pointer-events: none;
}
</style>
`
Insert cell
temp_color = d3.scaleLinear()
.domain([-10,0,15,20])
.range([d3.hcl(290,70,15),d3.hcl(230,70,45),d3.hcl(80,70,75),d3.hcl(10,70,45)])
.interpolate(d3.interpolateHcl)
Insert cell
Insert cell
Insert cell
weather_data = d3.csvParse(await FileAttachment("Temperatura_media_anno.csv").text(), d3.autoType)
Insert cell
units_subunits_data = d3.csvParse(await FileAttachment("units_subunits.csv").text(), d3.autoType)
Insert cell
usu = new Map(units_subunits_data.map(d => [d.codice_provincia, d]))
Insert cell
Insert cell
italy = FileAttachment("italy.json").json()
Insert cell
provinces = topojson.feature(italy, italy.objects.subunits)
Insert cell
Insert cell
Insert cell
projection = d3.geoAzimuthalEqualArea() // Lambert equal-area
.rotate([-9, -53]) // centered in Germany
.fitExtent([[0, 0], [w, h]], provinces)
Insert cell
path = d3.geoPath().projection(projection)
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more