Skip to content

Instantly share code, notes, and snippets.

@zachdunn
Last active December 18, 2015 03:29
Show Gist options
  • Save zachdunn/5718686 to your computer and use it in GitHub Desktop.
Save zachdunn/5718686 to your computer and use it in GitHub Desktop.
Time series using range input and smart markers. Built off a AngularJS directive structure.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
#wrapper{width:960px; margin:10px auto;}
#time-series{
margin-top:40px;
}
*{
font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
}
.time-bracket{background:#EFEFEF;}
.time-bracket p{margin:0; color:#222; text-align:center;}
.time-bracket .ts-label{text-transform: uppercase; font-weight:bold; letter-spacing:1px; font-size:11px; margin-bottom:6px;}
.ts-startTime, .ts-endTime{
font-size:12px;
}
.start-time{float:left;}
.end-time{float:left;}
.time-bracket{
display:inline-block; width:175px; padding:15px; box-sizing:border-box;
}
.ts-startTime span, .ts-endTime span{display:block;}
.tick{width:2px; height:77px; position:absolute; background:#222; background:rgba(0,0,0,.3);}
.tick .indicator-arrow{
margin-left:-5px;
position:absolute;
bottom:-11px;
opacity:.5;
}
.tick.active .indicator-arrow {
opacity:1;
}
.day-list ul{
margin:0 175px 25px 175px;
padding:0;
list-style:none;
display:block;
clear:both;
}
.day-list li{
font-size:13px;
width:122px;
box-sizing:border-box;
margin:0; padding:0;
display:inline-block;
float:left;
border-bottom:5px solid #efefef;
text-align:center;
line-height:1.3em;
}
.day-list li.active, .day-list li.active:hover{
border-bottom:5px solid #EF3344;
}
.day-list li:hover{
border-bottom:5px solid #F07D86;
}
.day-list li span.day{
clear:both;
display:block;
}
.day-list a{
display:block;
height:100%; width:100%;
padding:15px;
box-sizing:border-box;
text-decoration:none;
color:#888;
}
.day-list a .day{
color:#333;
}
.day-list li .date{
font-style:italic;
font-size:12px;
}
.day-list li.active .day{
font-weight:bold;
}
input[type="range"]{
-webkit-appearance:none;
background:#EF3344;
width:610px;
height:77px;
cursor:pointer;
margin:0;
}
input[type="range"]::-webkit-slider-thumb{
-webkit-appearance:none;
background:#FFF;
opacity:.7;
width:2px;
height:77px;
}
.ts-marker{
background:#222;
color:#FFF;
font-size:11px;
text-align:center;
border-radius:3px;
padding:10px;
position:absolute;
top:-15px;
}
.ts-tickContainer{float:left;}
.ts-marker p{line-height:1.0em; margin:0;}
#time-bar-wrap{position:relative; display:inline-block; width:610px; float:left;}
/* Regular Content */
.content{
clear:both;
padding:30px;
}
.content h2{
color:#333;
}
.content.faded{
opacity:0.5;
}
.clearfix{
zoom: 1;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
zoom: 1;
}
.clearfix:after {
clear: both;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Time Series</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="time-series.js"></script>
<link rel="stylesheet" href="time-series.css">
</head>
<body>
<div id="wrapper">
<div id="time-series">
<div class="day-list">
<ul class="clearfix">
<li>
<a href="#">
<span class="day">Wednesday</span>
<span class="date">May 29, 2013</a>
</a>
</li>
<li>
<a href="#">
<span class="day">Thursday</span>
<span class="date">May 30, 2013</a>
</a>
</li>
<li class="active">
<a href="#">
<span class="day">Friday</span>
<span class="date">May 31, 2013</a>
</a>
</li>
</ul>
</div>
<time-slider callback="layoutSliderChanged" min="layoutStartTimeMS" max="layoutEndTimeMS" ticks="layoutSectionTimes" step="60000" class="ng-isolate-scope ng-scope">
<div class="ts-container clearfix">
<div class="start-time time-bracket">
<p class="ts-label">Start Time</p>
<p class="ts-startTime">
<span class="time">2:00 AM</span>
<span class="date">Friday May 31, 2013</span>
</p>
</div>
<div id="time-bar-wrap">
<div style="display: inline-block" class="ts-tickContainer">
<div class="tick" style="left: 389.56111111111113px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 423.89444444444445px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 465.6666666666667px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 436.48333333333335px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 441.6333333333333px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 294px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 355.22777777777776px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 474.25px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 180px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 362.66666666666663px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
<div class="tick" style="left: 50px;">
<img class="indicator-arrow" width="12" height="12" src="arrow.svg">
</div>
</div>
<input id="time-selection" type="range" min="1369980000000" max="1370001600000" step="60000">
<div class="ts-marker">
<p>
<span class="ts-time">4:47 AM</span>
<span class="ts-date">Friday, May 31</span>
</p>
</div>
</div>
<div class="end-time time-bracket">
<p class="ts-label">End Time</p>
<p class="ts-endTime">
<span class="time">8:00 PM</span>
<span class="date">Friday May 31, 2013</span>
</p>
</div>
</div>
</time-slider>
</div>
<div class="content">
<h2>Scheduled Content (<span class="active-count">0</span> active)</h2>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</div>
</div>
</body>
</html>
$(function() {
var el, newPoint, newPlace, offset, selectLocation;
// Get marker for later
var marker = $('.ts-marker');
// Select all range inputs, watch for change
$("#time-selection").on('mousedown', function(){
$('.content').addClass('faded');
}).on('mouseup', function(){
$('.content').removeClass('faded');
});
$("#time-selection").on('change', function() {
// Cache this for efficiency
el = $(this);
// Measure width of range input
width = el.width();
// Figure out placement percentage between left and right of input
newPoint = (el.val() - el.attr("min")) / (el.attr("max") - el.attr("min"));
marker.find('p').text(new Date(parseInt(el.val())).toUTCString());
// Not really needed anymore
offset = -(marker.width() / 2);
// Prevent bubble from going beyond left or right (unsupported browsers)
if (newPoint < 0) { newPlace = 0; }
else if (newPoint > 1) { newPlace = width; }
else { newPlace = width * newPoint + offset; offset -= newPoint; }
selectLocation = width * newPoint //Same as newPlace without offset
// Move bubble
marker.css({
left: newPlace
});
// Highlight tick marks in a 10px range of slider
$('.tick').removeClass('active').css({top:0});
var activeTick = $('.tick').filter(function(){
upperBound = selectLocation + 10;
lowerBound = selectLocation - 10;
tickPos = parseInt($(this).position().left);
return tickPos < upperBound && tickPos > lowerBound;
});
//console.log('Eval from ' + selectLocation);
$(activeTick).addClass('active');
// Display the current active count in body
$('.active-count').text(activeTick.length);
// Stagger multiple active ticks to prevent crowding
if (activeTick.length > 0) {
stepOffset = 0;
activeTick.each(function(index, value){
el = $(value);
el.css({top: 11*stepOffset});
stepOffset++;
});
}
}).trigger('change'); // Fake a change to position bubble at page load
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment