Last active
November 24, 2017 04:15
-
-
Save narensulegai/9cf8315bea69f599ddbbff21dc7f2b60 to your computer and use it in GitHub Desktop.
Simple slider
This file contains 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> | |
<meta charset="utf-8"> | |
<style> | |
.container { | |
height: 500px; | |
width: 50%; | |
margin: auto; | |
} | |
.tick > line { | |
stroke-width: 3px; | |
cursor: pointer; | |
} | |
.tick > text { | |
display: none; | |
text-anchor: middle; | |
} | |
.tick.showLabel > text { | |
display: inline; | |
} | |
.tick.active > text { | |
display: inline; | |
} | |
.currentValue { | |
text-anchor: middle; | |
} | |
.sliderFull, .sliderRight, .sliderLeft { | |
pointer-events: stroke; | |
stroke-width: 10px; | |
stroke: transparent; | |
cursor: pointer; | |
} | |
.sliderRight, .sliderLeft { | |
stroke: grey; | |
opacity: 0.5; | |
} | |
.sliderLeft { | |
stroke: grey; | |
} | |
.tick.fail, .fail .sliderLeft, .fail .cog { | |
stroke: red; | |
fill: red; | |
} | |
.tick.pass, .pass .sliderLeft, .pass .cog { | |
stroke: orange; | |
fill: orange; | |
} | |
.tick.firstClass, .firstClass .sliderLeft, .firstClass .cog { | |
stroke: yellow; | |
fill: yellow; | |
} | |
.tick.distinction, .distinction .sliderLeft, .distinction .cog { | |
stroke: green; | |
fill: green; | |
} | |
.tick.perfect, .perfect .sliderLeft, .perfect .cog { | |
stroke: blue; | |
fill: blue; | |
} | |
.cog { | |
stroke: #000; | |
stroke-width: 1px; | |
} | |
</style> | |
<body> | |
<div class="container"> | |
<svg></svg> | |
</div> | |
</body> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
//assuming the value are sorted | |
var data = [ | |
{name: 'fail', value: 0, showLabel: true}, | |
{name: 'pass', value: 35, showLabel: false}, | |
{name: 'firstClass', value: 60, showLabel: false}, | |
{name: 'distinction', value: 70, showLabel: false}, | |
{name: 'perfect', value: 100, showLabel: true} | |
]; | |
var container = d3.select('.container').node().getBoundingClientRect(); | |
var svg = d3.select("svg"); | |
svg.attr("height", container.height); | |
svg.attr("width", container.width); | |
var margin = {top: 10, right: 40, bottom: 20, left: 40}; | |
var height = container.height - margin.bottom - margin.top; | |
var width = container.width - margin.left - margin.right; | |
var svgContent = svg.append('g'); | |
svgContent.attr("transform", "translate(" + [margin.left, margin.top].join(',') + ")"); | |
var x = d3.scaleLinear() | |
.domain([d3.min(data, function (d) { | |
return d.value; | |
}), d3.max(data, function (d) { | |
return d.value; | |
})]) | |
.range([0, width]) | |
.clamp(true); | |
var currValue = svgContent.append('text') | |
.attr("transform", "translate(0," + height / 2 + ")") | |
.attr("x", 0) | |
.attr("dy", -20) | |
.attr("class", "currentValue"); | |
var slider = svgContent.append("g") | |
.attr("transform", "translate(0," + height / 2 + ")"); | |
var tickHeight = 10; | |
var ticks = svgContent.append("g") | |
.classed("ticks", true) | |
.attr("transform", "translate(0," + ((height / 2) + 10) + ")") | |
.selectAll() | |
.data(data) | |
.enter() | |
.append('g') | |
.attr("class", function (d) { | |
return d.name; | |
}) | |
.classed("tick", true) | |
.classed('showLabel', function (d) { | |
return d.showLabel; | |
}).on('click', function (d) { | |
moveCog(x(d.value)) | |
}); | |
ticks.append("text") | |
.attr("x", function (d) { | |
return x(d.value) | |
}) | |
.attr("dy", 28) | |
.text(function (d) { | |
return d.value; | |
}); | |
ticks.append("line") | |
.attr("x1", function (d) { | |
return x(d.value) | |
}) | |
.attr("x2", function (d) { | |
return x(d.value) | |
}) | |
.attr("y1", tickHeight / 2) | |
.attr("y2", -tickHeight / 2) | |
.on("mouseenter", function () { | |
d3.select(this.parentNode).classed('active', true); | |
}) | |
.on("mouseleave", function () { | |
d3.select(this.parentNode).classed('active', false); | |
}); | |
var sliderLeft = slider.append("line") | |
.attr("x1", x.range()[0]) | |
.attr("x2", x.range()[0]) | |
.attr("class", "sliderLeft"); | |
var sliderRight = slider.append("line") | |
.attr("x1", x.range()[0]) | |
.attr("x2", x.range()[1]) | |
.attr("class", "sliderRight"); | |
slider.append("line") | |
.attr("x1", x.range()[0]) | |
.attr("x2", x.range()[1]) | |
.attr("class", "sliderFull") | |
.call(d3.drag() | |
.on("end", function () { | |
moveCog(d3.event.x) | |
})); | |
var calcClass = function (marks) { | |
var cl = data[0].name; | |
for (var i = 0; i < data.length; i++) { | |
if (data[i].value > marks) { | |
break | |
} | |
cl = data[i].name | |
} | |
return cl; | |
}; | |
var moveCog = function (mcx) { | |
var cx = mcx; | |
if (mcx < 0) cx = 0; | |
if (mcx > width) cx = width; | |
//quantize to 2 decimal | |
var val = parseFloat(x.invert(cx).toFixed(2)); | |
svgContent.attr("class", calcClass(val)); | |
currValue.text(val); | |
var qcx = x(val); | |
currValue.attr("x", qcx); | |
cog.attr("cx", qcx); | |
sliderLeft.attr("x2", qcx); | |
sliderRight.attr("x1", qcx); | |
}; | |
var cog = slider.append("circle") | |
.classed("cog", true) | |
.attr("r", 9) | |
.call(d3.drag() | |
.on("start", function () { | |
moveCog(d3.event.x) | |
}) | |
.on("end", function () { | |
moveCog(d3.event.x) | |
}) | |
.on("drag", function () { | |
moveCog(d3.event.x) | |
})); | |
moveCog(x(35)) | |
</script> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment