Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active September 28, 2016 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/dd611c0e4dae1d38eab67aedae7ac44f to your computer and use it in GitHub Desktop.
Save nitaku/dd611c0e4dae1d38eab67aedae7ac44f to your computer and use it in GitHub Desktop.
Cushion Voronoi

A Voronoi diagram colored with a radial gradient centered on each cell's site. The luminance of each point is proportional to the cost of reaching the nearest site (the darker the color, the higher the cost).

svg = d3.select 'svg'
width = svg.node().getBoundingClientRect().width
height = svg.node().getBoundingClientRect().height
defs = svg.append 'defs'
radius = 10
sites_data = d3.range(20).map () ->
return {
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius)
}
voronoi = d3.voronoi()
.x (d) -> d.x
.y (d) -> d.y
.extent [[-1, -1], [width + 1, height + 1]]
cells_data = voronoi.polygons(sites_data)
# define cells gradients
gradients = defs.selectAll '.gradient'
.data sites_data
enter_gradients = gradients.enter().append 'radialGradient'
.attrs
class: 'gradient'
gradientUnits: 'userSpaceOnUse'
id: (d,i) -> "gradient_#{i}"
cx: (d) -> d.x
cy: (d) -> d.y
r: 300
enter_gradients.append 'stop'
.attrs
offset: '0%'
'stop-color': 'white'
enter_gradients.append 'stop'
.attrs
offset: '100%'
'stop-color': 'black'
# render cells
cells = svg.selectAll '.cell'
.data cells_data
cells.enter().append 'path'
.attrs
class: 'cell'
d: (d) -> if not d? then null else "M" + d.join("L") + "Z"
fill: (d,i) -> "url(#gradient_#{i})"
# render sites
sites = svg.selectAll '.site'
.data sites_data
sites.enter().append 'circle'
.attrs
class: 'site'
r: radius
cx: (d) -> d.x
cy: (d) -> d.y
body, html {
padding: 0;
margin: 0;
height: 100%;
}
svg {
width: 100%;
height: 100%;
background: white;
}
.site {
fill: #DDD;
stroke: gray;
}
.cell {
shape-rendering: crispEdges;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cushion Voronoi</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
</head>
<body>
<svg></svg>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var cells, cells_data, defs, enter_gradients, gradients, height, radius, sites, sites_data, svg, voronoi, width;
svg = d3.select('svg');
width = svg.node().getBoundingClientRect().width;
height = svg.node().getBoundingClientRect().height;
defs = svg.append('defs');
radius = 10;
sites_data = d3.range(20).map(function() {
return {
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius)
};
});
voronoi = d3.voronoi().x(function(d) {
return d.x;
}).y(function(d) {
return d.y;
}).extent([[-1, -1], [width + 1, height + 1]]);
cells_data = voronoi.polygons(sites_data);
gradients = defs.selectAll('.gradient').data(sites_data);
enter_gradients = gradients.enter().append('radialGradient').attrs({
"class": 'gradient',
gradientUnits: 'userSpaceOnUse',
id: function(d, i) {
return "gradient_" + i;
},
cx: function(d) {
return d.x;
},
cy: function(d) {
return d.y;
},
r: 300
});
enter_gradients.append('stop').attrs({
offset: '0%',
'stop-color': 'white'
});
enter_gradients.append('stop').attrs({
offset: '100%',
'stop-color': 'black'
});
cells = svg.selectAll('.cell').data(cells_data);
cells.enter().append('path').attrs({
"class": 'cell',
d: function(d) {
if (d == null) {
return null;
} else {
return "M" + d.join("L") + "Z";
}
},
fill: function(d, i) {
return "url(#gradient_" + i + ")";
}
});
sites = svg.selectAll('.site').data(sites_data);
sites.enter().append('circle').attrs({
"class": 'site',
r: radius,
cx: function(d) {
return d.x;
},
cy: function(d) {
return d.y;
}
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment