Skip to content

Instantly share code, notes, and snippets.

@StrongerMyself
Created August 20, 2019 14:08
Show Gist options
  • Save StrongerMyself/081507b387d9b3036f560f744f293698 to your computer and use it in GitHub Desktop.
Save StrongerMyself/081507b387d9b3036f560f744f293698 to your computer and use it in GitHub Desktop.
d3-v5-line-chart
import * as d3 from 'd3'
import c from '../styles.css'
const svg = d3.select('svg')
const margin = { top: 20, right: 20, bottom: 110, left: 40 }
const width = +svg.attr('width') - margin.left - margin.right
const height = +svg.attr('height') - margin.top - margin.bottom
const margin2 = { top: 430, right: 20, bottom: 30, left: 40 }
const height2 = +svg.attr('height') - margin2.top - margin2.bottom
const x = d3.scaleTime().range([0, width])
const y = d3.scaleLinear().range([height, 0])
const xAxis = d3.axisBottom(x)
const yAxis = d3.axisLeft(y)
const x2 = d3.scaleTime().range([0, width])
const y2 = d3.scaleLinear().range([height2, 0])
const xAxis2 = d3.axisBottom(x2)
const brush = d3.brushX()
.extent([[0, 0], [width, height2]])
.on('brush end', brushed)
const zoom = d3.zoom()
.scaleExtent([1, Infinity])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [width, height]])
.on('zoom', zoomed)
const line = d3.line()
.x((d) => x(d.date))
.y((d) => y(d.value))
const line2 = d3.line()
.x((d) => x2(d.date))
.y((d) => y2(d.value))
const lineChart = svg.append('g')
.attr('class', 'lineChart')
.attr('transform', `translate(${margin.left},${margin.top})`)
const focus = svg.append('g')
.attr('class', 'focus')
.attr('transform', `translate(${margin.left},${margin.top})`)
const context = svg.append('g')
.attr('class', 'context')
.attr('transform', `translate(${margin2.left},${margin2.top})`)
const draw = (data) => {
x.domain(d3.extent(data, (d) => d.date))
y.domain([0, d3.max(data, (d) => d.value)])
x2.domain(x.domain())
y2.domain(y.domain())
focus.append('g')
.attr('class', 'axis axis--x')
.attr('transform', `translate(0,${height})`)
.call(xAxis)
focus.append('g')
.attr('class', 'axis axis--y')
.call(yAxis)
lineChart.append('path')
.datum(data)
.attr('class', c.line)
.attr('d', line)
context.append('path')
.datum(data)
.attr('class', c.line)
.attr('d', line2)
context.append('g')
.attr('class', 'axis axis--x')
.attr('transform', `translate(0,${height2})`)
.call(xAxis2)
context.append('g')
.attr('class', 'brush')
.call(brush)
.call(brush.move, x.range())
svg.append('rect')
.attr('class', c.zoom)
.attr('width', width)
.attr('height', height)
.attr('transform', `translate(${margin.left},${margin.top})`)
.call(zoom)
}
function brushed() {
if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'zoom') return // ignore brush-by-zoom
let s = d3.event.selection || x2.range()
x.domain(s.map(x2.invert, x2))
lineChart.select(`.${c.line}`).attr('d', line)
focus.select('.axis--x').call(xAxis)
svg.select(`.${c.zoom}`).call(
zoom.transform,
d3.zoomIdentity.scale(width / (s[1] - s[0])).translate(-s[0], 0)
)
}
function zoomed() {
if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'brush') return // ignore zoom-by-brush
let t = d3.event.transform
x.domain(t.rescaleX(x2).domain())
lineChart.select(`.${c.line}`).attr('d', line)
focus.select('.axis--x').call(xAxis)
context.select('.brush').call(brush.move, x.range().map(t.invertX, t))
}
const urlData = 'https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/3_TwoNumOrdered_comma.csv'
const parseDate = d3.timeParse('%Y-%m-%d')
Promise.all([
d3.csv(urlData, (d) => ({ date: parseDate(d.date), value: +d.value }))
]).then(result => {
draw(result[0])
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment