Skip to content

Commit

Permalink
Update handle position when slider.value() changes.
Browse files Browse the repository at this point in the history
When setting the slider value: slider.value(newValue), one needs to
update the handle position.
  • Loading branch information
François Sausset committed Sep 29, 2014
1 parent c8b52cd commit bb33d87
Showing 1 changed file with 85 additions and 78 deletions.
163 changes: 85 additions & 78 deletions d3.slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ return function module() {
dispatch = d3.dispatch("slide", "slideend"),
formatPercent = d3.format(".2%"),
tickFormat = d3.format(".0"),
handle1,
handle2 = null,
sliderLength;

function slider(selection) {
Expand All @@ -65,7 +67,7 @@ return function module() {

// Slider handle
//if range slider, create two
var handle1, handle2 = null, divRange;
var divRange;

if ( value.length == 2 ) {
handle1 = div.append("a")
Expand Down Expand Up @@ -205,87 +207,17 @@ return function module() {

}


// Move slider handle on click/drag
function moveHandle(pos) {

var newValue = stepValue(scale.invert(pos / sliderLength)),
currentValue = value.length ? value[active - 1]: value;

if (currentValue !== newValue) {
var oldPos = formatPercent(scale(stepValue(currentValue))),
newPos = formatPercent(scale(stepValue(newValue))),
position = (orientation === "horizontal") ? "left" : "bottom";

if ( value.length === 2) {
value[ active - 1 ] = newValue;
dispatch.slide(d3.event, value );
} else {
dispatch.slide(d3.event.sourceEvent || d3.event, value = newValue);
}

if ( value[ 0 ] >= value[ 1 ] ) return;
if ( active === 1 ) {

if (value.length === 2) {
(position === "left") ? divRange.style("left", newPos) : divRange.style("bottom", newPos);
}

if (animate) {
handle1.transition()
.styleTween(position, function() { return d3.interpolate(oldPos, newPos); })
.duration((typeof animate === "number") ? animate : 250);
} else {
handle1.style(position, newPos);
}
} else {

var width = 100 - parseFloat(newPos);
var top = 100 - parseFloat(newPos);

(position === "left") ? divRange.style("right", width + "%") : divRange.style("top", top + "%");

if (animate) {
handle2.transition()
.styleTween(position, function() { return d3.interpolate(oldPos, newPos); })
.duration((typeof animate === "number") ? animate : 250);
} else {
handle2.style(position, newPos);
}
}
}

}


// Calculate nearest step value
function stepValue(val) {

if (val === scale.domain()[0] || val === scale.domain()[1]) {
return val;
}

var valModStep = (val - scale.domain()[0]) % step,
alignValue = val - valModStep;

if (Math.abs(valModStep) * 2 >= step) {
alignValue += (valModStep > 0) ? step : -step;
}

return alignValue;

}


function onClickHorizontal() {
if (!value.length) {
moveHandle(Math.max(0, Math.min(sliderLength, d3.event.offsetX || d3.event.layerX)));
var pos = Math.max(0, Math.min(sliderLength, d3.event.offsetX || d3.event.layerX));
moveHandle(stepValue(scale.invert(pos / sliderLength)));
}
}

function onClickVertical() {
if (!value.length) {
moveHandle(sliderLength - Math.max(0, Math.min(sliderLength, d3.event.offsetY || d3.event.layerY)));
var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.offsetY || d3.event.layerY));
moveHandle(stepValue(scale.invert(pos / sliderLength)));
}
}

Expand All @@ -295,7 +227,8 @@ return function module() {
} else if ( d3.event.sourceEvent.target.id == "handle-two" ) {
active = 2;
}
moveHandle(Math.max(0, Math.min(sliderLength, d3.event.x)));
var pos = Math.max(0, Math.min(sliderLength, d3.event.x));
moveHandle(stepValue(scale.invert(pos / sliderLength)));
}

function onDragVertical() {
Expand All @@ -304,7 +237,8 @@ return function module() {
} else if ( d3.event.sourceEvent.target.id == "handle-two" ) {
active = 2;
}
moveHandle(sliderLength - Math.max(0, Math.min(sliderLength, d3.event.y)));
var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.y))
moveHandle(stepValue(scale.invert(pos / sliderLength)));
}

function stopPropagation() {
Expand All @@ -315,6 +249,76 @@ return function module() {

}

// Move slider handle on click/drag
function moveHandle(newValue) {
var currentValue = value.length ? value[active - 1]: value;

if (currentValue !== newValue) {
var oldPos = formatPercent(scale(stepValue(currentValue))),
newPos = formatPercent(scale(stepValue(newValue))),
position = (orientation === "horizontal") ? "left" : "bottom";

if ( value.length === 2) {
value[ active - 1 ] = newValue;
if (d3.event) {
dispatch.slide(d3.event, value );
};
} else {
if (d3.event) {
dispatch.slide(d3.event.sourceEvent || d3.event, value = newValue);
};
}

if ( value[ 0 ] >= value[ 1 ] ) return;
if ( active === 1 ) {

if (value.length === 2) {
(position === "left") ? divRange.style("left", newPos) : divRange.style("bottom", newPos);
}

if (animate) {
handle1.transition()
.styleTween(position, function() { return d3.interpolate(oldPos, newPos); })
.duration((typeof animate === "number") ? animate : 250);
} else {
handle1.style(position, newPos);
}
} else {

var width = 100 - parseFloat(newPos);
var top = 100 - parseFloat(newPos);

(position === "left") ? divRange.style("right", width + "%") : divRange.style("top", top + "%");

if (animate) {
handle2.transition()
.styleTween(position, function() { return d3.interpolate(oldPos, newPos); })
.duration((typeof animate === "number") ? animate : 250);
} else {
handle2.style(position, newPos);
}
}
}
}

// Calculate nearest step value
function stepValue(val) {

if (val === scale.domain()[0] || val === scale.domain()[1]) {
return val;
}

var valModStep = (val - scale.domain()[0]) % step,
alignValue = val - valModStep;

if (Math.abs(valModStep) * 2 >= step) {
alignValue += (valModStep > 0) ? step : -step;
}

return alignValue;

}

// Getter/setter functions
slider.min = function(_) {
if (!arguments.length) return min;
Expand Down Expand Up @@ -360,6 +364,9 @@ return function module() {

slider.value = function(_) {
if (!arguments.length) return value;
if (value) {
moveHandle(_);
};
value = _;
return slider;
};
Expand All @@ -375,4 +382,4 @@ return function module() {
return slider;

}
}));
}));

0 comments on commit bb33d87

Please sign in to comment.