Skip to content

Instantly share code, notes, and snippets.

@alex-r-bigelow
Forked from anonymous/.block
Last active July 31, 2017 18:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alex-r-bigelow/9e6d5f83b31e0f920b5e5d8ca8cf3558 to your computer and use it in GitHub Desktop.
Save alex-r-bigelow/9e6d5f83b31e0f920b5e5d8ca8cf3558 to your computer and use it in GitHub Desktop.
Illustrator Round Trip
license: mit
scrolling: no
border: yes
height: 612

This is a gist version of the first part of the hanpuku demo. Apologies that this (and hanpuku) still use D3 v3!

In theory, to pull this off without hanpuku, you first would have to run the script with an (almost) empty SVG tag:

<svg width="792" height="612">
  <g id="Layer_1"></g>
  <g id="Layer_2"></g>
</svg>

If you inspect the result in Chrome's developer tools, you could right-click the SVG tag, choose "Edit as HTML", copy the text, paste it into a file, and then open that file with Illustrator for editing. The really tricky bit is the part where you save the SVG file using Illustrator. It will completely mess up your IDs, class names, and possibly grouping structures that you created with your code (it totally does in this example). If somehow you can sort that part out, you'd paste all the text inline in the HTML file (because you can't manipulate an SVG IMG with D3!).

Of course, in practice, Illustrator messes with things to the point that it's impossible to export an SVG that is still compatible with the script that originally created it.

Data source: http://www.georgelmurphy.com/berrics/

Original template from blockbuilder.org

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<svg width="792" height="612">
<g id="Layer_1"></g>
<g id="Layer_2"></g>
</svg>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="script.js"></script>
</body>
</html>
id next_id round winner loser roshambo_winner roshambo_loser first_trick winner_score turnovers num_tricks misses order
7-1-1 7-2-1 1 Paul Rodriguez Jonny Giger Paul Rodriguez Jonny Giger Kickflip 3 4 24 12 5
7-1-10 7-2-5 1 Sewa Kroetkov Moses Adams Moses Adams Sewa Kroetkov Kickflip 4 3 35 12 5
7-1-11 7-2-6 1 Nyjah Huston Gavin Nolan Nyjah Huston Gavin Nolan 360 Flip 0 0 23 5 5
7-1-12 7-2-6 1 MikeMo Capaldi Nate Principato MikeMo Capaldi Nate Principato Kickflip 0 0 21 5 5
7-1-13 7-2-7 1 Shane O'Neill Cristian Vannella Cristian Vannella Shane O'Neill Switch Frontside 180 3 3 29 11 5
7-1-14 7-2-7 1 Cody Cepeda Trent McClung Trent McClung Cody Cepeda Kickflip 4 1 40 10 9
7-1-15 7-2-8 1 Tom Asta Cody Whitt Tom Asta Cody Whitt Kickflip 3 6 32 14 5
7-1-16 7-2-8 1 Eric Martinac Albert Nyberg Eric Martinac Albert Nyberg Switch Frontside Bigspin 0 0 12 5 5
7-1-2 7-2-1 1 Moose CJ Tambornino Moose CJ Tambornino Switch Kickflip 4 4 32 13 5
7-1-3 7-2-2 1 Luan Oliveira Tanner Lawler Tanner Lawler Luan Oliveira Kickflip 4 1 26 10 5
7-1-4 7-2-2 1 Chris Chann Chris Cole Chris Chann Chris Cole Backside Bigspin 4 6 32 15 5
7-1-5 7-2-3 1 Morgan Smith Spencer Brown Spencer Brown Morgan Smith Nollie Heelflip 4 7 31 16 5
7-1-6 7-2-3 1 Nick Holt PJ Ladd Nick Holt PJ Ladd 360 Flip 1 2 25 8 5
7-1-7 7-2-4 1 Griffin Gass W.V. Wagenigen Griffin Gass W.V. Wagenigen Kickflip 0 0 8 5 5
7-1-8 7-2-4 1 Eric Koston Chhandy Khon Chhandy Khon Eric Koston Kickflip 1 3 19 9 1
7-1-9 7-2-5 1 Will Fyock Chaz Ortiz Will Fyock Chaz Ortiz 360 Flip 0 2 25 7 5
7-2-1 7-3-1 2 Moose Paul Rodriguez Moose Paul Rodriguez Kickflip 0 0 11 5 5
7-2-2 7-3-1 2 Luan Oliveira Chris Chann Luan Oliveira Chris Chann 360 Flip 0 0 10 5 5
7-2-3 7-3-2 2 Nick Holt Morgan Smith Morgan Smith Nick Holt Nollie Heelflip 4 3 21 12 5
7-2-4 7-3-2 2 Eric Koston Griffin Gass Griffin Gass Eric Koston Kickflip 3 3 20 11 1
7-2-5 7-3-3 2 Sewa Kroetkov Will Fyock Will Fyock Sewa Kroetkov Nollie Heelflip 3 7 39 15 5
7-2-6 7-3-3 2 MikeMo Capaldi Nyjah Huston MikeMo Capaldi Nyjah Huston Nollie Kickflip 4 8 44 17 5
7-2-7 7-3-4 2 Cody Cepeda Shane O'Neill Cody Cepeda Shane O'Neill Switch Frontside Biggerspin 3 10 58 18 9
7-2-8 7-3-4 2 Tom Asta Eric Martinac Tom Asta Eric Martinac Kickflip 2 4 36 11 5
7-3-1 7-4-1 3 Luan Oliveira Moose Moose Luan Oliveira Kickflip 4 5 43 14 5
7-3-2 7-4-1 3 Eric Koston Nick Holt Eric Koston Nick Holt Backside 360 4 6 26 15 1
7-3-3 7-4-2 3 Sewa Kroetkov MikeMo Capaldi MikeMo Capaldi Sewa Kroetkov Kickflip 4 1 24 10 5
7-3-4 7-4-2 3 Cody Cepeda Tom Asta Tom Asta Cody Cepeda Kickflip 1 1 21 7 9
7-4-1 7-5-1 4 Luan Oliveira Eric Koston Luan Oliveira Eric Koston Kickflip 2 2 23 9 1
7-4-2 7-5-1 4 Cody Cepeda Sewa Kroetkov Sewa Kroetkov Cody Cepeda 360 Shuvit 0 1 14 6 9
7-5-1 NULL 5 Cody Cepeda Luan Oliveira Cody Cepeda Luan Oliveira Nollie Heelflip 0 0 19 5 9
var bounds = {
width: 792,
height: 612
};
var color = d3.scale.category20b();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([bounds.width, bounds.height]);
var nodeRadius = 7;
function drawPointyArc(d) {
var dx = d.target.x - d.source.x;
var dy = d.target.y - d.source.y;
var arcRadius = 10 * dx / Math.abs(dx);
var theta;
var edgePoint;
var front;
var back;
var arc;
if (dx === 0) {
if (dy >= 0) {
theta = Math.PI;
} else {
theta = -Math.PI;
}
edgePoint = {
x: 0,
y: nodeRadius
};
} else {
theta = Math.atan((d.target.y - d.source.y) / (d.target.x - d.source.x)) + Math.PI / 2;
edgePoint = {
x: nodeRadius * Math.cos(theta),
y: nodeRadius * Math.sin(theta)
};
}
front = {
x: d.source.x + edgePoint.x,
y: d.source.y + edgePoint.y
};
back = {
x: d.source.x - edgePoint.x,
y: d.source.y - edgePoint.y
};
arc = {
x: (d.source.x + d.target.x) / 2 + arcRadius * Math.cos(theta),
y: (d.source.y + d.target.y) / 2 + arcRadius * Math.sin(theta)
};
return 'M' +
front.x + ',' +
front.y + 'Q' +
arc.x + ',' +
arc.y + ',' +
d.target.x + ',' +
d.target.y + 'Q' +
arc.x + ',' +
arc.y + ',' +
back.x + ',' +
back.y + 'Z';
}
d3.csv('matches.csv', function (data) {
var skaterLookup = {};
var graph = {
nodes: [],
edges: []
};
data.sort(function (a, b) {
return a.round - b.round;
});
data.forEach(function (d) {
if (!skaterLookup.hasOwnProperty(d.winner)) {
skaterLookup[d.winner] = graph.nodes.length;
graph.nodes.push({
name: d.winner,
roundNumber: d.round,
highestRound: true
});
}
if (!skaterLookup.hasOwnProperty(d.loser)) {
skaterLookup[d.loser] = graph.nodes.length;
graph.nodes.push({
name: d.loser,
roundNumber: d.round,
highestRound: true
});
}
var oldWinner = skaterLookup[d.winner];
graph.nodes[oldWinner].highestRound = false;
skaterLookup[d.winner] = graph.nodes.length;
graph.nodes.push({
name: d.winner,
roundNumber: d.round,
highestRound: true
});
graph.edges.push({
source: oldWinner,
target: skaterLookup[d.winner]
});
graph.edges.push({
source: skaterLookup[d.loser],
target: skaterLookup[d.winner]
});
});
var linkLayer = d3.select('#Layer_1');
var nodeLayer = d3.select('#Layer_2');
force.nodes(graph.nodes)
.links(graph.edges)
.start();
var link = linkLayer.selectAll('path')
.data(graph.edges);
var linkEnter = link.enter();
linkEnter.append('path')
.attr('class', 'link');
var node = nodeLayer.selectAll('.node')
.data(graph.nodes);
var nodeEnter = node.enter().append('g')
.attr('class', 'node')
.attr('id', function (d, i) {
if (d.highestRound === false) {
return d.name + d.roundNumber;
} else {
return d.name;
}
});
nodeEnter.append('rect')
.attr('x', '-0.75em')
.attr('width', '1.5em')
.attr('y', '-1em')
.attr('height', '1.5em')
.attr('fill', function (d) {
return color(d.name);
});
node.call(force.drag);
force.on('tick', function (e) {
link.attr('d', drawPointyArc);
node.attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment