Published
Edited
Feb 20, 2019
5 forks
11 stars
Insert cell
Insert cell
chart = {
// Area

const area = d3.area()
.x(d => xScale(d.date))
.y1(d => yScale(d.population))
.y0(yScale(0))
;

svg.append('path')
.attr('d', area(data))
.attr('stroke', '#147F90')
.attr('stroke-width', '2px')
.attr('fill', '#A6E8F2')
;


// Axis

const xAxis = d3.axisBottom()
.scale(xScale);
const xAxisTranslate = height - margin.bottom;

svg.append('g')
.attr('transform', `translate(0, ${xAxisTranslate})`)
.call(xAxis)
;

const yAxis = d3.axisLeft()
.tickFormat(d3.format('~s'))
.scale(yScale);

svg.append('g')
.attr('transform', `translate(${margin.left}, 0)`)
.call(yAxis)
;
// Interactivity
svg.append('line').classed('hoverLine', true)
svg.append('circle').classed('hoverPoint', true);
svg.append("text").classed('hoverText', true);

svg.append('rect')
.attr('fill', 'transparent')
.attr('x', 0)
.attr('y', 0)
.attr('width', width)
.attr('height', height)
;

svg.on('mousemove', mouseMove);

// Render
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
svg = d3.select(DOM.svg(width, height));
Insert cell
Insert cell
xScale = {
const xExtent = d3.extent(data, d => d.date);
const xScale = d3.scaleTime()
.domain(xExtent)
.range([margin.left, width - margin.right]);
return xScale;
}
Insert cell
yScale = {
const yMax = d3.max(data, d => d.population);
const yMin = 0;
const yScale = d3.scaleLinear()
.domain([yMin, yMax])
.range([height - margin.bottom, margin.top]);
return yScale;
}
Insert cell
Insert cell
mouseMove = () => {
d3.event.preventDefault();
const mouse = d3.mouse(d3.event.target);
const [
xCoord,
yCoord,
] = mouse;

const mouseDate = xScale.invert(xCoord);
const mouseDateSnap = d3.timeYear.floor(mouseDate);
if (xScale(mouseDateSnap) < margin.left ||
xScale(mouseDateSnap) > width - margin.right) {
return;
}
const bisectDate = d3.bisector(d => d.date).right;
const xIndex = bisectDate(data, mouseDateSnap, 1);
const mousePopulation = data[xIndex].population;

svg.selectAll('.hoverLine')
.attr('x1', xScale(mouseDateSnap))
.attr('y1', margin.top)
.attr('x2', xScale(mouseDateSnap))
.attr('y2', height - margin.bottom)
.attr('stroke', '#147F90')
.attr('fill', '#A6E8F2')
;

svg.selectAll('.hoverPoint')
.attr('cx', xScale(mouseDateSnap))
.attr('cy', yScale(mousePopulation))
.attr('r', '7')
.attr('fill', '#147F90')
;
const isLessThanHalf = xIndex > data.length / 2;
const hoverTextX = isLessThanHalf ? '-0.75em' : '0.75em';
const hoverTextAnchor = isLessThanHalf ? 'end' : 'start';

svg.selectAll('.hoverText')
.attr('x', xScale(mouseDateSnap))
.attr('y', yScale(mousePopulation))
.attr('dx', hoverTextX)
.attr('dy', '-1.25em')
.style('text-anchor', hoverTextAnchor)
.text(d3.format('.5s')(mousePopulation));
};
Insert cell
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