Published
Edited
Jul 10, 2022
26 forks
44 stars
Insert cell
Insert cell
Insert cell
Insert cell
db = DuckDBClient.of([["papers", FileAttachment("IEEE VIS papers 1990-2021 - Main dataset.csv")]])
Insert cell
db
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
papers
Insert cell
Insert cell
Insert cell
venues = Plot.dot(
papers,
Plot.group({ r: "count" }, { x: "Year", y: "Conference" })
).plot({
marginLeft: 60,
x: { tickFormat: "", inset: 10 },
y: { domain: ["Vis", "InfoVis", "VAST", "SciVis"] }
})
Insert cell
xDomain = venues.scale("x").domain
Insert cell
conferences = venues.scale("y").domain
Insert cell
Insert cell
Insert cell
Plot.plot({
height: 180,
x: { domain: d3.range(1, 18), label: "# of coauthors", line: true },
y: { nice: true, grid: true },
color: {
legend: true,
tickFormat: paperType
},
marks: [
Plot.barY(
papers,
Plot.groupX(
{ y: "count" },
{
x: (d) => d["AuthorNames-Deduped"].split(";").length,
fill: "PaperType",
order: "sum"
}
)
)
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {WordCloud} from "@d3/word-cloud"
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
height: 612,
x: { axis: null, inset: 4, zero: true },
y: { reverse: true, tickSize: 0 },
marks: [
Plot.boxX(
papers.filter((d) => ["J", "C"].includes(d.PaperType) && d.Year <= 2019),
{
x: (d) => Math.pow(d["AminerCitationCount"], pow),
y: "Year",
title: d => `${d.Title}\n${(d["AuthorNames"]||"").split(";").join(", ")}`
}
)
]
})
Insert cell
Insert cell
htl.html`${d3
.rollups(
d3.sort(
papers.filter((d) => d["AminerCitationCount"] > 10),
(d) => -d.Year
),
(v) => d3.sort(v, (d) => -d["AminerCitationCount"]).slice(0, 5),
(d) => d.Year
)
.map(
([year, table]) =>
htl.html`<hr><h3>${year}</h3>${Inputs.table(table, {
width: {Title: 250, AuthorNames: 200, Award: 30, PaperType: 30},
format: {Link: d => htl.html`<a href="${d}" target="_blank">${d}</a>`},
columns: [
// "Conference",
// "Year",
"Title",
"AuthorNames",
"AminerCitationCount",
"CitationCount_CrossRef",
//"PubsCited",
"Award",
//"DOI",
"Link",
// "FirstPage",
// "LastPage",
"PaperType"
// "AuthorNames-Deduped",
//"AuthorAffiliation",
// "InternalReferences",
// "AuthorKeywords",
// "Abstract"
]
})}`
)}`
Insert cell
Insert cell
Insert cell
{
const data = papers.map((d, i) => ({
...d,
y: d.Year + ((i % 20) - 10) / 40, // jiggle
cited: +d["AminerCitationCount"] || 0
}));

const index = d3.index(data, (d) => d.DOI);

const links = data.flatMap(
(d) =>
d.InternalReferences?.split(";").map((ref) => ({
...d,
x1: d.cited,
x2: index.get(ref)?.cited,
y2: index.get(ref)?.y
})) || []
);

return Plot.plot({
width,
height: 1200,
marks: [
Plot.arrow(links, {
x1: "x1",
x2: "x2",
y1: "y",
y2: "y2",
bend: true,
strokeWidth: 1 / 16
}),
Plot.dot(data, {
x: "cited",
y: "y",
title: d => `${d.Title}\n${(d["AuthorNames"]||"").split(";").join(", ")}`,
href: "Link",
target: "_blank",
fill:
colorBy === "Conference"
? "Conference"
: colorBy === "Paper type"
? "PaperType"
: "currentColor"
})
],
x: { label: "Citations →", labelAnchor: "left", type: "pow", exponent: 0.3, transform: d => d + 1, tickRotate: 30 },
y: { tickFormat: "", grid: true },
color: {
legend: true,
tickFormat: d => (colorBy === "Conference" ? d : paperType(d)),
...(colorBy === "Conference" && { scheme: "plasma" })
}
});
}
Insert cell
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