Built with blockbuilder.org
forked from sxywu's block: d3.unconf 2016, v6
forked from sxywu's block: d3.unconf 2016, v7
forked from sxywu's block: d3.unconf 2016, v8
forked from sxywu's block: d3.unconf 2016, v9
license: mit |
Built with blockbuilder.org
forked from sxywu's block: d3.unconf 2016, v6
forked from sxywu's block: d3.unconf 2016, v7
forked from sxywu's block: d3.unconf 2016, v8
forked from sxywu's block: d3.unconf 2016, v9
First Name | Last Name | Ticket Type | version | first | favorite | |
---|---|---|---|---|---|---|
Alan | McLean | General Admission | v1 | Scatter plot | d3.timer | |
alanna | scott | General Admission | v3 | Bar chart, Line chart | ||
Alastair | Dant | General Admission | v1 | Treemap | d3.forceSimulation | |
Alex | Macy | General Admission | v3 | Line chart | d3.transition | |
Amit | Patel | General Admission | v1 | N/A | d3.behavior.zoom | |
Andrew | Wong | Invited | v3 | Radial plot | d3.scale | |
Angela | Pablo | Invited | v2 | Scatter plot | ||
Anna | Smylie | General Admission | v3 | Bar chart | ||
Anna | Vital | Invited | v2 | Tree | d3.line | |
Anuja | Verma | Scholarship | v3 | Tree | d3.hierarchy | |
Bo | Ericsson | General Admission | v3 | Line chart | selection.data | |
Brad | Lyon | General Admission | v2 | Chord diagram | d3.selectAll | |
Brent | Cohn | General Admission | v3 | Bar plot | d3.forceSimulation | |
Brian | Bailey | Scholarship | v4 | Bar chart | d3.voronoi | |
Casey | Haber | Scholarship | v3 | Bar chart | d3.force | |
Chris | Polis | General Admission | v3 | Time series | d3.transition | |
christophe | viau | Invited | v1 | Tooltip | d3.axis | |
Daniel | Overstreet | General Admission | v3 | Scatter plot | d3.nest | |
Daniel | Wolfe | General Admission | v3 | Map | d3.transition | |
David | Richards | General Admission | v3 | Force | d3.interpolate | |
David | Schnurr | General Admission | v3 | Charting library | d3.voronoi | |
David | Lin | General Admission | v3 | Bar chart | selection.data | |
Don | McCurdy | General Admission | v3 | Choropleth | d3.voronoi | |
Eric | Socolofsky | General Admission | v3 | Map | d3.transition | |
Erik | Cunningham | General Admission | v3 | Scatter plot | selection.data | |
Erik | Hazzard | General Admission | v1 | Radar chart | d3.voronoi | |
Francois | Chabbey | General Admission | v3 | Bar chart | d3.scale | |
Marcos | Iglesias | General Admission | v3 | Bar chart | d3.selectAll | |
Hourann | Bosci | General Admission | v3 | Map, Bubble chart | d3.scaleOrdinal | |
Ian | Johnson | Invited | v1 | Bar chart | d3.scaleLinear | |
Ivy | Wang | General Admission | v1 | Network graph | nest.rollup | |
James | Womack | Invited | v3 | Scatter plot | d3.scale | |
James | Wenzel | Scholarship | v3 | Line chart | nest.map | |
Jamie | Popkin | General Admission | v2 | Map | transform | |
Janine | Heiser | Invited | v3 | Bar chart | d3.selection | |
Jay | Mahabal | General Admission | v3 | Bar chart | d3.scale | |
Jeff | Zerger | Invited | v2 | Map | d3.geoProjection | |
Jeffrey | Catania | General Admission | v2 | Line chart | d3.voronoi | |
Jennifer | Lee | Invited | v3 | Bar chart | d3.transition | |
Jeremy | Wong | General Admission | v3 | Line Chart | d3.geoProjection | |
Jeremy | Wildfire | General Admission | v2 | Bar chart | d3.scale | |
Jim | Vallandingham | General Admission | v2 | Bubble chart | d3.nest | |
Jing | Lu | Scholarship | v4 | Scatter plot | d3.brush | |
John | Schulz | General Admission | v2 | Area chart | d3.histogram | |
John | Huynh | Scholarship | v3 | Scatter plot | d3.transition | |
Jon | Sadka | Invited | v4 | Bar chart | d3.transition | |
Jon | Nguyen | General Admission | v2 | Bar chart | d3.extent | |
Jonathan | Nesci | General Admission | v2 | Bar chart | scale.invert | |
Kai | Chang | Invited | v1 | Chord diagram | d3.interpolateMagma | |
Ken | Penn | General Admission | v3 | Bar chart | d3.forceSimulation | |
Kerry | Rodden | Invited | v1 | Chord diagram | d3.scale | |
Krist | Wongsuphasawat | General Admission | v3 | Scatter plot | d3.selection, d3.scale | |
Kristen | Judd | General Admission | v3 | Pie chart | d3.transition | |
Kristin | Henry | Invited | v2 | Chloropleth | d3.scale | |
Leland | Lee | Scholarship | v3 | Bar chart | arcTween | |
Logan | Carter | General Admission | v4 | Pie chart, Donut chart | d3.pie | |
Ludwig | Schubert | Scholarship | v3 | Tree | projection.fitSize | |
Marie | Swarzenski | Scholarship | v3 | Line chart | d3.transition | |
Mark | Vital | General Admission | v2 | Tree | d3.line | |
Matthew | Isanuk | Invited | v4 | Scatter plot | d3.scale | |
Mauro | Perez | Scholarship | v3 | Sunburst | selection.data | |
Micah | Stubbs | Invited | v3 | Map | d3.request | |
Michael | Freeman | General Admission | v2 | Bar chart | d3.pack | |
Mike | Bostock | Invited | v1 | N/A | d3.pack | |
Minwei | Xu | Scholarship | v4 | bar chart | d3.layout.force | |
Naoya | Kanai | Scholarship | v3 | bar chart | d3.scale | |
Noah | Veltman | Invited | v2 | Line chart | d3.transition | |
Patrick | Sun | General Admission | v3 | Scatter Plot | selection.attr | |
Paul | Rosenzweig | General Admission | v4 | Scatter plot | d3.selectAll | |
Paul | Van slembrouck | Invited | v1 | Bar chart | d3.scale | |
Philippe | Rivière | Invited | v3 | Map | d3.geoProjection | |
Phillip | Mispagel | General Admission | v4 | Donut chart | d3.scale, d3.zoom | |
Ramesh | Sampath | General Admission | v4 | Scatter plot | d3.scale | |
Ric | Cheng | Scholarship | v3 | Line chart | d3.brush | |
Robert | Crocker | Invited | v3 | Bar chart | d3.nest | |
Robert | Harris | General Admission | v2 | Force | d3.scale | |
Roger | Fischer | Invited | v3 | Map | d3.geo | |
Rumman | Chowdhury | Invited | v3 | Line chart | d3.voronoi | |
Saniya | Jesupaul | Scholarship | v3 | Scatter plot | d3.color | |
Sara | Quigley | Invited | v2 | Circle pack | d3.nest | |
Sara | Schnadt | General Admission | v3 | Scatter plot | ||
Sarah | Kwak | Scholarship | v4 | Donut chart | d3.transition | |
Seemant | Kulleen | Invited | v3 | Donut chart | d3.nest | |
Shan | Carter | Invited | v2 | Bubble chart | d3.scaleLinear | |
Shelby | Sturgis | Invited | v3 | Scatter plot | d3.scale | |
Shirley | Wu | Invited | v2 | Tree | d3.forceSimulation | |
Siu-Mei | Man | Invited | v4 | Bar chart | d3.voronoi | |
Susie | Lu | Invited | v2 | Bar chart | d3.nest | |
Tarek | Rached | General Admission | v2 | Bar chart | d3.layout.pack | |
Tim Hyon | Hyon | General Admission | v3 | Parallel coordinates | d3.scale | |
Tony | Chu | Invited | v3 | Bubble chart | d3.scale | |
Toshiyuki | Hayashi | General Admission | v3 | Network graph | selection.enter, selection.exit | |
Vasco | Asturiano | General Admission | v2 | Force | selection.data | |
Victor | Powell | General Admission | v4 | Scatter plot | d3.geo.path | |
Visnu | Pitiyanuvath | General Admission | v2 | Bar chart | d3.nest | |
Xianlin | Hu | General Admission | v3 | Force | d3.transition | |
Yukiko | Steineman | General Admission | v3 | Bar chart | d3.color | |
Zack | DeSario | Invited | v2 | Bar chart | selection.enter |
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script> | |
<script src="https://npmcdn.com/babel-core@5.8.34/browser.min.js"></script> | |
<script type="text/javascript" src="http://gka.github.io/chroma.js/vendor/chroma-js/chroma.min.js"></script> | |
<style> | |
body { | |
/* background-color: #000; */ | |
font-family: courier; | |
text-align: center; | |
} | |
h1 { | |
font-size: 36px; | |
width: 1000px; | |
padding-top: 40px; | |
} | |
#header { | |
width: 1000px; | |
/* padding: 40px 0; */ | |
position: relative; | |
margin: auto; | |
} | |
#legend { | |
width: 580px; | |
height: 600px; | |
margin: auto; | |
} | |
#annotation { | |
width: 1000px; | |
position: absolute; | |
top: 0; | |
font-size: 20px; | |
} | |
#content { | |
position: relative; | |
width: 1000px; | |
padding-bottom: 100px; | |
margin: auto; | |
} | |
#flowers { | |
width: 800px; | |
height: 1000px; | |
margin: auto; | |
} | |
#hover { | |
position: absolute; | |
width: 250px; | |
border: 1px solid #666; | |
border-radius: 5px; | |
box-shadow: 0 0 5px #666; | |
text-align: center; | |
background-color: #fff; | |
padding: 10px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id='header'> | |
<h1>d3.unconf 2016</h1> | |
<p>(Hover for attendee info ✨)</p> | |
<svg id='legend'></svg> | |
<div id='annotation'></svg> | |
</div> | |
<div id='content'> | |
<svg id='flowers'></svg> | |
<div id='hover'></div> | |
</div> | |
<script> | |
var midpoint = -2/3; | |
var halfSide = Math.sqrt(1 / 3); | |
var triangle = [ | |
(-halfSide) + ',-1', | |
(halfSide) + ',-1', | |
'0,0' | |
]; | |
var favoritesScale = d3.scaleLinear() | |
.range([midpoint - .05, -.85]); | |
var versionsScale = d3.scaleOrdinal() | |
.range(_.rangeRight(3, 7)); | |
var firstsScale = d3.scaleOrdinal(); | |
var hexScale = 40; | |
var hexSize = hexScale * 2 / Math.sqrt(3); | |
d3.csv('data.csv', data => { | |
/************************************** | |
** process data and add them to scales as domain | |
**************************************/ | |
var attendees = _.map(data, d => { | |
return { | |
name: d['First Name'], | |
first: d.first.split(', ')[0], | |
favorite: d.favorite.split(', ')[0], | |
version: parseInt(d.version.replace('v', '')), | |
}; | |
}); | |
var firsts = _.chain(attendees) | |
.map('first').flatten() | |
.countBy().toPairs() | |
.sortBy(d => -d[1]) | |
.map(0).value(); | |
var favorites = _.chain(attendees) | |
.map('favorite').flatten() | |
.countBy().value(); | |
var versions = _.chain(attendees) | |
.map('version').flatten() | |
.countBy().toPairs() | |
.sortBy(d => -d[1]) | |
.filter(d => d[1] > 1) | |
.map(0).value(); | |
// update colors with number of classes | |
var colors = chroma.cubehelix() | |
.start(280) | |
// .rotations(-1 / firsts.length) | |
.gamma(0.5) | |
.lightness([0.3, 0.4]) | |
.scale() // convert to chroma.scale | |
// .correctLightness() | |
.colors(firsts.length); | |
firstsScale.domain(firsts).range(colors); | |
versionsScale.domain(_.range(1, 5)); | |
var maxFavorites = _.max(_.values(favorites)); | |
favoritesScale.domain([1, maxFavorites]); | |
/************************************** | |
** legend | |
**************************************/ | |
var baseLegendData = { | |
version: 1, | |
first: 'Bar chart', | |
favorite: 'd3.scale', | |
}; | |
var legend = d3.select('#legend'); | |
var annotation = d3.select('#annotation'); | |
// first, the versions | |
// annotation.append('div') | |
// .style('position', 'absolute') | |
// .style('width', '1000px') | |
// .style('top', hexScale) | |
// .html('Which version of d3 did you start with?'); | |
var versionsData = _.times(4, i => { | |
return Object.assign(_.clone(baseLegendData), { | |
version: i + 1, | |
legendText: 'd3 v' + (i + 1), | |
}); | |
}); | |
legend.append('g') | |
.attr('transform', 'translate(' + [0, 0] + ')') | |
.call(drawHexagons, versionsData, 4); | |
// first | |
// annotation.append('div') | |
// .style('position', 'absolute') | |
// .style('width', '1000px') | |
// .style('top', 5.5 * hexScale) | |
// .html('Your first d3 project:<br />what type of visualization was it?'); | |
var firstData1 = _.times(4, i => { | |
var index = !i ? i : i * 4 - 1; | |
return Object.assign(_.clone(baseLegendData), { | |
first: firsts[index], | |
legendText: firsts[index], | |
}); | |
}); | |
var firstData2 = _.times(3, i => { | |
var index = (!i ? i : i * 4 - 1) + 14; | |
return Object.assign(_.clone(baseLegendData), { | |
first: firsts[index], | |
legendText: firsts[index], | |
}); | |
}); | |
legend.append('g') | |
.attr('transform', 'translate(' + [0, 4 * hexScale] + ')') | |
.call(drawHexagons, firstData1, 4); | |
legend.append('g') | |
.attr('transform', 'translate(' + [1.9 * hexScale, 6.75 * hexScale] + ')') | |
.call(drawHexagons, firstData2, 3); | |
// favorites | |
// annotation.append('div') | |
// .style('position', 'absolute') | |
// .style('width', '1000px') | |
// .style('top', 13.5 * hexScale) | |
// .html('What is your favorite d3 api function?'); | |
var favoriteNames = ['d3.scale', 'd3.transition', 'd3.forceSimulation', 'd3.hierarchy']; | |
var favoriteData = _.times(4, i => { | |
return Object.assign(_.clone(baseLegendData), { | |
favorite: favoriteNames[i], | |
legendText: favoriteNames[i], | |
}); | |
}); | |
legend.append('g') | |
.attr('transform', 'translate(' + [0, 10.75 * hexScale] + ')') | |
.call(drawHexagons, favoriteData, 4); | |
/************************************** | |
** draw the hexagons | |
**************************************/ | |
var perRow = 5; | |
var svg = d3.select('#flowers').append('g') | |
.call(drawHexagons, attendees, perRow); | |
function drawHexagons(selection, data, perRow) { | |
var hex = selection.selectAll('.hex') | |
.data(data).enter().append('g') | |
.classed('hex', true) | |
.attr('transform', (d, i) => { | |
var row = Math.floor(i / perRow); | |
var x = (i % perRow * 3.2 + 1.5) * hexSize; | |
if (row % 2) { | |
x += 1.6 * hexSize; | |
} | |
var y = (row * 1.05 + 2) * hexScale; | |
d.x = x; | |
d.y = y; | |
return 'translate(' + [x, y] + ')scale(' + hexScale + ')'; | |
}).on('mouseenter', mouseenter) | |
.on('mouseleave', mouseleave); | |
var triangles = hex.selectAll('triangle') | |
.data((d, j) => { | |
return _.times(versionsScale(d.version), i => { | |
return { | |
angle: i * 60, | |
midpoint: favoritesScale(favorites[d.favorite]), | |
color: firstsScale(d.first), | |
// color: colors[j], | |
}; | |
}); | |
}).enter().append('g') | |
.classed('triangle', true) | |
.attr('transform', d => 'rotate(' + d.angle + ')'); | |
triangles.append('polygon') | |
.attr('points', triangle.join(' ')) | |
.attr('fill', d => chroma(d.color).darken(2.5)); | |
// .attr('fill', '#fff'); | |
triangles.selectAll('.subtri') | |
.data(d => _.times(3, i => { | |
return Object.assign({ | |
subangle: i * 120, | |
subcolor: chroma(d.color).saturate(1.5).brighten(i), | |
}, d); | |
})).enter().append('polygon') | |
.classed('subtri', true) | |
.attr('transform', d => 'rotate(' + d.subangle + ' 0 ' + midpoint + ')') | |
.attr('points', d => { | |
return [ | |
(-halfSide) + ',-1', | |
'0,' + d.midpoint, | |
halfSide + ',-1' | |
].join(' '); | |
}).attr('fill', d => d.subcolor); | |
// add in text if it's for legend | |
var fontSize = 14; | |
hex.filter(d => d.legendText) | |
.append('text') | |
.attr('y', 1.25) | |
.attr('font-size', fontSize / hexScale) | |
.attr('text-anchor', 'middle') | |
.attr('dy', '.35em') | |
.text(d => d.legendText); | |
} | |
}); | |
/************************************** | |
** hover interaction | |
**************************************/ | |
var hover = d3.select('#hover') | |
.style('display', 'none'); | |
function mouseenter(d) { | |
if (!d.name) return; | |
var html = '<h2>' + d.name + '</h2>'; | |
html += '<p>started with d3.js v' + d.version; | |
if (d.first) { | |
html += ' and made a ' + d.first; | |
} | |
if (d.favorite) { | |
html += '. Their favorite d3 function is ' + d.favorite; | |
} | |
html += '.'; | |
var x = d.x + hexSize / 2; | |
var y = d.y + hexSize / 2; | |
hover.style('display', 'block') | |
.style('top', y + 'px') | |
.style('left', x + 'px') | |
.html(html); | |
} | |
function mouseleave() { | |
hover.style('display', 'none'); | |
} | |
</script> | |
</body> |