toolkit/javascript/d3/examples/superformula/superformula.js
changeset 47 c0b4a8b5a012
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolkit/javascript/d3/examples/superformula/superformula.js	Thu Apr 10 14:20:23 2014 +0200
@@ -0,0 +1,98 @@
+(function() {
+  var _symbol = d3.svg.symbol(),
+      _line = d3.svg.line();
+
+  superformula = function() {
+    var type = _symbol.type(),
+        size = _symbol.size(),
+        segments = size,
+        params = {};
+
+    function superformula(d, i) {
+      var n, p = _superformulaTypes[type.call(this, d, i)];
+      for (n in params) p[n] = params[n].call(this, d, i);
+      return _superformulaPath(p, segments.call(this, d, i), Math.sqrt(size.call(this, d, i)));
+    }
+
+    superformula.type = function(x) {
+      if (!arguments.length) return type;
+      type = d3.functor(x);
+      return superformula;
+    };
+
+    superformula.param = function(name, value) {
+      if (arguments.length < 2) return params[name];
+      params[name] = d3.functor(value);
+      return superformula;
+    };
+
+    // size of superformula in square pixels
+    superformula.size = function(x) {
+      if (!arguments.length) return size;
+      size = d3.functor(x);
+      return superformula;
+    };
+
+    // number of discrete line segments
+    superformula.segments = function(x) {
+      if (!arguments.length) return segments;
+      segments = d3.functor(x);
+      return superformula;
+    };
+
+    return superformula;
+  };
+
+  function _superformulaPath(params, n, diameter) {
+    var i = -1,
+        dt = 2 * Math.PI / n,
+        t,
+        r = 0,
+        x,
+        y,
+        points = [];
+
+    while (++i < n) {
+      t = params.m * (i * dt - Math.PI) / 4;
+      t = Math.pow(Math.abs(Math.pow(Math.abs(Math.cos(t) / params.a), params.n2)
+        + Math.pow(Math.abs(Math.sin(t) / params.b), params.n3)), -1 / params.n1);
+      if (t > r) r = t;
+      points.push(t);
+    }
+
+    r = diameter * Math.SQRT1_2 / r;
+    i = -1; while (++i < n) {
+      x = (t = points[i] * r) * Math.cos(i * dt);
+      y = t * Math.sin(i * dt);
+      points[i] = [Math.abs(x) < 1e-6 ? 0 : x, Math.abs(y) < 1e-6 ? 0 : y];
+    }
+
+    return _line(points) + "Z";
+  }
+
+  var _superformulaTypes = {
+    asterisk: {m: 12, n1: .3, n2: 0, n3: 10, a: 1, b: 1},
+    bean: {m: 2, n1: 1, n2: 4, n3: 8, a: 1, b: 1},
+    butterfly: {m: 3, n1: 1, n2: 6, n3: 2, a: .6, b: 1},
+    circle: {m: 4, n1: 2, n2: 2, n3: 2, a: 1, b: 1},
+    clover: {m: 6, n1: .3, n2: 0, n3: 10, a: 1, b: 1},
+    cloverFour: {m: 8, n1: 10, n2: -1, n3: -8, a: 1, b: 1},
+    cross: {m: 8, n1: 1.3, n2: .01, n3: 8, a: 1, b: 1},
+    diamond: {m: 4, n1: 1, n2: 1, n3: 1, a: 1, b: 1},
+    drop: {m: 1, n1: .5, n2: .5, n3: .5, a: 1, b: 1},
+    ellipse: {m: 4, n1: 2, n2: 2, n3: 2, a: 9, b: 6},
+    gear: {m: 19, n1: 100, n2: 50, n3: 50, a: 1, b: 1},
+    heart: {m: 1, n1: .8, n2: 1, n3: -8, a: 1, b: .18},
+    heptagon: {m: 7, n1: 1000, n2: 400, n3: 400, a: 1, b: 1},
+    hexagon: {m: 6, n1: 1000, n2: 400, n3: 400, a: 1, b: 1},
+    malteseCross: {m: 8, n1: .9, n2: .1, n3: 100, a: 1, b: 1},
+    pentagon: {m: 5, n1: 1000, n2: 600, n3: 600, a: 1, b: 1},
+    rectangle: {m: 4, n1: 100, n2: 100, n3: 100, a: 2, b: 1},
+    roundedStar: {m: 5, n1: 2, n2: 7, n3: 7, a: 1, b: 1},
+    square: {m: 4, n1: 100, n2: 100, n3: 100, a: 1, b: 1},
+    star: {m: 5, n1: 30, n2: 100, n3: 100, a: 1, b: 1},
+    triangle: {m: 3, n1: 100, n2: 200, n3: 200, a: 1, b: 1}
+  };
+
+  superformulaTypes = d3.keys(_superformulaTypes);
+})();