Skip to content

Instantly share code, notes, and snippets.

@widged
Last active December 11, 2015 04:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save widged/4547392 to your computer and use it in GitHub Desktop.
Save widged/4547392 to your computer and use it in GitHub Desktop.
D3 for layout management
d3.layout.circle = function(){
"use strict";
var exports = {};
var d3 = window.d3;
var pts = [];
var center = [0, 0],
radius = 100;
function circle(data) {
return circle.points(data);
}
circle.points = function(data) {
if (!arguments.length) return pts;
var qty = data.length;
var deg = d3.scale.linear().domain([0, qty]).range([0.0, 360.0]);
var rad = d3.scale.linear().domain([0, qty]).range([0.0, 6.283185307179586]);
var i = -1;
while (++i < qty) {
var d = data[i]; // if not object, make it so
d.x = (Math.sin(rad(i)) * radius) + center[0];
d.y = (Math.cos(rad(i)) * radius) + center[1];
d.r = -deg(i);
d.transform = "translate(" + d.x + " " + d.y + ") rotate(" + d.r + ")";
data[i] = d;
}
return data;
};
circle.center = function(x,y) {
if (!arguments.length) return center;
center = [x,y];
return circle;
};
circle.radius = function(r) {
if (!arguments.length) return radius;
radius = r;
return circle;
};
// ---------------------
// Public Interface
// ---------------------
return circle;
};
d3.layout.line = function(){
"use strict";
var exports = {};
var d3 = window.d3;
var pts = [];
var width = 100,
offsetX = 0,
offsetY = 0;
function line(data) {
return line.points(data);
}
line.points = function(data) {
if (!arguments.length) return pts;
var qty = data.length;
var s = d3.scale.linear().domain([-1, qty]).range([0, width]);
var i = -1;
while (++i < qty) {
var d = data[i]; // if not object, make it so
d.x = s(i) + offsetX;
d.y = offsetY;
d.transform = "translate(" + d.x + " " + d.y + ")";
data[i] = d;
}
return data;
};
line.width = function(number) {
if (!arguments.length) return width;
width = number;
return line;
};
line.offsetX = function(number) {
if (!arguments.length) return offsetX;
offsetX = number;
return line;
};
line.offsetY = function(number) {
if (!arguments.length) return offsetY;
offsetY = number;
return line;
};
// transform: function(d) { return "translate(" + d.x + " " + d.y + ") rotate(" + d.r + ")"; }
// ---------------------
// Public Interface
// ---------------------
return line;
};
d3.layout.randomspread = function(){
"use strict";
var exports = {};
var d3 = window.d3;
var pts = [];
var width = 100,
height = 100,
offsetX = 0,
offsetY = 0;
function randomspread(data) {
return randomspread.points(data);
}
randomspread.points = function(data) {
if (!arguments.length) return pts;
var qty = data.length;
var sx = d3.scale.linear().range([0, width]);
var sy = d3.scale.linear().range([0, height]);
var i = -1;
while (++i < qty) {
var d = data[i]; // if not object, make it so
d.x = sx(Math.random()) + offsetX;
d.y = sy(Math.random()) + offsetY;
d.transform = "translate(" + d.x + " " + d.y + ")";
data[i] = d;
}
return data;
};
randomspread.width = function(number) {
if (!arguments.length) return width;
width = number;
return randomspread;
};
randomspread.height = function(number) {
if (!arguments.length) return height;
height = number;
return randomspread;
};
randomspread.offsetX = function(number) {
if (!arguments.length) return offsetX;
offsetX = number;
return randomspread;
};
randomspread.offsetY = function(number) {
if (!arguments.length) return offsetY;
offsetY = number;
return randomspread;
};
// transform: function(d) { return "translate(" + d.x + " " + d.y + ") rotate(" + d.r + ")"; }
// ---------------------
// Public Interface
// ---------------------
return randomspread;
};
d3.layout.triangle = function(){
"use strict";
var exports = {};
var d3 = window.d3;
var pts = [];
var width = 100,
height = 100,
offsetX = 0,
offsetY = 0;
function triangle(data) {
return triangle.points(data);
}
triangle.points = function(data) {
if (!arguments.length) return pts;
var qty = data.length, i = -1;
var halfW = width / 2;
var sx = d3.scale.linear().domain([0, qty]).range([0, halfW]);
var sy = d3.scale.linear().domain([0, qty]).range([0, height]);
while (++i < qty) {
var d = data[i]; // if not object, make it so
var level = [
[width-sx(i), sy(i)],
[sx(i), sy(i-1)],
[(sx(i+1) * 2), 0]
];
var pt = level[i % 3];
d.x = pt[0] + offsetX;
d.y = pt[1] + offsetY;
d.transform = "translate(" + d.x + " " + d.y + ")";
data[i] = d;
}
return data;
};
triangle.width = function(number) {
if (!arguments.length) return width;
width = number;
return triangle;
};
triangle.height = function(number) {
if (!arguments.length) return height;
height = number;
return triangle;
};
triangle.offsetX = function(number) {
if (!arguments.length) return offsetX;
offsetX = number;
return triangle;
};
triangle.offsetY = function(number) {
if (!arguments.length) return offsetY;
offsetY = number;
return triangle;
};
// transform: function(d) { return "translate(" + d.x + " " + d.y + ") rotate(" + d.r + ")"; }
// ---------------------
// Public Interface
// ---------------------
return triangle;
};
<html>
<head>
<title>D3 for layout management</title>
<meta charset="utf-8">
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.0.1/d3.v3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="container">
<svg id="kitchensink" width="1500" height="480" viewBox="0 0 1500 480" perserveAspectRatio="xMidYMid"></svg>
<div id="controls">
<button id="line-opt">line</button>
<button id="circle-opt">circle</button>
<button id="triangle-opt">triangle</button>
<button id="random-opt">random</button>
</div>
</div>
<script src="d3.layout.circle.js"></script>
<script src="d3.layout.line.js"></script>
<script src="d3.layout.triangle.js"></script>
<script src="d3.layout.randomspread.js"></script>
<script>
var width = 1500, height = 480, cardQty = 20;
var g = svgDisplay(width, height);
var hue = d3.scale.linear().domain([0, cardQty]).range([0.0, 360.0]);
var lineLt = d3.layout.line().width(800).offsetX((width-800)/2).offsetY((height-30)/2);
var circleLt = d3.layout.circle().center(width/2, height/2).radius(133);
var triangleLt = d3.layout.triangle().width(400).height(300).offsetX((width-400)/2).offsetY((height-300)/2);
var randomLt = d3.layout.randomspread().width(width - 80).height(height - 80).offsetX(80/2).offsetY((80-30)/2);
var DATA = d3.range(cardQty).map(function (d) {
return {
text: d+1,
color: d3.hsl((180.0 + hue(d)) % 360.0, 1, 0.5)
}
});
var cards = g.selectAll("g.card").data(lineLt.points(DATA));
cards
.enter()
.append("svg:g")
.attr("class", "card")
.attr("transform", function(d, i) { return d.transform; } )
.append("svg:rect")
.attr("width", 30)
.attr("height", 30 * 1.618)
.attr("rx", 3)
.attr("ry", 3)
.attr("stroke", function(d, i) {
return d3.hsl((180.0 + hue(i)) % 360.0, 1, 0.5);
})
.style("fill", function(d, i) { return d3.hsl(hue(i), 1, 0.75); })
.attr("transform", "translate(-15 0)")
cards
.append("text")
.attr("y", 17)
.attr("x", -12)
.text(function(d, i) { return "" + d.text; })
.style("fill", function(d, i) { return d.color; });
// ------------------
// Layout Demos
// ------------------
$("#line-opt").click(function(event) { applyLayout(cards, lineLt) });
$("#circle-opt").click(function(event) { applyLayout(cards, circleLt) });
$("#triangle-opt").click(function(event) { applyLayout(cards, triangleLt) });
$("#random-opt").click(function(event) { applyLayout(cards, randomLt) });
function applyLayout(cards, layout, duration) {
if(parseInt(duration, 10) !== duration) { duration = 1000; }
var data = d3.range(cards[0].length).map(function(d, i) { return {}; })
var pts = layout(data);
cards
.transition().duration(duration)
.attr("transform", function(d, i) { return pts[i].transform }); // where i is the index
return false;
}
// ------------------
// Utils
// ------------------
function svgDisplay(width, height) {
var $svg = $("#kitchensink");
var aspect = $svg.width() / $svg.height();
$(window).on("resize", function() {
var targetWidth = $("#container").width();
$svg.attr("width", targetWidth);
$svg.attr("height", Math.round(targetWidth / aspect));
}).trigger("resize");
var svg = d3.select("svg");
var g = svg.append("svg:g");
g.append("svg:rect")
.attr("class", "fram")
.attr("width", width)
.attr("height", height);
return g;
}
</script>
<p>Credits: derived from the <a href="http://calroc.github.com/aum-gravity/">skew demo</a> in the <a href="https://github.com/calroc/aum-gravity">aum-gravity github project</a></p>
</body>
</html>
body {
margin: 10;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 20px;
color: #333333;
background-color: #ffffff;
}
#controls {
margin-top: 1em;
}
/* SVG elements */
rect.fram {
fill: #dfdfdf;
}
g.card {
stroke-width: 1.5px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment