Published
Edited
Apr 18, 2019
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
//add d3
d3 = require("d3@5")
Insert cell
//add topojson
topojson = require("topojson-client@3")
Insert cell
//import the json
bostonjson = d3.json('https://gist.githubusercontent.com/cesandoval/09b2e39263c748fbcb84b927cecc7c46/raw/ab71d3638efd2545ec99c2651c6f2ddcea9d2a07/boston.json')
Insert cell
//import the csv
csv311 = await d3.csv('https://gist.githubusercontent.com/cesandoval/046a91586ae76889aeb5b3e9db53016e/raw/ffb0c410ce8503c8c839cde01235bafb39cb14ad/bostosn_311.csv')
Insert cell
//import the csv
csv311_reg = await d3.csv('https://gist.githubusercontent.com/cesandoval/046a91586ae76889aeb5b3e9db53016e/raw/ffb0c410ce8503c8c839cde01235bafb39cb14ad/bostosn_311.csv')
Insert cell
color = d3.scaleQuantize()
.domain([1, 4])
.range(d3.schemePurples[9]);
Insert cell
//set the projection
bosProjection = d3.geoAlbers()
.scale( 190000 )
.rotate( [71.057,0] ) //longitude
.center( [0, 42.313] ) //latitude
.translate( [width/2,height/2] );
Insert cell
// Create GeoPath function that uses built-in D3 functionality to turn
// lat/lon coordinates into screen coordinates
path = d3.geoPath()
.projection( bosProjection );
Insert cell
Insert cell
width = 700
Insert cell
height = 600
Insert cell
{
// Create SVG
let svg = d3.select(DOM.svg(width, height));

let g = svg.append("g");
g.selectAll("path") //bind TopoJSON data
.data( topojson.feature(bostonjson, bostonjson.objects.boston_neigh).features ) // Bind TopoJSON data elements
.enter()
.append("path")
.attr("d", path)

// get rate value for property matching data ID
.style("fill", d => color(Math.log(csv311_twitterByNeighborhood[d.properties.OBJECTID])))
.style("stroke", "black");
return svg.node();
}
Insert cell
{
// Create SVG
let svg = d3.select(DOM.svg(width, height));

let g = svg.append("g");
tooltip1
g.selectAll("path") //bind TopoJSON data
.data( topojson.feature(bostonjson, bostonjson.objects.boston_neigh).features ) // Bind TopoJSON data elements
.enter()
.append("path")
.attr("d", path)

.style("fill", d => color(Math.log(csv311_twitterByNeighborhood[d.properties.OBJECTID]))) // get rate value for property matching data ID
.style("stroke", "black")
//on mouseover, show Name
.on("mouseover", d => tooltip1.style("visibility","visible").text(d.properties.id))
//on mousemove, show Name: Tweets
.on("mousemove", d => tooltip1.style("top", (d3.event.pageY-10)+"px").style("left", (d3.event.pageX+10)+"px").text(d.properties.Name + ": " + (csv311_twitterByNeighborhood[d.properties.OBJECTID]/500)*100+"%"))
//on mouseout, hide tooltip
.on("mouseout", d => tooltip1.style("visibility", "hidden"));
return svg.node();
}
Insert cell
Insert cell
tooltip1 = d3.select("body")
.append("div")
.style("position","absolute")
.style("opacity",.6) //60% opaque
.style("font-size", "12px")
.style("background","#fff") //white background color
.style("padding","5px"); //5 pixels of padding
Insert cell
Insert cell
legend = g => {
const x = d3.scaleLinear()
.domain(d3.extent(color.domain()))
.rangeRound([0, 250]);

g.selectAll("rect")
.data(color.range().map(d => color.invertExtent(d)))
.join("rect")
.attr("height", 10)
.attr("x", d => x(d[0]))
.attr("width", d => x(d[1]) - x(d[0]))
.attr("fill", d => color(d[0]));

g.append("text")
.attr("x", x.range()[0])
.attr("y", 50)
.attr("fill", "currentColor")
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text("Tweets per neighborhood (log scale)");

g.call(d3.axisBottom(x)
.tickSize(13)
.tickFormat(d => d3.format(".2n")(d)) //defining decimal numbers
.tickValues(color.range().slice(1).map(d => color.invertExtent(d)[0])))
.select(".domain")
.remove();
}
Insert cell
{
// Create SVG
let svg = d3.select(DOM.svg(width, height));

tooltip1
let g = svg.append("g")
.call(legend);
g.selectAll("path") //bind TopoJSON data
.data( topojson.feature(bostonjson, bostonjson.objects.boston_neigh).features ) // Bind TopoJSON data elements
.enter()
.append("path")
.attr("d", path)

.style("fill", d => color(Math.log(csv311_twitterByNeighborhood[d.properties.OBJECTID]))) // get rate value for property matching data ID
.style("stroke", "black")
//on mouseover, show Name
.on("mouseover", d => tooltip1.style("visibility","visible").text(d.properties.id))
//on mousemove, show Name: Tweets
.on("mousemove", d => tooltip1.style("top", (d3.event.pageY-10)+"px").style("left", (d3.event.pageX+10)+"px").text(d.properties.Name + ": " + (csv311_twitterByNeighborhood[d.properties.OBJECTID]/500)*100+"%"))
//on mouseout, hide tooltip
.on("mouseout", d => tooltip1.style("visibility", "hidden"));
return svg.node();
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more