Published
Edited
Sep 20, 2022
2 stars
Insert cell
Insert cell
timeline = {
const scale =1;
let svg = d3.create("svg")
.attr("width", scale * 1200)
.attr("height", 4000)
.style("background","black")

const chart = svg.append("g")
const timeScale = d3.scaleLinear()
.domain([1860, 2000])
.range([scale * 500, scale * 4000]);

const xScale = d3.scaleLinear()
.domain([0,4])
.range([scale * 200, scale * 1100]);
const topics = ["computer science","mathematics","physics","chemistry","biology",
"economics","psychology"];
const topicColors = ["#00ffeb","#00b9ff","violet","#ff8400","#83ff00",
"gold","#fa207b"];
chart.append("g")
.attr("transform", "translate(20,0)")
.call(d3.axisRight(timeScale)
.tickFormat(d => d)
.tickSize(10)
)
.style("color","lightgrey")
.style("opacity", 0.4)
.style("font-size",scale * 50)
.style("stroke-width", scale * 5);
const images = await Promise.all(scientists2.map(scientist => scientist.imgUrl));

let defs = svg.append("defs")
let radiusFunc = (rank) => 0.5*(Math.max(160 - 5*Math.sqrt(rank) , 50));
defs.selectAll(".bubbleClip")
.data(scientists2)
.join("clipPath")
.attr("id", d => d.name.replaceAll(" ","-") + "-clip")
.append("circle")
.attr("cx", (d,i)=> scale * d.xShift + xScale(topics.indexOf(d.field)))
.attr("cy", d=> ((timeScale(d.dates.split(" -")[0]))))
.attr("r" , d => scale * radiusFunc(d.rank))

chart.selectAll(".bubbleShadow2")
.data(scientists2)
.join("circle")
.attr("cx", (d,i)=> (scale * d.xShift + xScale(topics.indexOf(d.field))))
.attr("cy", d=> ((timeScale(d.dates.split(" -")[0]))))
.attr("r" , d => scale * radiusFunc(d.rank))
.attr("transform","scale(0.3,1.5)")
.attr("transform-origin",d=>scale * d.xShift + xScale(topics.indexOf(d.field)) + " " +
( -scale * radiusFunc(d.rank) + timeScale(d.dates.split(" -")[0])))
.style("opacity",0.2)
.style("filter",d=> "drop-shadow(0px "+-scale *1.8* radiusFunc(d.rank) +"px " + parseInt(scale * 0.7 * radiusFunc(d.rank)) + "px " + topicColors[topics.indexOf(d.field)] + ")")
chart.selectAll(".bubbleshadow1")
.data(scientists2)
.join("circle")
.attr("cx", (d,i)=> (scale * d.xShift + xScale(topics.indexOf(d.field))))
.attr("cy", d=> ((timeScale(d.dates.split(" -")[0]))))
.attr("r" , d => scale * radiusFunc(d.rank))
.attr("transform","scale(0.7,1)")
.attr("transform-origin",d=>scale * d.xShift + xScale(topics.indexOf(d.field)) + " " +
( -scale * radiusFunc(d.rank) + timeScale(d.dates.split(" -")[0])))
.style("opacity",0.3)
.style("filter",d=> "drop-shadow(0px "+-scale * 1.2 * radiusFunc(d.rank) +"px " + parseInt(scale * 0.7 * radiusFunc(d.rank)) + "px " + topicColors[topics.indexOf(d.field)] + ")")

chart.selectAll(".bubbleBorder")
.data(scientists2)
.join("circle")
.attr("cx", (d,i)=> (scale * d.xShift + xScale(topics.indexOf(d.field))))
.attr("cy", d=> ((timeScale(d.dates.split(" -")[0]))))
.attr("r" , d => scale * radiusFunc(d.rank))
.attr("stroke", d=> topicColors[topics.indexOf(d.field)])
.attr("stroke-width", d=> scale * (0.05 * radiusFunc(d.rank)))
.style("filter",d=> "drop-shadow(0px 0px " + parseInt(scale * 0.7 * radiusFunc(d.rank)) + "px " + topicColors[topics.indexOf(d.field)] + ")")
chart.selectAll(".bubble")
.data(scientists2)
.join("image")
.attr("href", (d,i) => images[i] ? images[i].src : "null")
.attr("width", (d,i) => scale * 2 * radiusFunc(d.rank))
.attr("height", (d,i) =>scale * 2 * radiusFunc(d.rank))
.attr("x", (d,i)=> (scale * (d.xShift - radiusFunc(d.rank)) + xScale(topics.indexOf(d.field))))
.attr("y", d=> (timeScale(d.dates.split(" -")[0]) - scale * radiusFunc(d.rank)))
.attr('clip-path', d => "url(#" + d.name.replaceAll(" ","-") + "-clip" + ")")

chart.selectAll(".nameLabelBG")
.data(scientists2)
.join("text")
.classed("nameLabelBG",true)
.attr("x", (d,i)=> (scale * 2 + scale * (d.xShift) + xScale(topics.indexOf(d.field))))
.attr("y", d => (scale * 18+ timeScale(d.dates.split(" -")[0]) + scale*(radiusFunc(d.rank))))
.text(d => d.name.split(" ").at(-1))
//.text(d => d.dates + ": " + d.name + " " + d.text.replace("PUB_NAME", " "+d.publication))
.attr("fill", "black")
.style("font-family", 'Catamaran, sans-serif')
.style("font-weight", 600)
.style("font-size", scale * 28)
.style("text-anchor","middle");
chart.selectAll(".nameLabel")
.data(scientists2)
.join("text")
.classed("nameLabel",true)
.attr("x", (d,i)=> (scale * d.xShift + xScale(topics.indexOf(d.field))))
.attr("y", d => (scale * 15+ timeScale(d.dates.split(" -")[0]) + scale*radiusFunc(d.rank)))
.text(d => d.name.split(" ").at(-1))
//.text(d => d.dates + ": " + d.name + " " + d.text.replace("PUB_NAME", " "+d.publication))
.attr("fill",d=> topicColors[topics.indexOf(d.field)])
.style("font-family", 'Catamaran, sans-serif')
.style("font-weight", 600)
//.style("font-size", d=> 10 + scale * (0.25 * scale*radiusFunc(d.rank)))
.style("font-size", scale * 28)
.style("text-anchor","middle");
chart.selectAll(".bubbleKey")
.data([[10,1200 - 335,88], [100,1200 - 200,70], [300,1200 - 100,52]])
.join("circle")
.attr("cx", d=> scale * d[1])
.attr("cy", d=> scale * d[2])
.attr("r" , d => scale * radiusFunc(d[0]))
.attr("stroke", "gold")
.attr("stroke-width", d=> scale * (0.025 * radiusFunc(d[0])))
.style("filter",d=> "drop-shadow(0px 0px " + parseInt(scale * 0.7 * radiusFunc(d[0])) + "px " + " gold)")

return svg.node()
}
Insert cell
scientists2 = {
let array = await FileAttachment("scientists_55.json").json();
array.map(scientist => {
scientist.imgUrl = images2[imageArray.findIndex(v => v.includes(scientist.name))]
return scientist;
})
return array
}
Insert cell
imageArray = ' FileAttachment("Alan Turing@1.png").image(), FileAttachment("Albert Einstein@1.png").image(), FileAttachment("Bernhard Riemann@1.png").image(), FileAttachment("Bertrand Russell@1.png").image(), FileAttachment("Carl Friedrich Gauss@1.png").image(), FileAttachment("Carl Jung@1.png").image(), FileAttachment("Carl Linnaeus@1.png").image(), FileAttachment("Charles Darwin@1.png").image(), FileAttachment("David Hilbert@1.png").image(), FileAttachment("Friedrich Engels@1.jpg").image(), FileAttachment("Gottfried Wilhelm Leibniz@1.png").image(), FileAttachment("Gottlieb Frege@1.png").image(), FileAttachment("Henri Poincaré@1.png").image(), FileAttachment("Herbert Simon@1.png").image(), FileAttachment("Immanuel Kant@1.png").image(), FileAttachment("Isaac Newton@1.png").image(), FileAttachment("Jacques Lacan@1.png").image(), FileAttachment("James Clerk Maxwell@3.png").image(), FileAttachment("Jeremy Bentham@1.png").image(), FileAttachment("John Dewey@1.png").image(), FileAttachment("John Maynard Keynes@1.png").image(), FileAttachment("John von-Neumann@1.png").image(), FileAttachment("Karl Marx@1.jpg").image(), FileAttachment("Kurt Gödel@1.png").image(), FileAttachment("Leonhard Euler@1.png").image(), FileAttachment("Ludwig Wittgenstein@1.jpg").image(), FileAttachment("Max Weber@1.png").image(), FileAttachment("Milton Friedman@1.png").image(), FileAttachment("Noam Chomsky@1.png").image(), FileAttachment("Richard Feynman@1.png").image(), FileAttachment("Sigmund Freud@1.png").image(), FileAttachment("Thomas Edison@1.png").image(), FileAttachment("Werner Heisenberg@1.png").image(), FileAttachment("William James@1.jpg").image(), FileAttachment("Karl Popper.jpg").image(), FileAttachment("Claude Shannon.jpg").image(), FileAttachment("Alexander Grothendieck.png").image(), FileAttachment("Alfred Tarski.png").image(), FileAttachment("Alonzo Church.png").image(), FileAttachment("Amartya Sen.png").image(), FileAttachment("Andrey Kolmogorov.png").image(), FileAttachment("Donald Knuth.png").image(), FileAttachment("Enrico Fermi.png").image(), FileAttachment("Francis Crick.png").image(), FileAttachment("Friedrich Hayek.png").image(), FileAttachment("Jacques Lacan@2.png").image(), FileAttachment("Jean Piaget.png").image(), FileAttachment("Linus Pauling.png").image(), FileAttachment("Marvin Minsky.png").image(), FileAttachment("Max Born.png").image(), FileAttachment("Michel Foucault.png").image(), FileAttachment("Niels Bohr.png").image(), FileAttachment("Paul Dirac.png").image(), FileAttachment("Paul Erdős.png").image(), FileAttachment("Paul Samuelson.png").image(), FileAttachment("Richard Dawkins.png").image(), FileAttachment("Roger Penrose.png").image(), FileAttachment("Ronald Fisher.png").image(), FileAttachment("Stephen Hawking.png").image(), FileAttachment("Stephen Jay Gould.png").image(),FileAttachment("Alexander Fleming.jpg").image(), FileAttachment("Andrew Wiles.png").image(), FileAttachment("B F Skinner.jpg").image(), FileAttachment("Edwin Hubble.jpg").image(), FileAttachment("Ernest Rutherford.jpg").image(), FileAttachment("Frederick Sanger.png").image(), FileAttachment("Grace Hopper.jpg").image(), FileAttachment("Grigori Perelman.jpg").image(), FileAttachment("James Chadwick.jpg").image(), FileAttachment("James Watson.png").image(), FileAttachment("Jane Goodall.jpg").image(), FileAttachment("Marie Curie.jpg").image(), FileAttachment("Max Planck.jpg").image(), FileAttachment("Rachel Carson.jpg").image(), FileAttachment("Srinivasa Ramanujan.jpg").image(), FileAttachment("Subrahmanyan Chandrasekhar.jpg").image(),FileAttachment("Dmitri Mendeleev.png").image(),FileAttachment("Alfred North Whitehead.jpg").image(), FileAttachment("Erwin Schrödinger.jpg").image(), FileAttachment("Felix Klein.jpg").image(), FileAttachment("Georg Cantor.jpg").image(), FileAttachment("Sophus Lie.jpg").image(), FileAttachment("Norbert Wiener.jpg").image(), FileAttachment("Michael Faraday.png").image(),FileAttachment("Gregor Mendel.jpg").image(),FileAttachment("Rosalind Franklin.png").image(), FileAttachment("Louis Pasteur.jpg").image(), FileAttachment("Allen Newell.jpg").image(),FileAttachment("Eugene Wigner.jpg").image(), FileAttachment("Hendrik Lorentz.jpg").image(), FileAttachment("Ludwig Boltzmann.jpg").image(), FileAttachment("Wolfgang Pauli.jpg").image(),FileAttachment("Kary Mullis.jpg").image(),FileAttachment("Otto Hahn.jpg").image(),FileAttachment("Robert Koch.jpg").image(),FileAttachment("Carl Woese.jpg").image(),FileAttachment("Ernst Haeckel.jpg").image(),FileAttachment("Lise Meitner.jpg").image(),FileAttachment("Ernst Mayr.jpg").image(),FileAttachment("Arnold Sommerfeld.png").image(),FileAttachment("Hermann Weyl.jpg").image(),FileAttachment("Murray Gell-Mann.jpg").image()'
.replaceAll("FileAttachment(","").replaceAll(").image()","").replaceAll('"',"").split(",")
Insert cell
images2 = [FileAttachment("Alan Turing@1.png").image(), FileAttachment("Albert Einstein@1.png").image(), FileAttachment("Bernhard Riemann@1.png").image(), FileAttachment("Bertrand Russell@1.png").image(), FileAttachment("Carl Friedrich Gauss@1.png").image(), FileAttachment("Carl Jung@1.png").image(), FileAttachment("Carl Linnaeus@1.png").image(), FileAttachment("Charles Darwin@1.png").image(), FileAttachment("David Hilbert@1.png").image(), FileAttachment("Friedrich Engels@1.jpg").image(), FileAttachment("Gottfried Wilhelm Leibniz@1.png").image(), FileAttachment("Gottlieb Frege.png").image(), FileAttachment("Henri Poincaré@1.png").image(), FileAttachment("Herbert Simon@1.png").image(), FileAttachment("Immanuel Kant@1.png").image(), FileAttachment("Isaac Newton@1.png").image(), FileAttachment("Jacques Lacan@1.png").image(), FileAttachment("James Clerk Maxwell@3.png").image(), FileAttachment("Jeremy Bentham@1.png").image(), FileAttachment("John Dewey@1.png").image(), FileAttachment("John Maynard Keynes@1.png").image(), FileAttachment("John von Neumann@1.png").image(), FileAttachment("Karl Marx@1.jpg").image(), FileAttachment("Kurt Gödel@1.png").image(), FileAttachment("Leonhard Euler@1.png").image(), FileAttachment("Ludwig Wittgenstein@1.jpg").image(), FileAttachment("Max Weber@1.png").image(), FileAttachment("Milton Friedman@1.png").image(), FileAttachment("Noam Chomsky@1.png").image(), FileAttachment("Richard Feynman@1.png").image(), FileAttachment("Sigmund Freud@1.png").image(), FileAttachment("Thomas Edison@1.png").image(), FileAttachment("Werner Heisenberg@1.png").image(), FileAttachment("William James@1.jpg").image(), FileAttachment("Karl Popper.jpg").image(), FileAttachment("Claude Shannon.jpg").image(), FileAttachment("Alexander Grothendieck.png").image(), FileAttachment("Alfred Tarski.png").image(), FileAttachment("Alonzo Church.png").image(), FileAttachment("Amartya Sen.png").image(), FileAttachment("Andrey Kolmogorov.png").image(), FileAttachment("Donald Knuth.png").image(), FileAttachment("Enrico Fermi.png").image(), FileAttachment("Francis Crick.png").image(), FileAttachment("Friedrich Hayek.png").image(), FileAttachment("Jacques Lacan@2.png").image(), FileAttachment("Jean Piaget.png").image(), FileAttachment("Linus Pauling.png").image(), FileAttachment("Marvin Minsky.png").image(), FileAttachment("Max Born.png").image(), FileAttachment("Michel Foucault.png").image(), FileAttachment("Niels Bohr.png").image(), FileAttachment("Paul Dirac.png").image(), FileAttachment("Paul Erdős.png").image(), FileAttachment("Paul Samuelson.png").image(), FileAttachment("Richard Dawkins.png").image(), FileAttachment("Roger Penrose.png").image(), FileAttachment("Ronald Fisher.png").image(), FileAttachment("Stephen Hawking.png").image(), FileAttachment("Stephen Jay Gould.png").image(),FileAttachment("Alexander Fleming.jpg").image(), FileAttachment("Andrew Wiles.png").image(), FileAttachment("B F Skinner.jpg").image(), FileAttachment("Edwin Hubble.jpg").image(), FileAttachment("Ernest Rutherford.jpg").image(), FileAttachment("Frederick Sanger.png").image(), FileAttachment("Grace Hopper.jpg").image(), FileAttachment("Grigori Perelman.jpg").image(), FileAttachment("James Chadwick.jpg").image(), FileAttachment("James Watson.png").image(), FileAttachment("Jane Goodall.jpg").image(), FileAttachment("Marie Curie.jpg").image(), FileAttachment("Max Planck.jpg").image(), FileAttachment("Rachel Carson.jpg").image(), FileAttachment("Srinivasa Ramanujan.jpg").image(), FileAttachment("Subrahmanyan Chandrasekhar.jpg").image(),FileAttachment("Dmitri Mendeleev.png").image(),FileAttachment("Alfred North Whitehead.jpg").image(), FileAttachment("Erwin Schrödinger.jpg").image(), FileAttachment("Felix Klein.jpg").image(), FileAttachment("Georg Cantor.jpg").image(), FileAttachment("Sophus Lie.jpg").image(), FileAttachment("Norbert Wiener.jpg").image(), FileAttachment("Michael Faraday.png").image(),FileAttachment("Gregor Mendel.jpg").image(),FileAttachment("Rosalind Franklin.png").image(), FileAttachment("Louis Pasteur.jpg").image(), FileAttachment("Allen Newell.jpg").image(),FileAttachment("Eugene Wigner.jpg").image(), FileAttachment("Hendrik Lorentz.jpg").image(), FileAttachment("Ludwig Boltzmann.jpg").image(), FileAttachment("Wolfgang Pauli.jpg").image(),FileAttachment("Kary Mullis.jpg").image(),FileAttachment("Otto Hahn.jpg").image(),FileAttachment("Robert Koch.jpg").image(),FileAttachment("Carl Woese.jpg").image(),FileAttachment("Ernst Haeckel.jpg").image(),FileAttachment("Lise Meitner.jpg").image(),FileAttachment("Ernst Mayr.jpg").image(),FileAttachment("Arnold Sommerfeld.png").image(),FileAttachment("Hermann Weyl.jpg").image(),FileAttachment("Murray Gell-Mann.jpg").image()]
Insert cell
Insert cell
styles = html`
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Catamaran:wght@300;400;500;600;700;800;900display=swap" rel="stylesheet">

</style>`
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