Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active August 29, 2015 14:06
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/5c05241a724bd559180a to your computer and use it in GitHub Desktop.
Save nitaku/5c05241a724bd559180a to your computer and use it in GitHub Desktop.
Basic sunburst (flare)

A basic reference implementation for sunburst diagrams, representing the flare software package hierarchy (using d3.js, of course!).

# layout, behaviors and scales
RADIUS = 250
partition = d3.layout.partition()
.sort(null)
.size([2 * Math.PI, RADIUS * RADIUS])
.value((node) -> node.size)
arc = d3.svg.arc()
.startAngle((d) -> d.x )
.endAngle((d) -> d.x + d.dx )
.innerRadius((d) -> Math.sqrt(d.y) )
.outerRadius((d) -> Math.sqrt(d.y + d.dy) )
svg = d3.select('svg')
width = svg.node().getBoundingClientRect().width
height = svg.node().getBoundingClientRect().height
# translate the viewBox to have (0,0) at the center of the vis
svg
.attr
viewBox: "#{-width/2} #{-height/2} #{width} #{height}"
# append a group for zoomable content
zoomable_layer = svg.append('g')
# define a zoom behavior
zoom = d3.behavior.zoom()
.scaleExtent([1,10]) # min-max zoom
.on 'zoom', () ->
# GEOMETRIC ZOOM
zoomable_layer
.attr
transform: "translate(#{zoom.translate()})scale(#{zoom.scale()})"
# bind the zoom behavior to the main SVG
svg.call(zoom)
# group the visualization
vis = zoomable_layer.append('g')
d3.json 'http://wafi.iit.cnr.it/webvis/tmp/flare.json', (tree) ->
vis.datum(tree)
nodes = vis.selectAll('.node')
.data((t) -> partition.nodes(t))
enter_nodes = nodes.enter().insert('path','path')
.attr
class: 'node'
d: arc
enter_nodes.append('title')
.text((node) -> node.name)
vis.append('text')
.text((tree) -> tree.name)
.attr
class: 'label'
dy: '0.35em'
svg {
background: white;
}
.node {
vector-effect: non-scaling-stroke;
fill: #AAB;
stroke: white;
stroke-width: 1;
}
.node:hover {
fill: #889;
}
.label {
pointer-events: none;
fill: #444;
text-anchor: middle;
font-family: sans-serif;
font-size: 28px;
text-shadow: -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="Basic sunburst (flare)" />
<title>Basic sunburst (flare)</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<svg height="500" width="960"></svg>
<script src="index.js"></script>
</body>
</html>
(function() {
var RADIUS, arc, height, partition, svg, vis, width, zoom, zoomable_layer;
RADIUS = 250;
partition = d3.layout.partition().sort(null).size([2 * Math.PI, RADIUS * RADIUS]).value(function(node) {
return node.size;
});
arc = d3.svg.arc().startAngle(function(d) {
return d.x;
}).endAngle(function(d) {
return d.x + d.dx;
}).innerRadius(function(d) {
return Math.sqrt(d.y);
}).outerRadius(function(d) {
return Math.sqrt(d.y + d.dy);
});
svg = d3.select('svg');
width = svg.node().getBoundingClientRect().width;
height = svg.node().getBoundingClientRect().height;
svg.attr({
viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height
});
zoomable_layer = svg.append('g');
zoom = d3.behavior.zoom().scaleExtent([1, 10]).on('zoom', function() {
return zoomable_layer.attr({
transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")"
});
});
svg.call(zoom);
vis = zoomable_layer.append('g');
d3.json('http://wafi.iit.cnr.it/webvis/tmp/flare.json', function(tree) {
var enter_nodes, nodes;
vis.datum(tree);
nodes = vis.selectAll('.node').data(function(t) {
return partition.nodes(t);
});
enter_nodes = nodes.enter().insert('path', 'path').attr({
"class": 'node',
d: arc
});
enter_nodes.append('title').text(function(node) {
return node.name;
});
return vis.append('text').text(function(tree) {
return tree.name;
}).attr({
"class": 'label',
dy: '0.35em'
});
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment