Public
Edited
Nov 10, 2022
Insert cell
Insert cell
Insert cell
meat = d3.csvParse(
await FileAttachment("country_percapita_peryear_meatconsumption@1.csv").text(),
d3.autoType()
)
Insert cell
years = _.uniqBy(meat.map(d => d['TIME']))
Insert cell
range = years.filter(d => d > 1990)
Insert cell
filteredMeat = meat.filter(d => d.TIME == meatYear)
Insert cell
meatSums = d3.rollup(filteredMeat, v => d3.sum(v, d => d.Value), d => d.LOCATION)
Insert cell
filteredCrop = crop.filter(d => d.year == meatYear)
Insert cell
focusedCrop = filteredCrop.filter(d => d.value < 100000000)
Insert cell
color = d3.scaleSequential([y_min, y_max], d3.interpolateTurbo)
Insert cell
focusedData = [focusedCrop, filteredCrop]
Insert cell
Insert cell
margin = ({top: 20, right: 30, left: 40, bottom: 40})
Insert cell
d3 = require("d3")
Insert cell
height = 600
Insert cell
d3.min(filteredCrop, d => d.value)
Insert cell
x_min = d3.min(filteredCrop, d => parseInt(d.value))
Insert cell
x_max = d3.max(filteredCrop, d => parseInt(d.value))
Insert cell
y_min = d3.min(meatSums.values())
Insert cell
y_max = d3.max(meatSums.values())
Insert cell
x_scale = d3.scaleLinear()
.domain([x_min - 1, x_max])
.range([margin.left, width - margin.right])
Insert cell
y_scale = d3.scaleLinear()
.domain([y_min, y_max + 10])
.range([height - margin.bottom, margin.top])
Insert cell
xAxis = g => g
.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x_scale).tickFormat(d3.format(".0f")))
Insert cell
filteredX_scale = d3.scaleLinear()
.domain([d3.min(focusedCrop, d => parseInt(d.value)), d3.max(focusedCrop, d => parseInt(d.value))])
.range([margin.left, width - margin.right])
Insert cell
filteredXAxis = g => g
.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(filteredX_scale).tickFormat(d3.format(".0f")))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left}, 0)`)
.call(d3.axisLeft(y_scale))
Insert cell
viewof meatYear = select(range)
Insert cell
Insert cell
scatter_chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
const title = svg
.append("text")
.attr("class", "chart_title")
.attr("transform", `translate(${width / 2},15)`)
.text("")
.style("text-anchor", "middle");
var data = filteredCrop;
if (dataset == "Zoomed In") {
data = focusedCrop;
svg.append("g")
.call(filteredXAxis);
svg.node().update = pos => {
const marks = svg.selectAll('circle')
.data(data)
.join(
enter => enter.append("circle")
.attr("cx", d => filteredX_scale(parseInt(d.value)))
.attr("cy", d => height - margin.bottom)
.attr("r", d => 100 / y_scale(meatSums.get(d.country_or_area)) * 50)
.attr("fill", d => color(meatSums.get(d.country_or_area)))
.style("opacity", 0.7),
update => update,
exit => exit
)
.transition(1000)
.duration(1000)
.delay(d => filteredX_scale(parseInt(d.value)))
.attr("cy", d => y_scale(meatSums.get(d.country_or_area)))
title.text("Cereals Production vs. Meat Consumption in " + meatYear)
}
} else {
data = filteredCrop;
svg.append("g")
.call(xAxis);
svg.node().update = pos => {
const marks = svg.selectAll('circle')
.data(data)
.join(
enter => enter.append("circle")
.attr("cx", d => x_scale(parseInt(d.value)))
.attr("cy", d => height - margin.bottom)
.attr("r", d => 100 / y_scale(meatSums.get(d.country_or_area)) * 30)
.attr("fill", d => color(meatSums.get(d.country_or_area)))
.style("opacity", 0.7),
update => update,
exit => exit
)
.transition(1000)
.duration(1000)
.delay(d => x_scale(parseInt(d.value)))
.attr("cy", d => y_scale(meatSums.get(d.country_or_area)))
title.text("Cereals Production vs. Meat Consumption in " + meatYear)
}
}
svg.append("text")
.attr("class", "x-axis")
.attr("transform", `translate(${width / 2}, ${height - margin.top + 10})`)
.style("text-anchor", "middle")
.text("Crop Production (tonnes)");

svg.append("g")
.call(yAxis);
svg.append("text")
.attr("class", "y-axis")
.attr("transform", `translate(15, ${height / 2})rotate(-90)`)
.style("text-anchor", "middle")
.text("Meat Consumption (KG per Capita)");
return svg.node()
}
Insert cell
scatter_chart.update(meatYear, dataset)
Insert cell
_ = require("lodash")
Insert cell
import {
displayCaution,
render_data_table,
table_styles
} from "@uw-info474/utilities"
Insert cell
import { select } from "@jashkenas/inputs"
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