d3 gradient slider
an exercise in drag-drop interaction
HTML
<script src="https://raw.github.com/mbostock/d3/master/d3.js"></script>
<div id="slider_div">
<svg version="1.1" baseProfile="basic" id="Layer_1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="108px" height="20px"
viewBox="0 0 108 20" xml:space="preserve">
<defs>
<symbol id="ticks" viewBox="-8.174 -24.479 16.148 24.479">
<polygon class="tick_icon" points="3.526,-13 0.081,-6.419 0.081,0 0.081,0 0.081,-6.419 -3.364,-13"/>
<polygon opacity="0" stroke-opacity:"0" fill="#ccf" points="4,2 -4,2 -4,-20 4,-20"/>
</symbol>
<linearGradient id="rg_gradient" gradientUnits="userSpaceOnUse" x1="0" x2="800">
<stop offset="0" style="stop-color:#FF0000"/>
<stop offset="0.1" style="stop-color:#FDB014"/>
<stop offset="0.4" style="stop-color:#FFFF00"/>
<stop offset="0.9" style="stop-color:#BFF219"/>
<stop offset="1.0" style="stop-color:#00FF00"/>
</linearGradient>
</defs>
<g transform="translate(4,0)">
<rect x="0" y="0" class="st0" width="300" height="40"/>
</g>
</svg>
<form action="nothing" method="get" name="overlap_tile_picker">
<input class="text_field" id="tick1text" type="text" value="25" size="2" maxlength="3" readonly="true" disabled="true" />
<input class="text_field" id="tick2text" type="text" value="50" size="2" maxlength="3" readonly="true" disabled="true"/>
<input class="text_field" id="tick3text" type="text" value="75" size="2" maxlength="3" readonly="true" disabled="true" />
</form>
</div>
CSS
.st0{
fill:url(#rg_gradient);
}
#ticks{fill:#ccc;}
#ticks:hover{fill:#000; stroke-width:.5; stroke:#000; cursor:auto}
#slider_div{
margin:auto;
padding-top:30px;
width:300px;
}
JavaScript
var tktg=null,
w = 8,
x= d3.scale.linear([0,100]).range([-w,100-w]),
drag = d3.behavior.drag()
.origin(Object)
.on("drag", dragmove)
;
function dragmove(d) {
var t = d3.select(this);
var vals= [];
d3.selectAll(".tick_target").each(function(d){vals.push(d3.select(this).attr("x"))});
vals.sort(function(a,b){return a-b;});
d3.selectAll(".text_field").each(function(d,i){ d3.select(this).attr("value",Math.round(x.invert(vals[i])*100))});
t.attr("x", function(d){ return d.x = Math.round(Math.min(100-w,Math.max(-w,d3.event.x)))})
;
}
var starting_position_data = [{x:25},{x:50},{x:75}];
tktg = d3.select("svg").select("g").selectAll(".tick_target")
.data(starting_position_data)
.enter()
.append("svg:use")
.attr("class","tick_target")
.attr("xlink:href","#ticks")
.attr("id",function(d,i){return "tick"+(i+1)})
.attr("width",16)
.attr("height",24)
.attr("x", function(d){return d.x-w;})
.attr("y", -24)
.attr("transform","matrix(1 0 0 -1 0 0)")
.call(drag);