2022-09-28 22:20:24 +02:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
|
|
|
|
<html>
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
|
|
|
|
|
<meta charset="utf-8" />
|
|
|
|
|
<meta name="generator" content="pandoc" />
|
|
|
|
|
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<meta name="author" content="Luis Gonzalez-Gracia (lagog6@ulaval.ca)" />
|
|
|
|
|
<meta name="author" content="Twitter - @gonzaluisandres" />
|
|
|
|
|
|
|
|
|
|
<meta name="date" content="2022-09-28" />
|
|
|
|
|
|
|
|
|
|
<title>Demo for the presentation ‘Getting insights from automatic feeder data’</title>
|
|
|
|
|
|
|
|
|
|
<script>// Pandoc 2.9 adds attributes on both header and div. We remove the former (to
|
|
|
|
|
// be compatible with the behavior of Pandoc < 2.8).
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function(e) {
|
|
|
|
|
var hs = document.querySelectorAll("div.section[class*='level'] > :first-child");
|
|
|
|
|
var i, h, a;
|
|
|
|
|
for (i = 0; i < hs.length; i++) {
|
|
|
|
|
h = hs[i];
|
|
|
|
|
if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6
|
|
|
|
|
a = h.attributes;
|
|
|
|
|
while (a.length > 0) h.removeAttribute(a[0].name);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
<script>/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
|
|
|
|
|
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e
|
|
|
|
|
</script>
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
|
<style type="text/css">html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(data:application/vnd.ms-fontobject;base64,n04AAEFNAAACAAIABAAAAAAABQAAAAAAAAABAJABAAAEAExQAAAAAAAAAAIAAAAAAAAAAAEAAAAAAAAAJxJ/LAAAAAAAAAAAAAAAAAAAAAAAACgARwBMAFkAUABIAEkAQwBPAE4AUwAgAEgAYQBsAGYAbABpAG4AZwBzAAAADgBSAGUAZwB1AGwAYQByAAAAeABWAGUAcgBzAGkAbwBuACAAMQAuADAAMAA5ADsAUABTACAAMAAwADEALgAwADAAOQA7AGgAbwB0AGMAbwBuAHYAIAAxAC4AMAAuADcAMAA7AG0AYQBrAGUAbwB0AGYALgBsAGkAYgAyAC4ANQAuADUAOAAzADIAOQAAADgARwBMAFkAUABIAEkAQwBPAE4AUwAgAEgAYQBsAGYAbABpAG4AZwBzACAAUgBlAGcAdQBsAGEAcgAAAAAAQlNHUAAAAAAAAAAAAAAAAAAAAAADAKncAE0TAE0ZAEbuFM3pjM/SEdmjKHUbyow8ATBE40IvWA3vTu8LiABDQ+pexwUMcm1SMnNryctQSiI1K5ZnbOlXKmnVV5YvRe6RnNMFNCOs1KNVpn6yZhCJkRtVRNzEufeIq7HgSrcx4S8h/v4vnrrKc6oCNxmSk2uKlZQHBii6iKFoH0746ThvkO1kJHlxjrkxs+LWORaDQBEtiYJIR5IB9Bi1UyL4Rmr0BNigNkMzlKQmnofBHviqVzUxwdMb3NdCn69hy+pRYVKGVS/1tnsqv4LL7wCCPZZAZPT4aCShHjHJVNuXbmMrY5LeQaGnvAkXlVrJgKRAUdFjrWEah9XebPeQMj7KS7DIBAFt8ycgC5PLGUOHSE3ErGZCiViNLL5ZARfywnCoZaKQCu6NuFX42AEeKtKUGnr/Cm2Cy8tpFhBPMW5Fxi4Qm4TkDWh4IWFDClhU2hRWosUWqcKLlgyXB+lSHaWaHiWlBAR8SeSgSPCQxdVQgzUixWKSTrIQEbU94viDctkvX+VSjJuUmV8L4CXShI11esnp0pjWNZIyxKHS4wVQ2ime1P4RnhvGw0aDN1OLAXGERsB7buFpFGGBAre4QEQR0HOIO5oYH305G+KspT/FupEGGafCCwxSe6ZUa+073rXHnNdVXE6eW
|
|
|
|
|
</style>
|
|
|
|
|
<script>/*!
|
|
|
|
|
* Bootstrap v3.3.5 (http://getbootstrap.com)
|
|
|
|
|
* Copyright 2011-2015 Twitter, Inc.
|
|
|
|
|
* Licensed under the MIT license
|
|
|
|
|
*/
|
|
|
|
|
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==type
|
|
|
|
|
d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.5",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affi
|
|
|
|
|
<script>/**
|
|
|
|
|
* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
|
|
|
|
*/
|
|
|
|
|
// Only run this code in IE 8
|
|
|
|
|
if (!!window.navigator.userAgent.match("MSIE 8")) {
|
|
|
|
|
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<script>/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
|
|
|
|
|
* Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
|
|
|
|
|
* */
|
|
|
|
|
|
|
|
|
|
// Only run this code in IE 8
|
|
|
|
|
if (!!window.navigator.userAgent.match("MSIE 8")) {
|
|
|
|
|
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='­<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmVal
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<style>h1 {font-size: 34px;}
|
|
|
|
|
h1.title {font-size: 38px;}
|
|
|
|
|
h2 {font-size: 30px;}
|
|
|
|
|
h3 {font-size: 24px;}
|
|
|
|
|
h4 {font-size: 18px;}
|
|
|
|
|
h5 {font-size: 16px;}
|
|
|
|
|
h6 {font-size: 12px;}
|
|
|
|
|
code {color: inherit; background-color: rgba(0, 0, 0, 0.04);}
|
|
|
|
|
pre:not([class]) { background-color: white }</style>
|
|
|
|
|
<style type="text/css">.pagedtable {
|
|
|
|
|
overflow: auto;
|
|
|
|
|
padding-left: 8px;
|
|
|
|
|
padding-right: 8px;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-wrapper {
|
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable table {
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable th {
|
|
|
|
|
padding: 0 5px 0 5px;
|
|
|
|
|
border: none;
|
|
|
|
|
border-bottom: 2px solid #dddddd;
|
|
|
|
|
min-width: 45px;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-empty th {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable td {
|
|
|
|
|
padding: 0 4px 0 4px;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable .even {
|
|
|
|
|
background-color: rgba(140, 140, 140, 0.1);
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-padding-col {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable a {
|
|
|
|
|
-webkit-touch-callout: none;
|
|
|
|
|
-webkit-user-select: none;
|
|
|
|
|
-khtml-user-select: none;
|
|
|
|
|
-moz-user-select: none;
|
|
|
|
|
-ms-user-select: none;
|
|
|
|
|
user-select: none;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-index-nav {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
padding: 0 5px 0 5px;
|
|
|
|
|
float: right;
|
|
|
|
|
border: 0;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-index-nav-disabled {
|
|
|
|
|
cursor: default;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
color: #999;
|
|
|
|
|
}
|
|
|
|
|
a.pagedtable-index-nav-disabled:hover {
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
color: #999;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-indexes {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
float: right;
|
|
|
|
|
border: 0;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-index-current {
|
|
|
|
|
cursor: default;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: #333;
|
|
|
|
|
border: 0;
|
|
|
|
|
}
|
|
|
|
|
a.pagedtable-index-current:hover {
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-index {
|
|
|
|
|
width: 30px;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
text-align: center;
|
|
|
|
|
border: 0;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-index-separator-left {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
color: #333;
|
|
|
|
|
font-size: 9px;
|
|
|
|
|
padding: 0 0 0 0;
|
|
|
|
|
cursor: default;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-index-separator-right {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
color: #333;
|
|
|
|
|
font-size: 9px;
|
|
|
|
|
padding: 0 4px 0 0;
|
|
|
|
|
cursor: default;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-footer {
|
|
|
|
|
padding-top: 4px;
|
|
|
|
|
padding-bottom: 5px;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-not-empty .pagedtable-footer {
|
|
|
|
|
border-top: 2px solid #dddddd;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-info {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
color: #999;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-header-name {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-header-type {
|
|
|
|
|
color: #999;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
}
|
|
|
|
|
.pagedtable-na-cell {
|
|
|
|
|
font-style: italic;
|
|
|
|
|
opacity: 0.3;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<script>// Production steps of ECMA-262, Edition 5, 15.4.4.18
|
|
|
|
|
// Reference: http://es5.github.io/#x15.4.4.18
|
|
|
|
|
if (!Array.prototype.forEach) {
|
|
|
|
|
|
|
|
|
|
Array.prototype.forEach = function(callback, thisArg) {
|
|
|
|
|
|
|
|
|
|
var T, k;
|
|
|
|
|
|
|
|
|
|
if (this === null) {
|
|
|
|
|
throw new TypeError(' this is null or not defined');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1. Let O be the result of calling toObject() passing the
|
|
|
|
|
// |this| value as the argument.
|
|
|
|
|
var O = Object(this);
|
|
|
|
|
|
|
|
|
|
// 2. Let lenValue be the result of calling the Get() internal
|
|
|
|
|
// method of O with the argument "length".
|
|
|
|
|
// 3. Let len be toUint32(lenValue).
|
|
|
|
|
var len = O.length >>> 0;
|
|
|
|
|
|
|
|
|
|
// 4. If isCallable(callback) is false, throw a TypeError exception.
|
|
|
|
|
// See: http://es5.github.com/#x9.11
|
|
|
|
|
if (typeof callback !== "function") {
|
|
|
|
|
throw new TypeError(callback + ' is not a function');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 5. If thisArg was supplied, let T be thisArg; else let
|
|
|
|
|
// T be undefined.
|
|
|
|
|
if (arguments.length > 1) {
|
|
|
|
|
T = thisArg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 6. Let k be 0
|
|
|
|
|
k = 0;
|
|
|
|
|
|
|
|
|
|
// 7. Repeat, while k < len
|
|
|
|
|
while (k < len) {
|
|
|
|
|
|
|
|
|
|
var kValue;
|
|
|
|
|
|
|
|
|
|
// a. Let Pk be ToString(k).
|
|
|
|
|
// This is implicit for LHS operands of the in operator
|
|
|
|
|
// b. Let kPresent be the result of calling the HasProperty
|
|
|
|
|
// internal method of O with argument Pk.
|
|
|
|
|
// This step can be combined with c
|
|
|
|
|
// c. If kPresent is true, then
|
|
|
|
|
if (k in O) {
|
|
|
|
|
|
|
|
|
|
// i. Let kValue be the result of calling the Get internal
|
|
|
|
|
// method of O with argument Pk.
|
|
|
|
|
kValue = O[k];
|
|
|
|
|
|
|
|
|
|
// ii. Call the Call internal method of callback with T as
|
|
|
|
|
// the this value and argument list containing kValue, k, and O.
|
|
|
|
|
callback.call(T, kValue, k, O);
|
|
|
|
|
}
|
|
|
|
|
// d. Increase k by 1.
|
|
|
|
|
k++;
|
|
|
|
|
}
|
|
|
|
|
// 8. return undefined
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
|
|
|
|
// Reference: http://es5.github.io/#x15.4.4.19
|
|
|
|
|
if (!Array.prototype.map) {
|
|
|
|
|
|
|
|
|
|
Array.prototype.map = function(callback, thisArg) {
|
|
|
|
|
|
|
|
|
|
var T, A, k;
|
|
|
|
|
|
|
|
|
|
if (this == null) {
|
|
|
|
|
throw new TypeError(' this is null or not defined');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1. Let O be the result of calling ToObject passing the |this|
|
|
|
|
|
// value as the argument.
|
|
|
|
|
var O = Object(this);
|
|
|
|
|
|
|
|
|
|
// 2. Let lenValue be the result of calling the Get internal
|
|
|
|
|
// method of O with the argument "length".
|
|
|
|
|
// 3. Let len be ToUint32(lenValue).
|
|
|
|
|
var len = O.length >>> 0;
|
|
|
|
|
|
|
|
|
|
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
|
|
|
|
// See: http://es5.github.com/#x9.11
|
|
|
|
|
if (typeof callback !== 'function') {
|
|
|
|
|
throw new TypeError(callback + ' is not a function');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
|
|
|
|
if (arguments.length > 1) {
|
|
|
|
|
T = thisArg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 6. Let A be a new array created as if by the expression new Array(len)
|
|
|
|
|
// where Array is the standard built-in constructor with that name and
|
|
|
|
|
// len is the value of len.
|
|
|
|
|
A = new Array(len);
|
|
|
|
|
|
|
|
|
|
// 7. Let k be 0
|
|
|
|
|
k = 0;
|
|
|
|
|
|
|
|
|
|
// 8. Repeat, while k < len
|
|
|
|
|
while (k < len) {
|
|
|
|
|
|
|
|
|
|
var kValue, mappedValue;
|
|
|
|
|
|
|
|
|
|
// a. Let Pk be ToString(k).
|
|
|
|
|
// This is implicit for LHS operands of the in operator
|
|
|
|
|
// b. Let kPresent be the result of calling the HasProperty internal
|
|
|
|
|
// method of O with argument Pk.
|
|
|
|
|
// This step can be combined with c
|
|
|
|
|
// c. If kPresent is true, then
|
|
|
|
|
if (k in O) {
|
|
|
|
|
|
|
|
|
|
// i. Let kValue be the result of calling the Get internal
|
|
|
|
|
// method of O with argument Pk.
|
|
|
|
|
kValue = O[k];
|
|
|
|
|
|
|
|
|
|
// ii. Let mappedValue be the result of calling the Call internal
|
|
|
|
|
// method of callback with T as the this value and argument
|
|
|
|
|
// list containing kValue, k, and O.
|
|
|
|
|
mappedValue = callback.call(T, kValue, k, O);
|
|
|
|
|
|
|
|
|
|
// iii. Call the DefineOwnProperty internal method of A with arguments
|
|
|
|
|
// Pk, Property Descriptor
|
|
|
|
|
// { Value: mappedValue,
|
|
|
|
|
// Writable: true,
|
|
|
|
|
// Enumerable: true,
|
|
|
|
|
// Configurable: true },
|
|
|
|
|
// and false.
|
|
|
|
|
|
|
|
|
|
// In browsers that support Object.defineProperty, use the following:
|
|
|
|
|
// Object.defineProperty(A, k, {
|
|
|
|
|
// value: mappedValue,
|
|
|
|
|
// writable: true,
|
|
|
|
|
// enumerable: true,
|
|
|
|
|
// configurable: true
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
// For best browser support, use the following:
|
|
|
|
|
A[k] = mappedValue;
|
|
|
|
|
}
|
|
|
|
|
// d. Increase k by 1.
|
|
|
|
|
k++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 9. return A
|
|
|
|
|
return A;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var PagedTable = function (pagedTable) {
|
|
|
|
|
var me = this;
|
|
|
|
|
|
|
|
|
|
var source = function(pagedTable) {
|
|
|
|
|
var sourceElems = [].slice.call(pagedTable.children).filter(function(e) {
|
|
|
|
|
return e.hasAttribute("data-pagedtable-source");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (sourceElems === null || sourceElems.length !== 1) {
|
|
|
|
|
throw("A single data-pagedtable-source was not found");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return JSON.parse(sourceElems[0].innerHTML);
|
|
|
|
|
}(pagedTable);
|
|
|
|
|
|
|
|
|
|
var options = function(source) {
|
|
|
|
|
var options = typeof(source.options) !== "undefined" &&
|
|
|
|
|
source.options !== null ? source.options : {};
|
|
|
|
|
|
|
|
|
|
var columns = typeof(options.columns) !== "undefined" ? options.columns : {};
|
|
|
|
|
var rows = typeof(options.rows) !== "undefined" ? options.rows : {};
|
|
|
|
|
|
|
|
|
|
var positiveIntOrNull = function(value) {
|
|
|
|
|
return parseInt(value) >= 0 ? parseInt(value) : null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
pages: positiveIntOrNull(options.pages),
|
|
|
|
|
rows: {
|
|
|
|
|
min: positiveIntOrNull(rows.min),
|
|
|
|
|
max: positiveIntOrNull(rows.max),
|
|
|
|
|
total: positiveIntOrNull(rows.total)
|
|
|
|
|
},
|
|
|
|
|
columns: {
|
|
|
|
|
min: positiveIntOrNull(columns.min),
|
|
|
|
|
max: positiveIntOrNull(columns.max),
|
|
|
|
|
total: positiveIntOrNull(columns.total)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}(source);
|
|
|
|
|
|
|
|
|
|
var Measurer = function() {
|
|
|
|
|
|
|
|
|
|
// set some default initial values that will get adjusted in runtime
|
|
|
|
|
me.measures = {
|
|
|
|
|
padding: 12,
|
|
|
|
|
character: 8,
|
|
|
|
|
height: 15,
|
|
|
|
|
defaults: true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.calculate = function(measuresCell) {
|
|
|
|
|
if (!me.measures.defaults)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var measuresCellStyle = window.getComputedStyle(measuresCell, null);
|
|
|
|
|
|
|
|
|
|
var newPadding = parsePadding(measuresCellStyle.paddingLeft) +
|
|
|
|
|
parsePadding(measuresCellStyle.paddingRight);
|
|
|
|
|
|
|
|
|
|
var sampleString = "ABCDEFGHIJ0123456789";
|
|
|
|
|
var newCharacter = Math.ceil(measuresCell.clientWidth / sampleString.length);
|
|
|
|
|
|
|
|
|
|
if (newPadding <= 0 || newCharacter <= 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
me.measures.padding = newPadding;
|
|
|
|
|
me.measures.character = newCharacter;
|
|
|
|
|
me.measures.height = measuresCell.clientHeight;
|
|
|
|
|
me.measures.defaults = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return me;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var Page = function(data, options) {
|
|
|
|
|
var me = this;
|
|
|
|
|
|
|
|
|
|
var defaults = {
|
|
|
|
|
max: 7,
|
|
|
|
|
rows: 10
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var totalPages = function() {
|
|
|
|
|
return Math.ceil(data.length / me.rows);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.number = 0;
|
|
|
|
|
me.max = options.pages !== null ? options.pages : defaults.max;
|
|
|
|
|
me.visible = me.max;
|
|
|
|
|
me.rows = options.rows.min !== null ? options.rows.min : defaults.rows;
|
|
|
|
|
me.total = totalPages();
|
|
|
|
|
|
|
|
|
|
me.setRows = function(newRows) {
|
|
|
|
|
me.rows = newRows;
|
|
|
|
|
me.total = totalPages();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.setPageNumber = function(newPageNumber) {
|
|
|
|
|
if (newPageNumber < 0) newPageNumber = 0;
|
|
|
|
|
if (newPageNumber >= me.total) newPageNumber = me.total - 1;
|
|
|
|
|
|
|
|
|
|
me.number = newPageNumber;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.setVisiblePages = function(visiblePages) {
|
|
|
|
|
me.visible = Math.min(me.max, visiblePages);
|
|
|
|
|
me.setPageNumber(me.number);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.getVisiblePageRange = function() {
|
|
|
|
|
var start = me.number - Math.max(Math.floor((me.visible - 1) / 2), 0);
|
|
|
|
|
var end = me.number + Math.floor(me.visible / 2) + 1;
|
|
|
|
|
var pageCount = me.total;
|
|
|
|
|
|
|
|
|
|
if (start < 0) {
|
|
|
|
|
var diffToStart = 0 - start;
|
|
|
|
|
start += diffToStart;
|
|
|
|
|
end += diffToStart;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (end > pageCount) {
|
|
|
|
|
var diffToEnd = end - pageCount;
|
|
|
|
|
start -= diffToEnd;
|
|
|
|
|
end -= diffToEnd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start = start < 0 ? 0 : start;
|
|
|
|
|
end = end >= pageCount ? pageCount : end;
|
|
|
|
|
|
|
|
|
|
var first = false;
|
|
|
|
|
var last = false;
|
|
|
|
|
|
|
|
|
|
if (start > 0 && me.visible > 1) {
|
|
|
|
|
start = start + 1;
|
|
|
|
|
first = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (end < pageCount && me.visible > 2) {
|
|
|
|
|
end = end - 1;
|
|
|
|
|
last = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
first: first,
|
|
|
|
|
start: start,
|
|
|
|
|
end: end,
|
|
|
|
|
last: last
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.getRowStart = function() {
|
|
|
|
|
var rowStart = page.number * page.rows;
|
|
|
|
|
if (rowStart < 0)
|
|
|
|
|
rowStart = 0;
|
|
|
|
|
|
|
|
|
|
return rowStart;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.getRowEnd = function() {
|
|
|
|
|
var rowStart = me.getRowStart();
|
|
|
|
|
return Math.min(rowStart + me.rows, data.length);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.getPaddingRows = function() {
|
|
|
|
|
var rowStart = me.getRowStart();
|
|
|
|
|
var rowEnd = me.getRowEnd();
|
|
|
|
|
return data.length > me.rows ? me.rows - (rowEnd - rowStart) : 0;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var Columns = function(data, columns, options) {
|
|
|
|
|
var me = this;
|
|
|
|
|
|
|
|
|
|
me.defaults = {
|
|
|
|
|
min: 5
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.number = 0;
|
|
|
|
|
me.visible = 0;
|
|
|
|
|
me.total = columns.length;
|
|
|
|
|
me.subset = [];
|
|
|
|
|
me.padding = 0;
|
|
|
|
|
me.min = options.columns.min !== null ? options.columns.min : me.defaults.min;
|
|
|
|
|
me.max = options.columns.max !== null ? options.columns.max : null;
|
|
|
|
|
me.widths = {};
|
|
|
|
|
|
|
|
|
|
var widthsLookAhead = Math.max(100, options.rows.min);
|
|
|
|
|
var paddingColChars = 10;
|
|
|
|
|
|
|
|
|
|
me.emptyNames = function() {
|
|
|
|
|
columns.forEach(function(column) {
|
|
|
|
|
if (columns.label !== null && columns.label !== "")
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var parsePadding = function(value) {
|
|
|
|
|
return parseInt(value) >= 0 ? parseInt(value) : 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.calculateWidths = function(measures) {
|
|
|
|
|
columns.forEach(function(column) {
|
|
|
|
|
var maxChars = Math.max(
|
|
|
|
|
column.label.toString().length,
|
|
|
|
|
column.type.toString().length
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (var idxRow = 0; idxRow < Math.min(widthsLookAhead, data.length); idxRow++) {
|
|
|
|
|
maxChars = Math.max(maxChars, data[idxRow][column.name.toString()].length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me.widths[column.name] = {
|
|
|
|
|
// width in characters
|
|
|
|
|
chars: maxChars,
|
|
|
|
|
// width for the inner html columns
|
|
|
|
|
inner: maxChars * measures.character,
|
|
|
|
|
// width adding outer styles like padding
|
|
|
|
|
outer: maxChars * measures.character + measures.padding
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.getWidth = function() {
|
|
|
|
|
var widthOuter = 0;
|
|
|
|
|
for (var idxCol = 0; idxCol < me.subset.length; idxCol++) {
|
|
|
|
|
var columnName = me.subset[idxCol].name;
|
|
|
|
|
widthOuter = widthOuter + me.widths[columnName].outer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
widthOuter = widthOuter + me.padding * paddingColChars * measurer.measures.character;
|
|
|
|
|
|
|
|
|
|
if (me.hasMoreLeftColumns()) {
|
|
|
|
|
widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (me.hasMoreRightColumns()) {
|
|
|
|
|
widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return widthOuter;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.updateSlice = function() {
|
|
|
|
|
if (me.number + me.visible >= me.total)
|
|
|
|
|
me.number = me.total - me.visible;
|
|
|
|
|
|
|
|
|
|
if (me.number < 0) me.number = 0;
|
|
|
|
|
|
|
|
|
|
me.subset = columns.slice(me.number, Math.min(me.number + me.visible, me.total));
|
|
|
|
|
|
|
|
|
|
me.subset = me.subset.map(function(column) {
|
|
|
|
|
Object.keys(column).forEach(function(colKey) {
|
|
|
|
|
column[colKey] = column[colKey] === null ? "" : column[colKey].toString();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
column.width = null;
|
|
|
|
|
return column;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.setVisibleColumns = function(columnNumber, newVisibleColumns, paddingCount) {
|
|
|
|
|
me.number = columnNumber;
|
|
|
|
|
me.visible = newVisibleColumns;
|
|
|
|
|
me.padding = paddingCount;
|
|
|
|
|
|
|
|
|
|
me.updateSlice();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.incColumnNumber = function(increment) {
|
|
|
|
|
me.number = me.number + increment;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.setColumnNumber = function(newNumber) {
|
|
|
|
|
me.number = newNumber;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.setPaddingCount = function(newPadding) {
|
|
|
|
|
me.padding = newPadding;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.getPaddingCount = function() {
|
|
|
|
|
return me.padding;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.hasMoreLeftColumns = function() {
|
|
|
|
|
return me.number > 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.hasMoreRightColumns = function() {
|
|
|
|
|
return me.number + me.visible < me.total;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.updateSlice(0);
|
|
|
|
|
return me;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var data = source.data;
|
|
|
|
|
var page = new Page(data, options);
|
|
|
|
|
var measurer = new Measurer(data, options);
|
|
|
|
|
var columns = new Columns(data, source.columns, options);
|
|
|
|
|
|
|
|
|
|
var table = null;
|
|
|
|
|
var tableDiv = null;
|
|
|
|
|
var header = null;
|
|
|
|
|
var footer = null;
|
|
|
|
|
var tbody = null;
|
|
|
|
|
|
|
|
|
|
// Caches pagedTable.clientWidth, specially for webkit
|
|
|
|
|
var cachedPagedTableClientWidth = null;
|
|
|
|
|
|
|
|
|
|
var onChangeCallbacks = [];
|
|
|
|
|
|
|
|
|
|
var clearSelection = function() {
|
|
|
|
|
if(document.selection && document.selection.empty) {
|
|
|
|
|
document.selection.empty();
|
|
|
|
|
} else if(window.getSelection) {
|
|
|
|
|
var sel = window.getSelection();
|
|
|
|
|
sel.removeAllRanges();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var columnNavigationWidthPX = 5;
|
|
|
|
|
|
|
|
|
|
var renderColumnNavigation = function(increment, backwards) {
|
|
|
|
|
var arrow = document.createElement("div");
|
|
|
|
|
arrow.setAttribute("style",
|
|
|
|
|
"border-top: " + columnNavigationWidthPX + "px solid transparent;" +
|
|
|
|
|
"border-bottom: " + columnNavigationWidthPX + "px solid transparent;" +
|
|
|
|
|
"border-" + (backwards ? "right" : "left") + ": " + columnNavigationWidthPX + "px solid;");
|
|
|
|
|
|
|
|
|
|
var header = document.createElement("th");
|
|
|
|
|
header.appendChild(arrow);
|
|
|
|
|
header.setAttribute("style",
|
|
|
|
|
"cursor: pointer;" +
|
|
|
|
|
"vertical-align: middle;" +
|
|
|
|
|
"min-width: " + columnNavigationWidthPX + "px;" +
|
|
|
|
|
"width: " + columnNavigationWidthPX + "px;");
|
|
|
|
|
|
|
|
|
|
header.onclick = function() {
|
|
|
|
|
columns.incColumnNumber(backwards ? -1 : increment);
|
|
|
|
|
|
|
|
|
|
me.animateColumns(backwards);
|
|
|
|
|
renderFooter();
|
|
|
|
|
|
|
|
|
|
clearSelection();
|
|
|
|
|
triggerOnChange();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return header;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var maxColumnWidth = function(width) {
|
|
|
|
|
var padding = 80;
|
|
|
|
|
var columnMax = Math.max(cachedPagedTableClientWidth - padding, 0);
|
|
|
|
|
|
|
|
|
|
return parseInt(width) > 0 ?
|
|
|
|
|
Math.min(columnMax, parseInt(width)) + "px" :
|
|
|
|
|
columnMax + "px";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var clearHeader = function() {
|
|
|
|
|
var thead = pagedTable.querySelectorAll("thead")[0];
|
|
|
|
|
thead.innerHTML = "";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var renderHeader = function(clear) {
|
|
|
|
|
cachedPagedTableClientWidth = pagedTable.clientWidth;
|
|
|
|
|
|
|
|
|
|
var fragment = document.createDocumentFragment();
|
|
|
|
|
|
|
|
|
|
header = document.createElement("tr");
|
|
|
|
|
fragment.appendChild(header);
|
|
|
|
|
|
|
|
|
|
if (columns.number > 0)
|
|
|
|
|
header.appendChild(renderColumnNavigation(-columns.visible, true));
|
|
|
|
|
|
|
|
|
|
columns.subset = columns.subset.map(function(columnData) {
|
|
|
|
|
var column = document.createElement("th");
|
|
|
|
|
column.setAttribute("align", columnData.align);
|
|
|
|
|
column.style.textAlign = columnData.align;
|
|
|
|
|
|
|
|
|
|
column.style.maxWidth = maxColumnWidth(null);
|
|
|
|
|
if (columnData.width) {
|
|
|
|
|
column.style.minWidth =
|
|
|
|
|
column.style.maxWidth = maxColumnWidth(columnData.width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var columnName = document.createElement("div");
|
|
|
|
|
columnName.setAttribute("class", "pagedtable-header-name");
|
|
|
|
|
if (columnData.label === "") {
|
|
|
|
|
columnName.innerHTML = " ";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
columnName.appendChild(document.createTextNode(columnData.label));
|
|
|
|
|
}
|
|
|
|
|
column.appendChild(columnName);
|
|
|
|
|
|
|
|
|
|
var columnType = document.createElement("div");
|
|
|
|
|
columnType.setAttribute("class", "pagedtable-header-type");
|
|
|
|
|
if (columnData.type === "") {
|
|
|
|
|
columnType.innerHTML = " ";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
columnType.appendChild(document.createTextNode("<" + columnData.type + ">"));
|
|
|
|
|
}
|
|
|
|
|
column.appendChild(columnType);
|
|
|
|
|
|
|
|
|
|
header.appendChild(column);
|
|
|
|
|
|
|
|
|
|
columnData.element = column;
|
|
|
|
|
|
|
|
|
|
return columnData;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (var idx = 0; idx < columns.getPaddingCount(); idx++) {
|
|
|
|
|
var paddingCol = document.createElement("th");
|
|
|
|
|
paddingCol.setAttribute("class", "pagedtable-padding-col");
|
|
|
|
|
header.appendChild(paddingCol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (columns.number + columns.visible < columns.total)
|
|
|
|
|
header.appendChild(renderColumnNavigation(columns.visible, false));
|
|
|
|
|
|
|
|
|
|
if (typeof(clear) == "undefined" || clear) clearHeader();
|
|
|
|
|
var thead = pagedTable.querySelectorAll("thead")[0];
|
|
|
|
|
thead.appendChild(fragment);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.animateColumns = function(backwards) {
|
|
|
|
|
var thead = pagedTable.querySelectorAll("thead")[0];
|
|
|
|
|
|
|
|
|
|
var headerOld = thead.querySelectorAll("tr")[0];
|
|
|
|
|
var tbodyOld = table.querySelectorAll("tbody")[0];
|
|
|
|
|
|
|
|
|
|
me.fitColumns(backwards);
|
|
|
|
|
|
|
|
|
|
renderHeader(false);
|
|
|
|
|
|
|
|
|
|
header.style.opacity = "0";
|
|
|
|
|
header.style.transform = backwards ? "translateX(-30px)" : "translateX(30px)";
|
|
|
|
|
header.style.transition = "transform 200ms linear, opacity 200ms";
|
|
|
|
|
header.style.transitionDelay = "0";
|
|
|
|
|
|
|
|
|
|
renderBody(false);
|
|
|
|
|
|
|
|
|
|
if (headerOld) {
|
|
|
|
|
headerOld.style.position = "absolute";
|
|
|
|
|
headerOld.style.transform = "translateX(0px)";
|
|
|
|
|
headerOld.style.opacity = "1";
|
|
|
|
|
headerOld.style.transition = "transform 100ms linear, opacity 100ms";
|
|
|
|
|
headerOld.setAttribute("class", "pagedtable-remove-head");
|
|
|
|
|
if (headerOld.style.transitionEnd) {
|
|
|
|
|
headerOld.addEventListener("transitionend", function() {
|
|
|
|
|
var headerOldByClass = thead.querySelector(".pagedtable-remove-head");
|
|
|
|
|
if (headerOldByClass) thead.removeChild(headerOldByClass);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
thead.removeChild(headerOld);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tbodyOld) table.removeChild(tbodyOld);
|
|
|
|
|
|
|
|
|
|
tbody.style.opacity = "0";
|
|
|
|
|
tbody.style.transition = "transform 200ms linear, opacity 200ms";
|
|
|
|
|
tbody.style.transitionDelay = "0ms";
|
|
|
|
|
|
|
|
|
|
// force relayout
|
|
|
|
|
window.getComputedStyle(header).opacity;
|
|
|
|
|
window.getComputedStyle(tbody).opacity;
|
|
|
|
|
|
|
|
|
|
if (headerOld) {
|
|
|
|
|
headerOld.style.transform = backwards ? "translateX(20px)" : "translateX(-30px)";
|
|
|
|
|
headerOld.style.opacity = "0";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
header.style.transform = "translateX(0px)";
|
|
|
|
|
header.style.opacity = "1";
|
|
|
|
|
|
|
|
|
|
tbody.style.opacity = "1";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me.onChange = function(callback) {
|
|
|
|
|
onChangeCallbacks.push(callback);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var triggerOnChange = function() {
|
|
|
|
|
onChangeCallbacks.forEach(function(onChange) {
|
|
|
|
|
onChange();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var clearBody = function() {
|
|
|
|
|
if (tbody) {
|
|
|
|
|
table.removeChild(tbody);
|
|
|
|
|
tbody = null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var renderBody = function(clear) {
|
|
|
|
|
cachedPagedTableClientWidth = pagedTable.clientWidth
|
|
|
|
|
|
|
|
|
|
var fragment = document.createDocumentFragment();
|
|
|
|
|
|
|
|
|
|
var pageData = data.slice(page.getRowStart(), page.getRowEnd());
|
|
|
|
|
|
|
|
|
|
pageData.forEach(function(dataRow, idxRow) {
|
|
|
|
|
var htmlRow = document.createElement("tr");
|
|
|
|
|
htmlRow.setAttribute("class", (idxRow % 2 !==0) ? "even" : "odd");
|
|
|
|
|
|
|
|
|
|
if (columns.hasMoreLeftColumns())
|
|
|
|
|
htmlRow.appendChild(document.createElement("td"));
|
|
|
|
|
|
|
|
|
|
columns.subset.forEach(function(columnData) {
|
|
|
|
|
var cellName = columnData.name;
|
|
|
|
|
var dataCell = dataRow[cellName];
|
|
|
|
|
var htmlCell = document.createElement("td");
|
|
|
|
|
|
|
|
|
|
if (dataCell === "NA") htmlCell.setAttribute("class", "pagedtable-na-cell");
|
|
|
|
|
if (dataCell === "__NA__") dataCell = "NA";
|
|
|
|
|
|
|
|
|
|
var cellText = document.createTextNode(dataCell);
|
|
|
|
|
htmlCell.appendChild(cellText);
|
|
|
|
|
if (dataCell.length > 50) {
|
|
|
|
|
htmlCell.setAttribute("title", dataCell);
|
|
|
|
|
}
|
|
|
|
|
htmlCell.setAttribute("align", columnData.align);
|
|
|
|
|
htmlCell.style.textAlign = columnData.align;
|
|
|
|
|
htmlCell.style.maxWidth = maxColumnWidth(null);
|
|
|
|
|
if (columnData.width) {
|
|
|
|
|
htmlCell.style.minWidth = htmlCell.style.maxWidth = maxColumnWidth(columnData.width);
|
|
|
|
|
}
|
|
|
|
|
htmlRow.appendChild(htmlCell);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (var idx = 0; idx < columns.getPaddingCount(); idx++) {
|
|
|
|
|
var paddingCol = document.createElement("td");
|
|
|
|
|
paddingCol.setAttribute("class", "pagedtable-padding-col");
|
|
|
|
|
htmlRow.appendChild(paddingCol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (columns.hasMoreRightColumns())
|
|
|
|
|
htmlRow.appendChild(document.createElement("td"));
|
|
|
|
|
|
|
|
|
|
fragment.appendChild(htmlRow);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (var idxPadding = 0; idxPadding < page.getPaddingRows(); idxPadding++) {
|
|
|
|
|
var paddingRow = document.createElement("tr");
|
|
|
|
|
|
|
|
|
|
var paddingCellRow = document.createElement("td");
|
|
|
|
|
paddingCellRow.innerHTML = " ";
|
|
|
|
|
paddingCellRow.setAttribute("colspan", "100%");
|
|
|
|
|
paddingRow.appendChild(paddingCellRow);
|
|
|
|
|
|
|
|
|
|
fragment.appendChild(paddingRow);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof(clear) == "undefined" || clear) clearBody();
|
|
|
|
|
tbody = document.createElement("tbody");
|
|
|
|
|
tbody.appendChild(fragment);
|
|
|
|
|
|
|
|
|
|
table.appendChild(tbody);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var getLabelInfo = function() {
|
|
|
|
|
var pageStart = page.getRowStart();
|
|
|
|
|
var pageEnd = page.getRowEnd();
|
|
|
|
|
var totalRows = data.length;
|
|
|
|
|
|
|
|
|
|
var totalRowsLabel = options.rows.total ? options.rows.total : totalRows;
|
|
|
|
|
var totalRowsLabelFormat = totalRowsLabel.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
|
|
|
|
|
|
|
|
|
|
var infoText = (pageStart + 1) + "-" + pageEnd + " of " + totalRowsLabelFormat + " rows";
|
|
|
|
|
if (totalRows < page.rows) {
|
|
|
|
|
infoText = totalRowsLabel + " row" + (totalRows != 1 ? "s" : "");
|
|
|
|
|
}
|
|
|
|
|
if (columns.total > columns.visible) {
|
|
|
|
|
var totalColumnsLabel = options.columns.total ? options.columns.total : columns.total;
|
|
|
|
|
|
|
|
|
|
infoText = infoText + " | " + (columns.number + 1) + "-" +
|
|
|
|
|
(Math.min(columns.number + columns.visible, columns.total)) +
|
|
|
|
|
" of " + totalColumnsLabel + " columns";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return infoText;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var clearFooter = function() {
|
|
|
|
|
footer = pagedTable.querySelectorAll("div.pagedtable-footer")[0];
|
|
|
|
|
footer.innerHTML = "";
|
|
|
|
|
|
|
|
|
|
return footer;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var createPageLink = function(idxPage) {
|
|
|
|
|
var pageLink = document.createElement("a");
|
|
|
|
|
pageLinkClass = idxPage === page.number ? "pagedtable-index pagedtable-index-current" : "pagedtable-index";
|
|
|
|
|
pageLink.setAttribute("class", pageLinkClass);
|
|
|
|
|
pageLink.setAttribute("data-page-index", idxPage);
|
|
|
|
|
pageLink.onclick = function() {
|
|
|
|
|
page.setPageNumber(parseInt(this.getAttribute("data-page-index")));
|
|
|
|
|
renderBody();
|
|
|
|
|
renderFooter();
|
|
|
|
|
|
|
|
|
|
triggerOnChange();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pageLink.appendChild(document.createTextNode(idxPage + 1));
|
|
|
|
|
|
|
|
|
|
return pageLink;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var renderFooter = function() {
|
|
|
|
|
footer = clearFooter();
|
|
|
|
|
|
|
|
|
|
var next = document.createElement("a");
|
|
|
|
|
next.appendChild(document.createTextNode("Next"));
|
|
|
|
|
next.onclick = function() {
|
|
|
|
|
page.setPageNumber(page.number + 1);
|
|
|
|
|
renderBody();
|
|
|
|
|
renderFooter();
|
|
|
|
|
|
|
|
|
|
triggerOnChange();
|
|
|
|
|
};
|
|
|
|
|
if (data.length > page.rows) footer.appendChild(next);
|
|
|
|
|
|
|
|
|
|
var pageNumbers = document.createElement("div");
|
|
|
|
|
pageNumbers.setAttribute("class", "pagedtable-indexes");
|
|
|
|
|
|
|
|
|
|
var pageRange = page.getVisiblePageRange();
|
|
|
|
|
|
|
|
|
|
if (pageRange.first) {
|
|
|
|
|
var pageLink = createPageLink(0);
|
|
|
|
|
pageNumbers.appendChild(pageLink);
|
|
|
|
|
|
|
|
|
|
var pageSeparator = document.createElement("div");
|
|
|
|
|
pageSeparator.setAttribute("class", "pagedtable-index-separator-left");
|
|
|
|
|
pageSeparator.appendChild(document.createTextNode("..."))
|
|
|
|
|
pageNumbers.appendChild(pageSeparator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var idxPage = pageRange.start; idxPage < pageRange.end; idxPage++) {
|
|
|
|
|
var pageLink = createPageLink(idxPage);
|
|
|
|
|
|
|
|
|
|
pageNumbers.appendChild(pageLink);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pageRange.last) {
|
|
|
|
|
var pageSeparator = document.createElement("div");
|
|
|
|
|
pageSeparator.setAttribute("class", "pagedtable-index-separator-right");
|
|
|
|
|
pageSeparator.appendChild(document.createTextNode("..."))
|
|
|
|
|
pageNumbers.appendChild(pageSeparator);
|
|
|
|
|
|
|
|
|
|
var pageLink = createPageLink(page.total - 1);
|
|
|
|
|
pageNumbers.appendChild(pageLink);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data.length > page.rows) footer.appendChild(pageNumbers);
|
|
|
|
|
|
|
|
|
|
var previous = document.createElement("a");
|
|
|
|
|
previous.appendChild(document.createTextNode("Previous"));
|
|
|
|
|
previous.onclick = function() {
|
|
|
|
|
page.setPageNumber(page.number - 1);
|
|
|
|
|
renderBody();
|
|
|
|
|
renderFooter();
|
|
|
|
|
|
|
|
|
|
triggerOnChange();
|
|
|
|
|
};
|
|
|
|
|
if (data.length > page.rows) footer.appendChild(previous);
|
|
|
|
|
|
|
|
|
|
var infoLabel = document.createElement("div");
|
|
|
|
|
infoLabel.setAttribute("class", "pagedtable-info");
|
|
|
|
|
infoLabel.setAttribute("title", getLabelInfo());
|
|
|
|
|
infoLabel.appendChild(document.createTextNode(getLabelInfo()));
|
|
|
|
|
footer.appendChild(infoLabel);
|
|
|
|
|
|
|
|
|
|
var enabledClass = "pagedtable-index-nav";
|
|
|
|
|
var disabledClass = "pagedtable-index-nav pagedtable-index-nav-disabled";
|
|
|
|
|
previous.setAttribute("class", page.number <= 0 ? disabledClass : enabledClass);
|
|
|
|
|
next.setAttribute("class", (page.number + 1) * page.rows >= data.length ? disabledClass : enabledClass);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var measuresCell = null;
|
|
|
|
|
|
|
|
|
|
var renderMeasures = function() {
|
|
|
|
|
var measuresTable = document.createElement("table");
|
|
|
|
|
measuresTable.style.visibility = "hidden";
|
|
|
|
|
measuresTable.style.position = "absolute";
|
|
|
|
|
measuresTable.style.whiteSpace = "nowrap";
|
|
|
|
|
measuresTable.style.height = "auto";
|
|
|
|
|
measuresTable.style.width = "auto";
|
|
|
|
|
|
|
|
|
|
var measuresRow = document.createElement("tr");
|
|
|
|
|
measuresTable.appendChild(measuresRow);
|
|
|
|
|
|
|
|
|
|
measuresCell = document.createElement("td");
|
|
|
|
|
var sampleString = "ABCDEFGHIJ0123456789";
|
|
|
|
|
measuresCell.appendChild(document.createTextNode(sampleString));
|
|
|
|
|
|
|
|
|
|
measuresRow.appendChild(measuresCell);
|
|
|
|
|
|
|
|
|
|
tableDiv.appendChild(measuresTable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me.init = function() {
|
|
|
|
|
tableDiv = document.createElement("div");
|
|
|
|
|
pagedTable.appendChild(tableDiv);
|
|
|
|
|
var pagedTableClass = data.length > 0 ?
|
|
|
|
|
"pagedtable pagedtable-not-empty" :
|
|
|
|
|
"pagedtable pagedtable-empty";
|
|
|
|
|
|
|
|
|
|
if (columns.total == 0 || (columns.emptyNames() && data.length == 0)) {
|
|
|
|
|
pagedTableClass = pagedTableClass + " pagedtable-empty-columns";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tableDiv.setAttribute("class", pagedTableClass);
|
|
|
|
|
|
|
|
|
|
renderMeasures();
|
|
|
|
|
measurer.calculate(measuresCell);
|
|
|
|
|
columns.calculateWidths(measurer.measures);
|
|
|
|
|
|
|
|
|
|
table = document.createElement("table");
|
|
|
|
|
table.setAttribute("cellspacing", "0");
|
|
|
|
|
table.setAttribute("class", "table table-condensed");
|
|
|
|
|
tableDiv.appendChild(table);
|
|
|
|
|
|
|
|
|
|
table.appendChild(document.createElement("thead"));
|
|
|
|
|
|
|
|
|
|
var footerDiv = document.createElement("div");
|
|
|
|
|
footerDiv.setAttribute("class", "pagedtable-footer");
|
|
|
|
|
tableDiv.appendChild(footerDiv);
|
|
|
|
|
|
|
|
|
|
// if the host has not yet provided horizontal space, render hidden
|
|
|
|
|
if (tableDiv.clientWidth <= 0) {
|
|
|
|
|
tableDiv.style.opacity = "0";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me.render();
|
|
|
|
|
|
|
|
|
|
// retry seizing columns later if the host has not provided space
|
|
|
|
|
function retryFit() {
|
|
|
|
|
if (tableDiv.clientWidth <= 0) {
|
|
|
|
|
setTimeout(retryFit, 100);
|
|
|
|
|
} else {
|
|
|
|
|
me.render();
|
|
|
|
|
triggerOnChange();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (tableDiv.clientWidth <= 0) {
|
|
|
|
|
retryFit();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var registerWidths = function() {
|
|
|
|
|
columns.subset = columns.subset.map(function(column) {
|
|
|
|
|
column.width = columns.widths[column.name].inner;
|
|
|
|
|
return column;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var parsePadding = function(value) {
|
|
|
|
|
return parseInt(value) >= 0 ? parseInt(value) : 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.fixedHeight = function() {
|
|
|
|
|
return options.rows.max != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me.fitRows = function() {
|
|
|
|
|
if (me.fixedHeight())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
measurer.calculate(measuresCell);
|
|
|
|
|
|
|
|
|
|
var rows = options.rows.min !== null ? options.rows.min : 0;
|
|
|
|
|
var headerHeight = header !== null && header.offsetHeight > 0 ? header.offsetHeight : 0;
|
|
|
|
|
var footerHeight = footer !== null && footer.offsetHeight > 0 ? footer.offsetHeight : 0;
|
|
|
|
|
|
|
|
|
|
if (pagedTable.offsetHeight > 0) {
|
|
|
|
|
var availableHeight = pagedTable.offsetHeight - headerHeight - footerHeight;
|
|
|
|
|
rows = Math.floor((availableHeight) / measurer.measures.height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows = options.rows.min !== null ? Math.max(options.rows.min, rows) : rows;
|
|
|
|
|
|
|
|
|
|
page.setRows(rows);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The goal of this function is to add as many columns as possible
|
|
|
|
|
// starting from left-to-right, when the right most limit is reached
|
|
|
|
|
// it tries to add columns from the left as well.
|
|
|
|
|
//
|
|
|
|
|
// When startBackwards is true columns are added from right-to-left
|
|
|
|
|
me.fitColumns = function(startBackwards) {
|
|
|
|
|
measurer.calculate(measuresCell);
|
|
|
|
|
columns.calculateWidths(measurer.measures);
|
|
|
|
|
|
|
|
|
|
if (tableDiv.clientWidth > 0) {
|
|
|
|
|
tableDiv.style.opacity = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var visibleColumns = tableDiv.clientWidth <= 0 ? Math.max(columns.min, 1) : 1;
|
|
|
|
|
var columnNumber = columns.number;
|
|
|
|
|
var paddingCount = 0;
|
|
|
|
|
|
|
|
|
|
// track a list of added columns as we build the visible ones to allow us
|
|
|
|
|
// to remove columns when they don't fit anymore.
|
|
|
|
|
var columnHistory = [];
|
|
|
|
|
|
|
|
|
|
var lastTableHeight = 0;
|
|
|
|
|
var backwards = startBackwards;
|
|
|
|
|
|
|
|
|
|
var tableDivStyle = window.getComputedStyle(tableDiv, null);
|
|
|
|
|
var tableDivPadding = parsePadding(tableDivStyle.paddingLeft) +
|
|
|
|
|
parsePadding(tableDivStyle.paddingRight);
|
|
|
|
|
|
|
|
|
|
var addPaddingCol = false;
|
|
|
|
|
var currentWidth = 0;
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
columns.setVisibleColumns(columnNumber, visibleColumns, paddingCount);
|
|
|
|
|
currentWidth = columns.getWidth();
|
|
|
|
|
|
|
|
|
|
if (tableDiv.clientWidth - tableDivPadding < currentWidth) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
columnHistory.push({
|
|
|
|
|
columnNumber: columnNumber,
|
|
|
|
|
visibleColumns: visibleColumns,
|
|
|
|
|
paddingCount: paddingCount
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (columnHistory.length > 100) {
|
|
|
|
|
console.error("More than 100 tries to fit columns, aborting");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (columns.max !== null &&
|
|
|
|
|
columns.visible + columns.getPaddingCount() >= columns.max) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we run out of right-columns
|
|
|
|
|
if (!backwards && columnNumber + columns.visible >= columns.total) {
|
|
|
|
|
// if we started adding right-columns, try adding left-columns
|
|
|
|
|
if (!startBackwards && columnNumber > 0) {
|
|
|
|
|
backwards = true;
|
|
|
|
|
}
|
|
|
|
|
else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
paddingCount = paddingCount + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we run out of left-columns
|
|
|
|
|
if (backwards && columnNumber == 0) {
|
|
|
|
|
// if we started adding left-columns, try adding right-columns
|
|
|
|
|
if (startBackwards && columnNumber + columns.visible < columns.total) {
|
|
|
|
|
backwards = false;
|
|
|
|
|
}
|
|
|
|
|
else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
paddingCount = paddingCount + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// when moving backwards try fitting left columns first
|
|
|
|
|
if (backwards && columnNumber > 0) {
|
|
|
|
|
columnNumber = columnNumber - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (columnNumber + visibleColumns < columns.total) {
|
|
|
|
|
visibleColumns = visibleColumns + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var lastRenderableColumn = {
|
|
|
|
|
columnNumber: columnNumber,
|
|
|
|
|
visibleColumns: visibleColumns,
|
|
|
|
|
paddingCount: paddingCount
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (columnHistory.length > 0) {
|
|
|
|
|
lastRenderableColumn = columnHistory[columnHistory.length - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
columns.setVisibleColumns(
|
|
|
|
|
lastRenderableColumn.columnNumber,
|
|
|
|
|
lastRenderableColumn.visibleColumns,
|
|
|
|
|
lastRenderableColumn.paddingCount);
|
|
|
|
|
|
|
|
|
|
if (pagedTable.offsetWidth > 0) {
|
|
|
|
|
page.setVisiblePages(Math.max(Math.ceil(1.0 * (pagedTable.offsetWidth - 250) / 40), 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
registerWidths();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
me.fit = function(startBackwards) {
|
|
|
|
|
me.fitRows();
|
|
|
|
|
me.fitColumns(startBackwards);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me.render = function() {
|
|
|
|
|
me.fitColumns(false);
|
|
|
|
|
|
|
|
|
|
// render header/footer to measure height accurately
|
|
|
|
|
renderHeader();
|
|
|
|
|
renderFooter();
|
|
|
|
|
|
|
|
|
|
me.fitRows();
|
|
|
|
|
renderBody();
|
|
|
|
|
|
|
|
|
|
// re-render footer to match new rows
|
|
|
|
|
renderFooter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var resizeLastWidth = -1;
|
|
|
|
|
var resizeLastHeight = -1;
|
|
|
|
|
var resizeNewWidth = -1;
|
|
|
|
|
var resizeNewHeight = -1;
|
|
|
|
|
var resizePending = false;
|
|
|
|
|
|
|
|
|
|
me.resize = function(newWidth, newHeight) {
|
|
|
|
|
|
|
|
|
|
function resizeDelayed() {
|
|
|
|
|
resizePending = false;
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(resizeNewWidth !== resizeLastWidth) ||
|
|
|
|
|
(!me.fixedHeight() && resizeNewHeight !== resizeLastHeight)
|
|
|
|
|
) {
|
|
|
|
|
resizeLastWidth = resizeNewWidth;
|
|
|
|
|
resizeLastHeight = resizeNewHeight;
|
|
|
|
|
|
|
|
|
|
setTimeout(resizeDelayed, 200);
|
|
|
|
|
resizePending = true;
|
|
|
|
|
} else {
|
|
|
|
|
me.render();
|
|
|
|
|
triggerOnChange();
|
|
|
|
|
|
|
|
|
|
resizeLastWidth = -1;
|
|
|
|
|
resizeLastHeight = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resizeNewWidth = newWidth;
|
|
|
|
|
resizeNewHeight = newHeight;
|
|
|
|
|
|
|
|
|
|
if (!resizePending) resizeDelayed();
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var PagedTableDoc;
|
|
|
|
|
(function (PagedTableDoc) {
|
|
|
|
|
var allPagedTables = [];
|
|
|
|
|
|
|
|
|
|
PagedTableDoc.initAll = function() {
|
|
|
|
|
allPagedTables = [];
|
|
|
|
|
|
|
|
|
|
var pagedTables = [].slice.call(document.querySelectorAll('[data-pagedtable="false"],[data-pagedtable=""]'));
|
|
|
|
|
pagedTables.forEach(function(pagedTable, idx) {
|
|
|
|
|
pagedTable.setAttribute("data-pagedtable", "true");
|
|
|
|
|
pagedTable.setAttribute("pagedtable-page", 0);
|
|
|
|
|
pagedTable.setAttribute("class", "pagedtable-wrapper");
|
|
|
|
|
|
|
|
|
|
var pagedTableInstance = new PagedTable(pagedTable);
|
|
|
|
|
pagedTableInstance.init();
|
|
|
|
|
|
|
|
|
|
allPagedTables.push(pagedTableInstance);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PagedTableDoc.resizeAll = function() {
|
|
|
|
|
allPagedTables.forEach(function(pagedTable) {
|
|
|
|
|
pagedTable.render();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
window.addEventListener("resize", PagedTableDoc.resizeAll);
|
|
|
|
|
|
|
|
|
|
return PagedTableDoc;
|
|
|
|
|
})(PagedTableDoc || (PagedTableDoc = {}));
|
|
|
|
|
|
|
|
|
|
window.onload = function() {
|
|
|
|
|
PagedTableDoc.initAll();
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* jQuery Plugin: Sticky Tabs
|
|
|
|
|
*
|
|
|
|
|
* @author Aidan Lister <aidan@php.net>
|
|
|
|
|
* adapted by Ruben Arslan to activate parent tabs too
|
|
|
|
|
* http://www.aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/
|
|
|
|
|
*/
|
|
|
|
|
(function($) {
|
|
|
|
|
"use strict";
|
|
|
|
|
$.fn.rmarkdownStickyTabs = function() {
|
|
|
|
|
var context = this;
|
|
|
|
|
// Show the tab corresponding with the hash in the URL, or the first tab
|
|
|
|
|
var showStuffFromHash = function() {
|
|
|
|
|
var hash = window.location.hash;
|
|
|
|
|
var selector = hash ? 'a[href="' + hash + '"]' : 'li.active > a';
|
|
|
|
|
var $selector = $(selector, context);
|
|
|
|
|
if($selector.data('toggle') === "tab") {
|
|
|
|
|
$selector.tab('show');
|
|
|
|
|
// walk up the ancestors of this element, show any hidden tabs
|
|
|
|
|
$selector.parents('.section.tabset').each(function(i, elm) {
|
|
|
|
|
var link = $('a[href="#' + $(elm).attr('id') + '"]');
|
|
|
|
|
if(link.data('toggle') === "tab") {
|
|
|
|
|
link.tab("show");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set the correct tab when the page loads
|
|
|
|
|
showStuffFromHash(context);
|
|
|
|
|
|
|
|
|
|
// Set the correct tab when a user uses their back/forward button
|
|
|
|
|
$(window).on('hashchange', function() {
|
|
|
|
|
showStuffFromHash(context);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Change the URL when tabs are clicked
|
|
|
|
|
$('a', context).on('click', function(e) {
|
|
|
|
|
history.pushState(null, null, this.href);
|
|
|
|
|
showStuffFromHash(context);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return this;
|
|
|
|
|
};
|
|
|
|
|
}(jQuery));
|
|
|
|
|
|
|
|
|
|
window.buildTabsets = function(tocID) {
|
|
|
|
|
|
|
|
|
|
// build a tabset from a section div with the .tabset class
|
|
|
|
|
function buildTabset(tabset) {
|
|
|
|
|
|
|
|
|
|
// check for fade and pills options
|
|
|
|
|
var fade = tabset.hasClass("tabset-fade");
|
|
|
|
|
var pills = tabset.hasClass("tabset-pills");
|
|
|
|
|
var navClass = pills ? "nav-pills" : "nav-tabs";
|
|
|
|
|
|
|
|
|
|
// determine the heading level of the tabset and tabs
|
|
|
|
|
var match = tabset.attr('class').match(/level(\d) /);
|
|
|
|
|
if (match === null)
|
|
|
|
|
return;
|
|
|
|
|
var tabsetLevel = Number(match[1]);
|
|
|
|
|
var tabLevel = tabsetLevel + 1;
|
|
|
|
|
|
|
|
|
|
// find all subheadings immediately below
|
|
|
|
|
var tabs = tabset.find("div.section.level" + tabLevel);
|
|
|
|
|
if (!tabs.length)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// create tablist and tab-content elements
|
|
|
|
|
var tabList = $('<ul class="nav ' + navClass + '" role="tablist"></ul>');
|
|
|
|
|
$(tabs[0]).before(tabList);
|
|
|
|
|
var tabContent = $('<div class="tab-content"></div>');
|
|
|
|
|
$(tabs[0]).before(tabContent);
|
|
|
|
|
|
|
|
|
|
// build the tabset
|
|
|
|
|
var activeTab = 0;
|
|
|
|
|
tabs.each(function(i) {
|
|
|
|
|
|
|
|
|
|
// get the tab div
|
|
|
|
|
var tab = $(tabs[i]);
|
|
|
|
|
|
|
|
|
|
// get the id then sanitize it for use with bootstrap tabs
|
|
|
|
|
var id = tab.attr('id');
|
|
|
|
|
|
|
|
|
|
// see if this is marked as the active tab
|
|
|
|
|
if (tab.hasClass('active'))
|
|
|
|
|
activeTab = i;
|
|
|
|
|
|
|
|
|
|
// remove any table of contents entries associated with
|
|
|
|
|
// this ID (since we'll be removing the heading element)
|
|
|
|
|
$("div#" + tocID + " li a[href='#" + id + "']").parent().remove();
|
|
|
|
|
|
|
|
|
|
// sanitize the id for use with bootstrap tabs
|
|
|
|
|
id = id.replace(/[.\/?&!#<>]/g, '').replace(/\s/g, '_');
|
|
|
|
|
tab.attr('id', id);
|
|
|
|
|
|
|
|
|
|
// get the heading element within it, grab it's text, then remove it
|
|
|
|
|
var heading = tab.find('h' + tabLevel + ':first');
|
|
|
|
|
var headingText = heading.html();
|
|
|
|
|
heading.remove();
|
|
|
|
|
|
|
|
|
|
// build and append the tab list item
|
|
|
|
|
var a = $('<a role="tab" data-toggle="tab">' + headingText + '</a>');
|
|
|
|
|
a.attr('href', '#' + id);
|
|
|
|
|
a.attr('aria-controls', id);
|
|
|
|
|
var li = $('<li role="presentation"></li>');
|
|
|
|
|
li.append(a);
|
|
|
|
|
tabList.append(li);
|
|
|
|
|
|
|
|
|
|
// set it's attributes
|
|
|
|
|
tab.attr('role', 'tabpanel');
|
|
|
|
|
tab.addClass('tab-pane');
|
|
|
|
|
tab.addClass('tabbed-pane');
|
|
|
|
|
if (fade)
|
|
|
|
|
tab.addClass('fade');
|
|
|
|
|
|
|
|
|
|
// move it into the tab content div
|
|
|
|
|
tab.detach().appendTo(tabContent);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// set active tab
|
|
|
|
|
$(tabList.children('li')[activeTab]).addClass('active');
|
|
|
|
|
var active = $(tabContent.children('div.section')[activeTab]);
|
|
|
|
|
active.addClass('active');
|
|
|
|
|
if (fade)
|
|
|
|
|
active.addClass('in');
|
|
|
|
|
|
|
|
|
|
if (tabset.hasClass("tabset-sticky"))
|
|
|
|
|
tabset.rmarkdownStickyTabs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// convert section divs with the .tabset class to tabsets
|
|
|
|
|
var tabsets = $("div.section.tabset");
|
|
|
|
|
tabsets.each(function(i) {
|
|
|
|
|
buildTabset($(tabsets[i]));
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
<script>
|
|
|
|
|
window.initializeCodeFolding = function(show) {
|
|
|
|
|
|
|
|
|
|
// handlers for show-all and hide all
|
|
|
|
|
$("#rmd-show-all-code").click(function() {
|
|
|
|
|
$('div.r-code-collapse').each(function() {
|
|
|
|
|
$(this).collapse('show');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
$("#rmd-hide-all-code").click(function() {
|
|
|
|
|
$('div.r-code-collapse').each(function() {
|
|
|
|
|
$(this).collapse('hide');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// index for unique code element ids
|
|
|
|
|
var currentIndex = 1;
|
|
|
|
|
|
|
|
|
|
// select all R code blocks
|
|
|
|
|
var rCodeBlocks = $('pre.r, pre.python, pre.bash, pre.sql, pre.cpp, pre.stan, pre.julia, pre.foldable');
|
|
|
|
|
rCodeBlocks.each(function() {
|
|
|
|
|
// skip if the block has fold-none class
|
|
|
|
|
if ($(this).hasClass('fold-none')) return;
|
|
|
|
|
|
|
|
|
|
// create a collapsable div to wrap the code in
|
|
|
|
|
var div = $('<div class="collapse r-code-collapse"></div>');
|
|
|
|
|
var showThis = (show || $(this).hasClass('fold-show')) && !$(this).hasClass('fold-hide');
|
|
|
|
|
var id = 'rcode-643E0F36' + currentIndex++;
|
|
|
|
|
div.attr('id', id);
|
|
|
|
|
$(this).before(div);
|
|
|
|
|
$(this).detach().appendTo(div);
|
|
|
|
|
|
|
|
|
|
// add a show code button right above
|
|
|
|
|
var showCodeText = $('<span>' + (showThis ? 'Hide' : 'Code') + '</span>');
|
|
|
|
|
var showCodeButton = $('<button type="button" class="btn btn-default btn-xs btn-secondary btn-sm code-folding-btn pull-right float-right"></button>');
|
|
|
|
|
showCodeButton.append(showCodeText);
|
|
|
|
|
showCodeButton
|
|
|
|
|
.attr('data-toggle', 'collapse')
|
|
|
|
|
.attr('data-bs-toggle', 'collapse') // BS5
|
|
|
|
|
.attr('data-target', '#' + id)
|
|
|
|
|
.attr('data-bs-target', '#' + id) // BS5
|
|
|
|
|
.attr('aria-expanded', showThis)
|
|
|
|
|
.attr('aria-controls', id);
|
|
|
|
|
|
|
|
|
|
var buttonRow = $('<div class="row"></div>');
|
|
|
|
|
var buttonCol = $('<div class="col-md-12"></div>');
|
|
|
|
|
|
|
|
|
|
buttonCol.append(showCodeButton);
|
|
|
|
|
buttonRow.append(buttonCol);
|
|
|
|
|
|
|
|
|
|
div.before(buttonRow);
|
|
|
|
|
|
|
|
|
|
// show the div if necessary
|
|
|
|
|
if (showThis) div.collapse('show');
|
|
|
|
|
|
|
|
|
|
// update state of button on show/hide
|
|
|
|
|
// * Change text
|
|
|
|
|
// * add a class for intermediate states styling
|
|
|
|
|
div.on('hide.bs.collapse', function () {
|
|
|
|
|
showCodeText.text('Code');
|
|
|
|
|
showCodeButton.addClass('btn-collapsing');
|
|
|
|
|
});
|
|
|
|
|
div.on('hidden.bs.collapse', function () {
|
|
|
|
|
showCodeButton.removeClass('btn-collapsing');
|
|
|
|
|
});
|
|
|
|
|
div.on('show.bs.collapse', function () {
|
|
|
|
|
showCodeText.text('Hide');
|
|
|
|
|
showCodeButton.addClass('btn-expanding');
|
|
|
|
|
});
|
|
|
|
|
div.on('shown.bs.collapse', function () {
|
|
|
|
|
showCodeButton.removeClass('btn-expanding');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
<script>
|
|
|
|
|
window.initializeSourceEmbed = function(filename) {
|
|
|
|
|
$("#rmd-download-source").click(function() {
|
|
|
|
|
var src = $("#rmd-source-code").html();
|
|
|
|
|
var a = document.createElement('a');
|
|
|
|
|
a.href = "data:text/x-r-markdown;base64," + src;
|
|
|
|
|
a.download = filename;
|
|
|
|
|
document.body.appendChild(a);
|
|
|
|
|
a.click();
|
|
|
|
|
document.body.removeChild(a);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<style type="text/css">.hljs-literal {
|
|
|
|
|
color: rgb(88, 72, 246);
|
|
|
|
|
}
|
|
|
|
|
.hljs-number {
|
|
|
|
|
color: rgb(0, 0, 205);
|
|
|
|
|
}
|
|
|
|
|
.hljs-comment {
|
|
|
|
|
color: rgb(76, 136, 107);
|
|
|
|
|
}
|
|
|
|
|
.hljs-keyword {
|
|
|
|
|
color: rgb(0, 0, 255);
|
|
|
|
|
}
|
|
|
|
|
.hljs-string {
|
|
|
|
|
color: rgb(3, 106, 7);
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<script src="data:application/javascript;base64,LyohIGhpZ2hsaWdodC5qcyB2OS4xMi4wIHwgQlNEMyBMaWNlbnNlIHwgZ2l0LmlvL2hsanNsaWNlbnNlICovCiFmdW5jdGlvbihlKXt2YXIgbj0ib2JqZWN0Ij09dHlwZW9mIHdpbmRvdyYmd2luZG93fHwib2JqZWN0Ij09dHlwZW9mIHNlbGYmJnNlbGY7InVuZGVmaW5lZCIhPXR5cGVvZiBleHBvcnRzP2UoZXhwb3J0cyk6biYmKG4uaGxqcz1lKHt9KSwiZnVuY3Rpb24iPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kJiZkZWZpbmUoW10sZnVuY3Rpb24oKXtyZXR1cm4gbi5obGpzfSkpfShmdW5jdGlvbihlKXtmdW5jdGlvbiBuKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsiKS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiB0KGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gcihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQuaW5kZXh9ZnVuY3Rpb24gYShlKXtyZXR1cm4gay50ZXN0KGUpfWZ1bmN0aW9uIGkoZSl7dmFyIG4sdCxyLGksbz1lLmNsYXNzTmFtZSsiICI7aWYobys9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1CLmV4ZWMobykpcmV0dXJuIHcodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobz1vLnNwbGl0KC9ccysvKSxuPTAscj1vLmxlbmd0aDtyPm47bisrKWlmKGk9b1tuXSxhKGkpfHx3KGkpKXJldHVybiBpfWZ1bmN0aW9uIG8oZSl7dmFyIG4sdD17fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1mdW5jdGlvbiB1KGUpe3ZhciBuPVtdO3JldHVybiBmdW5jdGlvbiByKGUsYSl7Zm9yKHZhciBpPWUuZmlyc3RDaGlsZDtpO2k9aS5uZXh0U2libGluZykzPT09aS5ub2RlVHlwZT9hKz1pLm5vZGVWYWx1ZS5sZW5ndGg6MT09PWkubm9kZVR5cGUmJihuLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OmEsbm9kZTppfSksYT1yKGksYSksdChpKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fG4ucHVzaCh7ZXZlbnQ6InN0b3AiLG9mZnNldDphLG5vZGU6aX0pKTtyZXR1cm4gYX0oZSwwKSxufWZ1bmN0aW9uIGMoZSxyLGEpe2Z1bmN0aW9uIGkoKXtyZXR1cm4gZS5sZW5ndGgmJnIubGVuZ3RoP2VbMF0ub2Zmc2V0IT09clswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8clswXS5vZmZzZXQ/ZTpyOiJzdGFydCI9PT1yWzBdLmV2ZW50P2U6cjplLmxlbmd0aD9lOnJ9ZnVuY3Rpb24gbyhlKXtmdW5jdGlvbiByKGUpe3JldHVybiIgIitlLm5vZGVOYW1lKyc9IicrbihlLnZhbHVlKS5yZXBsYWNlKCciJywiJnF1b3Q7IikrJyInfXMrPSI8Iit0KGUpK0UubWFwLmNhbGwoZS5hdHRyaWJ1dGVzLHIpLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1KGUpe3MrPSI8LyIrdChlKSsiPiJ9ZnVuY3Rpb24gYyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/bzp1KShlLm5vZGUpfWZvcih2YXIgbD0wLHM9IiIsZj1bXTtlLmxlbmd0aHx8ci5sZW5ndGg7KXt2YXIgZz1pKCk7aWYocys9bihhLnN1YnN0cmluZyhsLGdbMF0ub2Zmc2V0KSksbD1nWzBdLm9mZnNldCxnPT09ZSl7Zi5yZXZlcnNlKCkuZm9yRWFjaCh1KTtkbyBjKGcuc3BsaWNlKDAsMSlbMF0pLGc9aSgpO3doaWxlKGc9PT1lJiZnLmxlbmd0aCYmZ1swXS5vZmZzZXQ9PT1sKTtmLnJldmVyc2UoKS5mb3JFYWNoKG8pfWVsc2Uic3RhcnQiPT09Z1swXS5ldmVudD9mLnB1c2goZ1swXS5ub2RlKTpmLnBvcCgpLGMoZy5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIHMrbihhLnN1YnN0cihsKSl9ZnVuY3Rpb24gbChlKXtyZXR1cm4gZS52JiYhZS5jYWNoZWRfdmFyaWFudHMmJihlLmNhY2hlZF92YXJpYW50cz1lLnYubWFwKGZ1bmN0aW9uKG4pe3JldHVybiBvKGUse3Y6bnVsbH0sbil9KSksZS5jYWNoZWRfdmFyaWFudHN8fGUuZVcmJltvKGUpXXx8W2VdfWZ1bmN0aW9uIHMoZSl7ZnVuY3Rpb24gbihlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gdCh0LHIpe3JldHVybiBuZXcgUmVnRXhwKG4odCksIm0iKyhlLmNJPyJpIjoiIikrKHI/ImciOiIiKSl9ZnVuY3Rpb24gcihhLGkpe2lmKCFhLmNvbXBpbGVkKXtpZihhLmNvbXBpbGVkPSEwLGEuaz1hLmt8fGEuYkssYS5rKXt2YXIgbz17fSx1PWZ1bmN0aW9uKG4sdCl7ZS5jSSYmKHQ9dC50b0xvd2VyQ2FzZSgpKSx0LnNwbGl0KCIgIikuZm9yRWFjaChmdW5jdGlvbihlKXt2YXIgdD1lLnNwbGl0KCJ8Iik7b1t0WzBdXT1bbix0WzFdP051bWJlcih0WzFdKToxXX0pfTsic3RyaW5nIj09dHlwZW9mIGEuaz91KCJrZXl3b3JkIixhLmspOngoYS5rKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3UoZSxhLmtbZV0pfSksYS5rPW99YS5sUj10KGEubHx8L1x3Ky8sITApLGkmJihhLmJLJiYoYS5iPSJcXGIoIithLmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiksYS5ifHwoYS5iPS9cQnxcYi8pLGEuYlI9dChhLmIpLGEuZXx8YS5lV3x8KGEuZT0vXEJ8XGIvKSxhLmUmJihhLmVSPXQoYS5lKSksYS50RT1uKGEuZSl8fCIiLGEuZVcmJmkudEUmJihhLnRFKz0oYS5lPyJ8IjoiIikraS50RSkpLGEuaSYmKGEuaVI9dChhLmkpKSxudWxsPT1hLnImJihhLnI9MSksYS5jfHwoYS5jPVtdKSxhLmM9QXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSxhLmMubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBsKCJzZWxmIj09PWU/YTplKX0pKSxhLmMuZm9yRWFjaChmdW5jdGlvbihlKXtyKGUsYSl9KSxhLnN0YXJ0cyYmcihhLnN0YXJ0cyxpKTt2YXIgYz1hLmMubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBlLmJLPyJcXC4/KCIrZS5iKyIpXFwuPyI6ZS5ifSkuY29uY2F0KFthLnRFLGEuaV0pLm1hcChuKS5maWx0ZXIoQm9vbGVhbik7YS50PWMubGVuZ3RoP3QoYy5qb2luKCJ8IiksITApOntleGVjOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGx9fX19cihlKX1mdW5jdGlvbiBmKGUsdCxhLGkpe2Z1bmN0aW9uIG8oZSxuKXt2YXIgdCxhO2Zvcih0PTAsYT1uLmMubGVuZ3RoO2E+dDt0Kys
|
|
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
code{white-space: pre-wrap;}
|
|
|
|
|
span.smallcaps{font-variant: small-caps;}
|
|
|
|
|
span.underline{text-decoration: underline;}
|
|
|
|
|
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
|
|
|
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
|
|
|
|
ul.task-list{list-style: none;}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<style type="text/css">code{white-space: pre;}</style>
|
|
|
|
|
<script type="text/javascript">
|
|
|
|
|
if (window.hljs) {
|
|
|
|
|
hljs.configure({languages: []});
|
|
|
|
|
hljs.initHighlightingOnLoad();
|
|
|
|
|
if (document.readyState && document.readyState === "complete") {
|
|
|
|
|
window.setTimeout(function() { hljs.initHighlighting(); }, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
p.abstract{
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
div.abstract{
|
|
|
|
|
margin: auto;
|
|
|
|
|
width: 90%;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
#rmd-source-code {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
.main-container {
|
|
|
|
|
max-width: 940px;
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
margin-right: auto;
|
|
|
|
|
}
|
|
|
|
|
img {
|
|
|
|
|
max-width:100%;
|
|
|
|
|
}
|
|
|
|
|
.tabbed-pane {
|
|
|
|
|
padding-top: 12px;
|
|
|
|
|
}
|
|
|
|
|
.html-widget {
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
button.code-folding-btn:focus {
|
|
|
|
|
outline: none;
|
|
|
|
|
}
|
|
|
|
|
summary {
|
|
|
|
|
display: list-item;
|
|
|
|
|
}
|
|
|
|
|
details > summary > p:only-child {
|
|
|
|
|
display: inline;
|
|
|
|
|
}
|
|
|
|
|
pre code {
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
.kable-table {
|
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
padding-left: 8px;
|
|
|
|
|
padding-right: 8px;
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
max-height: 350px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.kable-table table {
|
|
|
|
|
margin-bottom: 0px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.kable-table table>thead>tr>th {
|
|
|
|
|
border: none;
|
|
|
|
|
border-bottom: 2px solid #dddddd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.kable-table table>thead {
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- tabsets -->
|
|
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
.tabset-dropdown > .nav-tabs {
|
|
|
|
|
display: inline-table;
|
|
|
|
|
max-height: 500px;
|
|
|
|
|
min-height: 44px;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tabset-dropdown > .nav-tabs > li.active:before {
|
|
|
|
|
content: "";
|
|
|
|
|
font-family: 'Glyphicons Halflings';
|
|
|
|
|
display: inline-block;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
border-right: 1px solid #ddd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tabset-dropdown > .nav-tabs.nav-tabs-open > li.active:before {
|
|
|
|
|
content: "";
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tabset-dropdown > .nav-tabs.nav-tabs-open:before {
|
|
|
|
|
content: "";
|
|
|
|
|
font-family: 'Glyphicons Halflings';
|
|
|
|
|
display: inline-block;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
border-right: 1px solid #ddd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tabset-dropdown > .nav-tabs > li.active {
|
|
|
|
|
display: block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tabset-dropdown > .nav-tabs > li > a,
|
|
|
|
|
.tabset-dropdown > .nav-tabs > li > a:focus,
|
|
|
|
|
.tabset-dropdown > .nav-tabs > li > a:hover {
|
|
|
|
|
border: none;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tabset-dropdown > .nav-tabs.nav-tabs-open > li {
|
|
|
|
|
display: block;
|
|
|
|
|
float: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tabset-dropdown > .nav-tabs > li {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<!-- code folding -->
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
.code-folding-btn { margin-bottom: 4px; }
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="container-fluid main-container">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div id="header">
|
|
|
|
|
|
|
|
|
|
<div class="btn-group pull-right float-right">
|
|
|
|
|
<button type="button" class="btn btn-default btn-xs btn-secondary btn-sm dropdown-toggle" data-toggle="dropdown" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span>Code</span> <span class="caret"></span></button>
|
|
|
|
|
<ul class="dropdown-menu dropdown-menu-right" style="min-width: 50px;">
|
|
|
|
|
<li><a id="rmd-show-all-code" href="#">Show All Code</a></li>
|
|
|
|
|
<li><a id="rmd-hide-all-code" href="#">Hide All Code</a></li>
|
|
|
|
|
<li role="separator" class="divider"></li>
|
|
|
|
|
<li><a id="rmd-download-source" href="#">Download Rmd</a></li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h1 class="title toc-ignore">Demo for the presentation ‘Getting insights
|
|
|
|
|
from automatic feeder data’</h1>
|
|
|
|
|
<h4 class="author">Luis Gonzalez-Gracia (<a href="mailto:lagog6@ulaval.ca" class="email">lagog6@ulaval.ca</a>)</h4>
|
|
|
|
|
<h4 class="author">Twitter - <span class="citation">@gonzaluisandres</span></h4>
|
|
|
|
|
<h4 class="date">28 September 2022</h4>
|
|
|
|
|
<div class="abstract">
|
|
|
|
|
<p class="abstract">Abstract</p>
|
|
|
|
|
This short R Notebook will show the workflow as presented in my
|
|
|
|
|
presentation today. We will grab to different sources of data, and do
|
|
|
|
|
some wrangling, visualization, and analysis. The script can also be
|
|
|
|
|
accessed in the <code>demo.R</code> file, also in this repository.
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<div id="how-to-get-and-run-this-files-on-your-own-computer" class="section level1">
|
|
|
|
|
<h1>How to get and run this files on your own computer:</h1>
|
2022-09-28 22:34:10 +02:00
|
|
|
|
<div class="figure">
|
|
|
|
|
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBAUEBAYFBQUGBgYHCQ4JCQgICRINDQoOFRIWFhUSFBQXGiEcFxgfGRQUHScdHyIjJSUlFhwpLCgkKyEkJST/2wBDAQYGBgkICREJCREkGBQYJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCT/wgARCAD7AZADASIAAhEBAxEB/8QAHAAAAQUBAQEAAAAAAAAAAAAABQIDBAYHAQAI/8QAGQEAAwEBAQAAAAAAAAAAAAAAAAECAwQF/9oADAMBAAIQAxAAAAGl8Wng70oWmmlC00OKaUhPJE2R8KWESHm+ictRLSV+n5qOvcCVoGYn+Ts06dSu+b3aNIzwh0c9lrgQKtDMeCjPV+Mj2uTcZ2H0Y8YcZ2jieOWI6omjsl6FlmQfDWxXZSNYjGgKrbXl2gF57t0nyvDLJdRy4NcVyhtp9mjr3FJqlQnYqULKi9cSldNBdctdPY19C64VEfSNQZUbmHvAZBf6hagqFVEw8tt2lFcj1xO88WBqnaXnqbt9qFiFT7fk30OwFlJ0anVCjPOXsIQuqJdNjiU7W8CSireVVygB41Tve7aJ8rjZpK+cnO3xzjGmpLNHvK8EdK2qZUe6xvzyxJmIhX0T88fQ+mPzvseObHUn3qBfwzDSc2soVOjRZmHR9BJViW/PciIU0BXPNDztBXSc2NMqljyHcQPYje3gzqK8nk6vSxhdsbaQt6NajbXPRu1ULzQTOt997bTvu+TMeVzm50q440hDyAZ4765FNnCXRnVpJgE4HS0QnJvffntSJOrZuPL0C+fNPqz0zSvnTiNVy/xCNNsxwaPuNHL5NIl7KewOG51a5YBNHdbRmXJ21vOatBqJbsWRjY4wInFS7hTTy3Ix2ExRvLb9Stc4neKe3vd6ma8vvPzMueUzjb6GmZjBDu5XpMRzXNVdsyR1ITYDMOhGlO4bFKvY1FU7piKA/wA9YbzFRNVp4wDU2DUy5oqNjpchgN1Bw/TycaWpA4Hl1uhpKevzo84XPqG5sNuLLHanPjU2SCyOjnLSazYLINJ05uN8w73vP3GnPLy5Gld7Rxt2Nrk4TZk9fOzzkFBdbDzQpBtQ/DuIy04Siy7gZV7aBio1lrpXHW60cvGW4OJbTxNCGahBazv168FSh6qIRUUWVNIJFtvBVQrIaTJR5BLSKERika55XCciqjTESGxhYLwK3GOg+T07Avq55WVr5Sid9I6eaU4mRpAAN5MO1vjJrJT0d6hQU6LQQbkKGKBW6jYdTaecx63ToLQHJVMbu3Op5k7N5s3NYzG2pPQiKf645YBM+qMQ4NoooUW4Urm34cBSySJEDbu3id4Xnl5ckTanmOq95o/N3WlxTxzsQiInXJUtiXtk7HkVJyDKhy+bKzGpVOa7FlJuQio9qUjrbIVbNiOTrhIebjpduVJONWeeFl7YT2m5KqoQrq7KoSrw81RZFxkgFMvzLUCXGab9Ry4nh7IyXmsWRPhjPq+Wr0kS1nep0C5VEjPNQzPDtt0hnqxFeU3vzyldbuXM813L87hkYU6ZOTh72hOeHkG5bHEo7Ejj05g2ZF5uqM2+3l0N+Wljs8V1B+ZVlubY5UlJ3D1Scm7WupOk2lFdXnZVESdz7scMRY0DxSY/bCeSFmPU8xoAcoGuVtLpntMVO51nPpID3W1ip1tW2Ti4pdM1Q7nUM9KbY61ZnnLfTItceQpt6FKDog18oJgtaHm8OuOhbmG0ZEppzH456hK1OyNLeXLYddeimHJC87YceVNeJRS06nB10idfHm8IpK5e0HZqtYfV8uuU2z13TC4WjO7pYUq9mAxsKlD3FjMlw5m0vPx0Y6TKfY6jLEzWCjzJTRJXRS+K6yOPMCwAwDw7JmUrRl0su+mc20duwDE4HlsoV5pqlKTEdY9JhkIvr8RzO50gW9nZoxXSmO9yl1wn6XlU2AbA8fpwDYC2ep5lFjERql4mIOdHPLlKkO6cRDmM062/3XNKGU8/Q5WjYIUSzVKw65EYylMMeWql0cVhAhJRIBIcyLydbpdqVhvY6jfa9041hopAIhcX5zxXFUlvMem5zsaVSdkx5blBcU/Oli9Fcx0hDLEMw66jZq6d6eSkxLlSduYgUinbnlhAMlV00FIqZqhzVQ6iJKw0aFPy6kBaoLFzKOi2WG1A5dIzGFyALoFxgfiIXz9BopWXrnRgcauWp4mWAlEE+dJZ9BKAJHkXZ15YA02pJSKvK0zsqgsZO9v0tsu+cpkYDfQ8SKL0Rw1WUm00goy1A1w46K1Cmxcs98FT174Ua406+AAMVe0BSMy1/IkfRlFvVFYSMFxAYlsWaWALkJH+AqQNBQdqdsChneuYtuqY+pimGtjGkgAV7S8/uoVYpMhg043NAC9GkhcMl1r5wD6FzTRcLDcct1nMg0jzzAZ9Z8lsoXqV2MGcwoVz5PTpb0Ijvw7e7mr+mT8+vthbSVHlhSQmt5GH0TRZNZDSOZycCnWUHIbsHgvUrfPpcsLdk9tJBmG44ZchlWDeXi3QAHlBGPZYcC8KpEwLNmNlqScy/wCYaSy7fOOlZ2LeML0TOg2PHtOrwXz1S8Aaw1NAKtWUacnm+nZpeeT0aR4V7fksg8dxMgkf4Rp8B7XKxSKr1lqdqXmXddIUF6GVlgVvk0d0dqTV+RdpTVPVFybqPkWKTVOMsbQDqdgbBeQe8A6B+TV+p29NTdbuhPO+j0AplfanSGM/fpW6rQWZU94R1BwbF8KbaqK9n0f/xAAxEAABBAEDAwMDBAIDAAMAAAACAAEDBAUGERITFCEQIjUVMTQgIzIzFiQwNkElQkP/2gAIAQEAAQUC/UPo7+YmKc222Z97Sll6ccp9QtlstvFa0UD4+73Ag6CRRzsu5ZSzclYLdGnZGKdkTIx3To/Tb0bd3iDghHmoxrCq83SKLKRdMjitRZXGdsf69k/pumdfdAPkWZvSH8ndZA9mW7LcXT8V9lSyLQP9YrizagqsoMzBMRXGBjz1dkWbYpCyVdDkICc78LOE8cylnAHe1G66gOjkFdRk2zrZV42ZgHk9on3hBUoQJPjglVEnqTGITNk64VLH6Nv0OtuSYfQP5Mn+0P5BnxVk+oeDxFCzivoGLV3CY6Ong8RQs4rJ4ynDnPoGLWm8fVt3PoGLWqMfVoVclL/r1sHjSr/QMWsRiqU97UuKpVMZhsPj58XqWtBj8hpWjVvj9Axa1TjK9ZY/TdGnF9Mxkw6gw44mcW3fbi1Ym5M28jBxKrLxKKfZsoH7gs/T1EwGP6tlsiHxsm9N9kMiH3DB+RZLgLg29W9dryrN5K6GS038Jla80meWkvz9QzSV8RLkLNlpSKRVPxdSZK7Wy2jJClbV3w+A+H1n8jof+rU1iWti6t+ezkVRvf43Jn87Wy9esCsuofYwOzOHE3LpxvEzON4d44d+GZ2/Vt6v+qL8av8A32vIxi7qQeNtZ75jTfwjyAJLSX58jgw6veGQbjbQ1PxTkrCWkv7NXfD4D4bWnyOh/wCqRwEdYnE8uE1LDcGxWhtxZzDPh54C2jL3G3l3D2xc2OOm89PH1pZpZa/RrVa3nPPxn/4C9NvR1uufGtFK0J9xWlQNsc35iz3zGm/hMx/2NaS/P1R8FVIBPIfap+Lqlt85of8Ar1d8PgPhta/IaH/q1d8PTAZbX+L4haUvTWI9XixYiH+gw8Ru/MX3ZtmLE7jVh6By3pWBN/XmLATTfr2TsnBvWQ9kJ+ZD8RtHtIXmAkf5XdV1mW62V0/YhDDZaeItQd3XWlpo473d11q2eKTF2fMFW1A1bUhDJm9GyxxR6rnikxOCswjie7rrCTxDkO7rrV1kHqYzM1cnHBUrUG1Vl4bQQl7ZU58Sjf27LGyEzP0YbFl3mYpehRN9y/S/q/o6EOaamPIakTI6goonZSw+0SdkDjM3Ygq8FVldpwwNwZcF0Q4NHXdNUB1DT5qxRCOYQ4k8LE8dIE+OFxKmwoaIOEWHCQQw0MalwsZKTFysu36Lwt5k+0rMzx
|
|
|
|
|
<p class="caption">Some of you might be too young to get the
|
|
|
|
|
reference</p>
|
|
|
|
|
</div>
|
|
|
|
|
<p>You can run and tweak this code by cloning my repository. If you do
|
|
|
|
|
not know what a repository is, I recommend you to begin reading about it
|
|
|
|
|
if you want to work collaboratively with other people.</p>
|
|
|
|
|
<ol style="list-style-type: decimal">
|
|
|
|
|
<li>Install git <a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git" class="uri">https://git-scm.com/book/en/v2/Getting-Started-Installing-Git</a></li>
|
|
|
|
|
<li>Go to the folder you want the folder with the files to be
|
|
|
|
|
located.</li>
|
|
|
|
|
<li>Open that folder in the terminal and type</li>
|
|
|
|
|
</ol>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgYmFzaFxuZ2l0IGNsb25lIGh0dHBzOi8vZ2l0LmRpc3Jvb3Qub3JnL2x1YW5nb256L2ZlZWRlci1hbmFseXRpY3MtZGVtby5naXRcbmBgYCJ9 -->
|
|
|
|
|
<pre class="bash"><code>git clone https://git.disroot.org/luangonz/feeder-analytics-demo.git</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>Git will automatically create a folder and download all the files
|
|
|
|
|
required to run this code.</p>
|
2022-09-28 22:20:24 +02:00
|
|
|
|
</div>
|
|
|
|
|
<div id="setup" class="section level1">
|
|
|
|
|
<h1>Setup</h1>
|
|
|
|
|
<p>Since the idea of this project is to be as modular and automated as
|
|
|
|
|
possible, I created a set of custom functions that do the heavy lifting
|
|
|
|
|
in the background, without cluttering too much the script file. This has
|
|
|
|
|
some advantages and disadvantages, since although it is easier to read
|
|
|
|
|
and the workflow is easy to follow along, if issues appear, then
|
|
|
|
|
debugging and following the function that originated the issue is more
|
|
|
|
|
time-consuming.</p>
|
|
|
|
|
<p>The folder is organized in the main project files and two
|
|
|
|
|
folders:</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li>The <code>data</code> folder holds the data files we will be loading
|
|
|
|
|
into the environment.</li>
|
|
|
|
|
<li>The <code>setup</code> folder (used in this section) holds two key
|
|
|
|
|
files:
|
|
|
|
|
<ul>
|
|
|
|
|
<li><code>functions.R</code> that holds all the custom functions</li>
|
|
|
|
|
<li><code>loadlibraries.R</code> that has all the libraries needed for
|
|
|
|
|
any script file that uses the same set of libraries (so you do not need
|
|
|
|
|
to copy and paste it in every file of the project)</li>
|
|
|
|
|
</ul></li>
|
|
|
|
|
</ul>
|
|
|
|
|
<p>When we run the <code>source()</code> function at this step, we are
|
|
|
|
|
loading both the libraries and the functions that we are going to use
|
|
|
|
|
throughout the demo.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuc291cmNlKFwic2V0dXAvZnVuY3Rpb25zLlJcIilcbnNvdXJjZShcInNldHVwL2xvYWRsaWJyYXJpZXMuUlwiKVxuYGBgIn0= -->
|
|
|
|
|
<pre class="r"><code>source("setup/functions.R")
|
|
|
|
|
source("setup/loadlibraries.R")</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
</div>
|
|
|
|
|
<div id="importing-data" class="section level1">
|
|
|
|
|
<h1>Importing data</h1>
|
|
|
|
|
<p>First step in the process is to load the excel file in the
|
|
|
|
|
environment. There are packages that can natively import excel files
|
|
|
|
|
that are very straightforward, but some of them do not handle the Date
|
|
|
|
|
information properly. For this I have a custom function that takes into
|
|
|
|
|
account some common issues and with the <code>method =</code> parameter,
|
|
|
|
|
I can fine-tune the importing method according to where the data comes
|
|
|
|
|
from.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuZmFybUEgPC0geGxzeF90b19kYXRhZnJhbWUoZmlsZW5hbWUgPSBcImRhdGEvZmFybV9BX2RlbW8ueGxzeFwiLCAjIHNlbGVjdHMgdGhlIGZpbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IFwiZmFybV9BXzExcm93c1wiKSAjIHNlbGVjdHMgdGhlIGZhcm0gQSBtZXRob2RcbmBgYCJ9 -->
|
|
|
|
|
<pre class="r"><code>farmA <- xlsx_to_dataframe(filename = "data/farm_A_demo.xlsx", # selects the file
|
|
|
|
|
method = "farm_A_11rows") # selects the farm A method</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>Lucky for us, farm B has its data directly formatted in the RData
|
|
|
|
|
format, which helps a lot in the importing process. A simple
|
|
|
|
|
<code>load()</code> function and the data is there.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
</div>
|
|
|
|
|
<div id="checking-structure-of-data" class="section level1">
|
|
|
|
|
<h1>Checking structure of data</h1>
|
|
|
|
|
<p>We will look at the raw imported data as it comes from the import
|
|
|
|
|
procedure.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuc3RyKGZhcm1BKVxuXG5gYGAifQ== -->
|
|
|
|
|
<pre class="r"><code>str(farmA)
|
|
|
|
|
</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-output-begin eyJkYXRhIjoidGliYmxlIFsyNjgsMTk5IHggMTBdIChTMzogdGJsX2RmL3RibC9kYXRhLmZyYW1lKVxuICQgRGF0ZSAgICA6IFBPU0lYY3RbMToyNjgxOTldLCBmb3JtYXQ6IFwiMjAyMS0wNC0yN1wiIFwiMjAyMS0wNC0yN1wiIFwiMjAyMS0wNC0yN1wiIC4uLlxuICQgVGF0b3VhZ2U6IGNociBbMToyNjgxOTldIE5BIE5BIE5BIE5BIC4uLlxuICQgU3RhdGlvbiA6IG51bSBbMToyNjgxOTldIDEgMSAxIDEgMSAxIDEgMSAxIDEgLi4uXG4gJCBwZHNkZWIgIDogbnVtIFsxOjI2ODE5OV0gMS40MDggMS4zOTIgMC43NzggMS4yNDggMS4yNDcgLi4uXG4gJCBwZHNmaW4gIDogbnVtIFsxOjI2ODE5OV0gMS4zOTIgMS4zODUgMC43NzEgMS4xODkgMS4yNDUgLi4uXG4gJCBjb25zICAgIDogbnVtIFsxOjI2ODE5OV0gMC4wMTYgMC4wMDcgMC4wMDcgMC4wNTkgMC4wMDIgMC4wMiAwLjA0IDAuNDY4IDAuMjYxIDAuMzY0IC4uLlxuICQgcmVtcCAgICA6IG51bSBbMToyNjgxOTldIDAgMCAwIDAgMCAwIDAgMCAwIDAuNDggLi4uXG4gJCBocmVkZWIgIDogY2hyIFsxOjI2ODE5OV0gXCI0OjQzOjE5XCIgXCI0OjQ0OjA5XCIgXCI4OjA2OjI4XCIgXCI4OjM4OjIwXCIgLi4uXG4gJCBocmVmaW4gIDogY2hyIFsxOjI2ODE5OV0gXCI0OjQzOjQzXCIgXCI0OjQ0OjE0XCIgXCI4OjA2OjQwXCIgXCI4OjQwOjUyXCIgLi4uXG4gJCBkdXJlZTEgIDogY2hyIFsxOjI2ODE5OV0gXCIwOjAwOjI0XCIgXCIwOjAwOjA1XCIgXCIwOjAwOjEyXCIgXCIwOjAyOjMyXCIgLi4uXG4ifQ== -->
|
|
|
|
|
<pre><code>tibble [268,199 x 10] (S3: tbl_df/tbl/data.frame)
|
|
|
|
|
$ Date : POSIXct[1:268199], format: "2021-04-27" "2021-04-27" "2021-04-27" ...
|
|
|
|
|
$ Tatouage: chr [1:268199] NA NA NA NA ...
|
|
|
|
|
$ Station : num [1:268199] 1 1 1 1 1 1 1 1 1 1 ...
|
|
|
|
|
$ pdsdeb : num [1:268199] 1.408 1.392 0.778 1.248 1.247 ...
|
|
|
|
|
$ pdsfin : num [1:268199] 1.392 1.385 0.771 1.189 1.245 ...
|
|
|
|
|
$ cons : num [1:268199] 0.016 0.007 0.007 0.059 0.002 0.02 0.04 0.468 0.261 0.364 ...
|
|
|
|
|
$ remp : num [1:268199] 0 0 0 0 0 0 0 0 0 0.48 ...
|
|
|
|
|
$ hredeb : chr [1:268199] "4:43:19" "4:44:09" "8:06:28" "8:38:20" ...
|
|
|
|
|
$ hrefin : chr [1:268199] "4:43:43" "4:44:14" "8:06:40" "8:40:52" ...
|
|
|
|
|
$ duree1 : chr [1:268199] "0:00:24" "0:00:05" "0:00:12" "0:02:32" ...</code></pre>
|
|
|
|
|
<!-- rnb-output-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>We see some issues that are of concern, for example time of start of
|
|
|
|
|
visit is not in a proper date/time type, but it is only a character.
|
|
|
|
|
Lets check Farm B:</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuc3RyKGZhcm1CKVxuXG5gYGAifQ== -->
|
|
|
|
|
<pre class="r"><code>str(farmB)
|
|
|
|
|
</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-output-begin eyJkYXRhIjoiJ2RhdGEuZnJhbWUnOlx0MzI4Mjcgb2JzLiBvZiAgMTIgdmFyaWFibGVzOlxuICQgRGF0ZV9maW4gICAgICAgICAgIDogRGF0ZSwgZm9ybWF0OiBcIjIwMjAtMDUtMTJcIiBcIjIwMjAtMDUtMTJcIiBcIjIwMjAtMDUtMTJcIiAuLi5cbiAkIEFuaW1hbCAgICAgICAgICAgICA6IGNociAgXCI0ODE3XCIgXCI0ODE3XCIgXCI0ODE1XCIgXCI0ODE3XCIgLi4uXG4gJCBSRklEICAgICAgICAgICAgICAgOiBudW0gIDc0MDY0ODcgNzQwNjQ4NyAxMzMzMzk4MiA3NDA2NDg3IDEzMzMzOTgyIC4uLlxuICQgUGFyYyAgICAgICAgICAgICAgIDogaW50ICA2IDYgNiA2IDYgNiA2IDYgNiA2IC4uLlxuICQgUG9pZHNfYWxpbWVudF9kZWJ1dDogbnVtICAxMy40IDEzLjQgMTMuNCAxMy40IDEzLjQgLi4uXG4gJCBQb2lkc19hbGltZW50X2ZpbiAgOiBudW0gIDEzLjQgMTMuNCAxMy40IDEzLjQgMTMuNCAuLi5cbiAkIFF0ZV9hbGltZW50ICAgICAgICA6IG51bSAgMCAwLjAxIC0wLjAxIDAgMCAwIDAgMCAwIDAuMDEgLi4uXG4gJCBUZGVidXQgICAgICAgICAgICAgOiBjaHIgIFwiMTA6Mjg6MTVcIiBcIjEwOjMwOjA2XCIgXCIxMDozMjo0N1wiIFwiMTA6MzQ6MTdcIiAuLi5cbiAkIFRmaW4gICAgICAgICAgICAgICA6IGNociAgXCIxMDoyODo1NlwiIFwiMTA6MzI6NDdcIiBcIjEwOjM0OjE3XCIgXCIxMDozNDo0MlwiIC4uLlxuICQgRHVyZWVfaW5zZW50ZWMgICAgIDogbnVtICAwLjQxIDIuNDEgMS4zIDAuMjUgMC4zNiAwLjIxIDAuMDUgMC4xIDAuNTggMC4wMiAuLi5cbiAkIER1bW15ICAgICAgICAgICAgICA6IG51bSAgMCAwIDAgMCAwIDAgMCAwIDAgMCAuLi5cbiAkIER1cmVlX3MgICAgICAgICAgICA6IG51bSAgNDEgMTYxIDkwIDI1IDM2IDIxIDUgMTAgNTggMiAuLi5cbiJ9 -->
|
|
|
|
|
<pre><code>'data.frame': 32827 obs. of 12 variables:
|
|
|
|
|
$ Date_fin : Date, format: "2020-05-12" "2020-05-12" "2020-05-12" ...
|
|
|
|
|
$ Animal : chr "4817" "4817" "4815" "4817" ...
|
|
|
|
|
$ RFID : num 7406487 7406487 13333982 7406487 13333982 ...
|
|
|
|
|
$ Parc : int 6 6 6 6 6 6 6 6 6 6 ...
|
|
|
|
|
$ Poids_aliment_debut: num 13.4 13.4 13.4 13.4 13.4 ...
|
|
|
|
|
$ Poids_aliment_fin : num 13.4 13.4 13.4 13.4 13.4 ...
|
|
|
|
|
$ Qte_aliment : num 0 0.01 -0.01 0 0 0 0 0 0 0.01 ...
|
|
|
|
|
$ Tdebut : chr "10:28:15" "10:30:06" "10:32:47" "10:34:17" ...
|
|
|
|
|
$ Tfin : chr "10:28:56" "10:32:47" "10:34:17" "10:34:42" ...
|
|
|
|
|
$ Duree_insentec : num 0.41 2.41 1.3 0.25 0.36 0.21 0.05 0.1 0.58 0.02 ...
|
|
|
|
|
$ Dummy : num 0 0 0 0 0 0 0 0 0 0 ...
|
|
|
|
|
$ Duree_s : num 41 161 90 25 36 21 5 10 58 2 ...</code></pre>
|
|
|
|
|
<!-- rnb-output-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>Similar issues with the time and also the titles of the variables
|
|
|
|
|
between these two are different, making it hard to work with them with
|
|
|
|
|
just a piece of code. So the strategy is to take this (or any) kind of
|
|
|
|
|
dataframe that we work with, and standardize it to a format that any of
|
|
|
|
|
the next functions can work with. Next step then, is
|
|
|
|
|
standardization.</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div id="standardization" class="section level1">
|
|
|
|
|
<h1>Standardization</h1>
|
|
|
|
|
<p>The <code>harmonize_feeder_data()</code> function is a custom
|
|
|
|
|
function that allows us to funnel any kind of source file into a single,
|
|
|
|
|
homogenous data structure so it can be fed into the following functions
|
|
|
|
|
in the workflow. It has two parameters:</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li><code>groupstations</code>: If TRUE, the station number becomes a
|
|
|
|
|
group in the dataframe (useful for summarizations).</li>
|
|
|
|
|
<li><code>method</code>: a selector for the method that it will use,
|
|
|
|
|
according to which source the data frame comes from</li>
|
|
|
|
|
<li><code>remove_filling</code>: if TRUE, it will remove the FILLING
|
|
|
|
|
events of the feeder (when the feeder is filled up).</li>
|
|
|
|
|
<li><code>remove_na</code>: if TRUE, it will remove unavailable data
|
|
|
|
|
that might interfere in some of the calculations.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>We will check the structure again to see if everything is in
|
|
|
|
|
order:</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuc3RyKGZhcm1BX3N0YW5kYXJkKVxuXG5gYGAifQ== -->
|
|
|
|
|
<pre class="r"><code>str(farmA_standard)
|
|
|
|
|
</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-output-begin eyJkYXRhIjoidGliYmxlIFsyNjEsNjM2IHggOV0gKFMzOiB0YmxfZGYvdGJsL2RhdGEuZnJhbWUpXG4gJCBEYXRlICAgICAgICAgIDogUE9TSVhjdFsxOjI2MTYzNl0sIGZvcm1hdDogXCIyMDIxLTA0LTI3XCIgXCIyMDIxLTA0LTI3XCIgXCIyMDIxLTA0LTI3XCIgLi4uXG4gJCBpZCAgICAgICAgICAgIDogRmFjdG9yIHcvIDMwOCBsZXZlbHMgXCJTT0dFNjAyODFKXCIsXCJTT0dFNjAyODZKXCIsLi46IDQgNCA0IDQgNyA3IDcgNyA3IDcgLi4uXG4gJCBzdGF0aW9uICAgICAgIDogRmFjdG9yIHcvIDIyIGxldmVscyBcIjFcIixcIjJcIixcIjNcIixcIjRcIiwuLjogMSAxIDEgMSAxIDEgMSAxIDEgMSAuLi5cbiAkIHBkc2RlYiAgICAgICAgOiBudW0gWzE6MjYxNjM2XSAxLjI4MiAxLjA2OCAwLjk5MSAxLjAzIDEuNDQ4IC4uLlxuICQgcGRzZmluICAgICAgICA6IG51bSBbMToyNjE2MzZdIDAuODE0IDAuODA3IDAuNjI3IDAuNTI0IDEuMjgyIC4uLlxuICQgY29ucyAgICAgICAgICA6IG51bSBbMToyNjE2MzZdIDAuNDY4IDAuMjYxIDAuMzY0IDAuNTA2IDAuMTY2IDAuMjY1IDAuMjA5IDAuMDkyIDAuMTIyIDAuMjk1IC4uLlxuICQgaG91ci5pbiAgICAgICA6IFBPU0lYY3RbMToyNjE2MzZdLCBmb3JtYXQ6IFwiMjAyMS0wNC0yNyAwNDo1NjoyOFwiIFwiMjAyMS0wNC0yNyAwODo1NDowMFwiIFwiMjAyMS0wNC0yNyAxMzoyNDoyOVwiIC4uLlxuICQgaG91ci5vdXQgICAgICA6IFBPU0lYY3RbMToyNjE2MzZdLCBmb3JtYXQ6IFwiMjAyMS0wNC0yNyAwNToxNTo0OFwiIFwiMjAyMS0wNC0yNyAwOTowNTo0NFwiIFwiMjAyMS0wNC0yNyAxMzo0NjoxNVwiIC4uLlxuICQgdmlzaXRfZHVyX3NlY3M6ICdkaWZmdGltZScgbnVtIFsxOjI2MTYzNl0gMTE2MCA3MDQgMTMwNiAxNjUxIC4uLlxuICAuLi0gYXR0cigqLCBcInVuaXRzXCIpPSBjaHIgXCJzZWNzXCJcbiJ9 -->
|
|
|
|
|
<pre><code>tibble [261,636 x 9] (S3: tbl_df/tbl/data.frame)
|
|
|
|
|
$ Date : POSIXct[1:261636], format: "2021-04-27" "2021-04-27" "2021-04-27" ...
|
|
|
|
|
$ id : Factor w/ 308 levels "SOGE60281J","SOGE60286J",..: 4 4 4 4 7 7 7 7 7 7 ...
|
|
|
|
|
$ station : Factor w/ 22 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
|
|
|
|
|
$ pdsdeb : num [1:261636] 1.282 1.068 0.991 1.03 1.448 ...
|
|
|
|
|
$ pdsfin : num [1:261636] 0.814 0.807 0.627 0.524 1.282 ...
|
|
|
|
|
$ cons : num [1:261636] 0.468 0.261 0.364 0.506 0.166 0.265 0.209 0.092 0.122 0.295 ...
|
|
|
|
|
$ hour.in : POSIXct[1:261636], format: "2021-04-27 04:56:28" "2021-04-27 08:54:00" "2021-04-27 13:24:29" ...
|
|
|
|
|
$ hour.out : POSIXct[1:261636], format: "2021-04-27 05:15:48" "2021-04-27 09:05:44" "2021-04-27 13:46:15" ...
|
|
|
|
|
$ visit_dur_secs: 'difftime' num [1:261636] 1160 704 1306 1651 ...
|
|
|
|
|
..- attr(*, "units")= chr "secs"</code></pre>
|
|
|
|
|
<!-- rnb-output-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuc3RyKGZhcm1CX3N0YW5kYXJkKVxuXG5gYGAifQ== -->
|
|
|
|
|
<pre class="r"><code>str(farmB_standard)
|
|
|
|
|
</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-output-begin eyJkYXRhIjoiJ2RhdGEuZnJhbWUnOlx0MjY4NTMgb2JzLiBvZiAgOSB2YXJpYWJsZXM6XG4gJCBEYXRlICAgICAgICAgIDogRGF0ZSwgZm9ybWF0OiBcIjIwMjAtMDUtMTJcIiBcIjIwMjAtMDUtMTJcIiBcIjIwMjAtMDUtMTJcIiAuLi5cbiAkIGlkICAgICAgICAgICAgOiBGYWN0b3Igdy8gMjAgbGV2ZWxzIFwiNDgwNFwiLFwiNDgwNVwiLC4uOiAxNCAxNCAxMiAxNCAxMiAxNCAxIDE0IDUgNSAuLi5cbiAkIHN0YXRpb24gICAgICAgOiBGYWN0b3Igdy8gMSBsZXZlbCBcIjZcIjogMSAxIDEgMSAxIDEgMSAxIDEgMSAuLi5cbiAkIHBkc2RlYiAgICAgICAgOiBudW0gIDEzLjQgMTMuNCAxMy40IDEzLjQgMTMuNCAuLi5cbiAkIHBkc2ZpbiAgICAgICAgOiBudW0gIDEzLjQgMTMuNCAxMy40IDEzLjQgMTMuNCAuLi5cbiAkIGNvbnMgICAgICAgICAgOiBudW0gIDAgMC4wMSAtMC4wMSAwIDAgMCAwIDAgMCAwLjAxIC4uLlxuICQgaG91ci5pbiAgICAgICA6IFBPU0lYY3QsIGZvcm1hdDogXCIyMDIwLTA1LTEyIDEwOjI4OjE1XCIgXCIyMDIwLTA1LTEyIDEwOjMwOjA2XCIgXCIyMDIwLTA1LTEyIDEwOjMyOjQ3XCIgLi4uXG4gJCBob3VyLm91dCAgICAgIDogUE9TSVhjdCwgZm9ybWF0OiBcIjIwMjAtMDUtMTIgMTA6Mjg6NTZcIiBcIjIwMjAtMDUtMTIgMTA6MzI6NDdcIiBcIjIwMjAtMDUtMTIgMTA6MzQ6MTdcIiAuLi5cbiAkIHZpc2l0X2R1cl9zZWNzOiAnZGlmZnRpbWUnIG51bSAgNDEgMTYxIDkwIDI1IC4uLlxuICAuLi0gYXR0cigqLCBcInVuaXRzXCIpPSBjaHIgXCJzZWNzXCJcbiJ9 -->
|
|
|
|
|
<pre><code>'data.frame': 26853 obs. of 9 variables:
|
|
|
|
|
$ Date : Date, format: "2020-05-12" "2020-05-12" "2020-05-12" ...
|
|
|
|
|
$ id : Factor w/ 20 levels "4804","4805",..: 14 14 12 14 12 14 1 14 5 5 ...
|
|
|
|
|
$ station : Factor w/ 1 level "6": 1 1 1 1 1 1 1 1 1 1 ...
|
|
|
|
|
$ pdsdeb : num 13.4 13.4 13.4 13.4 13.4 ...
|
|
|
|
|
$ pdsfin : num 13.4 13.4 13.4 13.4 13.4 ...
|
|
|
|
|
$ cons : num 0 0.01 -0.01 0 0 0 0 0 0 0.01 ...
|
|
|
|
|
$ hour.in : POSIXct, format: "2020-05-12 10:28:15" "2020-05-12 10:30:06" "2020-05-12 10:32:47" ...
|
|
|
|
|
$ hour.out : POSIXct, format: "2020-05-12 10:28:56" "2020-05-12 10:32:47" "2020-05-12 10:34:17" ...
|
|
|
|
|
$ visit_dur_secs: 'difftime' num 41 161 90 25 ...
|
|
|
|
|
..- attr(*, "units")= chr "secs"</code></pre>
|
|
|
|
|
<!-- rnb-output-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>With this function we`ve managed to homogenize the data structure so
|
|
|
|
|
we can move on now to our next step.</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div id="inspecting-data-integrity" class="section level1">
|
|
|
|
|
<h1>Inspecting data integrity</h1>
|
|
|
|
|
<p>Well be running some more custom functions to plot valuable data.</p>
|
|
|
|
|
<div id="population-plot" class="section level2">
|
|
|
|
|
<h2>Population plot</h2>
|
|
|
|
|
<p>Farm A has 22 different pens. It would be valuable to see if there
|
|
|
|
|
are any issues regarding the population of these pens, for example a
|
|
|
|
|
quick reduction or increase in size or a quick drop due to data loss
|
|
|
|
|
form the hardware</p>
|
|
|
|
|
<div id="population-plot-of-farm-a" class="section level3">
|
|
|
|
|
<h3>Population plot of farm A</h3>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxucG9wdWxhdGlvblBsb3QoZmFybUFfc3RhbmRhcmQpXG5cbmBgYCJ9 -->
|
|
|
|
|
<pre class="r"><code>populationPlot(farmA_standard)
|
|
|
|
|
</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
</div>
|
|
|
|
|
<div id="population-plot-of-farm-b" class="section level3">
|
|
|
|
|
<h3>Population plot of farm B</h3>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxucG9wdWxhdGlvblBsb3QoZmFybUJfc3RhbmRhcmQpXG5gYGAifQ== -->
|
|
|
|
|
<pre class="r"><code>populationPlot(farmB_standard)</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>We can evidence with these plots that there are some pen size
|
|
|
|
|
fluctuations and some data loss in some of the periods. These losses
|
|
|
|
|
will need to be taken into account during the analyses.</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div id="visualizing-visits-to-the-feeder" class="section level2">
|
|
|
|
|
<h2>Visualizing visits to the feeder</h2>
|
|
|
|
|
<p>We can visualize a timeline of visits to the feeder for any station
|
|
|
|
|
or day with this custom function, <code>visitPlotsDay()</code>:</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxudmlzaXRQbG90c0RheShmYXJtQV9zdGFuZGFyZCwgXG4gICAgICAgICAgICAgIHRoZWRhdGUgPSBcIjIwMjEtMDYtMDNcIiwgXG4gICAgICAgICAgICAgIHRoZXN0YXRpb24gPSAxMSxcbiAgICAgICAgICAgICAgc2luZ2xlc3RyaXAgPSBGQUxTRSlcbmBgYCJ9 -->
|
|
|
|
|
<pre class="r"><code>visitPlotsDay(farmA_standard,
|
|
|
|
|
thedate = "2021-06-03",
|
|
|
|
|
thestation = 11,
|
|
|
|
|
singlestrip = FALSE)</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>With the last plot, we have one line per pig, but sometimes seeing
|
|
|
|
|
all the visit in a single line is useful. This is what the
|
|
|
|
|
<code>singlestrip</code> parameter is useful for.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxudmlzaXRQbG90c0RheShmYXJtQV9zdGFuZGFyZCwgXG4gICAgICAgICAgICAgIHRoZWRhdGUgPSBcIjIwMjEtMDYtMDNcIiwgXG4gICAgICAgICAgICAgIHRoZXN0YXRpb24gPSAxMSxcbiAgICAgICAgICAgICAgc2luZ2xlc3RyaXAgPSBUUlVFKVxuYGBgIn0= -->
|
|
|
|
|
<pre class="r"><code>visitPlotsDay(farmA_standard,
|
|
|
|
|
thedate = "2021-06-03",
|
|
|
|
|
thestation = 11,
|
|
|
|
|
singlestrip = TRUE)</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
</div>
|
|
|
|
|
<div id="a-birdseye-view-of-all-the-data-for-a-station" class="section level2">
|
|
|
|
|
<h2>A birdseye view of all the data for a station</h2>
|
|
|
|
|
<p>The <code>inspectDay</code> function can show the visits to a feeder
|
|
|
|
|
for the whole period, in a single plot. It can also show a population
|
|
|
|
|
plot similar to the previous section.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuaW5zcGVjdERheShmYXJtQV9zdGFuZGFyZCwgdGhlc3RhdGlvbiA9IDExKVxuYGBgIn0= -->
|
|
|
|
|
<pre class="r"><code>inspectDay(farmA_standard, thestation = 11)</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div id="building-network-visualizations-and-analyisis" class="section level1">
|
|
|
|
|
<h1>Building network visualizations and analyisis</h1>
|
|
|
|
|
<div id="building-the-igraph-objects-and-plotting" class="section level2">
|
|
|
|
|
<h2>Building the igraph objects and plotting</h2>
|
|
|
|
|
<p>The following steps succesively converts the data into the network
|
|
|
|
|
objects of the <code>igraph</code> package.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuZmFybUFfbGlzdCA8LSBtYWtlQWxsU3RhdGlvbnNQZXJkYXRlKGZhcm1BX3N0YW5kYXJkLCBkb21lcmdlID0gXCJGXCIpXG5cbmZhcm1BX3BhaXJzIDwtIG1ha2VQYWlyc1BlclN0YXRpb24oZmFybUFfbGlzdCwgbXl0aHJlc2hvbGQgPSA1KSAjIFRBS0VTIEEgTE9ORyBUSU1FXG5cbmZhcm1BX25ldHdvcmsgPC0gbWFrZUlHcmFwaE9iamVjdHMoZmFybUFfcGFpcnMsIGRpcmVjdGVkID0gVClcblxucGxvdChmYXJtQV9uZXR3b3JrW1tcIjEyXCJdXVtbXCIyMDIxLTA1LTIwXCJdXSlcbmBgYCJ9 -->
|
|
|
|
|
<pre class="r"><code>farmA_list <- makeAllStationsPerdate(farmA_standard, domerge = "F")
|
|
|
|
|
|
|
|
|
|
farmA_pairs <- makePairsPerStation(farmA_list, mythreshold = 5) # TAKES A LONG TIME
|
|
|
|
|
|
|
|
|
|
farmA_network <- makeIGraphObjects(farmA_pairs, directed = T)
|
|
|
|
|
|
|
|
|
|
plot(farmA_network[["12"]][["2021-05-20"]])</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
</div>
|
|
|
|
|
<div id="making-summarizations-based-on-the-network-data" class="section level2">
|
|
|
|
|
<h2>Making summarizations based on the network data</h2>
|
|
|
|
|
<p>The following steps will analyze how a whole-network parameter, the
|
|
|
|
|
<a href="https://methods.sagepub.com/reference/the-sage-encyclopedia-of-educational-research-measurement-and-evaluation/i14550.xml">Network
|
|
|
|
|
Density</a> progresses through time. It looks that there is a downward
|
|
|
|
|
trend in the group we are studying.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuZ2V0bWV0aGVwbG90X3BsaXooc2l0ZSA9IFwiRmFybSBBXCIsXG4gICAgICAgICAgICAgICAgICBkZiA9IGZhcm1BX3N0YW5kYXJkLFxuICAgICAgICAgICAgICAgICAgdGhlc3RhdGlvbiA9IDEyKVxuYGBgIn0= -->
|
|
|
|
|
<pre class="r"><code>getmetheplot_pliz(site = "Farm A",
|
|
|
|
|
df = farmA_standard,
|
|
|
|
|
thestation = 12)</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>The reason why this trend occurs is not clear, but it could be that
|
|
|
|
|
these animals are learning to avoid each other. Another possible
|
|
|
|
|
explanation is that the animals are going less to the feeder as they
|
|
|
|
|
grow, and thus there is less of a chance that the animals can interact
|
|
|
|
|
with each other. The
|
|
|
|
|
<code>getmetheplot_pliz_but_corrected_this_time()</code> function
|
|
|
|
|
corrects the network density by the times the animals visit the
|
|
|
|
|
feeder.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
<!-- rnb-chunk-begin -->
|
|
|
|
|
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuZ2V0bWV0aGVwbG90X3BsaXpfYnV0X2NvcnJlY3RlZF90aGlzX3RpbWUoc2l0ZSA9IFwiRmFybSBBXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZiA9IGZhcm1BX3N0YW5kYXJkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlc3RhdGlvbiA9IDUpXG5gYGAifQ== -->
|
|
|
|
|
<pre class="r"><code>getmetheplot_pliz_but_corrected_this_time(site = "Farm A",
|
|
|
|
|
df = farmA_standard,
|
|
|
|
|
thestation = 5)</code></pre>
|
|
|
|
|
<!-- rnb-source-end -->
|
|
|
|
|
<!-- rnb-plot-begin eyJoZWlnaHQiOjQzMi42MzI5LCJ3aWR0aCI6NzAwLCJzaXplX2JlaGF2aW9yIjowLCJjb25kaXRpb25zIjpbXX0= -->
|
|
|
|
|
<p><img src="data:image/png;base64,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
|
|
|
|
|
<!-- rnb-plot-end -->
|
|
|
|
|
<!-- rnb-chunk-end -->
|
|
|
|
|
<!-- rnb-text-begin -->
|
|
|
|
|
<p>Even with this correction, we still see a downward trend.</p>
|
|
|
|
|
<p>Thanks for reading all of this, you can reach me at Microsoft Teams
|
|
|
|
|
or e-mail at <em><a href="mailto:lagog6@ulaval.ca" class="email">lagog6@ulaval.ca</a></em>.</p>
|
|
|
|
|
<!-- rnb-text-end -->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2022-09-28 22:34:10 +02:00
|
|
|
|
<div id="rmd-source-code">LS0tDQp0aXRsZTogIkRlbW8gZm9yIHRoZSBwcmVzZW50YXRpb24gJ0dldHRpbmcgaW5zaWdodHMgZnJvbSBhdXRvbWF0aWMgZmVlZGVyIGRhdGEnIg0KYXV0aG9yOg0KLSBMdWlzIEdvbnphbGV6LUdyYWNpYSAobGFnb2c2QHVsYXZhbC5jYSkgDQotIFR3aXR0ZXIgLSBAZ29uemFsdWlzYW5kcmVzDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiAlWScpYCINCnRhZ3M6IFtzb2NpYWwgbmV0d29yayBhbmFseXNpcywgYW5pbWFsIHNjaWVuY2VdDQphYnN0cmFjdDoNCiAgVGhpcyBzaG9ydCBSIE5vdGVib29rIHdpbGwgc2hvdyB0aGUgd29ya2Zsb3cgYXMgcHJlc2VudGVkIGluIG15IHByZXNlbnRhdGlvbiB0b2RheS4NCg0KICBXZSB3aWxsIGdyYWIgdG8gZGlmZmVyZW50IHNvdXJjZXMgb2YgZGF0YSwgYW5kIGRvIHNvbWUgd3JhbmdsaW5nLCB2aXN1YWxpemF0aW9uLA0KICBhbmQgYW5hbHlzaXMuIA0KDQogIFRoZSBzY3JpcHQgY2FuIGFsc28gYmUgYWNjZXNzZWQgaW4gdGhlIGBkZW1vLlIgYCBmaWxlLCBhbHNvIGluIHRoaXMgcmVwb3NpdG9yeS4gDQpvdXRwdXQ6DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCg0KDQojIEhvdyB0byBnZXQgYW5kIHJ1biB0aGlzIGZpbGVzIG9uIHlvdXIgb3duIGNvbXB1dGVyOg0KIVtTb21lIG9mIHlvdSBtaWdodCBiZSB0b28geW91bmcgdG8gZ2V0IHRoZSByZWZlcmVuY2VdKGltZy96b29sYW5kZXJmaWxlc2luY29tcHV0ZXIuanBnKQ0KDQpZb3UgY2FuIHJ1biBhbmQgdHdlYWsgdGhpcyBjb2RlIGJ5IGNsb25pbmcgbXkgcmVwb3NpdG9yeS4gSWYgeW91IGRvIG5vdCBrbm93IHdoYXQNCmEgcmVwb3NpdG9yeSBpcywgSSByZWNvbW1lbmQgeW91IHRvIGJlZ2luIHJlYWRpbmcgYWJvdXQgaXQgaWYgeW91IHdhbnQgdG8gd29yaw0KY29sbGFib3JhdGl2ZWx5IHdpdGggb3RoZXIgcGVvcGxlLiANCg0KIDEuIEluc3RhbGwgZ2l0IGh0dHBzOi8vZ2l0LXNjbS5jb20vYm9vay9lbi92Mi9HZXR0aW5nLVN0YXJ0ZWQtSW5zdGFsbGluZy1HaXQNCiAyLiBHbyB0byB0aGUgZm9sZGVyIHlvdSB3YW50IHRoZSBmb2xkZXIgd2l0aCB0aGUgZmlsZXMgdG8gYmUgbG9jYXRlZC4NCiAzLiBPcGVuIHRoYXQgZm9sZGVyIGluIHRoZSB0ZXJtaW5hbCBhbmQgdHlwZQ0KIA0KYGBge2Jhc2h9DQpnaXQgY2xvbmUgaHR0cHM6Ly9naXQuZGlzcm9vdC5vcmcvbHVhbmdvbnovZmVlZGVyLWFuYWx5dGljcy1kZW1vLmdpdA0KYGBgDQoNCkdpdCB3aWxsIGF1dG9tYXRpY2FsbHkgY3JlYXRlIGEgZm9sZGVyIGFuZCBkb3dubG9hZCBhbGwgdGhlIGZpbGVzIHJlcXVpcmVkIHRvIHJ1bg0KdGhpcyBjb2RlLiANCg0KIyBTZXR1cA0KDQpTaW5jZSB0aGUgaWRlYSBvZiB0aGlzIHByb2plY3QgaXMgdG8gYmUgYXMgbW9kdWxhciBhbmQgYXV0b21hdGVkIGFzIHBvc3NpYmxlLCANCkkgY3JlYXRlZCBhIHNldCBvZiBjdXN0b20gZnVuY3Rpb25zIHRoYXQgZG8gdGhlIGhlYXZ5IGxpZnRpbmcgaW4gdGhlIGJhY2tncm91bmQsIA0Kd2l0aG91dCBjbHV0dGVyaW5nIHRvbyBtdWNoIHRoZSBzY3JpcHQgZmlsZS4gVGhpcyBoYXMgc29tZSBhZHZhbnRhZ2VzIGFuZCBkaXNhZHZhbnRhZ2VzLA0Kc2luY2UgYWx0aG91Z2ggaXQgaXMgZWFzaWVyIHRvIHJlYWQgYW5kIHRoZSB3b3JrZmxvdyBpcyBlYXN5IHRvIGZvbGxvdyBhbG9uZywgaWYNCmlzc3VlcyBhcHBlYXIsIHRoZW4gZGVidWdnaW5nIGFuZCBmb2xsb3dpbmcgdGhlIGZ1bmN0aW9uIHRoYXQgb3JpZ2luYXRlZCB0aGUgaXNzdWUNCmlzIG1vcmUgdGltZS1jb25zdW1pbmcuIA0KDQpUaGUgZm9sZGVyIGlzIG9yZ2FuaXplZCBpbiB0aGUgbWFpbiBwcm9qZWN0IGZpbGVzIGFuZCB0d28gZm9sZGVyczoNCg0KIC0gVGhlIGBkYXRhYCBmb2xkZXIgaG9sZHMgdGhlIGRhdGEgZmlsZXMgd2Ugd2lsbCBiZSBsb2FkaW5nIGludG8gdGhlIGVudmlyb25tZW50LiANCiAtIFRoZSBgc2V0dXBgIGZvbGRlciAodXNlZCBpbiB0aGlzIHNlY3Rpb24pIGhvbGRzIHR3byBrZXkgZmlsZXM6DQogICAgLSBgZnVuY3Rpb25zLlJgIHRoYXQgaG9sZHMgYWxsIHRoZSBjdXN0b20gZnVuY3Rpb25zDQogICAgLSBgbG9hZGxpYnJhcmllcy5SYCB0aGF0IGhhcyBhbGwgdGhlIGxpYnJhcmllcyBuZWVkZWQgZm9yIGFueSBzY3JpcHQgZmlsZSB0aGF0IA0KICAgIHVzZXMgdGhlIHNhbWUgc2V0IG9mIGxpYnJhcmllcyAoc28geW91IGRvIG5vdCBuZWVkIHRvIGNvcHkgYW5kIHBhc3RlIGl0IGluIGV2ZXJ5DQogICAgZmlsZSBvZiB0aGUgcHJvamVjdCkNCiAgICANCldoZW4gd2UgcnVuIHRoZSBgc291cmNlKClgIGZ1bmN0aW9uIGF0IHRoaXMgc3RlcCwgd2UgYXJlIGxvYWRpbmcgYm90aCB0aGUgbGlicmFyaWVzDQphbmQgdGhlIGZ1bmN0aW9ucyB0aGF0IHdlIGFyZSBnb2luZyB0byB1c2UgdGhyb3VnaG91dCB0aGUgZGVtby4gDQoNCmBgYHtyIHNldHVwLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzb3VyY2UoInNldHVwL2Z1bmN0aW9ucy5SIikNCnNvdXJjZSgic2V0dXAvbG9hZGxpYnJhcmllcy5SIikNCmBgYA0KDQoNCiMgSW1wb3J0aW5nIGRhdGEgDQoNCkZpcnN0IHN0ZXAgaW4gdGhlIHByb2Nlc3MgaXMgdG8gbG9hZCB0aGUgZXhjZWwgZmlsZSBpbiB0aGUgZW52aXJvbm1lbnQuIA0KVGhlcmUgYXJlIHBhY2thZ2VzIHRoYXQgY2FuIG5hdGl2ZWx5IGltcG9ydCBleGNlbCBmaWxlcyB0aGF0IGFyZSB2ZXJ5IHN0cmFpZ2h0Zm9yd2FyZCwgDQpidXQgc29tZSBvZiB0aGVtIGRvIG5vdCBoYW5kbGUgdGhlIERhdGUgaW5mb3JtYXRpb24gcHJvcGVybHkuIEZvciB0aGlzIEkgaGF2ZSBhIGN1c3RvbSBmdW5jdGlvbiB0aGF0IHRha2VzIGludG8gYWNjb3VudCBzb21lIGNvbW1vbiBpc3N1ZXMgYW5kIHdpdGggdGhlIGBtZXRob2QgPWAgcGFyYW1ldGVyLCBJIA0KY2FuIGZpbmUtdHVuZSB0aGUgaW1wb3J0aW5nIG1ldGhvZCBhY2NvcmRpbmcgdG8gd2hlcmUgdGhlIGRhdGEgY29tZ
|
2022-09-28 22:20:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
// add bootstrap table styles to pandoc tables
|
|
|
|
|
function bootstrapStylePandocTables() {
|
|
|
|
|
$('tr.odd').parent('tbody').parent('table').addClass('table table-condensed');
|
|
|
|
|
}
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
bootstrapStylePandocTables();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
$('.knitsql-table').addClass('kable-table');
|
|
|
|
|
var container = $('.kable-table');
|
|
|
|
|
container.each(function() {
|
|
|
|
|
|
|
|
|
|
// move the caption out of the table
|
|
|
|
|
var table = $(this).children('table');
|
|
|
|
|
var caption = table.children('caption').detach();
|
|
|
|
|
caption.insertBefore($(this)).css('display', 'inherit');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<!-- tabsets -->
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
window.buildTabsets("TOC");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
$('.tabset-dropdown > .nav-tabs > li').click(function () {
|
|
|
|
|
$(this).parent().toggleClass('nav-tabs-open');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<!-- code folding -->
|
|
|
|
|
<script>
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
window.initializeSourceEmbed("demo-notebook.Rmd");
|
|
|
|
|
window.initializeCodeFolding("show" === "show");
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- dynamically load mathjax for compatibility with self-contained -->
|
|
|
|
|
<script>
|
|
|
|
|
(function () {
|
|
|
|
|
var script = document.createElement("script");
|
|
|
|
|
script.type = "text/javascript";
|
|
|
|
|
script.src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
|
|
|
|
|
document.getElementsByTagName("head")[0].appendChild(script);
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|