'use strict'; /** * */ function Point(x, y, name, hex) { if (typeof x !== typeof 1) { throw new Error("x = " + x + " must be of type 'number'; it is currently of type '" + (typeof x) + "'."); } if (typeof y !== typeof 1) { throw new Error("y = " + y + " must be of type 'number'; it is currently of type '" + (typeof y) + "'."); } if (x < 0 || y < 0) { throw new Error("X and Y must be greater than 0."); } this.x = x; this.y = y; this.name = name; this.hex = hex; } /** * */ function Triangle(a, b, c) { if (!(a instanceof Point) || !(b instanceof Point) || !(c instanceof Point)) { throw new Error("All three arguments must be of type Point."); } this.a = a; this.b = b; this.c = c; } /** * */ Triangle.prototype = { /** * */ findMidpoint: function(p1, p2) { var minX = Math.min(p1.x, p2.x); var maxX = Math.max(p1.x, p2.x); var minY = Math.min(p1.y, p2.y); var maxY = Math.max(p1.y, p2.y); var midX = minX + ((maxX - minX) / 2); var midY = minY + ((maxY - minY) / 2); return new Point(midX, midY); }, /** * */ buildGradient: function(p) { var opp1, opp2; if (p === this.a) { opp1 = this.b; opp2 = this.c; } if (p === this.b) { opp1 = this.a; opp2 = this.c; } if (p === this.c) { opp1 = this.a; opp2 = this.b; } var fill = d3.select(document.createElementNS(d3.ns.prefix.svg, "linearGradient")) .attr("gradientUnits", "userSpaceOnUse") .attr("id", `fill${p.name}`) .attr("x1", p.x) .attr("y1", p.y) .attr("x2", this.findMidpoint(opp1, opp2).x) .attr("y2", this.findMidpoint(opp1, opp2).y) fill.append("stop") .attr("offset", "0%") .attr("stop-color", p.hex) fill.append("stop") .attr("offset", "100%") .attr("stop-color", "#fff") .attr("stop-opacity", "0") return function() { return fill.node(); }; }, /** * */ buildPath: function(p) { var path = d3.select(document.createElementNS(d3.ns.prefix.svg, "path")) .attr("d", `M${this.a.x},${this.a.y} L${this.b.x},${this.b.y} L${this.c.x},${this.c.y} Z`) .attr("fill", `url(#fill${p.name})`) return function() { return path.node(); }; } }; /** * */ (function() { var svg = d3.select("body").append("svg") .attr("width", 500) .attr("height", 500); var defs = svg.append("defs"); var points = [ [ new Point(100, 0, 'A1', '#f00'), new Point(200, 200, 'B1', '#0f0'), new Point(0, 200, 'C1', '#00f') ], [ new Point(100, 0, 'A2', '#f00'), new Point(200, 200, 'B2', '#0f0'), new Point(300, 0, 'C2', '#00f') ], [ new Point(300, 300, 'A3', '#f00'), new Point(300, 0, 'C3', '#00f'), new Point(200, 200, 'B3', '#0f0'), ], ]; for (var i = 0, len = points.length; i < len; i++) { var T = new Triangle(points[i][0], points[i][1], points[i][2]); defs.append(T.buildGradient(points[i][0])); defs.append(T.buildGradient(points[i][1])); defs.append(T.buildGradient(points[i][2])); svg.append(T.buildPath(points[i][0])); svg.append(T.buildPath(points[i][1])); svg.append(T.buildPath(points[i][2])); } }());