Published
Edited
Mar 12, 2021
10 forks
Importers
42 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
.attr('font-family', 'sans-serif')
.call(xAxis)
.call(labels);

return Object.assign(svg.node(), {
update(data) {
svg.selectAll('.date-bin')
.data(data, d => d[0])
.join('g')
.attr('class', 'date-bin')
.attr('transform', d => `translate(${xScale(new Date(d[0]))}, ${height / 2})`)
.selectAll('.date-bin-group')
.data(d => d[1], d => d[0])
.join('g')
.attr('class', 'date-bin-group')
.attr('transform', d => `translate(0, ${15 * (d[0] ? 1 : -1 )})`)
.selectAll('.event')
.data(d => d[1], d => d.uid)
.join(
enter => enter.append('circle')
.attr('fill', d => d3.schemeTableau10[d.category])
.attr('r', 4)
.attr('cx', 0)
.attr('cy', 0)
.attr('class', 'event')
.attr('transform', (d, i, nodes) => `translate(0, ${i * 10 * (d.position ? 1 : -1)})`)
.call(el => el.attr('opacity', 0)
.transition().duration(200)
.attr('opacity', 1)),
update => update
.call(els => els.transition().duration(200)
.attr('transform', (d, i, nodes) => `translate(0, ${i * 10 * (d.position ? 1 : -1)})`)),
exit => exit.remove());
}
});
}
Insert cell
chart.update(groupedEvents);
Insert cell
Insert cell
xAxis = svg => svg.append('g')
.attr('color', '#3a3a3a')
.attr('transform', `translate(0,${height / 2})`)
.call(d3.axisBottom(xScale).tickSize(30).tickSizeOuter(0))
.call(el => el.select('.tick:last-of-type').remove())
.call(el => el.selectAll('.tick line')
.attr('transform', 'translate(0, -15)'))
.call(el => el.selectAll('.tick text')
.attr('text-anchor', 'start')
.attr('transform', 'translate(3, -36)'))
.call(el => el.selectAll('.tick')
.insert('rect', 'text')
.attr('fill', 'white')
.attr('x', 1)
.attr('height', 4)
.attr('width', 26)
.attr('transform', 'translate(0, -2)'));
Insert cell
labels = svg => svg.append('g')
.attr('transform', `translate(20, ${height / 2})`)
.call(el => el.append('text')
.text('PRO')
.attr('alignment-baseline', 'mathematical')
.attr('transform', 'translate(0, -15)'))
.call(el => el.append('text')
.text('CON')
.attr('alignment-baseline', 'mathematical')
.attr('transform', 'translate(0, 15)'));
Insert cell
Insert cell
dateRange = [new Date(2015, 0).getTime(), new Date(2020, 0).getTime()];
Insert cell
groupedEvents = d3.group(
events.filter(e => categories.includes(`${e.category}`)),
d => new Date(d.date.getFullYear(), d.date.getMonth()).toDateString(),
d => d.position)
Insert cell
Insert cell
Insert cell
xScale = d3.scaleTime().range([80, width - 20]).domain(dateRange);
Insert cell
height = 300;
Insert cell
d3 = require("d3");
Insert cell
import {checkbox, slider, number} from "@jashkenas/inputs";
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