A first draft of d3.svg.circularBrush which allows you to select cyclical ranges. It's patterned after d3.svg.brush, so you drag the resize handles to change the extent or drag the extent to move it around the selection surface. In this case it's mapped to an array of 24 values (1-24), each represented in a pie arc, thus implying a clock. By dragging and resizing the brush, you select the corresponding arcs.
Cyclical time is an obvious application for a brush like this, allowing you to select a period of time such as "between 10PM and 2AM" to filter your results by.
xxxxxxxxxx
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<title>Circular Brush</title>
<meta charset="utf-8" />
</head>
<style>
#viz, svg {
width: 1000px;
height: 1000px;
}
.resize {
fill-opacity: .5;
cursor: move;
stroke: black;
stroke-width: 1px;
}
.extent {
fill-opacity: .25;
fill: rgb(205,130,42);
cursor: grab;
stroke: black;
stroke-width: 1px;
}
.e {
fill: rgb(111,111,111);
cursor: move;
}
.w {
fill: rgb(169,169,169);
cursor: move;
}
path.piehours {
fill: rgb(246,139,51);
stroke: black;
stroke-width: 1px;
}
</style>
<script>
function makeViz() {
piebrush = d3.svg.circularbrush();
piebrush
.range([1,24])
.innerRadius(80)
.outerRadius(120)
.on("brushstart", pieBrushStart)
.on("brushend", pieBrushEnd)
.on("brush", pieBrush);
d3.select("svg")
.append("g")
.attr("transform", "translate(250,250)")
.call(piebrush);
var hours = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];
var pie = d3.layout.pie().value(function() {return 1}).sort(d3.ascending);
var pieArc = d3.svg.arc().innerRadius(130).outerRadius(160);
d3.select("svg")
.append("g")
.attr("transform", "translate(250,250)")
.selectAll("path")
.data(pie(hours))
.enter()
.append("path")
.attr("class", "piehours")
.attr("d", pieArc)
.on("click", function(d) {console.log(d)})
function pieBrush() {
d3.selectAll("path.piehours")
.style("fill", piebrushIntersect)
}
function piebrushIntersect(d,i) {
var _e = piebrush.extent();
if (_e[0] < _e[1]) {
var intersect = (d.data >= _e[0] && d.data <= _e[1]);
}
else {
var intersect = (d.data >= _e[0]) || (d.data <= _e[1]);
}
return intersect ? "rgb(241,90,64)" : "rgb(231,231,231)"
}
function pieBrushStart() {
var _e = piebrush.extent();
}
function pieBrushEnd() {
var _e = piebrush.extent();
}
}
</script>
<body onload="makeViz()">
<div id="viz"><svg></svg><div id="buttons"></div></div>
<footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="d3.svg.circularbrush.js" charset="utf-8" type="text/javascript"></script>
</footer>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js