Published
Edited
Apr 12, 2022
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
wikichanges = update, changes.filter(d => d.meta.uri.indexOf("wikipedia.org/wiki") >= 0)
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.barX(wikichanges, Plot.groupY({x: "count"}, {y: "type", fill: "type"})),
],
marginLeft: 100,
width,
grid: true
})
Insert cell
wikiedits = update, changes.filter(d => d.meta.uri.indexOf("wikipedia.org/wiki") >= 0)
Insert cell
Plot.plot({
marks: [
Plot.barX(
wikichanges,
Plot.groupY({ x: "count" }, {
y: (d) => d.meta.domain.split(".")[0],
fill: "type",
sort: { y: "x", reverse: true, limit: 20 }
})
)
],
color: { legend: true },
grid: true,
marginLeft: 100
})
Insert cell
Insert cell
viewof language = Inputs.select(languages, {label: "Select one", value: "all"})
Insert cell
Plot.plot({
marks: [
Plot.dot(
wikichanges.filter(d => d.type == "edit" && (language == "all" || language == d.meta.domain.split(".")[0]) ) ,
{
x: d => new Date(d.timestamp * 1000),
y: d => d.length.new - d.length.old,
fill: "timestamp",
fillOpacity: 0.6,
title: d => `${d.length.new - d.length.old} by ${d.user}\n${d.meta.uri}`,
// fill: d => d.meta.domain.split(".")[0],
sort: { y: "x", reverse: true, limit: 20 }
})
],
color: { scheme: "blues" },
y: { type: "symlog" },
grid: true,
marginLeft: 100
})
Insert cell
changes = reset, []
Insert cell
change = Generators.queue(notify => {
const source = new EventSource("https://stream.wikimedia.org/v2/stream/recentchange");
source.onmessage = message => notify(JSON.parse(message.data));
return () => source.close();
})
Insert cell
updateChanges = {
// we directly change the value of the `changes` cell, which is usually a no-no
// in this case we want to control the update speed since the changes come in so fast
// this updates the value of `changes` but doesn't trigger a refresh of the dataflow
changes.push(change)
}
Insert cell
update = {
// this code controls the "refresh rate" of the visualizations in this notebook
// we don't actually use the value of this cell in any calculations,
// we depend on observable to re-run cells that reference it to drive our "animations"
yield interval();
while (keepupdating) {
const then = interval.ceil(Date.now() + 1);
// Promises.when returns the 2nd argument when the time passes the first argument
yield Promises.when(then, then);
}
}
Insert cell
interval = d3.utcMillisecond.every(300)
Insert cell
import { Plot } from "@mkfreeman/plot-tooltip"
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