Skip to content

Commit

Permalink
greatly improve visits table
Browse files Browse the repository at this point in the history
with duration computed from start-end-date and dates sortable

probably fixes #43

Signed-off-by: Torbjörn Klatt <[email protected]>
  • Loading branch information
torbjoernk committed Feb 10, 2016
1 parent 0282abd commit 40fa7d3
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 12 deletions.
14 changes: 8 additions & 6 deletions _assets/js/custom.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//= require 'vendor/bootstrap.min.js'
//= require 'vendor/jquery.dataTables.min.js'
//= require 'vendor/dataTables.bootstrap.min.js'
//= require 'vendor/moment.min.js'
//= require 'vendor/dataTables.plugins.datetime_moment.js'


$(document).ready(function() {
function reverse(value) {
return value.split("").reverse().join("");
Expand Down Expand Up @@ -58,13 +65,8 @@ $(document).ready(function() {
}
});

$.fn.dataTable.moment('DD MMM YYYY');
$('#visits-db').DataTable({
"columns": [
null,
null,
{ "type": "date" },
{ "type": "date" }
],
"lengthMenu": [ [5, 10, 25, 50, 100, -1], [5, 10, 25, 50, 100, "All"]],
"pageLength": 25,
"language": {
Expand Down
59 changes: 59 additions & 0 deletions _assets/js/vendor/dataTables.plugins.datetime_moment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* This plug-in for DataTables represents the ultimate option in extensibility
* for sorting date / time strings correctly. It uses
* [Moment.js](http://momentjs.com) to create automatic type detection and
* sorting plug-ins for DataTables based on a given format. This way, DataTables
* will automatically detect your temporal information and sort it correctly.
*
* For usage instructions, please see the DataTables blog
* post that [introduces it](//datatables.net/blog/2014-12-18).
*
* @name Ultimate Date / Time sorting
* @summary Sort date and time in any format using Moment.js
* @author [Allan Jardine](//datatables.net)
* @depends DataTables 1.10+, Moment.js 1.7+
*
* @example
* $.fn.dataTable.moment( 'HH:mm MMM D, YY' );
* $.fn.dataTable.moment( 'dddd, MMMM Do, YYYY' );
*
* $('#example').DataTable();
*/

(function (factory) {
if (typeof define === "function" && define.amd) {
define(["jquery", "moment", "datatables"], factory);
} else {
factory(jQuery, moment);
}
}(function ($, moment) {

$.fn.dataTable.moment = function ( format, locale ) {
var types = $.fn.dataTable.ext.type;

// Add type detection
types.detect.unshift( function ( d ) {
// Strip HTML tags if possible
if ( d && d.replace ) {
d = d.replace(/<.*?>/g, '');
}

// Null and empty values are acceptable
if ( d === '' || d === null ) {
return 'moment-'+format;
}

return moment( d, format, locale, true ).isValid() ?
'moment-'+format :
null;
} );

// Add sorting method - use an integer for the sorting
types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
return d === '' || d === null ?
-Infinity :
parseInt( moment( d.replace ? d.replace(/<.*?>/g, '') : d, format, locale, true ).format( 'x' ), 10 );
};
};

}));
7 changes: 7 additions & 0 deletions _assets/js/vendor/moment.min.js

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion _data/visits.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
- from: haensel_d
to: balaji_p
start: 2015-02-04
end: 2015-02-15

- from: haensel_d
to: balaji_p
start: 2016-02-04
end: 2016-02-14
end: 2016-02-15

- from: haensel_d
to: balaji_p
start: 2015-02-04
end: 2016-02-15

- from: haensel_d
to: balaji_p
start: 2015-12-04
end: 2016-01-15
3 changes: 0 additions & 3 deletions _includes/after_footer.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
<!-- Latest compiled and minified JavaScript -->
{% js vendor/bootstrap.min.js %}
{% js vendor/jquery.dataTables.min.js %}
{% js vendor/dataTables.bootstrap.min.js %}
{% js custom %}
82 changes: 82 additions & 0 deletions _plugins/duration_tag.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module Jekyll
module Tags
class DurationTagError < StandardError
def initialize(msg)
super
end
end

class DurationPMsTagError < DurationTagError
def initialize(msg)
super(msg)
end
end

class DurationHumanizedTagError < DurationTagError
def initialize(msg)
super(msg)
end
end

class DurationTag < Liquid::Tag
SECONDS_PER_DAY = 86400

def initialize(tag_name, markup, tokens)
super
@markup = markup.strip
end

def days_from_seconds(context)
seconds = Float(Liquid::Template.parse(@markup).render(context))

if seconds < 0
raise DurationTagError.new "Invalid duration. Must be at least one second: #{seconds}"
end

(seconds / 86400) + 1
end
end

class DurationPMsTag < DurationTag
def render(context)
days = days_from_seconds(context)
"#{(days / 30.0).round(2)} PM"
end
end

class DurationHumanizedTag < DurationTag
DAYS_PER_MONTHS = 30

def days_to_s(days)
if days == 1
"#{days} day"
else
"#{days} days"
end
end

def months_to_s(months)
if months == 1
"#{months} month"
else
"#{months} months"
end
end

def render(context)
total_days = days_from_seconds(context)
days = Integer(total_days % DAYS_PER_MONTHS)
months = Integer((total_days - days) / DAYS_PER_MONTHS)

if months == 0
days_to_s(days)
else
"#{months_to_s(months)} and #{days_to_s(days)}"
end
end
end
end
end

Liquid::Template.register_tag('duration_pms', Jekyll::Tags::DurationPMsTag)
Liquid::Template.register_tag('duration_humanized', Jekyll::Tags::DurationHumanizedTag)
17 changes: 15 additions & 2 deletions research/visits.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,34 @@ subnavbar: Visits
<th class="col-host">Host</th>
<th class="col-start">From</th>
<th class="col-end">To</th>
<th class="col-pm"><abbr title="Person-Months">PM</abbr></th>
</tr>
</thead>
<tbody>
{% for visit in site.data.visits %}
{% assign visit_start_stamp = visit.start | date:"%s" %}
{% assign visit_duration = visit.end | date:"%s" | minus:visit_start_stamp %}
<tr>
<td class="col-visitor">{% person_inverse {{ visit.from }} %}</td>
<td class="col-host">{% person_inverse {{ visit.to }} %}</td>
<td class="col-start">
<time datetime="{{ visit.start | date_to_rfc822 }}">{{ visit.start | date_to_string }}</time>
{{ visit.start | date_to_string }}
</td>
<td class="col-end">
<time datetime="{{ visit.end | date_to_rfc822 }}">{{ visit.end | date_to_string }}</time>
{{ visit.end | date_to_string }}
</td>
<td class="col-pm">
<abbr title="{% duration_humanized {{ visit_duration }} %}">
{% duration_pms {{ visit_duration }} %}
</abbr>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<p class="text-muted">
The amount of <em>Person-Months</em> is computed from the start and end date of each visit with
the assumption of 30 days per month.
</p>

0 comments on commit 40fa7d3

Please sign in to comment.