Files
coriolis/app/js/directives/directive-slider.js
2015-06-02 23:57:31 -07:00

74 lines
2.8 KiB
JavaScript

angular.module('app').directive('slider', ['$window', function ($window) {
return {
restrict: 'A',
scope:{
max: '=',
unit: '=',
change: '&onChange'
},
link: function(scope, element) {
var margin = {top: -10, right: 130, bottom: 0, left: 50},
height = 40, // Height is fixed
h = height - margin.top - margin.bottom,
fmt = d3.format('.2f'),
pct = d3.format('.1%'),
unit = scope.unit,
val = scope.max,
svg = d3.select(element[0]).append("svg"),
vis = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"),
xAxis = vis.append("g").attr("class", "x slider-axis").attr("transform", "translate(0," + h / 2 + ")"),
x = d3.scale.linear(),
slider = vis.append("g").attr("class", "slider"),
filled = slider.append('path').attr('class', 'filled').attr("transform", "translate(0," + h/2 + ")"),
brush = d3.svg.brush().x(x).extent([scope.max, scope.max]).on("brush", brushed),
handle = slider.append("circle").attr("class", "handle").attr("r", '0.75em'),
lbl = slider.append("g").append("text").attr("y", h/2);
slider.call(brush);
slider.select(".background").attr("height", h);
handle.attr("transform", "translate(0," + h / 2 + ")");
/**
* Watch for changes in the max, window size
*/
scope.$watch('max', function(newMax, oldMax) {
val = newMax * (val / oldMax); // Retain percentage filled
render();
});
angular.element($window).bind('orientationchange resize', render);
function render() {
var width = element[0].offsetWidth, w = width - margin.left - margin.right;
svg.attr("width", width).attr("height", height);
x.domain([0, scope.max]).range([0, w]).clamp(true);
handle.attr("cx", x(val));
xAxis
.call(d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(function(d) { return d + unit; })
.tickSize(0)
.tickPadding(12))
.select(".domain");
lbl.attr('x', w + 20).text(fmt(val) + ' ' + unit + ' (' + pct(val / scope.max) + ')');
slider.call(brush.extent([val, val])).call(brush.event);
slider.selectAll(".extent,.resize").remove();
}
function brushed() {
val = brush.extent()[0];
if (d3.event.sourceEvent) { // not a programmatic event
val = x.invert(d3.mouse(this)[0]);
brush.extent([val, val]);
}
lbl.text(fmt(val) + ' ' + unit + ' (' + pct(val / scope.max) + ')');
scope.change({val: val});
handle.attr("cx", x(val));
filled.attr("d", "M0,0V0H" + x(val) + "V0");
}
}
};
}]);