Skip to content
Snippets Groups Projects
Select Git revision
  • d913aa21b33212443c3be360ad99c5d2d0484f1d
  • master default protected
2 results

mpithreadpi.cpp

Blame
  • flink.js 3.55 KiB
    import constant from "./fconstant.js";
    import jiggle from "./fjiggle.js";
    
    function index(d) {
      return d.index;
    }
    
    function find(nodeById, nodeId) {
      var node = nodeById.get(nodeId);
      if (!node) throw new Error("missing: " + nodeId);
      return node;
    }
    
    export default function(links) {
      var id = index,
          strength = defaultStrength,
          strengths,
          distance = constant(30),
          distances,
          nodes,
          count,
          bias,
          iterations = 1;
    
      // forgive me,
      var lheight = 27
    
      if (links == null) links = [];
    
      function defaultStrength(link) {
        return 1 / Math.min(count[link.source.index], count[link.target.index]);
      }
    
      function force(alpha) {
        for (var k = 0, n = links.length; k < iterations; ++k) {
          for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
            link = links[i], source = link.source, target = link.target;
            // little more premonition here
            // to start, refactor so that source (outputs) x- terms are offset to their right-most side
            // and that target (inputs) x- terms are offset to their left-most side,
            x = target.x + target.vx + target.bb.x1 - (source.x - source.vx + source.bb.x2) || jiggle();
            y = target.y + target.vy + link.toff + link.ty * lheight - source.y - source.vy - link.soff - link.sy * lheight || jiggle();
            l = Math.sqrt(x * x + y * y);
            l = (l - distances[i]) / l * alpha * strengths[i];
            x *= l, y *= l;
            // seems like we *should* just have to mux here?
            target.vx -= x * (b = bias[i]);
            target.vy -= y * b;
            source.vx += x * (b = 1 - b);
            source.vy += y * b;
          }
        }
      }
    
      function initialize() {
        if (!nodes) return;
    
        var i,
            n = nodes.length,
            m = links.length,
            nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d])),
            link;
    
        for (i = 0, count = new Array(n); i < m; ++i) {
          link = links[i], link.index = i;
          if (typeof link.source !== "object") link.source = find(nodeById, link.source);
          if (typeof link.target !== "object") link.target = find(nodeById, link.target);
          count[link.source.index] = (count[link.source.index] || 0) + 1;
          count[link.target.index] = (count[link.target.index] || 0) + 1;
        }
    
        for (i = 0, bias = new Array(m); i < m; ++i) {
          link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
        }
    
        strengths = new Array(m), initializeStrength();
        distances = new Array(m), initializeDistance();
      }
    
      function initializeStrength() {
        if (!nodes) return;
    
        for (var i = 0, n = links.length; i < n; ++i) {
          strengths[i] = +strength(links[i], i, links);
        }
      }
    
      function initializeDistance() {
        if (!nodes) return;
    
        for (var i = 0, n = links.length; i < n; ++i) {
          distances[i] = +distance(links[i], i, links);
        }
      }
    
      force.initialize = function(_) {
        nodes = _;
        initialize();
      };
    
      force.links = function(_) {
        return arguments.length ? (links = _, initialize(), force) : links;
      };
    
      force.id = function(_) {
        return arguments.length ? (id = _, force) : id;
      };
    
      force.iterations = function(_) {
        return arguments.length ? (iterations = +_, force) : iterations;
      };
    
      force.strength = function(_) {
        return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initializeStrength(), force) : strength;
      };
    
      force.distance = function(_) {
        return arguments.length ? (distance = typeof _ === "function" ? _ : constant(+_), initializeDistance(), force) : distance;
      };
    
      return force;
    }