Published
Edited
Apr 10, 2019
Insert cell
Insert cell
Insert cell
//import {chart} from "@mbostock/d3-choropleth"
import {chart as choropleth} from "@chagel/d3-choropleth"
Insert cell
choropleth
Insert cell
Insert cell
Insert cell
bosNeighborhoods = d3.json('https://gist.githubusercontent.com/jdev42092/5c285c4a3608eb9f9864f5da27db4e49/raw/a1c33b1432ca2948f14f656cc14c7c7335f78d95/boston_neighborhoods.json')
//geoJSON has type and feature. the feature is what we want.
Insert cell
Insert cell
width = 700;
Insert cell
height = 580;
Insert cell
{
// Create SVG
let svg = d3.select( "body" )
.append( "svg" )
.attr( "width", width )
.attr( "height", height );

// Append empty placeholder g element to the SVG
// g will contain geometry elements
let g = svg.append( "g" );
//adding a group tag in the SVG
//the order you draw will affect the shape if the figure (which you draw after will be on the top)
return svg.node();
}
Insert cell
Insert cell
bosProjection = d3.geoEquirectangular()
.scale( 190000 )
.rotate( [71.057,0] )
.center( [0, 42.313] )
.translate( [width/2,height/2] );
//when don't know which projection to use, start with geoAlbers
//passing a projection object (d3.geoAlbers()) and save them as a variable.
Insert cell
Insert cell
// Create GeoPath function that uses built-in D3 functionality to turn
// lat/lon coordinates into screen coordinates
bos_geoPath = d3.geoPath()
.projection( bosProjection );
Insert cell
Insert cell
// your code here
//change the projection at bosProjection = d3.Albers() part
Insert cell
Insert cell
{
// Create SVG
let svg = d3.select(DOM.svg(width, height));

// Append empty placeholder g element to the SVG
// g will contain geometry elements
let g = svg.append("g");
//g help group elements in the same level. Could do the same operation for the whole group without looping.
// Classic D3... Select non-existent elements, bind the data, append the elements, and apply attributes
g.selectAll( "path" )
.data( bosNeighborhoods.features )
//this time we add ".features"
.enter()
.append( "path" )
.attr( "fill", "red" )
//can use language/ RGB, etc.
.attr( "stroke", "#333")
.attr( "d", bos_geoPath );
//d corresponding eaach point in the geometry (loop in all the points in the geoJSON)
return svg.node();
}
Insert cell
Insert cell
//the advantage of SVG: could add another data set on
rodentData = d3.json('https://gist.githubusercontent.com/jdev42092/ee94f6d469d7084e8dca4e8533817e0e/raw/7cfd6c34c974d3a86ff19c6180cfa22ee9ce3946/boston_rodents.json')
//type is just points now
Insert cell
Insert cell
{
// Create SVG
let svg = d3.select(DOM.svg(width, height));

// Append empty placeholder g element to the SVG
// g will contain geometry elements
let g = svg.append( "g" );
let rodents = svg.append( "g" );
// Classic D3... Select non-existent elements, bind the data, append the elements, and apply attributes
g.selectAll( "path" )
.data( bosNeighborhoods.features )
.enter()
.append( "path" )
.attr( "fill", "#ccc" )
.attr( "stroke", "#333")
.attr( "d", bos_geoPath );
rodents.selectAll( "path" )
.data( rodentData.features )
.enter()
.append( "path" )
.attr( "fill", "#900" )
.attr( "stroke", "#999" )
.attr( "d", bos_geoPath );
//bos_geoPath is already defined, the projection. loop through all the points in this projection
return svg.node();
}
Insert cell
Insert cell
Insert cell
// your code here

