Published
Edited
Dec 7, 2020
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = {top: 0, right: 0, bottom: 0, left: 0};
const visWidth = 600 - margin.left - margin.right;
const visHeight = 400 - margin.top - margin.bottom;

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
// draw map
const projection = d3.geoAlbersUsa()
.fitSize([visWidth, visHeight], usaGeo);

const path = d3.geoPath().projection(projection);

g.selectAll('.border')
// we're not going to show Puerto Rico and it's not in the
// unemployment rate data, so we'll filter it out
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('path')
.attr('class', 'border')
.attr('d', path)
.attr('fill', d => color(stateToRate[d.properties.NAME]))
.attr('stroke', 'white')

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
maxRadius = 10
Insert cell
maxUnemployment = d3.max(unemployment, d => d.rate)
Insert cell
minUnemployment = d3.min(unemployment, d => d.rate)
Insert cell
radius = d3.scaleSqrt()
.domain([minUnemployment, maxUnemployment])
.range([2, maxRadius])
Insert cell
Insert cell
{
const margin = {top: 10, right: 30, bottom: 10, left: 30};
const visWidth = 600 - margin.left - margin.right;
const visHeight = 400 - margin.top - margin.bottom;

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
// dray legend
const legend = g.append("g")
.selectAll("g")
.data([minUnemployment, minUnemployment + ((maxUnemployment - minUnemployment)/3), maxUnemployment - ((maxUnemployment - minUnemployment)/4), maxUnemployment])
.join("g")
.attr("transform", (d, i) => `translate(0, ${i * 2.5 * maxRadius})`);
legend.append("circle")
.attr("r", d => radius(d))
.attr("fill", "orange");

legend.append("text")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.attr("dominant-baseline", "middle")
.attr("x", maxRadius + 5)
.text(d => d);
// draw map
const projection = d3.geoAlbersUsa()
.fitSize([visWidth, visHeight], usaGeo);

const path = d3.geoPath().projection(projection);

g.selectAll('.border')
// we're not going to show Puerto Rico and it's not in the
// unemployment rate data, so we'll filter it out
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('path')
.attr('class', 'border')
.attr('d', path)
.attr('fill', d => 'lightgrey')
.attr('stroke', 'white')
g.selectAll('dot')
.data(usaGeo.features.filter(d => d.properties.NAME !== 'Puerto Rico'))
.join('circle')
.attr('class', 'dot')
.attr('fill', 'orange')
.attr('r', d => radius(stateToRate[d.properties.NAME]))
.attr('transform', d=> `translate(${path.centroid(d)})`)

return svg.node();
}
Insert cell
Insert cell
md`Just a simple bar chart.`
Insert cell
states = unemployment.map(d => d.state)
Insert cell
Insert cell
{
const margin = {top: 10, right: 60, bottom: 50, left: 100};
const visWidth = 600 - margin.left - margin.right;
const visHeight = 800 - margin.top - margin.bottom;
const yScale = d3.scaleBand()
.domain(unemployment.map(d => d.state))
.range([0, visHeight])
.padding(0.2)
const xScale = d3.scaleLinear()
.domain([0, maxUnemployment])
.range([0, visWidth])
const yaxis = d3.axisLeft(yScale)
const xaxis = d3.axisBottom(xScale)

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
g.selectAll('rect')
.data(usaGeo.features)
.join('rect')
.attr('fill', 'steelblue')
.attr('x', 0)
.attr('y', d => yScale(d.properties.NAME))
.attr('width', d=> xScale(stateToRate[d.properties.NAME]))
.attr('height', d=> yScale.bandwidth())
g.append('g')
.call(yaxis)
g.append('g')
.attr('transform', `translate(0, ${visHeight})`)
.call(xaxis)
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', visWidth/2)
.attr('y', 40)
.text('Unemployment Rate')
return svg.node()
}
Insert cell
Insert cell
Insert cell
Insert cell
{
const margin = {top: 10, right: 60, bottom: 150, left: 100};
const visWidth = 600 - margin.left - margin.right;
const visHeight = 1400 - margin.top - margin.bottom;
const yScale = d3.scaleBand()
.domain(unemployment.map(d => d.state))
.range([0, visHeight])
.padding(0.4)
const xScale = d3.scaleLinear()
.domain([0, maxUnemployment])
.range([0, visWidth])
const yaxis = d3.axisLeft(yScale)
//const xaxis = d3.axisBottom(xScale)

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const legend = g.append("g")
.selectAll("g")
.data([minUnemployment, minUnemployment + ((maxUnemployment - minUnemployment)/3), maxUnemployment - ((maxUnemployment - minUnemployment)/4), maxUnemployment])
.join("g")
.attr("transform", (d, i) => `translate(0, ${visHeight + 50 + i * 20})`);
legend.append("text")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.attr("dominant-baseline", "middle")
.attr("x", visWidth + 2)
.text(d => d);
g.selectAll('line')
.data(usaGeo.features)
.join('line')
.attr('stroke', 'steelblue')
.attr('stroke-width', 4)
.attr('x1', d => (visWidth - xScale(stateToRate[d.properties.NAME]))/2)
.attr('x2', d => (visWidth + xScale(stateToRate[d.properties.NAME]))/2)
.attr('y1', d => yScale(d.properties.NAME))
.attr('y2', d => yScale(d.properties.NAME))
legend.append("line")
.attr("stroke", "steelblue")
.attr('stroke-width', 4)
.attr("x1", d => (visWidth - xScale(d))/2)
.attr("x2", d => (visWidth + xScale(d))/2)
.attr('y1', (d, i) => 0)
.attr('y2', (d, i) => 0)
g.append('text')
.attr("font-family", "sans-serif")
.attr("font-size", 16)
.attr("dominant-baseline", "middle")
.attr("x", 0)
.attr('y', visHeight + 20)
.text('Length of line corresoponds to percent unemployment for each state');
g.append('g')
.call(yaxis)
// g.append('g')
// .attr('transform', `translate(0, ${visHeight})`)
// .call(xaxis)
// .append('text')
// .attr('fill', 'black')
// .attr('font-family', 'sans-serif')
// .attr('x', visWidth/2)
// .attr('y', 40)
// .text('Unemployment Rate')
return svg.node()
}
Insert cell
Insert cell
Insert cell
meanUnemployment = d3.mean(unemployment, d => d.rate)
Insert cell
pieUnemployment = {
var arr = []
var arrayLength = unemployment.length;
for (var i = 0; i < arrayLength; i++) {
var obj = {state: unemployment[i].state, rate: [{status: "Unemployed" , percent: unemployment[i].rate},{ status:"Employed", percent: 100 - unemployment[i].rate}]}
arr.push(obj)
}
return arr
}
Insert cell
unemploymentPieWithGrid = d3.zip(pieUnemployment, gridPositions)
.map(([data, pos]) => ({...data, ...pos}))
Insert cell
Insert cell
Insert cell
{
const margin = {top: 10, right: 20, bottom: 0, left: 50};
const visWidth = 750 - margin.left - margin.right;
const visHeight = 800 - margin.top - margin.bottom;

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom)
.attr('font-family', 'sans-serif')
.attr('text-anchor', 'middle');

