Published
Edited
Feb 10, 2021
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
// Final data structure
genre_groups
Insert cell
Insert cell
// Create a single data object, nested by genre and year
by_year_genre = T.tidy(
data,
T.arrange('Year'), // sort by year
T.mutate({ reviews: d => +d.Reviews }), // create a numeric value of "Reviews"
T.groupBy(
['Genre', 'Year'], // what to group by
[T.summarize({ total: T.sum("reviews") })] // summarise to compute total
)
)
Insert cell
Insert cell
// Get the domain of the x axis
x_domain = d3.extent(by_year_genre, d => +d.Year)
Insert cell
// Get the domain of the y axis
y_domain = d3.extent(by_year_genre, d => d.total)
Insert cell
// Create a scale function for the x position
x_scale = d3
.scaleLinear()
.domain(x_domain)
.range([margin.left, width - margin.right])
Insert cell
// Create a scale function for the y position
y_scale = d3
.scaleLinear()
.domain(y_domain)
.range([height - margin.bottom, margin.top])
Insert cell
Insert cell
// Group the data into two keys
genre_groups = d3.group(by_year_genre, d => d.Genre)
Insert cell
Insert cell
// Define a line function that takes in an **array of values** and returns a **single path**
line_fn = d3.line()
.x(d => x_scale(+d.Year)) // use the year of each object in the array to set the x position
.y(d => y_scale(+d.total)) // use the total reviews of each object in the array to set the y position
Insert cell
Insert cell
chart = {
// Create the svg container
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height);

// Draw the paths
svg
.selectAll("path")
.data(genre_groups) // bind the grouped data
.join("path")
.attr("d", d => line_fn(d[1])) // pass in the *array of values* from the genre
.style("stroke", "black")
.style("fill", "none");
return svg.node();
}
Insert cell
Insert cell
d3 = require("d3")
Insert cell
T = require('@tidyjs/tidy/dist/umd/tidy.min.js')
Insert cell
// Source: https://www.kaggle.com/sootersaalu/amazon-top-50-bestselling-books-2009-2019
data = FileAttachment("bestsellers with categories.csv").csv()
Insert cell
margin = ({ top: 20, right: 30, bottom: 30, left: 40 })
Insert cell
height = 500
Insert cell
import {
table_styles,
code_styles,
render_data_table
} from "@uw-info474/utilities"
Insert cell
table_styles
Insert cell
code_styles
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more