Insert cell
{
// Create SVG
let svg = d3.select(DOM.svg(width, height));

// Append empty placeholder g element to the SVG
// g will contain geometry elements
let g = svg.append( "g" );
let rodents = svg.append( "g" );
// Classic D3... Select non-existent elements, bind the data, append the elements, and apply attributes
g.selectAll( "path" )
.data( bosNeighborhoods.features )
.enter()
.append( "path" )
.attr( "fill", "#ccc" )
.attr( "stroke", "#333")
.attr( "d", bos_geoPath );
rodents.selectAll( "path" )
.data( rodentData.features )
.enter()
.append( "path" )
.attr( "fill", "blue" )
.attr( "stroke", "#999" )
.attr( "d", bos_geoPath );
//bos_geoPath is already defined, the projection. loop through all the points in this projection
return svg.node();
}
Insert cell
Insert cell
html`
<h1>Rodent Incidents in Boston</h1>

<div id = "label"></div>
`
// add an empty text element to put in name
//div is a html element lives outside the observable. after selecting it becomes the object you can manipulate with.
Insert cell
{
// Create SVG
let svg = d3.select(DOM.svg(width, height));

// Append empty placeholder g element to the SVG
// g will contain geometry elements
let g = svg.append( "g" );
let rodents = svg.append( "g" );

// Classic D3... Select non-existent elements, bind the data, append the elements, and apply attributes
g.selectAll( "path" )
.data( bosNeighborhoods.features )
.enter()
.append( "path" )
.attr( "fill", "#ccc" )
.attr( "stroke", "#333")
.attr( "d", bos_geoPath );
rodents.selectAll( "path" )
.data( rodentData.features )
.enter()
.append( "path" )
.attr( "fill", "steelblue" )
.attr( "stroke", "none" )
.attr( "opacity", 0.5)
.attr( "d", bos_geoPath )
.attr("class", "incident")
.on("mouseover", d => d3.select("#label").text(d.properties.LOCATION_STREET_NAME))
// .on("mouseover",myFunction)
//select the html element we select (the d), we will return the name of this point (d) in the text
.on("mouseout", d => d3.select("#label").text("Empty Selection"));
//"mouseout" means the mouse not on the dot
return svg.node();
}
Insert cell
Insert cell
{
// Create Event Handlers for mouse
function handleMouseOver(d, i) { // Add interactivity
// Use D3 to select element, change color and size
d3.select(this)
.attr("fill", "orange");
}

function handleMouseOut(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this).attr({
fill: "steelblue"
});
}
}
Insert cell
// your code here
{
function handleMouseOver(d, i) { // Add interactivity
// Use D3 to select element, change color and size
//we can choose two functions as well
d3.select("#label").text(d.properties.SOURCE)
d3.select(this)
.attr("fill", "orange");
}

function handleMouseOut(d, i) {
// Use D3 to select element, change color back to normal
d3.select(this)
.attr("fill", "steelblue");
}
// Create SVG
let svg = d3.select(DOM.svg(width, height));

// Append empty placeholder g element to the SVG
// g will contain geometry elements
let g = svg.append( "g" );
let rodents = svg.append( "g" );

// Classic D3... Select non-existent elements, bind the data, append the elements, and apply attributes
g.selectAll( "path" )
.data( bosNeighborhoods.features )
.enter()
.append( "path" )
.attr( "fill", "#ccc" )
.attr( "stroke", "#333")
.attr( "d", bos_geoPath );
rodents.selectAll( "path" )
.data( rodentData.features )
.enter()
.append( "path" )
.attr( "fill", "steelblue" )
.attr( "stroke", "none" )
.attr( "opacity", 0.5)
.attr( "d", bos_geoPath )
.attr("class", "incident")
.on("click", d => d3.select("#label").text(d.properties.SOURCE))
.on("mouseover", handleMouseOver)
// .on("mouseover",myFunction)
//select the html element we select (the d), we will return the name of this point (d) in the text
.on("mouseout", handleMouseOut);
//"mouseout" means the mouse not on the dot
return svg.node();
}
Insert cell
Insert cell
topojson = require("topojson-client@3")
//topojson requires a different file.
//topojson 的重合交叠的线只画一次,所以文件会小很多。
Insert cell
Insert cell
Insert cell
us = d3.json("https://unpkg.com/us-atlas@1/us/10m.json")
Insert cell
Insert cell
path = d3.geoPath();
Insert cell
Insert cell
{
let width = 960;
let height = 600;
// Create SVG
let svg = d3.select(DOM.svg(width, height));

let g = svg.append("g");
// Bind TopoJSON data
g.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features) // Bind TopoJSON data elements
.enter().append("path")
.attr("d", path)
.style("fill", "white")
.style("stroke", "black");

return svg.node();
}
Insert cell
Insert cell
// your code here

Insert cell
Insert cell
unemployment = d3.tsv("https://gist.githubusercontent.com/jdev42092/9a314291805640a097e16e58248627eb/raw/365c199c5a173a0018608615b6823b5cdcaa6bae/unemployment.tsv", ({id, rate}) => ({county: id, rate : +rate}))
Insert cell
Insert cell
unemp_data = {
// Create empty object for holding dataset
const rateById = {};
// Create property for each ID, give it value from rate
unemployment.forEach(d => (rateById[d.county] = +d.rate));

return rateById;
}
Insert cell
Insert cell
Insert cell
color = d3.scaleQuantize()
.domain([1, 10])
.range(d3.schemePurples[9]);
Insert cell
Insert cell
{
let width = 960;
let height = 600;
// Create SVG
let svg = d3.select(DOM.svg(width, height));

let g = svg.append("g");
// Create empty object for holding dataset
const rateById = {};
// Create property for each ID, give it value from rate
unemployment.forEach(d => (rateById[d.county] = +d.rate));
// Bind TopoJSON data
g.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features) // Bind TopoJSON data elements
.enter().append("path")
.attr("d", path)
.style("fill", d => color(rateById[d.id])) // get rate value for property matching data ID
// pass rate value to color function, return color based on domain and range
.style("stroke", "black");

return svg.node();
}
Insert cell
Insert cell
{
let width = 960;
let height = 600;
// Create SVG
let svg = d3.select(DOM.svg(width, height));

let g = svg.append("g");
// Create empty object for holding dataset
const rateById = {};
// Create property for each ID, give it value from rate
unemployment.forEach(d => (rateById[d.county] = +d.rate));
// Bind TopoJSON data
g.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features) // Bind TopoJSON data elements
.enter().append("path")
.attr("d", path)
.style("fill", d => color(rateById[d.id]));

g.append("path")
.datum(topojson.mesh(us, us.objects.states, (a, b) => a !== b))
.attr("fill", "none")
.attr("stroke", "white")
.attr("d", path);

return svg.node();
}
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