Published
Edited
Dec 9, 2020
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
render_data_table(table_info)
Insert cell
Insert cell
Insert cell
Insert cell
foods = _.uniqBy(data, d => d.food_category).map(d => d.food_category)
Insert cell
dd = aq
.from(data)
.groupby('food_category')
.rollup({
Min: d => Math.round(100 * op.min(+d.consumption)) / 100,
Max: d => Math.round(100 * op.max(+d.consumption)) / 100,
Mean: d => Math.round(100 * op.mean(+d.consumption)) / 100,
Median: d => Math.round(100 * op.median(+d.consumption)) / 100,
q1: d => d3.quantile(+d.consumption, 0.25),
q2: d => d3.quantile(+d.consumption, 0.50),
q3: d => d3.quantile(+d.consumption, 0.75),
iqr: d =>
d3.quantile(+d.consumption, 0.75) - d3.quantile(+d.consumption, 0.25)
})
.objects()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
color = d3
.scaleSequential()
.domain(d3.extent(Array.from(grouped.get(food).values())))
.interpolator(d3.interpolateBuPu)
.unknown("#ccc")
Insert cell
showToolTip = (text, coords) => {
d3.select(".tooltip")
.text(text)
.style("top", coords[1] + "px")
.style("left", coords[0] + "px")
.style("visibility", "visible")
}
Insert cell
Insert cell
// dd[0].
dd
Insert cell
d3.max(dd)
Insert cell
xb = d3
.scaleLinear()
.domain([0, 200])
.range([margin.left + 60, width - margin.right])
// .range([height, 0])
Insert cell
yb = d3
.scaleBand()
.domain(foods)
.range([height - margin.top, margin.bottom])
Insert cell
con_box = {
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height);

svg
.append("text")
.text("Consumption (kg/person)")
.attr("x", width / 2)
.attr("y", 475)
.attr("font-size", "small");

svg
.append("text")
.text("Food Category Consumption Distribution")
.attr("x", width / 2 - 100)
.attr("y", 50);

const tooltip = d3
.select("body")
.append("div")
.attr("class", "tooltip2")
.style("position", "absolute")
.style("background-color", "#d5e3f2")
.style("opacity", 0.7)
.style("visibility", "hidden");

const tip = svg
.append("text")
.style("pointer-events", "none")
.style("text-anchor", "left");

svg
.selectAll("vertLines")
.data(dd)
.enter()
.append("line")
.attr("x1", d => xb(d.Min))
.attr("x2", d => xb(d.Max))
.attr("y1", d => yb(d.food_category) + 20)
.attr("y2", d => yb(d.food_category) + 20)
.attr("stroke", "black");

svg
.selectAll("boxes")
.data(dd)
.enter()
.append("rect")
.attr("x", d => xb(d.q1))
.attr("y", d => yb(d.food_category) + 8)
.attr("height", 25)
.attr("width", d => xb(d.q3) - xb(d.q1))
.attr("stroke", "black")
.attr("fill", "#5f94cf")
.style("opacity", 0.7)
.on("mouseover", function(event, d) {
let t = "median: " + d.Median + "\n max: " + d.Max;
showToolTip(t, [event.pageX, event.pageY]);
})
.on("mousemove", function(event) {
d3.select(".tooltip")
.style("top", event.pageY - 10 + "px")
.style("left", event.pageX + 10 + "px");
})
.on("mouseout", function() {
d3.select(".tooltip").style("visibility", "hidden");
});
// Min Lines
svg
.selectAll("toto")
.data(dd)
.enter()
.append("line")
.attr("x1", d => xb(d.Min))
.attr("x2", d => xb(d.Min))
.attr("y1", d => yb(d.food_category) + 8)
.attr("y2", d => yb(d.food_category) + 33)
.attr("stroke", "black");

// Median lines
svg
.selectAll("toto")
.data(dd)
.enter()
.append("line")
.attr("x1", d => xb(d.Median))
.attr("x2", d => xb(d.Median))
.attr("y1", d => yb(d.food_category) + 8)
.attr("y2", d => yb(d.food_category) + 33)
.attr("stroke", "black");

// Max lines
svg
.selectAll("toto")
.data(dd)
.enter()
.append("line")
.attr("x1", d => xb(d.Max))
.attr("x2", d => xb(d.Max))
.attr("y1", d => yb(d.food_category) + 8)
.attr("y2", d => yb(d.food_category) + 33)
.attr("stroke", "black");

svg.append("g").call(xAx);

svg.append("g").call(yAx);

return svg.node();
}
Insert cell
xb()
Insert cell
yAx = g =>
g.attr("transform", `translate(${margin.left + 50},0)`).call(d3.axisLeft(yb))
Insert cell
xAx = g => g.attr("transform", "translate(0, 480)").call(d3.axisBottom(xb))
Insert cell
xb(dd[0].Median)
Insert cell
xb(dd[0].q1)
Insert cell
// bins = d3.histogram()
// .thresholds(n)
// .value(d => d.y)
// (data)
// .map(bin => {
// bin.sort((a, b) => a.x - b.x);
// const values = bin.map(d => d.x);
// const min = values[0];
// const max = values[values.length - 1];
// const q1 = d3.quantile(values, 0.25);
// const q2 = d3.quantile(values, 0.50);
// const q3 = d3.quantile(values, 0.75);
// const iqr = q3 - q1; // interquartile range
// const r0 = Math.max(min, q1 - iqr * 1.5);
// const r1 = Math.min(max, q3 + iqr * 1.5);
// bin.quartiles = [q1, q2, q3];
// bin.range = [r0, r1];
// bin.outliers = bin.filter(v => v.x < r0 || v.x > r1); // TODO
// return bin;
// })
Insert cell
bins = d3
.bin()
.thresholds(width / 40)
.value(d => d.food_category)
(data)
.map(bin => {
// bin.sort((a, b) => +a.consumption - +b.consumption);
const vals = bin.map(d => +d.consumption);
console.log(bin);
const min = d3.min(vals);
const max = d3.max(vals);
const q1 = d3.quantile(vals, 0.25);
const q2 = d3.quantile(vals, 0.50);
const q3 = d3.quantile(vals, 0.75);
const iqr = q3 - q1;
const r0 = Math.max(min, q1 - iqr * 1.5);
const r1 = Math.min(max, q3 + iqr * 1.5);
bin.quartiles = [q1, q2, q3];
bin.range = [r0, r1];
return bin;
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { legend } from "@d3/color-legend"
Insert cell
_ = require("lodash")
Insert cell
Insert cell
Insert cell
Insert cell
projection = d3.geoEqualEarth()
Insert cell
path = d3.geoPath(projection)
Insert cell
outline = ({ type: "Sphere" })
Insert cell
countries = topojson.feature(world, world.objects.countries)
Insert cell
height = 500
Insert cell
margin = ({ top: 20, right: 30, bottom: 30, left: 40 })
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