const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
// set up scales
const color = d3.scaleOrdinal()
.domain(["Unemployed", "Employed"])
.range(d3.schemeTableau10);
const column = d3.scaleBand()
.domain(d3.range(numCols))
.range([0, visWidth])
.paddingInner(0.05);
const row = d3.scaleBand()
.domain(d3.range(numRows))
.range([0, 450])
.paddingInner(0.05);
const outerRadius = Math.min(column.bandwidth(), row.bandwidth()) / 2;
// create the pie and area generators

const pie = d3.pie()
.value(d => d.percent);

const arc = d3.arc()
.innerRadius(0)
.outerRadius(outerRadius);

const pieGroups = g.selectAll('.pieGroup')
.data(unemploymentPieWithGrid)
.join('g')
.attr('class', 'pieGroup')
// .attr('transform', d => `translate(${column(d.column)},${d.row})`);
.attr('transform', (d, i) => `translate(${10 + (i % 8) * (outerRadius * 2 + 30)},${40 + (Math.floor(i/8)) * (outerRadius * 2 + 30)})`);

pieGroups.selectAll('path')
.data(d => pie(d.rate))
.join('path')
.attr('d', d => arc(d))
.attr('fill', d => color(d.data.status))
pieGroups.append('text')
.attr('font-size', '12px')
.attr('fill', 'black')
.text(d => d.state)
.attr('transform', (d) => `translate(${0},${outerRadius + 15})`);
return svg.node()
}
Insert cell
function legend2() {
const size = 10;
const lineHeight = size * 1.5;
const color = d3.scaleOrdinal()
.domain(["Unemployed", "Employed"])
.range(d3.schemeTableau10);
const svg = d3.select(DOM.svg(width, color.domain().length * lineHeight));
const rows = svg
.selectAll("g")
.data(color.domain())
.join("g")
.attr("transform", (d, i) => `translate(0, ${i * lineHeight})`);
rows.append("rect")
.attr("height", size)
.attr("width", size)
.attr("fill", d => color(d));
rows.append("text")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.attr("dominant-baseline", "hanging")
.attr("x", lineHeight)
.text(d => d);
return svg.node();
}
Insert cell
Insert cell
Insert cell
{
const margin = {top: 10, right: 60, bottom: 50, left: 100};
const visWidth = 1000 - margin.left - margin.right;
const visHeight = 600 - margin.top - margin.bottom;
const xScale = d3.scaleBand()
.domain(unemployment.map(d => stateToAbbr[d.state]))
.range([0, visWidth])
.padding(0.4)
const yScale = d3.scaleLinear()
.domain([maxUnemployment, 0])
.range([0, visHeight])
const yAxisScale = d3.scaleLinear()
.domain([maxUnemployment - meanUnemployment, 0 -meanUnemployment])
.range([0, visHeight])
const yaxis = d3.axisLeft(yAxisScale)
const xaxis = d3.axisBottom(xScale)

const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);

const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
g.append('line')
.style("stroke", "red")
.style("stroke-width", 2)
.attr("x1", 0)
.attr("y1", yScale(meanUnemployment))
.attr("x2", visWidth)
.attr("y2", yScale(meanUnemployment));
g.selectAll('rect')
.data(usaGeo.features)
.join('rect')
.attr('fill', 'steelblue')
.attr('x', d=> xScale(stateToAbbr[d.properties.NAME]))
.attr('y', d=> d3.min([yScale(meanUnemployment), yScale(stateToRate[d.properties.NAME])]))
.attr('width', d=> xScale.bandwidth())
.attr('height', d=> Math.abs(yScale(meanUnemployment) - yScale(stateToRate[d.properties.NAME])))
g.append('g')
.call(yaxis)
g.append('g')
.attr('transform', `translate(0, ${visHeight})`)
.call(xaxis)
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', visWidth/2)
.attr('y', 40)
.text('Unemployment Rate')
return svg.node()
}
Insert cell
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