Skip to content

Instantly share code, notes, and snippets.

@hughes
Last active August 29, 2015 14:15
Show Gist options
  • Save hughes/58969de0a5b5e1accc4d to your computer and use it in GitHub Desktop.
Save hughes/58969de0a5b5e1accc4d to your computer and use it in GitHub Desktop.
grid-test
{"description":"grid-test","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"d3":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"stuff.css":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"pingpong","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"ajax-caching":true,"thumbnail":"http://i.imgur.com/aWxOjnt.png"}
'use strict';
var Node = function (contents, group) {
this.child = null;
this.left = null;
this.right = null;
this.up = null;
this.down = null;
this.contents = contents === undefined ? null : contents;
this.width = 1;
this.height = 1;
this.isGroup = group === undefined ? false : group;
};
var root = new Node('group', true);
var a = root.child = new Node('a');
var b = a.down = new Node('b');
var c = b.down = new Node('c');
var d = c.right = new Node('d');
var e = c.left = new Node('e');
var f = e.up = new Node('f');
var g = f.right = new Node('g');
var X = 0, Y = 1, WIDTH = 0, HEIGHT = 1;
var MARGIN = 0.25;
function getBoundingBox(node) {
/* returns a set of bounds and an anchor point for this node */
var bounds = [node.width, node.height]; // width, height of bounds
var anchor = [node.width / 2, node.height / 2]; // anchor of bounds
if (node.child) {
var childBounds = getBoundingBox(node.child);
bounds = childBounds.bounds;
//anchor = [bounds[WIDTH]/2, bounds[HEIGHT]/2];
node.width = childBounds.bounds[WIDTH] + MARGIN*2;
node.height = childBounds.bounds[HEIGHT] + MARGIN*2;
}
if (node.down) {
var downBounds = getBoundingBox(node.down);
bounds[HEIGHT] += downBounds.bounds[HEIGHT] + MARGIN*2;
bounds[WIDTH] = Math.max(bounds[WIDTH], downBounds.bounds[WIDTH]);
anchor[X] = Math.max(anchor[X], downBounds.anchor[X]);
}
if (node.up) {
var upBounds = getBoundingBox(node.up);
bounds[HEIGHT] += upBounds.bounds[HEIGHT] + MARGIN*2;
bounds[WIDTH] = Math.max(bounds[WIDTH], upBounds.bounds[WIDTH]);
anchor[X] = Math.max(anchor[X], upBounds.anchor[X]);
anchor[Y] += upBounds.bounds[HEIGHT] + MARGIN*2;
}
if (node.right) {
var rightBounds = getBoundingBox(node.right);
bounds[WIDTH] += rightBounds.bounds[WIDTH] + MARGIN*2;
bounds[HEIGHT] = Math.max(bounds[HEIGHT], rightBounds.bounds[HEIGHT]);
anchor[Y] = Math.max(anchor[Y], rightBounds.anchor[Y]);
}
if (node.left) {
var leftBounds = getBoundingBox(node.left);
bounds[WIDTH] += leftBounds.bounds[WIDTH] + MARGIN*2;
bounds[HEIGHT] = Math.max(bounds[HEIGHT], leftBounds.bounds[HEIGHT])
anchor[X] += leftBounds.bounds[WIDTH] + MARGIN*2;
anchor[Y] = Math.max(anchor[Y], leftBounds.anchor[Y])
}
node.bounds = bounds;
node.anchor = anchor;
return {
bounds: bounds,
anchor: anchor
}
}
function flatten(node) {
var result = [[node.anchor[X], node.anchor[Y], node.width, node.height, node.contents, node.isGroup]];
var i;
if (node.child) {
var childResult = flatten(node.child);
for (i=0; i<childResult.length; i++) {
childResult[i][X] += MARGIN;
childResult[i][Y] += MARGIN;
result.push(childResult[i]);
}
}
if (node.down) {
var downResult = flatten(node.down);
var downOffsetX = node.anchor[X] - node.down.anchor[X];
var downOffsetY = node.bounds[HEIGHT] - node.down.bounds[HEIGHT];
for (i=0; i<downResult.length; i++) {
downResult[i][X] += downOffsetX;
downResult[i][Y] += downOffsetY;
result.push(downResult[i]);
}
}
if (node.up) {
var upResult = flatten(node.up);
var upOffsetX = node.anchor[X] - node.up.anchor[X];
for (i=0; i<upResult.length; i++) {
upResult[i][X] += upOffsetX;
result.push(upResult[i]);
}
}
if (node.right) {
var rightResult = flatten(node.right);
var rightOffsetX = node.bounds[WIDTH] - node.right.bounds[WIDTH];
var rightOffsetY = node.anchor[Y] - node.right.anchor[Y];
for (i=0; i<rightResult.length; i++) {
rightResult[i][X] += rightOffsetX;
rightResult[i][Y] += rightOffsetY;
result.push(rightResult[i]);
}
}
if (node.left) {
var leftResult = flatten(node.left);
var leftOffsetY = node.anchor[Y] - node.left.anchor[Y];
for (i=0; i<leftResult.length; i++) {
leftResult[i][Y] += leftOffsetY;
result.push(leftResult[i]);
}
}
return result;
}
getBoundingBox(root);
var flat = flatten(root);
var svg = d3.select('svg')
.attr('viewBox', '0 0 10 10')
svg.append("g")
.attr("class", "x axis")
.selectAll("line")
.data(d3.range(0, 11, 1))
.enter().append("line")
.attr("x1", function(d) { return d; })
.attr("y1", 0)
.attr("x2", function(d) { return d; })
.attr("y2", 10)
svg.append("g")
.attr("class", "y axis")
.selectAll("line")
.data(d3.range(0, 11, 1))
.enter().append("line")
.attr("x1", 0)
.attr("y1", function(d) { return d; })
.attr("x2", 10)
.attr("y2", function(d) { return d; })
var dragStart = [0,0];
var origTransform = '';
var drag = d3.behavior.drag()
.on('drag', function (d) {
d3.event.sourceEvent.stopPropagation();
dragStart[X] += d3.event.dx;
dragStart[Y] += d3.event.dy;
d3.select(this)
.attr('transform', 'translate('+dragStart[X]+','+dragStart[Y]+')' + origTransform)
})
.on('dragstart', function (d) {
d3.event.sourceEvent.stopPropagation();
dragStart = [0,0]
origTransform = d3.select(this)
.attr('data-dragging', true)
.attr('transform');
})
.on('dragend', function (d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this)
.attr('transform', origTransform)
.attr('data-dragging', null);
})
function drawNodes() {
var nodes = svg.selectAll('.node')
.data(flat)
.enter()
.append('g')
.attr('class', 'node')
.attr('transform', function (d) {
return 'translate('+d[0]+','+d[1]+')';
})
.call(drag)
.on('mouseover', function () {
d3.select(this).attr('data-hover', 'true')
})
.on('mouseout', function () {
d3.select(this).attr('data-hover', null)
})
nodes
.filter(function (d) { return !d[5];})
.append('rect')
.attr('width', function (d) {return d[2] + MARGIN*2})
.attr('height', function (d) {return d[3] + MARGIN*2})
.attr('x', function (d) { return -0.5-MARGIN})
.attr('y', function (d) { return -0.5-MARGIN})
.attr('class', 'margin')
nodes
.filter(function (d) { return !d[5];})
.append('rect')
.attr('width', function (d) {return d[2];})
.attr('height', function (d) {return d[3];})
.attr('x', function (d) {return -0.5;})
.attr('y', function (d) {return -0.5;})
.attr('class', 'box')
nodes
.filter(function (d) {
return d[5]
;})
.append('rect')
.attr('width', function (d) {return d[2];})
.attr('height', function (d) {return d[3];})
.attr('x', function (d) {return -0.5;})
.attr('y', function (d) {return -0.5;})
.attr('class', 'group')
nodes
.append('text')
.text(function (d) { return d[4];})
.attr('font-size', '0.18')
}
drawNodes()
function updateNodes() {
var nodes = svg.selectAll('.node').data(flat)
nodes.attr('transform', function (d) {
return 'translate('+d[0]+','+d[1]+')';
})
}
/*setTimeout(function () {
getBoundingBox(root);
flat = flatten(root);
console.log(flat)
updateNodes();
}, 1000)*/
.axis {
stroke: #f6f6f6;
stroke-width: 0.0;
}
.margin {
stroke: rgba(50, 50, 255, 0.348);
fill: rgba(50, 50, 255, 0);
stroke-width: 0.0;
cursor: pointer;
}
.box {
stroke: #000;
stroke-width: 0.01;
fill: rgba(0,0,0,0.0399999999999999);
}
.group {
stroke: #000;
stroke-width: 0.012;
stroke-dasharray: 0.06, 0.06;
fill: none;
}
[data-hover=true] {
stroke-width: 0.0512;
fill: #f00;
}
[data-dragging=true] {
pointer-events:none;
opacity: 0.5;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment