Skip to content

Instantly share code, notes, and snippets.

@jColeChanged
Last active August 29, 2015 14:25
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 jColeChanged/2012160ee39c915efa4b to your computer and use it in GitHub Desktop.
Save jColeChanged/2012160ee39c915efa4b to your computer and use it in GitHub Desktop.
Naruto Visualization
<html>
<head>
<script type="text/javascript"
src="http://d3js.org/d3.v3.min.js"
charset="utf-8">
</script>
<style type="text/css">
.two-col {
display: -ms-flex;
display: -webkit-flex;
display: flex;
}
.two-col > div {
padding: 10px;
}
h1 {
text-align: center;
}
.outlines {
fill: none;
stroke: black;
stroke-width: .5;
}
.stats {
stroke: black;
fill: white;
opacity: 0.9;
}
</style>
</head>
<body>
<div class="two-col">
<div>
<h1>Naruto Stats</h1>
<svg id="narutoChart" width="250" height="250"></svg>
</div>
<div>
<h1>Sasuke Stats</h1>
<svg id="sasukeChart" width="250" height="250"></svg>
</div>
</div>
<p><small>*The listed stats were adapted from leafninja.com and the Naruto databooks.</small></p>
<script type="text/javascript">
function statogram(config) {
var width = config.width,
height = config.height,
radius = Math.min(width, height) / 2,
scale = radius / 6,
fourtyFiveDegrees = Math.sqrt(2) / 2;
var nameToTranslation = {
"fuinjutsu": [-fourtyFiveDegrees, -fourtyFiveDegrees],
"ninjutsu": [0, -1],
"taijutsu": [fourtyFiveDegrees, -fourtyFiveDegrees],
"genjutsu": [1, 0],
"intelligence": [fourtyFiveDegrees, fourtyFiveDegrees],
"force": [0, 1],
"speed": [-fourtyFiveDegrees, fourtyFiveDegrees],
"stamina": [-1, 0]
};
function x(stats, key) {
return stats[key] * nameToTranslation[key][0] * scale;
}
function y(stats, key) {
return stats[key] * nameToTranslation[key][1] * scale;
}
function projection(stats) {
/* Accepts an object in which ninja stats are recorded from [0, 5].
Returns a list of [x, y] coordinates for the given stats. */
var coordinates = Object.keys(nameToTranslation).map(function(key) {
return [x(stats, key), y(stats, key)];
});
return coordinates;
}
function computePath(stats) {
var coordinates = projection(stats);
var path = "M " + coordinates[0][0] + "," + coordinates[0][1];
for (var i=1; i < coordinates.length; i++) {
path += " L " + coordinates[i][0] + "," + coordinates[i][1];
}
path += " Z";
return path;
}
var chart = d3.select(config.select);
var svg = chart.append("g")
.attr({"width": width, "height": height})
.attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");
var defs = svg.append("defs");
var grads = defs.append("radialGradient").attr("id", "orangeGradient");
grads.append("stop").attr("offset", "20%").style("stop-color", "yellow");
grads.append("stop").attr("offset", "90%").style("stop-color", "#FF4500");
var container = svg.append("g");
var circle = container.selectAll("circle").data([1]);
circle.enter().append("circle")
.attr("fill", "url(#orangeGradient)")
.attr("r", radius);
var ringPaths = [1, 2, 3, 4, 5].map(function(val) {
return ringStats = {
"fuinjutsu": val,
"ninjutsu": val,
"taijutsu": val,
"genjutsu": val,
"intelligence": val,
"force": val,
"speed": val,
"stamina": val
};
}).map(computePath);
var rings = container.selectAll('path.outlines').data(ringPaths);
rings.enter().append("path")
.classed("outlines", true);
rings.attr("d", function(d) { return d; });
rings.exit().remove();
maxStats = {
"fuinjutsu": 5,
"ninjutsu": 5,
"taijutsu": 5,
"genjutsu": 5,
"intelligence": 5,
"force": 5,
"speed": 5,
"stamina": 5
};
var maxCoordinates = projection(maxStats);
var lines = container.selectAll('line.outlines').data(maxCoordinates);
lines.enter().append("line")
.classed("outlines", true)
.style("stroke-width", 1.5);
lines
.attr("x1", 0)
.attr("y2", 0)
.attr("x2", function(d) { return d[0]; })
.attr("y2", function(d) { return d[1]; });
lines.exit().remove()
var labelData = Object.keys(maxStats).map(function(key) {
return {
label: key,
x: x(maxStats, key),
y: y(maxStats, key)
};
});
var labels = container.selectAll("text").data(labelData);
labels.enter().append("text")
.attr("text-anchor", "middle")
labels
.text(function(d) { return d.label; })
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
labels.exit().remove();
function tick() {
var stat = config.stats.shift();
config.stats.push(stat);
var statPaths = [computePath(stat)]
var stats = container.selectAll('path.stats').data(statPaths);
stats.enter().append("path")
.classed("stats", true);
stats.transition()
.duration(3000)
.attr("d", function(d) { return d; })
.each("end", tick);
stats.exit().remove();
}
return tick;
}
var statogramWidth = 250;
var statogramHeight = 250;
var narutoStats = [
{
"ninjutsu": 2,
"taijutsu": 1.5,
"genjutsu": 1,
"intelligence": 1,
"force": 2,
"speed": 2,
"stamina": 4,
"fuinjutsu": 1
},
{
"ninjutsu": 3,
"taijutsu": 2,
"genjutsu": 1,
"intelligence": 1.5,
"force": 3,
"speed": 3,
"stamina": 4,
"fuinjutsu": 1
},
{
"ninjutsu": 4,
"taijutsu": 3.5,
"genjutsu": 2,
"intelligence": 3,
"force": 3.5,
"speed": 3.5,
"stamina": 5,
"fuinjutsu": 1.5
}
];
var narutoChart = statogram({
select: "#narutoChart",
width: statogramWidth,
height: statogramHeight,
stats: narutoStats
});
narutoChart();
var sasukeStats = [
{
"ninjutsu": 2.5,
"taijutsu": 2.5,
"genjutsu": 1.5,
"intelligence": 2,
"force": 2,
"speed": 3,
"stamina": 2,
"fuinjutsu": 3
},
{
"ninjutsu": 3.5,
"taijutsu": 2.5,
"genjutsu": 1.5,
"intelligence": 2.5,
"force": 3,
"speed": 3.5,
"stamina": 3,
"fuinjutsu": 3
},
{
"ninjutsu": 5,
"taijutsu": 3.5,
"genjutsu": 4,
"intelligence": 3.5,
"force": 3.5,
"speed": 4.5,
"stamina": 3.5,
"fuinjutsu": 4
}
]
var sasukeChart = statogram({
select: "#sasukeChart",
width: statogramWidth,
height: statogramHeight,
stats: sasukeStats
});
sasukeChart();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment