SVG Slider Libraries that are close to desired behavior
- http://thematicmapping.org/playground/d3/d3.slider/ — the code by Bjorn Sandvik is very capable, with animation, etc., but a bit dense
- https://bl.ocks.org/Lulkafe/3832d628340038d9484fbd9edb705e01 –The code done by Seimei Matsusaki has a cleaner implementation
Web Page
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> <script src="simpleD3Slider.js"></script> </head> <body> <div id="vis"></div> </body> <script> var svg = d3.select("#vis").append("svg").attr("width", 1000).attr("height", 700), slider1 = new simpleSlider(), slider2 = new simpleSlider(), circle = svg.append("circle").attr("cx", 50).attr("cy", 100).attr("r", 30); slider1.width(200).x(30).y(200).value(1.0).event(function(){ circle.attr("r", 30 * slider1.value()); }); slider2.width(200).x(30).y(230).value(0.5).event(function(){ circle.attr("cx", 50 + (170 * slider2.value())); }); svg.call(slider1); svg.call(slider2); </script> </html>
/* Simple, reusable slider in pure d3 */ function simpleSlider () { var width = 100, value = 0.5, /* Domain assumes to be [0 - 1] */ event, x = 0, y = 0; function slider (selection) { //Line to represent the current value var valueLine = selection.append("line") .attr("x1", x) .attr("x2", x + (width * value)) .attr("y1", y) .attr("y2", y) .style({stroke: "#51CB3F", "stroke-linecap": "round", "stroke-width": 6 }); //Line to show the remaining value var emptyLine = selection.append("line") .attr("x1", x + (width * value)) .attr("x2", x + width) .attr("y1", y) .attr("y2", y) .style({ "stroke": "#ECECEC", "stroke-linecap": "round", "stroke-width": 6 }); var drag = d3.behavior.drag().on("drag", function() { var newX = d3.mouse(this)[0]; if (newX < x) newX = x; else if (newX > x + width) newX = x + width; value = (newX - x) / width; valueCircle.attr("cx", newX); valueLine.attr("x2", x + (width * value)); emptyLine.attr("x1", x + (width * value)); if (event) event(); d3.event.sourceEvent.stopPropagation(); }) //Draggable circle to represent the current value var valueCircle = selection.append("circle") .attr("cx", x + (width * value)) .attr("cy", y) .attr("r", 8) .style({ "stroke": "black", "stroke-width": 1.0, "fill": "white" }) .call(drag); } slider.x = function (val) { x = val; return slider; } slider.y = function (val) { y = val; return slider; } slider.value = function (val) { if (val) { value = val; return slider; } else { return value; } } slider.width = function (val) { width = val; return slider; } slider.event = function (val) { event = val; return slider; } return slider; }