Advertisement
Guest User

Untitled

a guest
Jan 17th, 2019
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Copyright (c) 2013, Jason Davies, http://www.jasondavies.com/
  2. // License: https://raw.github.com/jasondavies/d3-cloud/master/LICENSE
  3. (function() {
  4.   function Tree(x, y, r, b) {
  5.     this.x = x;
  6.     this.y = y;
  7.     this.r = r;
  8.     this.b = b;
  9.     this.children = null;
  10.   }
  11.  
  12.   var minBoxSize = 1;
  13.  
  14.   function makeTree(shape, x, y, r, b) {
  15.     if (contains(shape, x, y, r, b)) {
  16.       return new Tree(x, y, r, b);
  17.     } else if (intersects(shape, x, y, r, b)){
  18.       var cx = (x + r) >> 1,
  19.           cy = (y + b) >> 1,
  20.           tree = new Tree(x, y, r, b);
  21.       if (r - x > minBoxSize || b - y > minBoxSize) {
  22.         var children = [],
  23.             c0 = makeTree(shape,  x,  y, cx, cy),
  24.             c1 = makeTree(shape, cx,  y,  r, cy),
  25.             c2 = makeTree(shape,  x, cy, cx,  b),
  26.             c3 = makeTree(shape, cx, cy,  r,  b);
  27.         if (c0) children.push(c0);
  28.         if (c1) children.push(c1);
  29.         if (c2) children.push(c2);
  30.         if (c3) children.push(c3);
  31.         if (children.length) tree.children = children;
  32.       }
  33.       return tree;
  34.     }
  35.     return null;
  36.   }
  37.  
  38.   function contains(shape, x, y, r, b) {
  39.     if (x < shape.x || y < shape.y || r >= shape.r || b >= shape.b) return false;
  40.     x -= shape.x;
  41.     y -= shape.y;
  42.     r -= shape.x;
  43.     b -= shape.y;
  44.     var w = shape.r - shape.x,
  45.         sprite = shape.sprite;
  46.     for (var j=y; j<b; j++) {
  47.       for (var i=x; i<r; i++) if (!sprite[j * w + i]) return false;
  48.     }
  49.     return true;
  50.   }
  51.  
  52.   function intersects(shape, x, y, r, b) {
  53.     x = Math.max(0, x - shape.x);
  54.     y = Math.max(0, y - shape.y);
  55.     r = Math.min(shape.r, r) - shape.x;
  56.     b = Math.min(shape.b, b) - shape.y;
  57.     var w = shape.r - shape.x,
  58.         sprite = shape.sprite;
  59.     for (var j=y; j<b; j++) {
  60.       for (var i=x; i<r; i++) if (sprite[j * w + i]) return true;
  61.     }
  62.     return false;
  63.   }
  64.  
  65.   function overlaps(tree, otherTree, aox, aoy, box, boy) {
  66.     if (rectCollide(tree, otherTree, aox, aoy, box, boy)) {
  67.       if (tree.children == null) {
  68.         if (otherTree.children == null) return true;
  69.         else for (var i=0, n=otherTree.children.length; i<n; i++) {
  70.           if (overlaps(tree, otherTree.children[i], aox, aoy, box, boy)) return true;
  71.         }
  72.       } else for (var i=0, n=tree.children.length; i<n; i++) {
  73.         if (overlaps(otherTree, tree.children[i], box, boy, aox, aoy)) return true;
  74.       }
  75.     }
  76.     return false;
  77.   }
  78.  
  79.   function rectCollide(a, b, aox, aoy, box, boy) {
  80.     return aoy + a.b > boy + b.y
  81.         && aoy + a.y < boy + b.b
  82.         && aox + a.r > box + b.x
  83.         && aox + a.x < box + b.r;
  84.   }
  85.  
  86.   var w = 960,
  87.       h = 270,
  88.       p = 5;
  89.  
  90.   var canvas = document.createElement("canvas");
  91.   canvas.width = 1;
  92.   canvas.height = 1;
  93.   var ratio = Math.sqrt(canvas.getContext("2d").getImageData(0, 0, 1, 1).data.length >> 2);
  94.   canvas.width = 160;
  95.   canvas.height = 210;
  96.   var c = canvas.getContext("2d");
  97.   c.strokeStyle = "#f00";
  98.  
  99.   var vis = d3.select("#bbtree").append("svg")
  100.       .attr("width", w)
  101.       .attr("height", h)
  102.       .attr("pointer-events", "all")
  103.     .append("g")
  104.       .attr("transform", "translate(5,5)");
  105.  
  106.   var glyphs = d3.range(2).map(function(d, i) {
  107.     d += "";
  108.     return {
  109.       text: d,
  110.       code: d.charCodeAt(0),
  111.       tree: glyphTree(d),
  112.       position: [i * 160, 30]
  113.     };
  114.   });
  115.  
  116.   update();
  117.  
  118.   function glyphTree(d) {
  119.     return makeTree({sprite: sprite(c, d, 180, 150, 150, 200), x: 0, y: 0, r: 150, b: 200}, 0, 0, 150, 200);
  120.   }
  121.  
  122.   function update() {
  123.     var g = vis.selectAll("g")
  124.         .data(glyphs);
  125.     g.enter().append("g")
  126.         .attr("transform", function(d) { return "translate(" + d.position + ")"; })
  127.         .on("click", function(d) {
  128.           d.code = 32 + ((d.code - 32 + 1) % (0x7f - 32) || 9699);
  129.           d.text = String.fromCharCode(d.code);
  130.           d.tree = glyphTree(d.text);
  131.           update();
  132.         })
  133.         .call(d3.behavior.drag()
  134.           .origin(function(d) { return {x: d.position[0], y: d.position[1]}; })
  135.           .on("drag", function(d) {
  136.             d.position = [Math.max(0, Math.min(w - canvas.width, d3.event.x)), Math.max(0, Math.min(h - canvas.height, d3.event.y))];
  137.             d3.select(this)
  138.                 .attr("transform", function(d) { return "translate(" + d.position + ")"; });
  139.             collide();
  140.           })
  141.         )
  142.       .append("text")
  143.         .attr("x", 150 / 2)
  144.         .attr("y", 150)
  145.         .attr("text-anchor", "middle")
  146.         .style("font-size", "180px")
  147.         .style("font-family", "serif")
  148.         .attr("pointer-events", "all")
  149.     g.select("text").text(function(d) { return d.text; });
  150.  
  151.     var rect = g.selectAll("rect")
  152.         .data(function(d) { return flatten(d.tree); });
  153.     rect.enter().append("rect");
  154.     rect.exit().remove();
  155.     rect.attr("width", function(d) { return d.r - d.x; })
  156.         .attr("height", function(d) { return d.b - d.y; })
  157.         .attr("x", function(d) { return d.x; })
  158.         .attr("y", function(d) { return d.y; })
  159.         .style("stroke-width", function(d) { return 2 - d.depth / 2; });
  160.   }
  161.  
  162.   function collide() {
  163.     var a = glyphs[0],
  164.         b = glyphs[1];
  165.     vis.classed("collide", overlaps(a.tree, b.tree, a.position[0], a.position[1], b.position[0], b.position[1]));
  166.   }
  167.  
  168.   function sprite(c, text, s, dy, w, h) {
  169.     c.clearRect(0, 0, w + 2 * p, h + 2 * p);
  170.     c.save();
  171.     c.fillStyle = "#000";
  172.     c.textAlign = "center";
  173.     c.font = ~~(s / ratio) + "px serif";
  174.     c.translate(p + (w >> 1) / ratio, p + dy / ratio);
  175.     c.fillText(text, 0, 0);
  176.     c.restore();
  177.     var pixels = c.getImageData(p, p, w / ratio, h / ratio).data,
  178.         sprite = [];
  179.     for (var i = w * h; --i >= 0;) sprite[i] = pixels[(i << 2) + 3];
  180.     return sprite;
  181.   }
  182.  
  183.   function flatten(root) {
  184.     var nodes = [];
  185.  
  186.     recurse(root, 0);
  187.  
  188.     return nodes;
  189.  
  190.     function recurse(node, depth) {
  191.       node.depth = depth;
  192.       if (node.children) node.children.forEach(function(d) { recurse(d, depth + 1); });
  193.       nodes.push(node);
  194.     }
  195.   }
  196. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement