Published
Edited
Jan 27, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart_data = data.map((d, i) => {
return {
x: +d.year,
y: +d.points,
artist: d.artist,
id: i
};
})
Insert cell
// Get a unique set of artists(chart_data, d => d.artist)
artists = d3
.groups(chart_data, d => d.artist)
.map(d => d[0])
.sort((a, b) => (a > b ? 1 : -1))
Insert cell
// Get a unique set of artists(chart_data, d => d.artist)
titles = d3.groups(chart_data, d => d.id)
Insert cell
Insert cell
Insert cell
viewof size = slider({ min: 5, max: 25 })
Insert cell
Insert cell
Insert cell
image_chart = {
let svg, xAxis, yAxis, title;
if (!this) {
//Create the svg
svg = d3
.create("svg")
.attr("width", width)
.attr("height", height);

// Append the x axis
xAxis = svg.append("g").attr("class", "xaxis");

// Append the y axis
yAxis = svg.append("g").attr("class", "yaxis");

// Append the title
title = svg
.append("text")
.attr("class", "chart_title")
.attr("transform", `translate(${width / 2},15)`)
.style("text-anchor", "middle");
}
// Otherwise, define the svg as the cell's value and select the axes and title
else {
svg = d3.select(this);
xAxis = svg.select(".xaxis");
yAxis = svg.select(".yaxis");
title = svg.select(".chart_title");
}
// Update titles and axes
xAxis.call(xAxisFn);
yAxis.call(yAxisFn);
title.text("Chart title");

// Do our data join to manage the circles on the screen
// unselected artists in an array
const unselected_artists = chart_data.filter(d => d.artist !== artist);
const circles = svg.selectAll("image").data(unselected_artists, d => d.id);

circles
.join("image")
.attr(
"xlink:href",
"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/12in-Vinyl-LP-Record-Angle.jpg/440px-12in-Vinyl-LP-Record-Angle.jpg"
)
.attr("width", 10)
.attr("height", 10)
.attr("transform", d => `translate(${x(d.x)}, ${y(d.y)})`);
// .transition()
// .duration(500)
// .attr("r", d => (d.artist == artist || artist == "" ? 5 : 1))
// .attr("cx", d => x(d.x))
// .attr("cy", d => y(d.y))
// .attr("opacity", d => (d.artist == artist ? 1 : .3))
// .attr("fill", d => (d.artist == artist ? "green" : "black"));

// Do another data join to show small rectangles for the selected artist
const selected_artist_data = chart_data.filter(d => d.artist == artist);

const rects = svg.selectAll("rect").data(selected_artist_data);
rects
.join("rect")
.attr("x", d => x(d.x) - size / 2)
.attr("y", d => y(d.y) - size / 2)
.transition()
.duration(500)
.attr("width", size)
.attr("height", size);

return svg.node();
}
Insert cell
Insert cell
x = d3
.scaleLinear()
.domain(d3.extent(chart_data, d => d.x))
.range([margin.left, width - margin.right])
Insert cell
y_min = d3.min(chart_data, d => d.y)
Insert cell
y_max = d3.max(chart_data, d => d.y)
Insert cell
y = d3
.scaleLinear()
.domain([y_min, y_max])
.range([height - margin.bottom, margin.top])
Insert cell
Insert cell
xAxisFn = g =>
g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.format("")))
Insert cell
yAxisFn = g =>
g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).tickFormat(d3.format("")))
Insert cell
Insert cell
import { autoSelect, slider } from "@jashkenas/inputs"
Insert cell
d3 = require("d3@6")
Insert cell
margin = ({top: 20, right: 30, bottom: 30, left: 40})
Insert cell
height = 500
Insert cell
import {
render_data_table,
group_notebook_instructions,
table_styles
} from "@uw-info474/utilities"
Insert cell
data = await d3.csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-04-14/rankings.csv")
Insert cell
table_styles
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