diff --git a/pyscriptjs/examples/d3.html b/pyscriptjs/examples/d3.html
new file mode 100644
index 0000000..c5bdc68
--- /dev/null
+++ b/pyscriptjs/examples/d3.html
@@ -0,0 +1,161 @@
+
+
+ d3: JavaScript & PyScript visualizations side-by-side
+
+
+
+
+
+
+
+
+
+
+
+
+ Based on Learn D3: Shapes tutorial.
+
+
+
+
+
+
+from pyodide import create_proxy, to_js
+from js import d3
+
+fruits = [
+ dict(name="π", count=21),
+ dict(name="π", count=13),
+ dict(name="π", count=8),
+ dict(name="π", count=5),
+ dict(name="π", count=3),
+ dict(name="π", count=2),
+ dict(name="π", count=1),
+ dict(name="π", count=1),
+]
+
+fn = create_proxy(lambda d, *_: d["count"])
+data = d3.pie().value(fn)(to_js(fruits))
+
+arc = (d3.arc()
+ .innerRadius(210)
+ .outerRadius(310)
+ .padRadius(300)
+ .padAngle(2 / 300)
+ .cornerRadius(8))
+
+py = d3.select("#py")
+py.select(".loading").remove()
+
+svg = (py
+ .append("svg")
+ .attr("viewBox", "-320 -320 640 640")
+ .attr("width", "400")
+ .attr("height", "400"))
+
+for d in data:
+ d_py = d.to_py()
+
+ (svg.append("path")
+ .style("fill", "steelblue")
+ .attr("d", arc(d)))
+
+ text = (svg.append("text")
+ .style("fill", "white")
+ .attr("transform", f"translate({arc.centroid(d).join(',')})")
+ .attr("text-anchor", "middle"))
+
+ (text.append("tspan")
+ .style("font-size", "24")
+ .attr("x", "0")
+ .text(d_py["data"]["name"]))
+
+ (text.append("tspan")
+ .style("font-size", "18")
+ .attr("x", "0")
+ .attr("dy", "1.3em")
+ .text(d_py["value"]))
+
+
+
+
diff --git a/pyscriptjs/examples/index.html b/pyscriptjs/examples/index.html
index 986da26..df2c82e 100644
--- a/pyscriptjs/examples/index.html
+++ b/pyscriptjs/examples/index.html
@@ -36,16 +36,19 @@
WARNING: This examples takes a little longer to load. So be patient :)
-
+
+ Minimal d3 demo demonstrating how to create a visualization
+
+
A Python REPL (Read Eval Print Loop).
-
+
A Python REPL (Read Eval Print Loop) with slightly better formatting.
A static demo of the <py-script> tag
-
+
A dynamic demo of the <py-script> tag