Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active Nov 16, 2017
Embed
What would you like to do?
Range Slider
license: gpl-3.0
height: 160
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
}
.range-body {
fill: #666;
}
.range-dragger {
fill: tomato;
cursor: pointer;
}
.range-label {
fill: #fff;
text-anchor: middle;
font-size: 2em;
pointer-events: none;
}
.range-axis line, .range-axis path {
stroke: #666;
}
.range-axis text {
fill: #666;
}
</style>
</head>
<body>
<div id="range"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/d3-marcon@2.0.2/build/d3-marcon.min.js"></script>
<script>
var handle_radius = 50,
handle_start_val = 50,
handle_padding = 10,
slider_height = 5,
axis_height = 20;
var setup = d3.marcon()
.width(window.innerWidth)
.height(handle_radius * 2 + slider_height + handle_padding + axis_height)
.left(handle_radius)
.right(handle_radius)
.bottom(axis_height)
.element("#range");
setup.render();
var range_width = setup.innerWidth(), range_height = setup.innerHeight(), range_svg = setup.svg();
var range_x = d3.scaleLinear()
.range([0, range_width])
.domain([0, 100]);
// the range axis
range_svg.append("g")
.attr("class", "range-axis")
.attr("transform", "translate(0, " + range_height + ")")
.call(d3.axisBottom(range_x))
// the range scale
range_svg.append("rect")
.attr("class", "range-body")
.attr("x", 0)
.attr("y", range_height - slider_height)
.attr("width", range_width)
.attr("height", slider_height);
// the handle
range_svg.append("circle")
.attr("class", "range-dragger range-handle")
.attr("cx", range_x(handle_start_val))
.attr("cy", range_height - slider_height - handle_radius - handle_padding)
.attr("r", handle_radius)
.call(d3.drag()
.on("drag", dragged)
);
// the label
range_svg.append("text")
.attr("class", "range-label")
.attr("x", range_x(handle_start_val))
.attr("y", range_height - slider_height - handle_radius - handle_padding)
.attr("dy", ".3em")
.text(handle_start_val);
// the pointer
range_svg.append("polygon")
.attr("class", "range-dragger range-pointer")
.attr("points", calcPointerPoints(handle_start_val))
.call(d3.drag()
.on("drag", dragged)
);
function calcPointerPoints(handle_val){
var point_c = range_x(handle_val) + "," + (range_height - slider_height);
var point_a = (range_x(handle_val) - (handle_radius / 4)) + "," + (range_height - slider_height - handle_padding - (handle_radius / 10));
var point_b = (range_x(handle_val) + (handle_radius / 4)) + "," + (range_height - slider_height - handle_padding - (handle_radius / 10));
return point_a + " " + point_b + " " + point_c;
}
function dragged(){
var coordinates = [0, 0];
coordinates = d3.mouse(this);
var x = coordinates[0];
x = x > range_width ? range_width :
x < 0 ? 0 :
x;
// find the pct represented by the mouse position
var pct = Math.round(range_x.invert(x));
range_svg.select(".range-handle")
.attr("cx", range_x(pct));
range_svg.select(".range-label")
.attr("x", range_x(pct))
.text(pct);
range_svg.select(".range-pointer")
.attr("points", calcPointerPoints(pct));
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment