Skip to content

Instantly share code, notes, and snippets.

@bhvaleri
Last active August 29, 2015 14:22
Show Gist options
  • Save bhvaleri/c3d041026be380a3b0c1 to your computer and use it in GitHub Desktop.
Save bhvaleri/c3d041026be380a3b0c1 to your computer and use it in GitHub Desktop.
prototype time selector (mobile)
<!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