Published
Edited
Dec 18, 2020
1 fork
11 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = d3.create('svg')
.attr('width', width)
.attr('height', height)
.node()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
xScale = d3.scaleLinear()
.domain(d3.extent( data.map(d => d.year) ))
.range([ 0, width - margin.right - margin.left ])
Insert cell
xAxis = d3.axisBottom( xScale )
// Format differently if it's before year 0 vs after year 0
.tickFormat(d => d < 0 ? Math.abs(d).toLocaleString() + ' BCE' : d )
Insert cell
yScale = d3.scaleLinear()
.domain([ d3.min(data.map(d => d.concentration)), d3.max(data.map(d => d.concentration)) ])
.range([ height1, margin.top])
Insert cell
yAxis = d3.axisLeft( yScale )
Insert cell
Insert cell
area = d3.area()
.curve( d3.curveMonotoneX )
.x(d => xScale(d.year))
.y0( height1 )
.y1(d => yScale(d.concentration))
Insert cell
Insert cell
focusView = {
const svg = d3.select( chart )
// Placing the <defs> element
svg.append('defs')
// placing the clipPath
.append('clipPath')
// we use the id to refrence the clipPath later
.attr('id', 'clip')
.append('rect')
.attr('width', width - margin.left - margin.right)
.attr('height', height1)

// Place the focus chart
const focus = svg.append('g')
.attr('class', 'focus')
.attr('transform', `translate(${ margin.left },${ margin.top })`)
focus.append('path')
// datum binds the data to the pre-existing element
// without requiring us to call .join()
.datum( data )
.attr('class', 'area')
// here we set the path to be clipped
.attr('clip-path', 'url(#clip)')
.style('fill', '#cf5454')
.style('stroke', '#cf5454')
.style('stroke-width', 3)
// set the path using our area generator
.attr('d', area)

focus.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0,${ height1 })`)
.call( xAxis )
// remove the horizontal line on the x axis
.select('.domain')
.remove()

focus.append('g')
.attr('class', 'y-axis')
.call( yAxis )
// remove the vertical line on the y axis
.select('.domain')
.remove()
return focus.node()
}
Insert cell
Insert cell
xScale2 = d3.scaleLinear()
// re-use the domain from the other xScale
.domain(xScale.domain())
.range([ 0, width - margin.right - margin.left ])
Insert cell
xAxis2 = d3.axisBottom( xScale2 )
.tickFormat(d => d < 0 ? Math.abs(d).toLocaleString() + ' BCE' : d )
Insert cell
yScale2 = d3.scaleLinear()
// re-use the y domain as well
.domain(yScale.domain())
.range([ height2 - margin.bottom, 0 ])
Insert cell
area2 = d3.area()
.curve(d3.curveMonotoneX)
.x(d => xScale2(d.year))
.y0( height2 - margin.bottom )
.y1(d => yScale2(d.concentration))
Insert cell
contextView = {

const svg = d3.select( chart )
// The context chart
const context = svg.append('g')
.attr('class', 'context')
.attr('transform', `translate(${ margin.left },${ margin.top + height1 })`)
context.append('path')
.datum( data )
.attr('class', 'area')
.style('fill', '#cf5454')
.attr('d', area2)

context.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0,${ height2 - margin.bottom })`)
.call( xAxis2 )

context.append('g')
.attr('class', 'x-brush')

return context.node()

}
Insert cell
Insert cell
brush = {
function brushed({ selection }) {
let extent = selection.map(d => xScale2.invert(d))
xScale.domain( extent )
d3.select( chart ).select('.area').attr('d', area)
d3.select( chart ).select('.x-axis').call(xAxis)
}
const brush = d3.brushX(xScale2)
.extent([[ 0, 20 ], [ width - margin.right - margin.left, height2 - margin.bottom ]])
.on('brush', brushed)
d3.select( contextView )
.select('g.x-brush')
.call(brush)
return brush

}
Insert cell
Insert cell
Insert cell
d3 = require('d3@6')
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