block by mpmckenna8 320d28322a26ceff41ee9079a9c4fb16

320d28322a26ceff41ee

Full Screen

Another simple binary tree. But this one builds it a node at a time visually in the order that the elements are in the array.

Now I need to combine all the pieces and have it build the heap then run max-heap on it all in one go.

index.html

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="./style.css" />
      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.4/d3.js"></script>


  </head>
  <body>
    <div id="heap">
    </div>
  <script src="heaper.js"></script>

  </body>

</html>

heaper.js

// This will make a heap node by node in a nice animation type thing.

var arr = [ 1, 4, 6, 12, 23, 29, 89, 21, 30, 21, 40, 292]

var duration = 1000

var margin = {top: 20, right: 90, bottom: 30, left: 90},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var svg = d3.select("body")
        .append("svg")
        .attr("width", width + margin.right + margin.left)
        .attr("height", height + margin.top + margin.bottom)

var g = svg.append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// declares a tree layout and assigns the size
var treemap = d3.tree()
    .size([width, height]);

var newsource = {name: arr[0], children: getChildren(0, arr) }

console.log(newsource);

var root = d3.hierarchy(newsource, function(d) { return d.children; });

root.x0 = 0;
root.y0 = width/2;

console.log('the descendants of the root', root.descendants())

collapse(root)

update(root);

runprom(root);

function runprom(dat) {
  promun(dat)
    .then(function(d){
	    console.log('finished the promise', d.descendants())
      for( i of root.descendants() ) {
		    console.log(i)
        if( i._children ) {
			    runprom(i)
			    break;
		    }
 	    }
    });
}


function promun(ino){
	var innodes = ino.descendants();
	return new Promise(function(res, rej){

	  //console.log('inpromise', ino)
    unfold(ino);

	 d3.timeout(function(){
		res(ino)
	 }, 3000);

	})
}

function unfold(data){
	console.log('unfolding, ', data)
//	update(data)
	if( data._children ){
	  if( data._children.length > 0 ) {
		  if(data.children === null ) { data.children = [] }

		  data.children.push(data._children.shift())
		  if( data._children.length === 0 ) {
			  data._children = null;
		  }
    }


	setTimeout(function(d){
      console.log('doidfdid timeing out', d)
      update(data)
		//console.log('should try to unfold data')
	     unfold(data)
    } , 1000)

  }

//	update(data)
}


var unfoldIndex = 1;
d3.timeout(function(d){
	console.log('do this once')
}, 2000)
//d3.timeout(function(d){ console.log('why not timing out oh so longdoidfdid timeing out')	update(root) 	} , 60000, 5000)
//update(root);

function getChildren(i, array) {
	var childs = [];
	var nextIndex = i * 2 + 1;
	if( array[ i * 2 + 1 ] ) {
		childs[0] = { name: array[i * 2 + 1], children: [] };
		if( array[ i * 2 + 2 ] ) {
			childs[1] = { name: array[ i * 2 + 2]  };
		}
	}

	if( arr[nextIndex *2  + 1]) {
		childs[0].children = getChildren( nextIndex, array)
		childs[0]._children = null;

		if( arr[nextIndex*2 + 2]){
			childs[1].children = getChildren(nextIndex + 1, array);
			childs[1]._children = null;
		}
	}

	return childs
}


function update(data) {

  var treeData = treemap(root);
  var nodes = treeData.descendants();

  var links = treeData.descendants().slice(1);

 // console.log(nodes);

  console.log("nodes = ", nodes, ", links = ", links);

  var node = g.selectAll('g.node')
    .data(nodes, function(d, i) {
	  	return d.id = i;
  	})

	console.log(node)

  var nodeEnter = node.enter().append('g')
    .attr('class', 'node')
	  .attr('transform', function(d) {
		  console.log(d);
		  return 'translate( ' + data.x0 + ', ' + data.y0 + ' )';
	  })
	  .attr('id', function(d, i) {
		  return 'nodey' + i;
	  })


  nodeEnter.append('circle')
	  .attr('class', 'node')
  	.attr('r', 1e-6)
  	.style('fill', function(d){
	  	return "green" //d._children ? "lightsteelblue" : "#fff";
	  })

  // Labels for the nodes
	nodeEnter.append('text')
          .attr("dy", ".35em")
          .attr("x", function(d) {
                return d.children || d._children ? -13 : 13;
          })
          .attr("text-anchor", function(d) {
                return d.children || d._children ? "end" : "start";
          })
          .attr("class", "valtext")
          .text(function(d) { return d.data.name; });

  // UPDATE
  var nodeUpdate = nodeEnter.merge(node);

  nodeUpdate.transition()
     .duration(duration)
    // .text(function(d) { return d.data.name; })
	   .attr('transform', function(d){
       return "translate(" + d.x + "," + d.y + ")"
	   })

  // Update the node attributes and style
  nodeUpdate.select('circle.node')
        .attr('r', 10)
        .style("fill", function(d) {
            return "yellow"//d._children ? "lightsteelblue" : "#fff";
        })
        .attr('cursor', 'pointer')
        .style('stroke', 'black')
        .style('stroke-width', '2px')

  // Remove any exiting nodes
  var nodeExit = node.exit().transition()
          .duration(duration)
          .attr("transform", function(d) {
                   return "translate(" + data.x + "," + data.y + ")";
               })
          .remove();

           // On exit reduce the node circles size to 0
  nodeExit.select('circle')
          .attr('r', 1e-6);

           // On exit reduce the opacity of text labels
  nodeExit.select('text')
          .style('fill-opacity', 1e-6);

	// ****************** links section ***************************

 // Update the links...
  var link = g.selectAll('path.link')
     .data(links, function(d) { return d.id; });

 // Enter any new links at the parent's previous position.
  var linkEnter = link.enter().insert('path', "g")
 //   .on('click', click)
     .attr("class", "link")
     .attr('d', function(d){
       var o = {y: data.y0, x: data.x0}
       return diagonal(o, o)
     })
	   .style('fill', 'none')
     .style('stroke', 'black');

 // UPDATE
  var linkUpdate = linkEnter.merge(link);

 // Transition back to the parent element position
  linkUpdate.transition()
     .duration(duration)
     .attr('d', function(d){ return diagonal(d, d.parent) });


 // Remove any exiting links
  var linkExit = link.exit().transition()
     .duration(duration)
     .attr('d', function(d) {
       var o = {x: data.x, y: data.y}
       return diagonal(o, o)
     })
     .remove();



 // Store the old positions for transition.
  nodes.forEach(function(d, i){
//   console.log(d)
    d.x0 = d.x;
    d.y0 = d.y;
  });



}


  function collapse(d) {
    if (d.children) {
      d._children = d.children;
      d._children.forEach(collapse);
      d.children = null;
    }
  }

// Creates a curved (diagonal) path from parent to the child nodes
// switched around all the x's and y's from orig so it's verticle
function diagonal(s, d) {
  //console.log('in diag and s = ', s);
  //console.log('d = ', d)

  path = `M ${s.x} ${s.y}
          C ${(s.x + d.x) / 2} ${s.y},
            ${(s.x + d.x) / 2} ${d.y},
            ${d.x} ${d.y}`

  return path;

}

style.css

.node {
  cursor: pointer;
}

.node circle {
  fill: #fff;
  stroke: steelblue;
  stroke-width: 1.5px;
}

.node text {
  font: 10px sans-serif;
}

.link {
  fill: none;
  stroke: #ccc;
  stroke-width: 1.5px;
}