Renders a simple interactive slider with added accessibility features.
Inspired by The New York Times Is It Better to Rent or Buy?
Source code and documentation available on Github.
forked from johnwalley's block: d3-simple-slider
forked from henryjameslau's block: d3-simple-slider with added accessibility features
xxxxxxxxxx
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>d3-simple-slider</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="d3-simple-slider.js"></script>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous"
/>
<style>
body{
max-width:700px;
}
.slider text{
font-size: 18px;
}
#slider-simple text{
font-size: 18px;
}
.parameter-value path{
fill:#0F8243;
stroke:white;
stroke-width:1.5px;
}
.parameter-value path:focus{
fill:#0F8243;
stroke:orange;
stroke-width:3px;
}
input{
border: none;
border-radius: 0;
border-bottom: solid 1px #ddd;
font-size: 18px;
line-height: 32px;
margin:16px 0;
padding: 6px 0 0 0;
}
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
p{
line-height: 32px;
font-size: 18px;
margin:16px 0;
padding: 6px 0 10px 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Blue callout box</h1>
<div class="row align-items-center">
<div class="col-sm-6"><p>Label for number</p></div>
<div class="col-sm-6"><input id="value-simple" type="number" value="175000" oninput="sliderchange()" min="0" max="400000"></div>
<div class="col-sm-12"><div id="slider-simple"></div></div>
</div>
</div>
<script>
// Simple
var sliderSimple = d3
.sliderBottom()
.min(0)
.max(400000)
.width(parseInt(d3.select('body').style("width"))-80)
.tickFormat(d3.format(',.0f'))
.ticks(5)
.default(175000)
.handle(
d3.symbol()
.type(d3.symbolCircle)
.size(500)
)
.fill("#206595")
.on('onchange', val => {
document.getElementById("value-simple").value=d3.format('.0f')(val)
});
var gSimple = d3
.select('div#slider-simple')
.append('svg')
.attr('width', parseInt(d3.select('body').style("width")))
.attr('height', 100)
.append('g')
.attr('transform', 'translate(40,30)');
gSimple.call(sliderSimple);
document.getElementById("value-simple").value=d3.format('.0f')(sliderSimple.value());
//
// var text = d3.select('g.parameter-value text')
// var bbox = text.node().getBBox();
// var padding = 5;
// var rect = d3.select('g.parameter-value').append("rect")
// .attr("x", bbox.x - padding)
// .attr("y", bbox.y - padding)
// .attr("ry",5)
// .attr("width", bbox.width + (padding*2))
// .attr("height", bbox.height + (padding*2))
// .style("fill", "#206095");
// console.log(text)
// d3.select('g.parameter-value')
// .append('text')
// .text(text._groups[0][0].innerHTML)
// .style('fill','white')
// .attr('y',text.attr('y'))
// .attr('dy',text.attr('dy'))
function sliderchange(){
sliderSimple.silentValue(document.getElementById('value-simple').value)
}
d3.select('body').on('keydown',function(){
if(document.getElementById("handle")===document.activeElement){//if handle is focussed
var max = document.getElementById('value-simple').max
var min = document.getElementById('value-simple').min
if (d3.event.key=='ArrowLeft') {
if(+document.getElementById('value-simple').value-100<min){
sliderSimple.silentValue(min)
document.getElementById("value-simple").value=min
}else{
sliderSimple.silentValue(+document.getElementById('value-simple').value-100)
document.getElementById("value-simple").value=+document.getElementById("value-simple").value-100
}
}
if (d3.event.key=='ArrowUp') {
d3.event.preventDefault();
if(+document.getElementById('value-simple').value+100>max){
sliderSimple.silentValue(max)
document.getElementById("value-simple").value=max
}else{
sliderSimple.silentValue(+document.getElementById('value-simple').value+100)
document.getElementById("value-simple").value=+document.getElementById("value-simple").value+100
}
}
if (d3.event.key=='ArrowRight') {
if(+document.getElementById('value-simple').value+100>max){
sliderSimple.silentValue(max)
document.getElementById("value-simple").value=max
}else{
sliderSimple.silentValue(+document.getElementById('value-simple').value+100)
document.getElementById("value-simple").value=+document.getElementById("value-simple").value+100
} }
if (d3.event.key=='ArrowDown') {
d3.event.preventDefault();
if(+document.getElementById('value-simple').value-100<min){
sliderSimple.silentValue(min)
document.getElementById("value-simple").value=min
}else{
sliderSimple.silentValue(+document.getElementById('value-simple').value-100)
document.getElementById("value-simple").value=+document.getElementById("value-simple").value-100
}
}
if (d3.event.key=='PageDown') {
d3.event.preventDefault();
if(+document.getElementById('value-simple').value-1000<min){
sliderSimple.silentValue(min)
document.getElementById("value-simple").value=min
}else{
sliderSimple.silentValue(+document.getElementById('value-simple').value-1000)
document.getElementById("value-simple").value=+document.getElementById("value-simple").value-1000
}
}
if (d3.event.key=='PageUp') {
d3.event.preventDefault();
if(+document.getElementById('value-simple').value+1000>max){
sliderSimple.silentValue(max)
document.getElementById("value-simple").value=max
}else{
sliderSimple.silentValue(+document.getElementById('value-simple').value+1000)
document.getElementById("value-simple").value=+document.getElementById("value-simple").value+1000
} }
if (d3.event.key=='Home') {
d3.event.preventDefault();
sliderSimple.silentValue(min)
document.getElementById("value-simple").value=min
}
if (d3.event.key=='End') {
d3.event.preventDefault();
sliderSimple.silentValue(max)
document.getElementById("value-simple").value=max
}
}
})
</script>
</body>
</html>
https://d3js.org/d3.v5.min.js