Skip to content

Instantly share code, notes, and snippets.

@jonsadka

jonsadka/README.md

Last active Apr 19, 2016
Embed
What would you like to do?
Linked List
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
* {
font: sans-serif;
}
body {
margin:0;position:fixed;top:0;right:0;bottom:0;left:0;
background-color: #564b71;
}
.btn {
float: right;
box-sizing: border-box;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: transparent;
border: 2px solid white;
border-radius: 0.6em;
color: white;
cursor: pointer;
display: inline-block;
-webkit-align-self: center;
-ms-flex-item-align: center;
align-self: center;
font-size: 1rem;
font-weight: 400;
line-height: 1;
margin: 20px;
padding: 0.6em 1.4em;
text-decoration: none;
text-align: center;
text-transform: uppercase;
-webkit-transition: box-shadow 300ms ease-in-out, color 300ms ease-in-out;
transition: box-shadow 300ms ease-in-out, color 300ms ease-in-out;
}
.btn:hover, .btn:focus {
color: #564b71;
outline: 0;
box-shadow: 0 0 40px 40px white inset;
}
#status-text {
display: inline-block;
color: white;
font: 300 48px Helvetica Neue;
margin: 20px;
text-transform: uppercase;
opacity: 0.90;
}
</style>
</head>
<body>
<h1 id="status-text">Linked list</h1>
<button class="btn" onclick="manualRemoveHead()">Remove node</button>
<button class="btn" onclick="manualAddToTail()">Add node</button>
<script>
var LinkedList = function (){
this.head = null;
this.tail = null;
};
LinkedList.prototype.addToTail = function(value){
var node = this.makeNode(value);
if (!this.head){ this.head = node; }
if (this.tail){ this.tail.next = node; }
this.tail = node;
}
LinkedList.prototype.removeHead = function(){
if (this.head){
var currentHeadValue = this.head.value;
if (this.head.next){
this.head = this.head.next;
} else {
this.head = null;
this.tail = null;
}
return currentHeadValue
} else {
console.log('No head to remove.');
}
}
LinkedList.prototype.contains = function(value){
var currentNode = this.head;
while (currentNode && currentNode.value){
if (currentNode.value === value) return true;
currentNode = currentNode.next;
}
return false;
}
LinkedList.prototype.makeNode = function(value){
var node = {};
node.value = value;
node.next = null;
return node;
};
</script>
<script>
var MAXRADIUS = 30;
var WIDTH = 960;
var HEIGHT = 500 - 97;
var TEXT_PADDING = 8;
var FONT_SIZE = 14;
var MARGIN = 24;
var linkedList = new LinkedList();
initializeLinkedList(linkedList);
var data = flattenLinkedList(linkedList)
var svg = d3.select('body').append('svg')
.style('background-color', '#665A88')
.attr('width', WIDTH)
.attr('height', HEIGHT)
.append('g')
.attr('transform', 'translate(' + MARGIN + ',' + MARGIN + ')' )
var BOX_SIZE = 2 * (WIDTH - 2*MARGIN) / (data.length + 1);
var BOX_PORTION_OFFSET = MAXRADIUS*2;
var MAX_BOX_PORTION = HEIGHT - BOX_PORTION_OFFSET;
setInterval(function(){
randomLinkedListAction(linkedList);
updateViz();
}, 2000)
svg.selectAll('.nodes-circ').data(data, function(d){return d;}).enter()
.append('circle')
.attr('class', 'nodes-circ')
.attr('r', function(d){return d/25;})
.attr('cx', function(d, i){return i * (BOX_SIZE)/2 + BOX_SIZE/2;})
.attr('cy', MAXRADIUS)
.attr('fill', 'none')
.attr('stroke', 'white')
.attr('opacity', 0.85)
svg.selectAll('.nodes-rect').data(data, function(d){return d;}).enter()
.append('rect')
.attr('class', 'nodes-rect')
.attr('x', function(d, i){return i * (BOX_SIZE)/2;})
.attr('y', function(d, i){return BOX_PORTION_OFFSET + i*(MAX_BOX_PORTION - BOX_SIZE - 2*MARGIN)/(data.length - 1)})
.attr('width', BOX_SIZE)
.attr('height', BOX_SIZE)
.attr('rx', BOX_SIZE/10)
.attr('ry', BOX_SIZE/10)
.attr('fill', 'white')
.attr('stroke', '#665A88')
.attr('opacity', 0.85)
svg.selectAll('.nodes-text').data(data, function(d){return d;}).enter()
.append('text')
.attr('class', 'nodes-text')
.attr('font-size', FONT_SIZE)
.attr('x', function(d, i){return i * (BOX_SIZE)/2 + TEXT_PADDING;})
.attr('y', function(d, i){return BOX_PORTION_OFFSET + i*(MAX_BOX_PORTION - BOX_SIZE - 2*MARGIN)/(data.length - 1) + FONT_SIZE + TEXT_PADDING;})
.text(function(d, i){
if (i === 0) return d + ' (H)';
if (i === (data.length - 1)) return d + ' (T)';
return d;
})
.attr('fill', '#665A88')
function updateViz(){
var data = flattenLinkedList(linkedList)
var nodesCirc = svg.selectAll('.nodes-circ').data(data, function(d){return d;});
var nodesRect = svg.selectAll('.nodes-rect').data(data, function(d){return d;});
var nodesText = svg.selectAll('.nodes-text').data(data, function(d){return d;});
// update
BOX_SIZE = 2 * (WIDTH - 2*MARGIN) / (data.length + 1);
nodesCirc.transition().duration(1000)
.attr('cx', function(d, i){return i * (BOX_SIZE)/2 + BOX_SIZE/2;})
nodesRect.transition().duration(1000)
.attr('x', function(d, i){return i * (BOX_SIZE)/2;})
.attr('y', function(d, i){return BOX_PORTION_OFFSET + i*(MAX_BOX_PORTION - BOX_SIZE - 2*MARGIN)/(data.length - 1)})
.attr('width', BOX_SIZE)
.attr('height', BOX_SIZE)
.attr('rx', BOX_SIZE/10)
.attr('ry', BOX_SIZE/10)
nodesText.transition().duration(1000)
.attr('x', function(d, i){return i * (BOX_SIZE)/2 + TEXT_PADDING;})
.attr('y', function(d, i){return BOX_PORTION_OFFSET + i*(MAX_BOX_PORTION - BOX_SIZE - 2*MARGIN)/(data.length - 1) + FONT_SIZE + TEXT_PADDING;})
.text(function(d, i){
if (i === 0) return d + ' (H)';
if (i === (data.length - 1)) return d + ' (T)';
return d;
})
// enter
nodesCirc.enter()
.append('circle')
.attr('class', 'nodes-circ')
.attr('r', function(d){return d/25;})
.attr('cx', function(d, i){return i * (BOX_SIZE)/2 + BOX_SIZE/2;})
.attr('cy', MAXRADIUS)
.attr('fill', 'none')
.attr('stroke', 'white')
.attr('opacity', 0.85)
nodesRect.enter()
.append('rect')
.attr('class', 'nodes-rect')
.attr('x', function(d, i){return i * (BOX_SIZE)/2;})
.attr('y', function(d, i){return BOX_PORTION_OFFSET + i*(MAX_BOX_PORTION - BOX_SIZE - 2*MARGIN)/(data.length - 1)})
.attr('width', BOX_SIZE)
.attr('height', BOX_SIZE)
.attr('rx', BOX_SIZE/10)
.attr('ry', BOX_SIZE/10)
.attr('fill', 'white')
.attr('stroke', '#665A88')
.attr('opacity', 0.85)
nodesText.enter()
.append('text')
.attr('class', 'nodes-text')
.attr('font-size', FONT_SIZE)
.attr('x', function(d, i){return i * (BOX_SIZE)/2 + TEXT_PADDING;})
.attr('y', function(d, i){return BOX_PORTION_OFFSET + i*(MAX_BOX_PORTION - BOX_SIZE - 2*MARGIN)/(data.length - 1) + FONT_SIZE + TEXT_PADDING;})
.text(function(d, i){
if (i === 0) return d + ' (H)';
if (i === (data.length - 1)) return d + ' (T)';
return d;
})
.attr('fill', '#665A88')
//exit
nodesCirc.exit()
.transition().duration(1000)
.attr('opacity', 0)
.remove()
nodesRect.exit()
.transition().duration(1000)
.attr('opacity', 0)
.remove()
nodesText.exit()
.transition().duration(1000)
.attr('opacity', 0)
.remove()
}
function flattenLinkedList(linkedList){
var data = [];
var cursor = linkedList.head;
while (cursor && cursor.value){
data.push(cursor.value);
cursor = cursor.next;
}
return data;
}
function initializeLinkedList(linkedList){
var initializeAmount = d3.range(0,11);
initializeAmount.forEach(function(){
linkedList.addToTail(Math.round(Math.random()*MAXRADIUS*25));
})
}
function randomLinkedListAction(linkedList){
var action = Math.round(Math.random()*1);
if (action === 0){
manualAddToTail();
} else if (action === 1){
manualRemoveHead();
}
}
function manualAddToTail(){
var value = Math.round(Math.random()*MAXRADIUS*25);
linkedList.addToTail(value);
document.getElementById('status-text').innerHTML = 'Added ' + value;
updateViz();
}
function manualRemoveHead(){
var value = linkedList.removeHead();
document.getElementById('status-text').innerHTML = 'Removed ' + value;
updateViz();
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment