D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
psunnn
Full window
Github gist
d3-unconf-submission
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>D3</title> <style> circle { fill: rgba(39, 54, 107, 0.25); } .leaf circle { fill-opacity: 1; } text { font: 12px sans-serif; } .topbar { flex-flow: row nowrap; justify-content: flex-start; align-items: center; height: 48px; border-bottom: 1px solid whitesmoke; margin-bottom: 12px; display: none; } select { font-size: 16px; } </style> </head> <body> <div id="root"></div> <script src="//d3js.org/d3.v3.min.js"></script> <script> const metrics = [ 'incidents', 'fatal_accidents', 'fatalities' ] const thresholds = [5, 10, 25] const topbar = d3.select('#root').append('div') .attr({ class: 'topbar' }) topbar.append('p').text('View airlines that had a minimum of') const thresholdSelect = topbar.append('select') .attr({ id: 'thresholdSelect' }) const metricSelect = topbar.append('select') .attr({ id: 'metricSelect' }) topbar.append('p').text('between 1985-1999 or between 2000-2014.') // Map the metrics to options in select metrics.forEach(m => { metricSelect.append('option') .text(m) }); thresholds.forEach(m => thresholdSelect.append('option').text(m)) // d3.select(thresholdSelect) // .data(thresholds) // .enter() // .append('option') // .text(String) const diameter = 800 const format = d3.format(',d') const pack = d3.layout.pack() .size([ diameter - 4, diameter - 4 ]) .value(d => d.size) const svg = d3.select('#root').append('svg') .attr({ width: diameter, height: diameter }) .append('g') .attr({ transform: 'translate(2, 2)' }) const colorScale = d3.scale.linear() .range(['#2C7BB6', '#D7191C']) d3.csv('airlineSafety.csv', (err, data) => { if (err) throw err else { let _state = { metric: metricSelect.property('value'), threshold: thresholdSelect.property('value') } const reducedByMetric = (metric, threshold) => { const toReturn = data.reduce((acc, val, i) => { if (val[`${metric}_85_99`] > +threshold || val[`${metric}_00_14`] > +threshold) { acc.children.push({ name: val.airline, delay: i, isAirlineName: true, children: [ { name: '1985-1999', size: val[`${metric}_85_99`], delay: i }, { name: '2000-2014', size: val[`${metric}_00_14`], delay: i } ] }) } return acc }, { name: 'airline_safety', children: [] }) return toReturn } const updateGraph = (metric, threshold) => { console.log(metric, threshold) const valsArray = reducedByMetric(metric, threshold).children.reduce((acc, val) => { const vals = val.children.map(c => +c.size) return [ ...acc, ...vals ] }, []) const properData = reducedByMetric(metric, threshold) const node = svg.datum(reducedByMetric(metric, threshold)).selectAll('.node') .data(pack.nodes, d => Math.random()) colorScale.domain(d3.extent(valsArray)) if (properData.children.length > 0) { const nodeEnter = node.enter() .append('g') .attr({ class: d => d.children ? 'node' : 'leaf node', transform: d => `translate(${d.x}, ${d.y})` }) nodeEnter .append('title') .text(d => d.name + (d.children ? '' : `: ${format(d.size)}`)) nodeEnter.append('circle') .attr({ r: 0 }) nodeEnter.filter(d => !d.children || d.isAirlineName).append('text') .attr({ dy: '0.3em' }) .style({ 'text-anchor': 'middle' }) .text(d => d.isAirlineName ? d.name : `${d.value}`) .attr({ transform: d => d.isAirlineName ? `translate(0, ${d.r - 20})` : '', 'font-size': 20, fill: 'white' }) // .style({ visibility: 'hidden' }) // Update ---------------------------- node.selectAll('g') .attr({ class: d => d.children ? 'node' : 'leaf node', transform: d => `translate(${d.x}, ${d.y})` }) node .selectAll('title') .text(d => d.name + (d.children ? '' : `: ${format(d.size)}`)) node.selectAll('circle') .attr({ r: 0 }) node.filter(d => !d.children || d.isAirlineName).selectAll('text') .attr({ dy: '0.3em' }) .style({ 'text-anchor': 'middle' }) .text(d => d.isAirlineName ? d.name : `${d.value}`) .attr({ transform: d => d.isAirlineName ? `translate(0, ${d.r - 20})` : '', fill: 'white' }) // .style({ visibility: 'hidden' }) const animateCircles = () => { d3.selectAll('circle') .transition() .duration(1000) // .delay(d => d.delay ? d.delay * 40 : 0) .attr({ r: d => d.r }) d3.selectAll('.leaf').selectAll('circle') .style({ fill: d => colorScale(d.value) }) } animateCircles() } node.exit().remove() .transition() .duration(500) } const updateGraphWithState = (obj) => { _state = Object.assign({}, _state, obj) updateGraph(_state.metric, _state.threshold) } metricSelect.on('change', () => { updateGraphWithState({ metric: metricSelect.property('value') }) }) thresholdSelect.on('change', () => { updateGraphWithState({ threshold: thresholdSelect.property('value') }) }) window.setInterval(() => { updateGraphWithState({ metric: metrics[Math.floor(Math.random() * metrics.length)], threshold: thresholds[Math.floor(Math.random() * thresholds.length)] }) }, 2000) updateGraphWithState() } }) </script> </body> </html>
https://d3js.org/d3.v3.min.js