Skip to content

Instantly share code, notes, and snippets.

@sxywu
Last active October 16, 2016 05:59
Show Gist options
  • Save sxywu/82144236b9a920f77e3af1776d265c57 to your computer and use it in GitHub Desktop.
Save sxywu/82144236b9a920f77e3af1776d265c57 to your computer and use it in GitHub Desktop.
d3.unconf 2016, v10
license: mit
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment