From 1539d18cfce0e9b4dcf4a54f7adf00a03ad2b203 Mon Sep 17 00:00:00 2001
From: "Wonko T. Sane" <42@wonko.de>
Date: Fri, 6 Mar 2020 18:04:21 +0100
Subject: [PATCH] Refactored to look like d3.pie and d3.arc

---
 index.html         |  32 ++++++++----
 src/arrowonpath.js | 120 +++++++++++++++++++++++++--------------------
 src/cyclicarrow.js |  45 +++++------------
 src/index.js       |   1 +
 4 files changed, 105 insertions(+), 93 deletions(-)

diff --git a/index.html b/index.html
index 8f5c039..afc875b 100644
--- a/index.html
+++ b/index.html
@@ -22,22 +22,36 @@
 
 
 <body>
-    <div id='arrows'></div>
+    <div id='arrows' style="width:30px;"></div>
 
     <script src="https://d3js.org/d3.v5.min.js"></script>
     <script src="dist/d3-cyclicarrow.js"></script>
     <script>
-    d3.svg('path.svg').then(function (svg) {
+
+
+        // Create dummy data
+        var data = ["first", "second", "third", "fourth"];
+
+        var arr = d3.cyclicarrow()(data);
+        console.log(d3.entries(arr));
+        d3.svg('path.svg').then(function (svg) {
             svgnode = document.importNode(svg.documentElement, true);
-            console.log(svgnode);
             d3.select("div#arrows").node().append(svgnode);
-            console.log('sss');
-            bh = d3.cyclicarrow()([]);
-            console.log(bh);
-            console.log('aaa');
+            svg = d3.select("div#arrows svg");
+
+            console.log(svg);
+            svg.selectAll("whatever")
+                .data(arr)
+                .enter()
+                .append('path')
+                .attr('d', d3.arrowonpath());
+
+
+            //bh = d3.cyclicarrow()([]);
+            //console.log(bh);
         });
-    
-   
+
+
     </script>
 
 </body>
\ No newline at end of file
diff --git a/src/arrowonpath.js b/src/arrowonpath.js
index ae2086a..f7012ea 100644
--- a/src/arrowonpath.js
+++ b/src/arrowonpath.js
@@ -17,102 +17,118 @@ function controlPoints(x) {
     for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
     return [a, b];
 }
-
-
-export default class ArrowOnPath {
-    constructor(path, start, end, parts = 3, thickness = 5, angle = 2, padding = 1) {
-        this.path = path;
-
-        this.angle = angle;
-        this.thickness = thickness;
-        var length = end - start;
-        var partlen = (length - (2 * padding)) / (2 * parts);
-        console.log("ArrowOnPath", start, end, partlen);
-        this.p = [this.pointsAt(start + padding, (-1 * padding))];
-        for (var i = 1; i < (2 * parts); i++) {
-            this.p.push(this.pointsAt(start + (i * partlen)));
-        }
-        this.p.push(this.pointsAt(start + length - padding, (1 * padding)));
-    }
-    pointAngle(length) {
-        var p1 = this.path.getPointAtLength(length);
-        var p2 = this.path.getPointAtLength(length + 0.01);
+function svgpath() {
+    var circularSvg = d3.select("svg"), // Move out of here it doesnt belong
+        circularPath = circularSvg.select("path").node();
+    return circularPath;
+};
+
+
+export default function () {
+    var parts = 3,
+        thickness = 5,
+        angle = 2,
+        padding = 1,
+        path = svgpath(),
+        path_l = path.getTotalLength(),
+
+        context = null;
+
+    function pointAngle(length) {
+        var p1 = path.getPointAtLength(length);
+        var p2 = path.getPointAtLength(length + 0.01);
         if (p1.x == p2.x && p1.y == p2.y) {
-            p1 = this.path.getPointAtLength(length - 0.01);
+            p1 = path.getPointAtLength(length - 0.01);
         }
         console.log(p1, p2);
         return Math.atan2((p2.y - p1.y), (p2.x - p1.x));
 
     }
-    pointsAt(length, angleoffset = 0) {
-        var m = this.path.getPointAtLength(length);
-        var m_angle = this.pointAngle(length + angleoffset)
+
+    function pointsAt(length, angleoffset = 0) {
+        var m = path.getPointAtLength(length);
+        var m_angle = pointAngle(length + angleoffset)
         console.log("a", m_angle);
         var a = {
-            x: m.x + (this.thickness * Math.cos(m_angle + this.angle))
-            , y: m.y + (this.thickness * Math.sin(m_angle + this.angle))
+            x: m.x + (thickness * Math.cos(m_angle + angle))
+            , y: m.y + (thickness * Math.sin(m_angle + angle))
         };
 
         var b = {
-            x: m.x + (this.thickness * Math.cos(m_angle - this.angle))
-            , y: m.y + (this.thickness * Math.sin(m_angle - this.angle))
+            x: m.x + (thickness * Math.cos(m_angle - angle))
+            , y: m.y + (thickness * Math.sin(m_angle - angle))
         };
 
         return { a: a, m: m, b: b }
     }
 
-    p2s(point) {
-        return point.x.toString() + "," + point.y.toString();
-    }
+
+    function arrowonpath() {
+        var buffer,
+            start = path_l * arguments[0].start,
+            end = path_l * arguments[0].end,
+            length = end - start,
+            partlen = (length - (2 * padding)) / (2 * parts);
+
+        console.log("ArrowOnPath", start, end, partlen);
+
+        if (!context) context = buffer = d3.path();
+
+        var p = [pointsAt(start + padding, (-1 * padding))];
+        for (var i = 1; i < (2 * parts); i++) {
+            p.push(pointsAt(start + (i * partlen)));
+        }
+        p.push(pointsAt(start + length - padding, (1 * padding)));
 
 
-    d3path() {
-        var path = d3.path();
         var i = 0
 
-        path.moveTo(this.p[i].m.x, this.p[i].m.y);
-        path.lineTo(this.p[i].a.x, this.p[i].a.y);
+        context.moveTo(p[i].m.x, p[i].m.y);
+        context.lineTo(p[i].a.x, p[i].a.y);
 
-        var nat = d3.curveNatural(path);
+        var nat = d3.curveNatural(context);
         nat.lineStart();
-        for (var i = 0; i < this.p.length; i++) {
-            nat.point(this.p[i].a.x, this.p[i].a.y);
+        for (var i = 0; i < p.length; i++) {
+            nat.point(p[i].a.x, p[i].a.y);
 
         }
         var px = controlPoints(nat._x),
             py = controlPoints(nat._y);
-        var n = this.p.length;
+        var n = p.length;
         var x = nat._x,
             y = nat._y;
         for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
-            path.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
+            context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
         }
 
 
-        i = this.p.length - 1;
-        path.lineTo(this.p[i].m.x, this.p[i].m.y);
-        path.lineTo(this.p[i].b.x, this.p[i].b.y);
+        i = p.length - 1;
+        context.lineTo(p[i].m.x, p[i].m.y);
+        context.lineTo(p[i].b.x, p[i].b.y);
 
         nat.lineStart();
 
-        for (var i = this.p.length - 1; i >= 0; --i) {
+        for (var i = p.length - 1; i >= 0; --i) {
 
-            nat.point(this.p[i].b.x, this.p[i].b.y);
+            nat.point(p[i].b.x, p[i].b.y);
 
         }
         var px = controlPoints(nat._x),
             py = controlPoints(nat._y);
-        var n = this.p.length;
+        var n = p.length;
         var x = nat._x,
             y = nat._y;
         for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
-            path.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
+            context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
         }
 
-        path.closePath();
-        return path;
-    }
-    toString() {
-        return this.d3path().toString();
+        context.closePath();
+        if (buffer) return context = null, buffer + "" || null;
     }
+    arrowonpath.svgpath = function (_) {
+        return arguments.length ? (svgpath = typeof _ === "function" ? _ : constant(+_), arrowonpath) : svgpath;
+    };
+
+    return arrowonpath;
 }
+
diff --git a/src/cyclicarrow.js b/src/cyclicarrow.js
index 917fa26..2effe86 100644
--- a/src/cyclicarrow.js
+++ b/src/cyclicarrow.js
@@ -1,44 +1,25 @@
 import constant from "./constant.js";
-import ArrowOnPath from "./arrowonpath.js";
 
-function getRandomColorRgb() {
-  let red = Math.floor(Math.random() * 256);
-  let green = Math.floor(Math.random() * 256);
-  let blue = Math.floor(Math.random() * 256);
-  return `rgb(${red}, ${green}, ${blue})`;
-}
 
 export default function () {
-  console.log('ssksk');
-  var arrowParts = constant(3),
-    arrowThickness = constant(5),
-    arrowAngle = constant(2),
-    arrowPadding = constant(1),
-    output = null,
-    circularSvg = d3.select("svg"), // Move out of here it doesnt belong
-    circularPath = circularSvg.select("path").node();
-  console.log('ezteze');
+  //var value =  
+  //TODO implement the ability for arrow length bsed on value like in d3.pie
+
   function cyclicarrow(data) {
-    console.log('blah');
-    var l = circularPath.getTotalLength();
-    var segs = 8;
-    var seg_l = l / segs;
+    var fractions = data.length,
+      seg = 1 / fractions,
+      segments = new Array(fractions);
+
 
-    console.log(l, seg_l)
-    for (var i = 0; i < segs; i++) {
-      var start = i * seg_l;
-      var end = (i + 1) * seg_l;
-      console.log(i, start, start);
-      var ar = new ArrowOnPath(circularPath, start, end);
-      circularSvg.append("path")
-        .attr("d", ar.toString())
-        .attr("style", "fill:" + getRandomColorRgb());
+    for (var i = 0; i < fractions; i++) {
+      segments[i] = {
+        start: i * seg,
+        end: (i + 1) * seg
+      }
     }
+    return segments;
   }
 
-  cyclicarrow.arrowAngle = function (_) {
-    return arguments.length ? (arrowAngle = typeof _ === "function" ? _ : constant(+_), cyclicarrow) : arrowAngle;
-  };
   return cyclicarrow;
 }
 
diff --git a/src/index.js b/src/index.js
index e078f80..ce2b586 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1 +1,2 @@
 export {default as cyclicarrow} from "./cyclicarrow.js";
+export {default as arrowonpath } from "./arrowonpath.js";
\ No newline at end of file
-- 
GitLab