summaryrefslogtreecommitdiff
path: root/js/util/trellis-chart.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/util/trellis-chart.js')
-rw-r--r--js/util/trellis-chart.js130
1 files changed, 130 insertions, 0 deletions
diff --git a/js/util/trellis-chart.js b/js/util/trellis-chart.js
new file mode 100644
index 0000000..139d663
--- /dev/null
+++ b/js/util/trellis-chart.js
@@ -0,0 +1,130 @@
+function trellisChart(anchor, monoGroups) {
+ /* attr -> {dim, group} key -> str amount, value -> { str, agi, vit, dex, int, luk } */
+
+ var attrs = monoGroups.map(function(d) { return d.name; });
+ var attrsIdByName = {};
+ monoGroups.forEach(function(d, i) { attrsIdByName[d.name] = i; });
+
+ var cellWidth = 5;
+ var radius = cellWidth / 2;
+ var subChartLength = 57;
+ var subChartUnpaddedLength = 50;
+ var subChartPadding = 7;
+
+ var margin = {top: 10, right: 10, bottom: 20, left: 10};
+ var anchor = d3.select(anchor);
+ var g = anchor.select("g");
+ var filler = d3.scale.log().domain([1, 2]).range([0, 255]);
+
+ var _chart = function() {
+ if (g.empty()) {
+ /* Make stuff! */
+ var svg = anchor.append("svg");
+ g = svg
+ .append("g");
+ attrs.forEach(function(d, i) {
+ g
+ .append("text")
+ .attr("transform", function(d) { return "translate(0," + ((attrs.length - i) * subChartLength + 10 - subChartLength / 2) + ")"; })
+ .text(d)
+ ;
+ g
+ .append("text")
+ .attr("transform", function(d) { return "translate(" + (i * subChartLength + 25 + 22) + "," + (attrs.length * subChartLength + 18) + ")"; })
+ .text(d)
+ ;
+ })
+ g = svg
+ .append("g")
+ .attr("transform", "translate(" + (margin.left + 25) + "," + (margin.top) + ")");
+ }
+ /* Group first into columns for each stat. We have one column for each of the stat monoGroups. */
+ /*
+ * monoGroups is an array of each stat dimension. We can consider each column to have data in the following format:
+ * { group: function, dim: function, name: stat }
+ */
+ var columns = g.selectAll(".column")
+ .data(monoGroups);
+ var colE = columns
+ .enter().append("g")
+ .attr("class", "column")
+ .attr("transform", function(d) { return "translate(" + (attrsIdByName[d.name] * subChartLength) + ",0)"; })
+ ;
+ colE
+ .append("line")
+ .attr("x1", -cellWidth)
+ .attr("x2", -cellWidth)
+ .attr("y1", -cellWidth)
+ .attr("y2", subChartLength * attrs.length - subChartPadding)
+ .attr("class", "border-line")
+ ;
+ colE
+ .append("line")
+ .attr("x1", subChartUnpaddedLength)
+ .attr("x2", subChartUnpaddedLength)
+ .attr("y1", -cellWidth)
+ .attr("y2", subChartLength * attrs.length - subChartPadding)
+ .attr("class", "border-line")
+ ;
+ /* Each stat has an array for its value. Group these to find the x position. */
+ /*
+ * The function transforms the data to take the grouping. We can consider each x position grouping to have data in the following format:
+ * { key: position, value: [{[stat] -> [y pos] -> count}] }
+ */
+ var colposg = columns.selectAll(".colpos")
+ .data(function(d, i) {
+// console.log("Incoming colposg format:", d, i, "Transformed to:", d.group.all().map(function(d2) { d2.name = d.name; return d2; }));
+ return d.group.all().map(function(d2) { d2.name = d.name; return d2; });
+ }, function(d) { return d.key; });
+ colposg
+ .enter().append("g")
+ .attr("class", "colpos")
+ .attr("transform", function(d) { return "translate(" + (d.key * cellWidth) + ",0)"; })
+ ;
+ /* Next, split up each x position grouping into its y stat grouping. */
+ /*
+ * We can consider each y stat grouping to have data in the following format:
+ * v[y pos] -> count; v.name -> name
+ */
+ var rows = colposg.selectAll(".row")
+ .data(function(d, i) {
+// console.log("Incoming row format:", d, i, "Transformed to:", attrs.map(function(d2) { return { name: d2, data: d.value[d2] }; }));
+ return attrs.map(function(d2) { return { name: d2, data: d.value[d2] }; });
+ });
+ rows
+ .enter().append("g")
+ .attr("class", "row")
+ .attr("transform", function(d) { return "translate(0," + ((attrs.length - attrsIdByName[d.name] - 1) * subChartLength) + ")"; })
+ ;
+ /* Finally, split up each y stat grouping into x. */
+ var vmax = 0;
+ var cells = rows.selectAll(".cell")
+ .data(function(d, i) {
+// console.log("Incoming cells format:", d, i, "Transformed to:", d.data);
+ return d.data;
+ });
+ cells
+ .enter().append("circle")
+ .attr("class", "cell")
+ .attr("r", radius)
+ ;
+ cells
+ .each(function(d) {
+ if (d > vmax) vmax = d;
+ })
+ ;
+ filler.domain([1, vmax + 1]);
+ cells
+ .attr("fill", function(d) {
+ return d ? d3.rgb(255 - filler(d + 1), 255 - filler(d + 1) / 2, 255 - filler(d + 1) / 3) : "white";
+ })
+ .attr("transform", function(d, i) { return "translate(0," + ((10-i) * cellWidth) + ")"; })
+ ;
+ cells
+ .exit()
+ .remove()
+ ;
+ }
+
+ return _chart;
+}