Last active
August 29, 2015 14:22
-
-
Save bhvaleri/c3d041026be380a3b0c1 to your computer and use it in GitHub Desktop.
prototype time selector (mobile)
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> | |
<html> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<style> | |
.background-line { | |
fill: none; | |
stroke: black; | |
stroke-width: 2px; | |
} | |
body { | |
width: 100%; | |
} | |
.range-segment, | |
.handle { | |
stroke: black; | |
cursor: pointer; | |
} | |
.time { | |
font-size: 144px; | |
} | |
.times { | |
padding: 100px 100px 0 100px; | |
} | |
.begin-time { | |
float: left; | |
} | |
.end-time { | |
float: right; | |
} | |
</style> | |
<body> | |
<div class="times"> | |
<div class="time begin-time">10</div> | |
<div class="time end-time">23</div> | |
</div> | |
<svg></svg> | |
<script> | |
var startingTimeRange = [ 2, 14 ]; | |
var margin = {top: -200, right: 100, bottom: 40, left: 100 }; | |
windowWidth = window.innerWidth | |
var width = windowWidth - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var svg = d3.select('svg') | |
.attr('width', width + margin.left + margin.right) | |
.attr('height', height + margin.top + margin.bottom) | |
.append('g') | |
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); | |
var domain = d3.range(24); | |
var xScale = d3.scale.ordinal() | |
.rangeRoundBands([0, width]) | |
.domain(domain); | |
var line = d3.svg.line(); | |
var backgroundLine = svg.append('path') | |
.attr('class', 'background-line'); | |
var middle = width / 2; | |
backgroundLine.datum([[xScale(0), middle], [xScale(23), middle]]) | |
.attr('d', line); | |
var beginTime = 2; | |
var endTime = 4; | |
var shiftRange = function (shiftFactor) { | |
shiftFactor = Math.round(shiftFactor) | |
shiftedBeginTime = ((currentBeginTime + shiftFactor) % 23 + 23) % 23; | |
shiftedEndTime = ((currentEndTime + shiftFactor) % 23 + 23) % 23; | |
updateRange(shiftedBeginTime, shiftedEndTime); | |
}; | |
var segmentHeight = 30; | |
var segmentGroup = svg.append('g').attr('class', 'segment-group') | |
.attr('transform', 'translate(0,' + (middle - segmentHeight/2) +')'); | |
var currentBeginTime = 0; | |
var currentEndTime = 23; | |
var updateTimeLabels = function () { | |
begin = document.getElementsByClassName('begin-time')[0] | |
begin.innerText = currentBeginTime; | |
end = document.getElementsByClassName('end-time')[0] | |
end.innerText = currentEndTime; | |
}; | |
var updateRange = function (newBeginTime, newEndTime) { | |
currentBeginTime = newBeginTime; | |
currentEndTime = newEndTime; | |
updateTimeLabels(); | |
if (newBeginTime < newEndTime) { | |
var hoursInRange = d3.range(newBeginTime, newEndTime); | |
hoursInRange.push(newEndTime); | |
} | |
else if (newBeginTime > newEndTime) { | |
var firstHalfRange = d3.range(0, newEndTime) | |
firstHalfRange.push(newEndTime); | |
var secondHalfRange = d3.range(newBeginTime, 24); | |
var hoursInRange = firstHalfRange.concat(secondHalfRange); | |
} | |
var segments = segmentGroup.selectAll('.range-segment').data(hoursInRange); | |
segments.enter().append('rect').attr('class', 'range-segment') | |
.attr('height', segmentHeight) | |
.attr('width', xScale.rangeBand) | |
.attr('x', function(d) { return xScale(d); }); | |
segments.attr('x', function(d) { return xScale(d); }); | |
segments.exit().remove(); | |
updateHandles(); | |
} | |
var updateHandles = function () { | |
//begin handle | |
var beginHandle = svg.selectAll('.begin-handle').data([currentBeginTime]); | |
beginHandle.enter().append('rect') | |
.attr('class', 'begin-handle handle') | |
.attr('height', segmentHeight * 6) | |
.attr('y', middle -(segmentHeight * 3)) | |
.attr('width', xScale.rangeBand()); | |
beginHandle.attr('x', function (d) { return xScale(d); }) | |
.on('touchstart', function () { | |
var startingX = d3.mouse(this)[0]; | |
d3.event.preventDefault(); | |
d3.select(window).on('touchmove', function () { | |
var currentX = d3.mouse(beginHandle.node())[0] | |
var differenceX = currentX - startingX; | |
if (Math.abs(differenceX) > xScale.rangeBand() / 2) { | |
differenceX > 0 ? updateRange(currentBeginTime + 1, currentEndTime) : updateRange(currentBeginTime - 1, currentEndTime); | |
startingX = currentX; | |
} | |
}).on('touchend', function() { | |
d3.select(window).on('touchmove', null); | |
d3.select(window).on('touchend', null); | |
}); | |
}) | |
beginHandle.exit().remove(); | |
var endHandle = svg.selectAll('.end-handle').data([currentEndTime]); | |
endHandle.enter().append('rect') | |
.attr('class', 'end-handle handle') | |
.attr('height', segmentHeight * 6) | |
.attr('y', middle -(segmentHeight * 3)) | |
.attr('width', xScale.rangeBand()); | |
endHandle.attr('x', function (d) { return xScale(d + 1); }) | |
.on('touchstart', function () { | |
var startingX = d3.mouse(this)[0]; | |
d3.event.preventDefault(); | |
d3.select(window).on('touchmove', function () { | |
var currentX = d3.mouse(endHandle.node())[0] | |
var differenceX = currentX - startingX; | |
if (Math.abs(differenceX) > xScale.rangeBand() / 2) { | |
differenceX > 0 ? updateRange(currentBeginTime, currentEndTime + 1) : updateRange(currentBeginTime, currentEndTime - 1); | |
startingX = currentX; | |
} | |
}).on('touchend', function() { | |
d3.select(window).on('touchmove', null); | |
d3.select(window).on('touchend', null); | |
}); | |
}) | |
endHandle.exit().remove(); | |
} | |
segmentGroup.on('touchstart', function () { | |
var startingX = d3.mouse(this)[0]; | |
d3.event.preventDefault(); | |
d3.select(window).on('touchmove', function () { | |
var currentX = d3.mouse(segmentGroup.node())[0] | |
var differenceX = currentX - startingX; | |
if (Math.abs(differenceX) > xScale.rangeBand() / 2) { | |
differenceX > 0 ? shiftRange(1) : shiftRange(-1); | |
startingX = currentX; | |
} | |
}).on('touchend', function() { | |
d3.select(window).on('touchmove', null); | |
d3.select(window).on('touchend', null); | |
}); | |
}); | |
updateRange(beginTime, endTime); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment