Use d3-selection, d3-scale, d3-drag, d3-axis and d3-marcon to make a range slider.
Last active
November 16, 2017 05:23
-
-
Save HarryStevens/d1bc769436b43438d9b02d25a3315e0d to your computer and use it in GitHub Desktop.
Range Slider
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: gpl-3.0 | |
height: 160 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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/[email protected]/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