Published
Edited
Oct 25, 2021
3 stars
Insert cell
Insert cell
Insert cell
svgEle = htl.html`<svg id="chart">
<circle cx="20" cy="20" r="30"></circle>
</svg>`
Insert cell
svgSel = d3.select(svgEle).selectAll("circle").style("fill", "#69b3a2")
Insert cell
svgSel.node()
Insert cell
attributes = Object.keys(data[0]).filter((a) => typeof data[0][a] === "number")
Insert cell
viewof maxR = Inputs.range([2, 20], { label: "Max Radius", step: 1 })
Insert cell
Insert cell
viewof yAttr = Inputs.select(attributes, { label: "Y Attribute", value: "Potential" })
Insert cell
viewof n = Inputs.range([1, fullData.length], {
step: 1,
value: fullData.length
})
Insert cell
data = fullData.slice(0, n)
Insert cell
chart = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

const g = svg
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.right})`);

g.append("g").call(d3.axisLeft(yScale));
g.append("g")
.call(d3.axisBottom(xScale))
.attr("transform", `translate(0, ${iheight})`);

g.selectAll("circle")
.data(data)
.join("circle")
.attr("cy", 0)
.attr("cx", (d) => xScale(d[xAttr]))
.attr("r", (d) => rScale(d[rAttr]))
.transition()
.duration(1000)
.attr("cy", (d) => yScale(d[yAttr]));

return svg.node();
}
Insert cell
rAttr = "Age"

Insert cell
maxR
Insert cell
rScale = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d[rAttr]))
.range([0, maxR])
Insert cell
xScale = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d[xAttr]))
.range([0, iwidth])
Insert cell
yScale = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d[yAttr]))
.range([iheight, 0])
Insert cell
margin = ({ left: 50, right: 20, top: 20, bottom: 50 })
Insert cell
iwidth = width - margin.left - margin.right
Insert cell
iheight = height - margin.top - margin.bottom
Insert cell
fullData = FileAttachment("fifaData.csv").csv({ typed: true })
Insert cell
height = 400
Insert cell
d3 = require("d3@7")
Insert cell
md`## Reusing D3 visualizations

[New D3 examples format](https://observablehq.com/@d3/charts)`
Insert cell
import { Scatterplot } from "@d3/scatterplot"
Insert cell
Scatterplot(data, { x: (d) => d[xAttr], y: (d) => d[yAttr], width, height })
Insert cell
Plot.plot({
marks: [Plot.dot(data, { x: xAttr, y: yAttr })]
})
Insert cell
myscp(data, {
x: (d) => d[xAttr],
y: (d) => d[yAttr],
width,
height,
onHover: (evt, i) => (mutable selected = data[i])
})
Insert cell
mutable selected = null
Insert cell
import { Scatterplot as myscp } from "d1b223a2656001f5"
Insert cell
md`## Building Larger Applications


* Modularization to the extreme
* Build separate reusable modules, document them
* [Unit Visualization](https://observablehq.com/d/a578473b724795d5)
* [D3 Tree Visualizations](https://observablehq.com/@john-guerra/try-d3-tree-visualizations)
* [UMAP Playground](https://observablehq.com/@john-guerra/umap-playground)

`
Insert cell

md`

|Related resources |
| -- | -- |
| Introduction to D3 in Observable | <iframe width="200" src="https://www.youtube.com/embed/p7rrmA23Ml4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| From Marks and Channels to D3 | <iframe width="200" src="https://www.youtube.com/embed/oc6ARb9iIic" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| D3 v6 Sections Explained | <iframe width="200" src="https://www.youtube.com/embed/36OUJhUJp5Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>|
| D3 Data Binding | <iframe width="200" src="https://www.youtube.com/embed/73mYrCaAhZo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| D3 Step by Step Histogram | <iframe width="200" src="https://www.youtube.com/embed/zEKKd471-gg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| D3 Faceting | <iframe width="200" src="https://www.youtube.com/embed/fClfsNt_9ww" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| D3 Transitions and Animations | <iframe width="200" src="https://www.youtube.com/embed/H8Qfk5z1_78" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| Networks with D3 | <iframe width="200" src="https://www.youtube.com/embed/YoHVbUk4wgc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| Trees with D3 | <iframe width="200" src="https://www.youtube.com/embed/-Cf6AGs02x4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| Maps with D3 | <iframe width="200" src="https://www.youtube.com/embed/opbjh4DX5so" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>|
_Break_
12:50 - 13:00

`
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