Built with blockbuilder.org
forked from sxywu's block: d3unconf 2016, v1
forked from sxywu's block: d3unconf 2016, v2
license: mit |
Built with blockbuilder.org
forked from sxywu's block: d3unconf 2016, v1
forked from sxywu's block: d3unconf 2016, v2
First Name | version | first | favorite | |
---|---|---|---|---|
Alan | v1 | Scatter plot | d3.timer | |
Alanna | v3 | Bar chart, Line chart | ||
Alastair | v1 | Treemap | d3.forceSimulation | |
Alex | v3 | Line chart | d3.transition | |
Amit | v1 | N/A | d3.behavior.zoom | |
Andrew | v3 | Radial plot | d3.scale | |
Angela | v2 | Scatter plot | ||
Anna | v3 | Bar chart | ||
Anna | v2 | Tree | d3.line | |
Anuja | v3 | Tree | d3.hierarchy | |
Bo | v3 | Line chart | selection.data | |
Brad | v2 | Chord diagram | d3.selectAll | |
Brent | v3 | Bar plot | d3.forceSimulation | |
Brian | v4 | Bar chart | d3.voronoi | |
Casey | v3 | Bar chart | d3.force | |
Chris | v3 | Time series | d3.transition | |
Christophe | v1 | Tooltip | d3.axis | |
Daniel | v3 | Scatter plot | d3.nest | |
Daniel | v3 | Map | d3.transition | |
David | v3 | Force | d3.interpolate | |
David | v3 | Charting library | d3.voronoi | |
David | v3 | Bar chart | selection.data | |
Don | v3 | Choropleth | d3.voronoi | |
Eric | v3 | Map | d3.transition | |
Erik | v3 | Scatter plot | selection.data | |
Erik | v1 | Radar chart | d3.voronoi | |
Francois | v3 | Bar chart | d3.scale | |
Marcos | v3 | Bar chart | d3.selectAll | |
Hourann | v3 | Map, Bubble chart | d3.scaleOrdinal | |
Ian | v1 | Bar chart | d3.scaleLinear | |
Ivy | v1 | Network graph | nest.rollup | |
James | v3 | Scatter plot | d3.scale | |
James | v3 | Line chart | nest.map | |
Jamie | v2 | Map | transform | |
Janine | v3 | Bar chart | d3.selection | |
Jay | v3 | Bar chart | d3.scale | |
Jeff | v2 | Map | d3.geoProjection | |
Jeffrey | v2 | Line chart | d3.voronoi | |
Jennifer | v3 | Bar chart | d3.transition | |
Jeremy | v3 | Line Chart | d3.geoProjection | |
Jeremy | v2 | Bar chart | d3.scale | |
Jim | v2 | Bubble chart | d3.nest | |
Jing | v4 | Scatter plot | d3.brush | |
John | v2 | Area chart | d3.histogram | |
John | v3 | Scatter plot | d3.transition | |
Jon | v4 | Bar chart | d3.transition | |
Jon | v2 | Bar chart | d3.extent | |
Jonathan | v2 | Bar chart | scale.invert | |
Kai | v1 | Chord diagram | d3.interpolateMagma | |
Ken | v3 | Bar chart | d3.forceSimulation | |
Kerry | v1 | Chord diagram | d3.scale | |
Krist | v3 | Scatter plot | d3.selection, d3.scale | |
Kristen | v3 | Pie chart | d3.transition | |
Kristin | v2 | Chloropleth | d3.scale | |
Leland | v3 | Bar chart | arcTween | |
Logan | v4 | Pie chart, Donut chart | d3.pie | |
Ludwig | v3 | Tree | projection.fitSize | |
Marie | v3 | Line chart | d3.transition | |
Mark | v2 | Tree | d3.line | |
Matthew | v4 | Scatter plot | d3.scale | |
Mauro | v3 | Sunburst | selection.data | |
Micah | v3 | Map | d3.request | |
Michael | v2 | Bar chart | d3.pack | |
Mike | v1 | N/A | d3.pack | |
Minwei | v4 | bar chart | d3.layout.force | |
Naoya | v3 | bar chart | d3.scale | |
Noah | v2 | Line chart | d3.transition | |
Patrick | v3 | Scatter Plot | selection.attr | |
Paul | v4 | Scatter plot | d3.selectAll | |
Paul | v1 | Bar chart | d3.scale | |
Philippe | v3 | Map | d3.geoProjection | |
Phillip | v4 | Donut chart | d3.scale, d3.zoom | |
Ramesh | v4 | Scatter plot | d3.scale | |
Ric | v3 | Line chart | d3.brush | |
Robert | v3 | Bar chart | d3.nest | |
Robert | v2 | Force | d3.scale | |
Roger | v3 | Map | d3.geo | |
Rumman | v3 | Line chart | d3.voronoi | |
Saniya | v3 | Scatter plot | d3.color | |
Sara | v2 | Circle pack | d3.nest | |
Sara | v3 | Scatter plot | ||
Sarah | v4 | Donut chart | d3.transition | |
Seemant | v3 | Donut chart | d3.nest | |
Shan | v2 | Bubble chart | d3.scaleLinear | |
Shelby | v3 | Scatter plot | d3.scale | |
Shirley | v2 | Tree | d3.forceSimulation | |
Siu-Mei | v4 | Bar chart | d3.voronoi | |
Susie | v2 | Bar chart | d3.nest | |
Tarek | v2 | Bar chart | d3.layout.pack | |
Tim Hyon | v3 | Parallel coordinates | d3.scale | |
Tony | v3 | Bubble chart | d3.scale | |
Toshiyuki | v3 | Network graph | selection.enter, selection.exit | |
Vasco | v2 | Force | selection.data | |
Victor | v4 | Scatter plot | d3.geo.path | |
Visnu | v2 | Bar chart | d3.nest | |
Xianlin | v3 | Force | d3.transition | |
Yukiko | v3 | Bar chart | d3.color | |
Zack | 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 { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; | |
} | |
svg { | |
width: 100%; | |
height: 100%; | |
} | |
text { | |
font-family: courier; | |
} | |
/* blend options taken from visual cinnamon tutorial: http://www.visualcinnamon.com/2016/05/beautiful-color-blending-svg-d3.html */ | |
/*Set isolate on the group element*/ | |
svg {isolation: isolate;} | |
/*Set blend mode on SVG element: e.g. screen, multiply*/ | |
/* path { mix-blend-mode: multiply; } */ | |
</style> | |
</head> | |
<body> | |
<svg></svg> | |
<script type="text/babel"> | |
var width = 800; | |
var height = 800; | |
var yellow = chroma('#FFFEDE').saturate(3); | |
var navy = '#000e20'; | |
var blue = chroma(navy).brighten(.5).saturate(); | |
var white = chroma(navy).brighten(4); | |
var colors = chroma.scale([blue, navy]) | |
.mode('hsl') | |
.colors(6); | |
d3.csv('data.csv', (data) => { | |
var attendees = _.map(data, d => { | |
return { | |
name: d['First Name'], | |
first: d.first.split(', '), | |
favorite: d.favorite.split(', '), | |
version: parseInt(d.version.replace('v', '')), | |
}; | |
}); | |
// create links between the different types | |
// of firsts, favorites, and versions | |
var firsts = _.chain(attendees) | |
.map('first').flatten() | |
.countBy().toPairs() | |
.sortBy(d => -d[1]) | |
.filter(d => d[0] !== 'N/A') | |
.map(0).value(); | |
var favorites = _.chain(attendees) | |
.map('favorite').flatten() | |
.countBy().toPairs() | |
.sortBy(d => -d[1]) | |
.filter(d => d[0]) | |
.map(0).value(); | |
var versions = _.chain(attendees) | |
.map('version').flatten() | |
.countBy().toPairs() | |
// .sortBy(d => -d[1]) | |
.filter(d => d[1] > 1) | |
.map(0).value(); | |
/************************************** | |
** calculate nodes and links | |
**************************************/ | |
// radius should be attendee's first experience with dataviz | |
var startRad = width * .01; | |
var perRad = width / firsts.length * .3; | |
var radiusScale = d3.scaleOrdinal().domain(firsts) | |
.range(_.times(firsts.length, (i) => (i + 1) * perRad + startRad)); | |
var startAngle = -.5 * Math.PI; | |
// angle is their current fav d3 API | |
var perAngle = (2 * Math.PI) / favorites.length; | |
var angleScale = d3.scaleOrdinal().domain(favorites) | |
.range(_.times(favorites.length, (i) => i * perAngle + startAngle)); | |
// YAH LOOPS | |
var points = []; | |
_.each(attendees, attendee => { | |
_.each(attendee.favorite, favorite => { | |
var angle = angleScale(favorite); | |
_.each(attendee.first, first => { | |
var radius = radiusScale(first); | |
points.push({ | |
name: attendee.name, | |
favorite, | |
first, | |
version: attendee.version, | |
focusX: Math.cos(angle) * radius, | |
focusY: Math.sin(angle) * radius, | |
}); | |
}); | |
}); | |
}); | |
// also loop through the favorites to | |
// make an actual circle | |
var outside = []; | |
var favoriteRad = width * .45; | |
_.each(favorites, favorite => { | |
var angle = angleScale(favorite); | |
outside.push({ | |
fx: Math.cos(angle) * favoriteRad, | |
fy: Math.sin(angle) * favoriteRad, | |
}); | |
}); | |
var nodes = _.union(points, outside); | |
var simulation = d3.forceSimulation(nodes) | |
.force('charge', d3.forceManyBody()) | |
.force("collide", d3.forceCollide(2)) | |
.force("x", d3.forceX().x(d => d.focusX)) | |
.force("y", d3.forceY().y(d => d.focusY)) | |
.on("tick", ticked); | |
var voronoi = d3.voronoi() | |
.x(d => d.x) | |
.y(d => d.y); | |
/************************************** | |
** draw the circles and links | |
**************************************/ | |
var svg = d3.select('svg') | |
.append('g') | |
.attr('transform', 'translate(' + [width / 2, height / 2] + ')'); | |
// motion blur taken from http://www.visualcinnamon.com/2016/05/real-life-motion-effects-d3-visualization.html | |
var defs = svg.append("defs"); | |
defs.append("filter") | |
.attr("id", "motionFilter") | |
.attr('width', '300%') | |
.attr('height', '300%') | |
.attr('x', '-100%') | |
.attr('y', '-100%') | |
.append("feGaussianBlur") | |
.attr("in", "SourceGraphic") | |
.attr("stdDeviation", "2"); | |
var pathContainer = svg.append('g'); | |
var paths, triangles; | |
var circles = svg.selectAll('g') | |
.data(points) | |
.enter().append('g'); | |
// first the blur | |
circles.append('circle') | |
.attr('fill', yellow) | |
.attr('r', d => (4 / d.version - 1) * 3.5) | |
.attr('opacity', .25) | |
.style("filter", "url(#motionFilter)"); | |
// then the actual star | |
circles.append('circle') | |
.attr('fill', yellow) | |
.attr('r', d => (4 / d.version - 1) * .75); | |
// add in text | |
var fontSize = 89; | |
var text = svg.append('g') | |
.attr('opacity', .75); | |
text.append('text') | |
.attr('text-anchor', 'middle') | |
.attr('dy', '.35em') | |
.attr('y', -fontSize * 1.15) | |
.attr('fill', white) | |
.attr('font-size', fontSize * .85) | |
.text('d3.unconf'); | |
text.append('text') | |
.attr('text-anchor', 'middle') | |
.attr('dy', '.35em') | |
.attr('y', fontSize * .3) | |
.attr('fill', white) | |
.attr('font-size', fontSize * 2.5) | |
.text('2016'); | |
text.append('line') | |
.attr('x1', -fontSize * 2) | |
.attr('x2', fontSize * 2) | |
.attr('y1', fontSize * 1.75) | |
.attr('y2', fontSize * 1.75) | |
.attr('stroke', white) | |
.attr('stroke-width', fontSize / 9) | |
.attr('stroke-linecap', 'round') | |
text.append('line') | |
.attr('x1', -fontSize * 2) | |
.attr('x2', fontSize * 2) | |
.attr('y1', -fontSize * 1.75) | |
.attr('y2', -fontSize * 1.75) | |
.attr('stroke', white) | |
.attr('stroke-width', fontSize / 9) | |
.attr('stroke-linecap', 'round') | |
function ticked() { | |
circles.attr('transform', (d) => | |
'translate(' + [d.x, d.y] + ')'); | |
triangles = voronoi.triangles(nodes); | |
// now create the triangles | |
paths = pathContainer.selectAll('path') | |
.data(triangles); | |
paths.exit().remove(); | |
paths.enter().append('path') | |
.merge(paths) | |
.attr('d', d => { | |
return 'M' + _.map(d, function(point) { | |
return point.x + ',' + point.y; | |
}).join(' L') + 'Z'; | |
}).attr('fill', (d, i) => colors[i % 6]) | |
.attr('stroke', (d, i) => colors[i % 6]) | |
.attr('opacity', .85); | |
} | |
}); | |
</script> | |
</body> |