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);