Skip to content

Instantly share code, notes, and snippets.

@dpopowich
Last active August 29, 2015 14:22
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save dpopowich/cb461f8adde6888af0ae to your computer and use it in GitHub Desktop.
Dots!

This sample application is a live-demo component of a blog post I wrote for Art & Logic, Inc..

/*jslint browser: true, indent: 3, white: true */
/*globals d3 */
d3.sample_dots = function(config) {
"use strict";
/* Sample D3 Application
*
* Usage: create a dots function, which is suitable to use in a
* selection.call():
*
* dots = d3.sample_dots()
* d3.select('#mydiv')
* .call(dots)
*
* This will start painting dots inside a 500x500 SVG element,
* within the specified div.
*
* Public functions:
*
* dots.stop() - stop painting dots
* dots.paint() - paint once, then stop
* dots.go() - paint forever
*/
var width, // svg width
height, // svg height
radius, // dot radius
to_id, // timeout timer id
crayola, // json crayola color data
vis, // main visualization element
// d3-tip, see: https://github.com/Caged/d3-tip
tip = d3.tip()
.attr('class', 'dot-tip')
.offset(function(d) {
var left = (d.x < 100) ? 100 : 0,
top = (d.y < 100) ? 20 : -10;
return [top, left];
})
.direction(function(d) {
return (d.y < 100) ? 's' : 'n';
})
.html(function(d) {
var strName = "<strong>Name:</strong> " + d.c.name + "</br></br>",
strHEX = "<strong>Hex value:</strong> " + d.c.hex + "</br></br>",
strRGB = "<strong>RGB value:</strong> " + d.c.rgb + "</br></br>";
return strName + strHEX + strRGB;
});
// initialize variables from config
config = config || {};
width = config.width || 400; // default svg width
height = config.height || 400; // default svg height
radius = config.radius || 10; // dot radius
function dots(selection) {
selection.selectAll('*').remove();
vis = selection.append('svg')
.attr('width', width)
.attr('height', height)
.call(tip);
// load the crayola 64+ pack, and do one paint
d3.json("https://gist.githubusercontent.com/jjdelc/1868136/raw/c734ad88bb3b5a2b27f4e91a24716024c66da421/crayola.json", function(error, json) {
if (error) {
return console.warn(error);
}
crayola = json;
dots.go();
});
}
function random(min, max) {
// random([[min], max])
if (!arguments.length) {
return Math.random();
}
if (arguments.length < 2) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max-min));
}
function randomRGB() {
/* return a random crayola color */
return crayola[random(crayola.length)];
}
function fetchData() {
/* fetch a batch of data
*
* 8-64 random dots, each dot is:
* {
* x: <x-coor>
* y: <y-coor>
* r: <radius>
* c: <color obj>
*/
// max radius will grow over iterations
if (radius < 31) {
radius += 1;
}
return d3.range(random(8,65)).map(function() {
return {x: random(width),
y: random(height),
r: random(radius),
c: randomRGB()
};
});
}
function dataKey(d) {
// create a key so each dot is unique
return String() + d.x + d.y + d.r + d.c.hex;
}
dots.paint = function() {
/* paint a new set of dots */
var update,
data = fetchData();
// get an update selection (probably empty) after binding to new
// set of data. See: http://bost.ocks.org/mike/join/
update = vis.selectAll('circle')
.data(data, dataKey);
// new dots
update.enter()
.append('circle')
.attr('r', 0)
.attr('opacity', 0.6)
.attr('fill', function(d){return d.c.hex;})
.on('mouseover', tip.show) // for mouse hovering over dots
.on('mouseout', tip.hide)
.transition() // animate radius growing
.duration(4500)// over 4.5 seconds
.attr('r', function(d) {return d.r;});
update
// place at x,y
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; });
update
// for exiting dots, transition radius to zero, then remove
// from dom
.exit()
.transition()
.duration(4500)
.attr('r', 0)
.remove();
};
dots.go = function() {
/* paint forever */
dots.paint();
to_id = setTimeout(function() {
dots.go();
}, 5000);
};
dots.stop = function() {
/* no, don't paint forever */
if (to_id) {
clearTimeout(to_id);
to_id = null;
}
};
return dots;
};
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<title>Dots!</title>
<style type="text/css">
svg {
display: block;
margin: 0 auto;
border: 3px solid #ccc;
}
.dot-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(204, 204, 204, 0.8);
color: blue;
border-radius: 12px;
}
</style>
</head>
<body>
<div id="dots"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-tip/0.6.3/d3-tip.min.js" charset="utf-8"></script>
<script src="./dots.js"></script>
<script>
dots = d3.sample_dots({width:600, height:300});
d3.select("#dots").call(dots);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment