D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
bhvaleri
Full window
Github gist
prototype time selector (mobile)
<!DOCTYPE html> <html> <script src="https://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>
Modified
http://d3js.org/d3.v3.min.js
to a secure url
https://d3js.org/d3.v3.min.js