A variation of the drag slider using smooth interpolation.
forked from mbostock's block: Smooth Slider
xxxxxxxxxx
<meta charset="utf-8">
<style>
.ticks {
font: 16px sans-serif;
}
.track,
.track-inset,
.track-overlay {
stroke-linecap: round;
}
.track {
stroke: #000;
stroke-opacity: 0.3;
stroke-width: 5px;
}
.track-inset {
stroke: #ddd;
stroke-width: 4px;
}
.track-overlay {
pointer-events: stroke;
stroke-width: 50px;
cursor: crosshair;
}
.handle {
fill: #fff;
stroke: #000;
stroke-opacity: 0.5;
stroke-width: 2.2px;
}
</style>
<svg width="300" height="300"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {left: 30, right: 30},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height")/2;
var hueActual = 0,
hueTarget = 211,
hueAlpha = 0.2,
hueTimer = d3.timer(hueTween);
var x = d3.scaleLinear()
.domain([70, 120])
.range([0, width])
.clamp(true);
var slider = svg.append("g")
.attr("class", "slider")
.attr("transform", "translate(" + margin.left + "," + (height + 5) / 1.5 + ")")
// .call(d3.axisBottom()
// .scale(x)
// .ticks(5));
slider.append("line")
.attr("class", "track")
.attr("x1", x.range()[0])
.attr("x2", x.range()[1])
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "track-inset")
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "track-overlay")
.call(d3.drag()
.on("start.interrupt", function() { slider.interrupt(); })
.on("start drag", function() { hue(x.invert(d3.event.x)); }));
slider.insert("g", ".track-overlay")
.attr("class", "ticks")
.attr("transform", "translate(0," + 30 + ")")
.selectAll("text")
.data(x.ticks(4))
.enter().append("text")
.attr("x", x)
.attr("text-anchor", "middle")
.text(function(d) { return "$" + d + "k"; });
var brush = d3.brushX()
.extent([[0,0], [width,height]])
.on("brush", brushed);
var brushg = svg.append("g")
.attr("class", "brush")
.attr("transform", "translate(" + margin.left + "," + (height - 0) / 4.4 + ")")
.call(brush)
// var brushRange = d3.brushSelection().map(x.invert)
// .selectAll("span")
// .text(function(d, i) {
// return "span" + Math.round(brushRange[i])
// })
// .enter().append("span")
// .attr("x", 100)
// .attr("text-anchor", "middle")
function brushed() {
var range = d3.brushSelection().map(x.invert)
d3.selectAll("span")
.text(function(d, i) {
return Math.round(range[i])
})
}
var handle = slider.insert("circle", ".track-overlay")
.attr("class", "handle")
.attr("r", 10);
function hue(h) {
hueTarget = h;
hueTimer.restart(hueTween);
}
function hueTween() {
var hueError = hueTarget - hueActual;
if (Math.abs(hueError) < 1e-3) hueActual = hueTarget, hueTimer.stop();
else hueActual += hueError * hueAlpha;
handle.attr("cx", x(hueActual));
svg.style("background-color", d3.hsl(hueActual, 0.8, 0.8));
}
brushed();
brush.move(brushg, [10, 30].map(x));
</script>
https://d3js.org/d3.v4.min.js