diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..646ac519 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +node_modules/ diff --git a/assets/atelier-forest.light.css b/assets/atelier-forest.light.css new file mode 100644 index 00000000..806ba739 --- /dev/null +++ b/assets/atelier-forest.light.css @@ -0,0 +1,93 @@ +/* Base16 Atelier Forest Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ +/* https://github.com/jmblog/color-themes-for-highlightjs */ + +/* Atelier Forest Light Comment */ +.hljs-comment, +.hljs-title { + color: #766e6b; +} + +/* Atelier Forest Light Red */ +.hljs-variable, +.hljs-attribute, +.hljs-tag, +.hljs-regexp, +.ruby .hljs-constant, +.xml .hljs-tag .hljs-title, +.xml .hljs-pi, +.xml .hljs-doctype, +.html .hljs-doctype, +.css .hljs-id, +.css .hljs-class, +.css .hljs-pseudo { + color: #f22c40; +} + +/* Atelier Forest Light Orange */ +.hljs-number, +.hljs-preprocessor, +.hljs-pragma, +.hljs-built_in, +.hljs-literal, +.hljs-params, +.hljs-constant { + color: #df5320; +} + +/* Atelier Forest Light Yellow */ +.hljs-ruby .hljs-class .hljs-title, +.css .hljs-rules .hljs-attribute { + color: #d5911a; +} + +/* Atelier Forest Light Green */ +.hljs-string, +.hljs-value, +.hljs-inheritance, +.hljs-header, +.ruby .hljs-symbol, +.xml .hljs-cdata { + color: #5ab738; +} + +/* Atelier Forest Light Aqua */ +.css .hljs-hexcolor { + color: #00ad9c; +} + +/* Atelier Forest Light Blue */ +.hljs-function, +.python .hljs-decorator, +.python .hljs-title, +.ruby .hljs-function .hljs-title, +.ruby .hljs-title .hljs-keyword, +.perl .hljs-sub, +.javascript .hljs-title, +.coffeescript .hljs-title { + color: #407ee7; +} + +/* Atelier Forest Light Purple */ +.hljs-keyword, +.javascript .hljs-function { + color: #6666ea; +} + +.hljs { + display: block; + background: #f1efee; + color: #68615e; + padding: 0.5em; +} + +.coffeescript .javascript, +.javascript .xml, +.tex .hljs-formula, +.xml .javascript, +.xml .vbscript, +.xml .css, +.xml .hljs-cdata { + opacity: 0.5; +} diff --git a/assets/highlight.css b/assets/highlight.css new file mode 100644 index 00000000..b71b008d --- /dev/null +++ b/assets/highlight.css @@ -0,0 +1,94 @@ +/* Base16 Atelier Forest Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ +/* https://github.com/jmblog/color-themes-for-highlightjs */ + +/* Atelier Forest Light Comment */ +.hljs-comment, +.hljs-title { + color: #acacac; +} + +/* Atelier Forest Light Red */ +.hljs-variable, +.hljs-attribute, +.hljs-tag, +.hljs-regexp, +.ruby .hljs-constant, +.xml .hljs-tag .hljs-title, +.xml .hljs-pi, +.xml .hljs-doctype, +.html .hljs-doctype, +.css .hljs-id, +.css .hljs-class, +.css .hljs-pseudo { + color: #0091FF; +} + +/* Atelier Forest Light Orange */ +.hljs-number, +.hljs-preprocessor, +.hljs-pragma, +.hljs-built_in, +.hljs-literal, +.hljs-params, +.hljs-constant { + color: #085896; +} + +/* Atelier Forest Light Yellow */ +.hljs-ruby .hljs-class .hljs-title, +.css .hljs-rules .hljs-attribute { + color: #d5911a; +} + +/* Atelier Forest Light Green */ +.hljs-string, +.hljs-value, +.hljs-inheritance, +.hljs-header, +.ruby .hljs-symbol, +.xml .hljs-cdata { + color: #09cc40; +} + +/* Atelier Forest Light Aqua */ +.css .hljs-hexcolor { + color: #00ad9c; +} + +/* Atelier Forest Light Blue */ +.hljs-function, +.python .hljs-decorator, +.python .hljs-title, +.ruby .hljs-function .hljs-title, +.ruby .hljs-title .hljs-keyword, +.perl .hljs-sub, +.javascript .hljs-title, +.coffeescript .hljs-title { + color: #407ee7; + font-weight: bold; +} + +/* Atelier Forest Light Purple */ +.hljs-keyword, +.javascript .hljs-function { + color: #6666ea; +} + +.hljs { + display: block; + /*background: #f1efee;*/ + color: #68615e; + /*padding: 0.5em;*/ +} + +/*.coffeescript .javascript, +.javascript .xml, +.tex .hljs-formula, +.xml .javascript, +.xml .vbscript, +.xml .css, +.xml .hljs-cdata { + opacity: 0.5; +}*/ diff --git a/assets/highlight.js b/assets/highlight.js new file mode 100644 index 00000000..5807522f --- /dev/null +++ b/assets/highlight.js @@ -0,0 +1 @@ +var hljs=new function(){function k(v){return v.replace(/&/gm,"&").replace(//gm,">")}function t(v){return v.nodeName.toLowerCase()}function i(w,x){var v=w&&w.exec(x);return v&&v.index==0}function d(v){return Array.prototype.map.call(v.childNodes,function(w){if(w.nodeType==3){return b.useBR?w.nodeValue.replace(/\n/g,""):w.nodeValue}if(t(w)=="br"){return"\n"}return d(w)}).join("")}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^language-/,"")});return v.filter(function(x){return j(x)||x=="no-highlight"})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(t(A)=="br"){z+=1}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset"}function E(G){F+=""}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=k(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+k(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};function E(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})}if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b=D.bK.split(" ").join("|")}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?\\b("+F.b+")\\b\\.?":F.b}).concat([D.tE]).concat([D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}};D.continuation={}}x(y)}function c(S,L,J,R){function v(U,V){for(var T=0;T";U+=Z+'">';return U+X+Y}function N(){var U=k(C);if(!I.k){return U}var T="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(U);while(V){T+=U.substr(X,V.index-X);var W=E(I,V);if(W){H+=W[1];T+=w(W[0],V[0])}else{T+=V[0]}X=I.lR.lastIndex;V=I.lR.exec(U)}return T+U.substr(X)}function F(){if(I.sL&&!f[I.sL]){return k(C)}var T=I.sL?c(I.sL,C,true,I.continuation.top):g(C);if(I.r>0){H+=T.r}if(I.subLanguageMode=="continuous"){I.continuation.top=T.top}return w(T.language,T.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(V,U){var T=V.cN?w(V.cN,"",true):"";if(V.rB){D+=T;C=""}else{if(V.eB){D+=k(U)+T;C=""}else{D+=T;C=U}}I=Object.create(V,{parent:{value:I}})}function G(T,X){C+=T;if(X===undefined){D+=Q();return 0}var V=v(X,I);if(V){D+=Q();P(V,X);return V.rB?0:X.length}var W=z(I,X);if(W){var U=I;if(!(U.rE||U.eE)){C+=X}D+=Q();do{if(I.cN){D+=""}H+=I.r;I=I.parent}while(I!=W.parent);if(U.eE){D+=k(X)}C="";if(W.starts){P(W.starts,"")}return U.rE?0:X.length}if(A(X,I)){throw new Error('Illegal lexeme "'+X+'" for mode "'+(I.cN||"")+'"')}C+=X;return X.length||1}var M=j(S);if(!M){throw new Error('Unknown language: "'+S+'"')}m(M);var I=R||M;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,D,true)}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+=""}}return{r:H,value:D,language:S,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:k(L)}}else{throw O}}}function g(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:k(y)};var w=v;x.forEach(function(z){if(!j(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function h(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"
")}return v}function p(z){var y=d(z);var A=r(z);if(A=="no-highlight"){return}var v=A?c(A,y,true):g(y);var w=u(z);if(w.length){var x=document.createElementNS("http://www.w3.org/1999/xhtml","pre");x.innerHTML=v.value;v.value=q(w,u(x),y)}v.value=h(v.value);z.innerHTML=v.value;z.className+=" hljs "+(!A&&v.language||"");z.result={language:v.language,re:v.r};if(v.second_best){z.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function e(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function j(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=g;this.fixMarkup=h;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=e;this.getLanguage=j;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("bash",function(b){var a={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]};var d={cN:"string",b:/"/,e:/"/,c:[b.BE,a,{cN:"variable",b:/\$\(/,e:/\)/,c:[b.BE]}]};var c={cN:"string",b:/'/,e:/'/};return{l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[b.inherit(b.TM,{b:/\w[\w\d_]*/})],r:0},b.HCM,b.NM,d,c,a]}});hljs.registerLanguage("diff",function(a){return{c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});hljs.registerLanguage("javascript",function(a){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:10},a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,c:[a.inherit(a.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+a.IR,r:0}]}});hljs.registerLanguage("xml",function(a){var c="[A-Za-z0-9\\._:-]+";var d={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"};var b={eW:true,i:/]+/}]}]}]};return{aliases:["html"],cI:true,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[b],starts:{e:"",rE:true,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},d,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:"[^ /><]+",r:0},b]}]}});hljs.registerLanguage("markdown",function(a){return{c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].+?[\\)\\]]",rB:true,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:true,rE:true,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:true,eE:true},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:true,eE:true,}],r:10},{b:"^\\[.+\\]:",e:"$",rB:true,c:[{cN:"link_reference",b:"\\[",e:"\\]",eB:true,eE:true},{cN:"link_url",b:"\\s",e:"$"}]}]}});hljs.registerLanguage("css",function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}});hljs.registerLanguage("http",function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}});hljs.registerLanguage("ini",function(a){return{cI:true,i:/\S/,c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM],r:0}]}]}});hljs.registerLanguage("json",function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}); \ No newline at end of file diff --git a/assets/sss.css b/assets/sss.css new file mode 100644 index 00000000..de9fa702 --- /dev/null +++ b/assets/sss.css @@ -0,0 +1,25 @@ +/* General */ + +body {margin: 0px auto;} +a {color: #333;} +input:focus {outline: none;} + +/* Table */ + +table {text-align: left; width: 100%} +th {padding: 10px 0px;} +td, text {padding: 3px 20px 3px 0px; font-size: 14px;} +.noMatches {margin-left: 20px; font-size: 11px; font-style: italic; visibility: hidden;} + +/* Line Chart */ + +.axis {shape-rendering: crispEdges;} +.x.axis .minor, .y.axis .minor {stroke-opacity: .5;} +.x.axis {stroke-opacity: 1;} +.y.axis line, .y.axis path {fill: none; stroke: #acacac; stroke-width: 1;} +.bigg {-webkit-transition: all .2s ease-in-out; -webkit-transform: scale(2);} +path.chartLine {stroke: #333; stroke-width: 3; fill: none;} +div.tooltip {position: absolute; text-align: left; padding: 4px 8px; width: auto; font-size: 10px; height: auto; background: #fff; border: 0px; pointer-events: none;} +circle {fill: #e6e6e6;} + +@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 320px) and (max-width: 1024px) {} diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 00000000..98fcfc14 --- /dev/null +++ b/assets/style.css @@ -0,0 +1,80 @@ +.container {max-width: 800px; margin: 0 auto; overflow: auto;} + +h3 {padding-top: 18px;} +h1 {font-size: 36px;} + +table {border-spacing: 0;} +tbody tr:nth-child(odd) {background-color: #f3f3f3;} +thead {text-align: left; font-family: Source Sans Pro, Arial, sans-serif;} +td {min-width: 140px; vertical-align: top; padding: 8px;} +td a {line-height: 24px;} +tr {height: 50px;} +ul, ol {text-indent: 0; margin: 0; padding-left: 20px;} +ul li {padding-bottom: 6px; line-height: 22px;} + +footer {padding-top: 20px; margin-top: 60px; border-top: 4px solid #CCF4FF; -webkit-column-count: 6; column-count: 6; -webkit-column-gap: 20px; column-gap: 20px; -moz-column-count: 6; -moz-column-gap: 20px; height: 125px;} +footer ul {list-style: none; padding-left: 0px; font-family: Source Sans Pro, Baskerville, Georgia, serif;} +footer li {line-height: inherit; font-size: 12px;} +footer h4 {font-size: 14px; -webkit-column-break-before: always; break-before: always; -moz-column-break-before: always; } +footer h4 {margin-top: 0px;} +footer a {border: none;} + +.half {max-width: 50%; display: inline-block; vertical-align: top;} +.half:nth-child(odd) {padding-left: 20px;} + +img[alt=sheetseeimg] { + width: 400px; + margin: 0 auto; +} + +.index p:first-of-type { + text-align: center; +} +/* older css */ + +body {font-family: 'Source Sans Pro'; background: #fff; color: #535353; border: 10px #47CCFC solid; margin: 0px; padding: 20px 20px 100px 20px; overflow: auto; } +h1, h2, h3, h4, h5, h6 {font-family: Source Sans Pro, Arial, sans-serif;} +h2 {margin-top: 40px;} + +img {width: 100%;} +hr {border: 2px solid #CCF4FF;} + +p {font-size: 18px;} +p a, a {color: #535353; text-decoration: none; padding-bottom: 0px; border-bottom: 2px #CCF4FF solid;} +a:hover {color: #47CCFC;} +a:active {color: #47CCFC;} +small {padding: 10px 0px;} +p, ol {line-height: 1.4;} +text {font-size: 12px;} + +body.index p:nth-of-type(2) {font-size: 30px;} +body.index table {border: 4px solid #CCF4FF; padding: 18px;} +.home-link {color: #47CCFC;} + +pre {word-wrap: break-word; padding: 10px; background: #F8F8F8;} +pre code {padding: 0;} +code {font-family: "Source Code Pro", monospace; line-height: 1; font-size: 14px; background: #F8F8F8; color: #636363; font-weight: 400; padding: 2px 6px; border-radius: 2px;} +h3 code {font-weight: bold; background: #CCF4FF; font-size: 19px;} +.hljs {background: #F8F8F8; color: #494949; line-height: 1.4em;} + +.new-news { + color: #47CCFC; + font-size: 30px; + font-weight: bold; + border: 8px solid #47CCFC; + /*border-radius: 3px;*/ + display: inline-block; + padding: 6px 16px; + margin-top: 40px; +} + +/* funsies */ +::selection {background: #44FFB4;} +::-moz-selection {background: #44FFB4;} + +/* Table */ +.ssExample table {min-width: 600px;} +.tHeader::after {content: " \2193 \2191 "; font-size: 10px; padding-left: 3px; cursor: pointer;} + +/* Map Popup Style */ +.leaflet-popup-content h2 {margin-bottom: 4px; margin-top: auto;} diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..52c2a7db --- /dev/null +++ b/bower.json @@ -0,0 +1,25 @@ +{ + "name": "sheetsee", + "main": [ + "js/sheetsee.js", + "css/sss.css" + ], + "ignore": [ + "contributing.md", + "docs", + "demos", + "img", + "site" + ], + "homepage": "http://jlord.github.io/sheetsee.js", + "description": "Sheetsee.js is a library for easily creating tables, charts and maps from spreadsheet data.", + "keywords": [ + "spreadsheet", + "tables", + "maps" + ], + "dependencies": { + "jquery": ">= 1.9.0", + "tabletop": ">= 1.3.5" + } +} diff --git a/changelog.md b/changelog.md deleted file mode 100644 index 6aba04ae..00000000 --- a/changelog.md +++ /dev/null @@ -1,22 +0,0 @@ -## August 13, 2013 -### Charting Intake - -D3 charts need an array of objects, and something to chart: the thing itself (aka labels) and the corresponding value (aka units). Your data usually contains more than D3 needs to make the chart, so you have to tell it what to chart from your data to chart. - -Previously Sheetsee required you pass your data through a function, `addUnitsAndLabels()` which took in your data and the things you wanted to chart, reformatted your data for you so that you could pass it into one of the d3 charts. This is one more step than actually needs to happen. - -Now Sheetsee just asks for what you want your _labels_ and _units_ to be in the options you give it when calling the chart function. It then sorts the data correctly on the inside of the chart function. Yay, easier! - -``` - var options = { - labels: "name", - units: "cuddleability", - m: [60, 60, 30, 150], - w: 600, h: 400, - div: "#barChart", - xaxis: "no. of pennies", - hiColor: "#FF317D" - } -``` - -Thanks @maxogden for the help with this. diff --git a/contributing.md b/contributing.md new file mode 100644 index 00000000..3296973c --- /dev/null +++ b/contributing.md @@ -0,0 +1,17 @@ +# Contributing to Sheetsee.js + +This repository (github/jlord/sheetsee.js) is primarily for documentation and the documentation website. It also contains a copy of a full sheetsee.js (one that includes the map, charts and table portions). + +### Use this repository to file issues and pull requests on documentation/documentation site. + +The documentation is contained in the `/docs` and `/demos` folders in the root. I build the site (on the `gh-pages` branch) from these files so **submit pull requests against the files in `/docs` and `/demos`** and not the `/site` folder or the `gh-pages` branch. + +### For issues and pull requests on the JavaScript, use the repository for the affected portion: + +- [sheetsee](http://www.github.com/jlord/sheetsee/issues/new) +- [sheetsee-core](http://www.github.com/jlord/sheetsee-core/issues/new) +- [sheetsee-tables](http://www.github.com/jlord/sheetsee-tables/issues/new) +- [sheetsee-maps](http://www.github.com/jlord/sheetsee-maps/issues/new) +- [sheetsee-charts](http://www.github.com/jlord/sheetsee-charts/issues/new) + +Thank you much! :heart: :octocat: diff --git a/css/site.css b/css/site.css deleted file mode 100644 index f12e0489..00000000 --- a/css/site.css +++ /dev/null @@ -1,90 +0,0 @@ -/* Page Specific CSS */ - -body {font-family: Merriweather; background: #fff; color: #333; font-size: 100%; border: 10px #47CCFC solid; margin: 0px; padding: 20px 20px 200px 20px; font-size: 16px; } -h1, h2, h3, h4, h5, h6 {font-family: Helvetica, Arial, sans-serif;} -h2 {margin-top: 82px;} - -h3.functionH {margin-left: -14px; margin-top: 52px; border-top: 3px solid #47CCFC; border-left: 3px solid #47CCFC; border-right: 3px solid #47CCFC; padding-left: 14px; padding-top: 9px; } -img {width: 100%;} - -p a, a {color: #333; text-decoration: none; padding-bottom: 0px; border-bottom: 2px #CCF4FF solid;} -p a:visted {color: #ff00ff;} -a:hover {color: #47CCFC;} -a:visited {color: #333;} -small {padding: 10px 0px;} -p, ol {line-height: 24px;} - -pre {word-wrap: break-word; padding: 14px; background: #F0F0F0;} -code {font-family: "Consolas", "Ubuntu Mono", monospace; line-height: 22px; font-size: 13px; color: #636363; font-weight: normal;} - -/* funsies */ -::selection {background: #44FFB4;} -::-moz-selection {background: #44FFB4;} - -img.petThumbs {height: 80px; width: 80px; border-radius: 1000px;} - -.button {padding: 5px 4px; background-color: #fff; font-size: 10px;} - -#menu {color: #fff; padding: 20px; float: left; position: fixed; left: 40px; top: 40px; max-width: 300px; font-family: Helvetica, Arial, sans-serif; font-size: 14px;} -#menu ul {list-style: none; margin: 0px; padding: 0px;} -#menu li {line-height: 34px;} -#menu li a {padding: 4px 8px; background-color: #F0F0F0; text-decoration: none; border: none;} -#menu li a.a2 {background-color: #CCF4FF;} -#menu li a:hover {background-color: #e7e7e7; color: #333;} - -#wrapper {margin: 0px auto; max-width: 800px; padding-top: 40px;} - -/* Examples */ -.ssExample {margin: 20px -28px; background-color: #CCF4FF; padding: 20px 28px; background-color: #CCF4FF; border: 8px solid #47CCFC; margin-top: 44px; padding-top: 0px; overflow: auto;} -.ssExample li {padding: 2px 0px;} -.ssExample h2 {margin-top: inherit;} - -/* Table */ -.ssExample table {min-width: 600px;} -.tHeader::after {content: " \2193 \2191 "; font-size: 10px; padding-left: 3px;} - -/* Map Popup Style */ -.leaflet-popup-content h2 {margin-bottom: 4px; margin-top: auto; font-family: Merriweather;} - -/* Most Cuddleable Template */ -#mostCuddle img.most {max-width: 400px; border-radius: 9999px; margin-top: 34px;} -#mostCuddle {text-align: center;} -#mostCuddle table {width: auto;} -#mostCuddle li {padding: 10px 0px; font-size: 18px; display: inline-block;} -.boxText {background-color: #47CCFC; padding: 4px 8px; font-family: Helvetica, Arial, sans-serif;} - -/* Bar Chart */ -#dogBar.labels text {text-align: right;} -#dogBar.bar .labels text {fill: #333;} -#dogBar.bar rect {fill: #e6e6e6;} -#dogBar.axis {shape-rendering: crispEdges;} -#dogBar .x.axis line {stroke: #CCF4FF; fill: none;} -#dogBar.x.axis path {fill: none;} -#dogBar.x.axis text {fill: #333;} -#dogBar.xLabel {font-family: sans-serif; font-size: 9px;} - - -/* Line Chart */ -#dogLine.axis {shape-rendering: crispEdges;} -#dogLine.x.axis .minor, #dogLine.y.axis .minor {stroke-opacity: .5;} -#dogLine.x.axis {stroke-opacity: 1;} -#dogLine.y.axis line, #dogLine.y.axis path, #dogLine.x.axis path {fill: none; stroke: #acacac; stroke-width: 1;} -#dogLine .x.axis line {stroke: #acacac; stroke-opacity: .75;} -.bigg {-webkit-transition: all .2s ease-in-out; -webkit-transform: scale(2);} -path.chartLine {stroke: #14ECC8; stroke-width: 3; fill: none;} -div.tooltip {position: absolute; text-align: left; padding: 4px 8px; width: auto; font-size: 10px; height: auto; background: #fff; border: 0px; pointer-events: none;} -circle {fill: #fff;} - -/* Pie Chart */ -.arc path { stroke: #fff;} - -/* Responsive Town */ - -@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 320px) and (max-width: 1024px) { - body {padding-bottom: 50px;} - #wrapper {max-width: 100%; padding-top: 20px;} - #menu {color: #fff; padding: 0px; float: none; position: relative; left: auto; top: auto; max-width: 100%; font-family: Helvetica, Arial, sans-serif;} - #menu li {display: inline-block;} - h3.functionH {margin: 0px; border-top: 5px solid #47CCFC; border-left: 0px; border-right: 0px; padding-top: 9px; word-wrap: break-word; padding-left: 0px;} - ul {padding-left: 20px;} -} diff --git a/css/style.css b/css/style.css deleted file mode 100644 index b0e42642..00000000 --- a/css/style.css +++ /dev/null @@ -1,56 +0,0 @@ - /* General */ - - body {margin: 0px auto;} - a {color: #333;} - #wrapper {margin: 0px auto; max-width: 600px;} - .button {padding: 5px 4px; background-color: #fff; font-size: 10px;} - .button:hover {cursor: hand;} - input:focus {outline: none;} - - /* Table */ - - table {text-align: left; width: 100%} - th {padding: 10px 0px;} - td, text {padding: 3px 20px 3px 0px; font-size: 14px;} - #tableFilter, #basicFilter, #dogFilter {margin: 12px 0px; border: none; border-bottom: 1px solid #333; background-color: transparent; padding: 0px; font-family: Merriweather; color: #FCB688; font-size: 13px; height: 22px;} - .tHeader {/* table column header style */} - .noMatches {margin-left: 20px; font-size: 11px; font-style: italic; visibility: hidden;} - - /* Containers */ - .container {margin: 14px 0px;} - #map {height: 400px; max-width: 800px; background: #DADADA; overflow: hidden;} - #holder {height: 400px; max-width: 600px; background: #FFE4E4;} - - /* Overflow for large tables and chart */ - .container {overflow-x: auto;} - #yourDiv {min-width: 600px} - - /* Bar Chart */ - - .labels text {text-align: right;} - .bar .labels text {fill: #333;} - .bar rect {fill: #e6e6e6;} - .axis {shape-rendering: crispEdges;} - .x.axis line {stroke: #fff; fill: none;} - .x.axis path {fill: none;} - .x.axis text {fill: #333;} - .xLabel {font-family: sans-serif; font-size: 9px;} - -/* Line Chart */ - - .axis {shape-rendering: crispEdges;} - .x.axis .minor, .y.axis .minor {stroke-opacity: .5;} - .x.axis {stroke-opacity: 1;} - .y.axis line, .y.axis path {fill: none; stroke: #acacac; stroke-width: 1;} - .bigg {-webkit-transition: all .2s ease-in-out; -webkit-transform: scale(2);} - path.chartLine {stroke: #333; stroke-width: 3; fill: none;} - div.tooltip {position: absolute; text-align: left; padding: 4px 8px; width: auto; font-size: 10px; height: auto; background: #fff; border: 0px; pointer-events: none;} - circle {fill: #e6e6e6;} - -/* Map */ - - .leaflet-popup-content {} - - @media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 320px) and (max-width: 1024px) { - -} diff --git a/demo.html b/demo.html deleted file mode 100644 index 7c07a7d5..00000000 --- a/demo.html +++ /dev/null @@ -1,503 +0,0 @@ - - - Yo, yo, yo! - - - - - - - - - - - - - - - - - -
-

sheetsee

-

Sheetsee.js

-

Sheetsee.js is a JavaScript library, or box of goodies, if you will, that makes it easy to use a Google Spreadsheet as the database feeding the tables, charts and maps on a website. Once set up, any changes to the spreadsheet will auto-saved by Google and be live on your site when a visitor refreshes the page.

-

Using Google Spreadsheets as the backend database is awesome because it is easy to use, share and collaborate with.

-

To use sheetsee.js you'll definitely need to know HTML, CSS and know JavaScript or be not afraid of it and just type what these docs tell you to type. Also, see JavaScript for Cats, Eloquent JavaScript or Mozilla's Developer Network.

- -

Dependencies

-

Sheetsee.js depends on a few other awesome JavaScript libraries to make all this happen. First, Tabletop.js gets the data from the Google Spreadsheet and makes it nice. Once you have your data Sheetsee.js makes it easy to set up tables or templates with IChanHas.js (built on mustache.js), maps with Mapbox.js, and charts with d3.js. And jQuery of course powers most of the interactions. It also has many sorting and filtering functions built in so that you can display different parts of your data if you want. Each of these are explained in more detail below.

- -

CSS

-

Sheetsee.js comes with a bare minimum stylesheet. This way you can customize your site to look the way you want to it or to match an existing site's design.

- -

Client-side or Server-side

-

Sheetsee.js comes in two flavors, client-side (this repo) and server-side (sheetsee-cache). The client-side is the most approachable and straightforward, you just include sheetsee.js and the dependencies on your page and use sheetsee.js as normal.

-

The server-side version is built with Node.js and you'll need to understand Node and be publishing to a server that runs Node.js apps. This version saves the data on the server so that the browser doesn't have to fetch from Google at every request, which can sometimes be slow. You can set when the cache expires. It also allows for offline development, huzzah!

- -
-

The Short & Sweet

-
    -
  1. Link to Sheetsee.js and dependencies in your HTML header.
  2. -
  3. Create a place holder <div> in your HTML for any chart, map or table you want to have.
  4. -
  5. Create templates for tables in <script> tags.
  6. -
  7. Create a script tag that waits for the document to load and then executes any of the map, chart or tables you've specified in it.
  8. -
  9. Set it and forget. Now all you need to do is edit the spreadsheet and visitors will get the latest information everytime they load the page.
  10. -
-
- -

Bare Minimum Setup

-

Ignoring some HTML things to conserve space, you get the point. This gives you a page with a map of your spreadsheets points.

-
<html>
-    <head>
-        <script type="text/javascript" src="http://api.tiles.mapbox.com/mapbox.js/v1.0.0/mapbox.js"></script>
-        <script type="text/javascript" src="js/ICanHaz.js"></script>
-        <script type="text/javascript" src="js/jquery.js"></script>
-        <script type="text/javascript" src="js/tabletop.js"></script>
-        <script type="text/javascript" src="js/d3.js"></script>
-        <script type="text/javascript" src="js/sheetsee.js"></script>
-        <link href='http://api.tiles.mapbox.com/mapbox.js/v1.0.0/mapbox.css' rel='stylesheet' />
-    </head>
-    <style> #map {height: 600px; width: 600px;} </style>
-    <body>
-    <div id="map"></div>
-    <script type="text/javascript">
-      document.addEventListener('DOMContentLoaded', function() {
-        var gData
-        var URL = "0AvFUWxii39gXdFhqZzdTeU5DTWtOdENkQ1Y5bHdqT0E"
-        Tabletop.init( { key: URL, callback: showInfo, simpleSheet: true } )
-      })
-      function showInfo(data) {
-        gData = data
-        optionsJSON = ["something", "something"]
-        var geoJSON = Sheetsee.createGeoJSON(gData, optionsJSON)
-        var map = Sheetsee.loadMap("map")
-        Sheetsee.addTileLayer(map, 'examples.map-20v6611k')
-        var markerLayer = Sheetsee.addMarkerLayer(geoJSON, map, 11)
-        // customize the popup content
-        addPopups(map, markerLayer)
-        function addPopups(map, markerLayer) {
-          markerLayer.on('click', function(e) {
-            var feature = e.layer.feature
-            var popupContent = '<h3>' + feature.opts.something + '</h3>'
-            e.layer.bindPopup(popupContent,{closeButton: false})
-          })
-        }
-      }
-    </script>
-    </body>
-</html>
- -

Awesome Possibilities

-
    -
  1. Small newsrooms with data for stories but small dev teams.
  2. -
  3. Friends or groups collaborating on data for a website/project.
  4. -
  5. Using iftt.com to auto populate spreadsheets which are hooked to a website with Sheetsee.js.
  6. -
- -

Examples

-
    -
  1. Hack Spots
  2. -
  3. James Sconfitto make a map of his relationship with his wife <3
  4. -
- -

Getting Started

-

This bit is the same for both client-side and server-side versions.

-

Your Data

-

sheetsee

-

Your Google Spreadsheet should be set up with row one as your column headers. Row two and beyond should be your data. Each header and row becomes an oject in the final array that Tabletop.js delivers of your data.

-

sheetsee

-

There shouldn't be any breaks or horizontal organization in the spreadsheet. But, feel free to format the style of your spreadsheet as you wish; borders, fonts and colors and such do not transfer or affect your data exporting.

-
[{"name":"Coco","breed":"Teacup Maltese","kind":"Dog","cuddlability":"5","lat":"37.74832","long":"-122.402158","picurl":"http://distilleryimage8.s3.amazonaws.com/98580826813011e2bbe622000a9f1270_7.jpg","hexcolor":"#ECECEC","rowNumber":1}...]
- -

Hexcolor

-

sheetsee

-

You must add a column to your spreadsheet with the heading hexcolor (case insensitive). The maps, charts and such use colors and this is the easiest way to standardize that. The color scheme is up to you, all you need to do is fill the column with hexidecimal color values. This color picker by Devin Hunt is really nice. #Funtip: Coloring the background of the cell it's hexcolor brings delight!

- -

Geocoding

-

If you intend to map your data and only have addresses you'll need to geocode the addresses into lat/long coordinates. Mapbox built a plugin - that does this for you in Google Docs. You can also use websites like latlong.net to get the coordinates and paste them into rows with column headers lat and long.

- sheetsee -

Publishing Your Spreadsheet

-

sheetsee

-

You need to do this in order to generate a unique key for your spreadsheet, which Tabletop.js will use to get your spreadsheet data. In your Google Spreadsheet, click File > Publish to the Web. Then in the next window click Start Publishing; it will then turn into a Stop Publishing button.

-

sheetsee

-

You should have an address in a box at the bottom, your key is the portion between the = and the &. You'll retrieve this later when you hook up your site to the spreadsheet.

-

Your Website

-

Before you get started with Sheetsee.js you should plan out your website. Design it, create the basic markup and stylesheet.

-

For now, create empty div placeholders for the map, chart and tables you plan on including.

-

Hooking Up Your Data

-

Here the paths diverge:

-

Client-side Hookup

-

For client-siders, all you need to do is include the depences and sheetsee in your HTML <head> and then in a script tag at the bottom of your page, right before the </body> tag, you'll include this:

-
<script type="text/javascript">
-    document.addEventListener('DOMContentLoaded', function() {
-        var gData
-        var URL = "0AvFUWxii39gXdFhqZzdTeU5DTWtOdENkQ1Y5bHdqT0E"
-        Tabletop.init( { key: URL, callback: showInfo, simpleSheet: true } )
-    })
-    function showInfo(data) {
-        gData = data
-        //
-        //everything you do with sheetsee goes here
-        //
-    }
-</script>
-

The URL variable is the key from your spreadsheet's longer URL, explained above. Tabletop.init() takes that URL and execute's Tabletop, when it's done generating the table it executes the callback showInfo function. It's inside of this function that you'll then use your spreadsheet data, gData, to do all the Sheetsee.js goodness with.

-

Server-side Hookup

-

The server-side version is in the repo sheetsee-cache. It uses Node.js to go to Google, get the spreadsheet data (with a Node.js version of Tabletop.js, thanks Max Ogden!) and save it on the server. This means every user that visits the page doesn't have to wait on Google's response to load the charts from the data.

-

When the server builds your page, it will build in your data as the variable gData. All you need to do is add your scripts to the bottom of the page. For the tables/templating you'll need to wrap them in an event listener so that it doesn't try and build them before the data has settled.

-
<script type="text/javascript">
-    document.addEventListener('DOMContentLoaded', function() {
-        // table/templating things the rest can be in their own script tags if you'd like
-    })
-</script>
-

Running Locally

-

You can run this locally and it will check your internet connection - if you're not online it will use the last saved data allowing you to develop offline, yay!

-

Once you clone the repo, navigate there in Terminal, install the node modules and launch the server.

-
cd sheetsee-cache
-npm install
-node server.js
-

This will launch a local server you can visit and develop locally with in your browser.

-

Working With Your Data

-

Tabletop.js will return all of your data and it will be passed into your site as an array of objects called gData. Sheetsee.js has functions built in to help you filter or use that data in other ways if you'd like.

-

Play Along!

-

This page is using sheetsee. If you (are in Chrome and) right click on the page and select Inspect Element it will bring up the Web Inspector. Select the Console tab. Now you can interact with the data and functions from Sheetsee. Give the functions below a try - gData is the variable with the data (from this spreadsheet). - sheetsee -

Sheetsee.getKeyword(data, keyword)

-

This takes in your data, an array of objects, and searches for a string, keyword, in each piece of your data (formerly the cells of your spreadsheet). It returns an array of each row that contained a keyword match. Similarly, using `getKeywordCount(data, keyword)` will return just the number of times the keyword occured.

-
getKeyword(gData, "cat")
-// returns [{breed: "Fat", kind: "cat", hexcolor: "#CDCF83"...}, {breed: "Grey", kind: "cat", hexcolor: "#9C9B9A"...}, {breed: "Creepy", kind: "cat", hexcolor: "#918376"...}]
-

Sheetsee.getColumnTotal(data, column)

-

Given your data, an array of objects and a string column header, this functions sums each cell in that column, so they best be numbers.

-
getColumnTotal(gData, "cuddlability")
-// returns 11
-

Sheetsee.getAveragefromColumn(data, column)

-

A really simple function that builds on getColumnTotal() by returning the average number in a column of numbers.

-
getColumnAverage(gData, "cuddlability")
-// returns 1.8333333333333333
-

Sheetsee.getMin(data, column)

-

This will return an array of object or objects (if there is a tie) of the element with the lowest number value in the column you specify from your data.

-
getMin(gData, "cuddlability")
-// returns [{breed: "Fat", cuddlability: "0", hexcolor: "#CDCF83"...}, {breed: "Grey", cuddlability: "0", hexcolor: "#9C9B9A"...}, {breed: "Creepy", cuddlability: "0", hexcolor: "#918376"...}]
- -

Sheetsee.getMax(data, column)

-

This will return an array of object or objects (if there is a tie) of the element with the highest number value in the column you specify from your data.

-
getMax(gData, "cuddlability")
-// returns {breed: "Teacup Maltese", cuddlability: "5", hexcolor: "#ECECEC", kind: "Dog", lat: "37.74832", long: "-122.402158", name: "Coco"...}
- -
- - -

Don't Forget JavaScript Math

-

Create variables that are the sums, differences, multiples and so forth of others. Lots of info on that here on MDN.

-
var profit09 = Sheetsee.getColumnTotal(gData, "2009")
-var profit10 = Sheetsee.getColumnTotal(gData, "2010")
-var difference = profit09 - profit10
-

What These Little Bits are Good For

-

You don't have to just create tables of your data. You can have other portions of your page that show things like, "The difference taco consumption between last week and this week is..." These are easy to create with javascirpt math functions and knowing a little bit more about icanhas.js. View source on this page to see how I created "Most Cuddlable".

- -

Sheetsee.getMatches(data, filter, category)

-

Takes data as an array of objects, a string you'd like to filter and a string of the category you want it to look in (a column header from your spreadsheet).

-
getMatches(gData, "dog", "kind")
-

Returns an array of objects matching the category's filter.

-
[{"name": "coco", "kind": "dog"...}, {"name": "wolfgang", "kind": "dog"...},{"name": "cooc", "kind": "dog"...} ]
- -

Sheetsee.getOccurance(data, category)

-

Takes data as an array of objects and a string for category (a column header from your spreadsheet) you want tally how often an element occured.

-
getOccurance(gData, "kind")
-

Returns an object with keys and values for each variation of the category and its occurance.

-
{"dog": 3, "cat": 3}
- -

Sheetsee.makeColorArrayOfObject(data, colors)

-

If you use getOccurance() and want to then chart that data with d3.js, you'll need to make it into an array (instead of an object) and add colors back in (since the hexcolor column applies to the datapoints in your original dataset and not this new dataset).

-

This function takes in your data, as an object, an array of hexidecimal color strings which you define and the category you used in getOccurance().

-
var kinds = getOccurance(gData, "kind")
-var kindColors = ["#ff00ff", "#DCF13C"]
-var kindData = makeColorArrayOfObjects(mostPopBreeds, kindColors, "kind")
-

It will return an array of objects with units as the title of the occurance amount like so:

-
[{"kind": "dog", "units": 2, "hexcolor": "#ff00ff"}, {"kind": "cat", "units": 3, "hexcolor": "#DCF13C"}]
-

If you pass in an array of just one color it will repeat that color for all items. If you pass fewer colors than data elements it will repeat the sequences of colors for the remainder elements.

- -

Make a Map

-
-

Sheetsee.js uses Mapbox.js, a Leaflet.js plugin, to make maps.

-

Create an empty <div> in your HTML, with an id.

-
<div id="map"></div>
-

Next you'll need to create geoJSON out of your data so that it can be mapped.

- -

Sheetsee.createGeoJSON(data, optionsJSON)

-

This takes in your data and the parts of your data, optionsJSON, that you plan in your map's popups. If you're not going to have popups on your markers, don't worry about it then and just pass in your data.

-
var optionsJSON = ["name", "breed", "cuddlability"]
-var geoJSON = Sheetsee.createGeoJSON(gData, optionsJSON)
-

It will return an array in the special geoJSON format that map making things love.

-
[{
-  "geometry": {"type": "Point", "coordinates": [long, lat]},
-  "properties": {
-    "marker-size": "small",
-    "marker-color": lineItem.hexcolor
-  },
-  "opts": {the options you pass in},
-}}
- -

Sheetsee.loadMap(mapDiv)

-

To create a simple map, with no data, you simply call `.loadMap() and pass in a string of the mapDiv (with no #) from your HTML.

-
var map = Sheetsee.loadMap("map")
- -

Sheetsee.addTileLayer(map, tileLayer)

-

To add a tile layer, aka a custom map scheme/design/background, you'll use this function which takes in your map and the source of the tileLayer. This source can be a Mapbox id, a URL to a TileJSON or your own generated TileJSON. See Mapbox's Documentation for more information.

-
Sheetsee.addTileLayer(map, 'examples.map-20v6611k')
-

You can add tiles from awesome mapmakers like Stamen or create your own in Mapbox's Tilemill or online.

- -

Sheetsee.addMarkerLayer(geoJSON, map, zoomLevel)

-

To add makers to your map, use this function and pass in your geoJSON so that it can get the coordinates, your map so that it places the markers there and a zoom level.

-
var markerLayer = Sheetsee.addMarkerLayer(geoJSON, map, 11)
- -

Sheetsee.addPopups(map, markerLayer)

-

To customize the marker popup content in your map use this function and pass in your map and markerLayer.

-
 Sheetsee.addPopups(map, markerLayer)
-

To customize the marker popup content in your map you'll need to use this entire function on your website.

-
function addPopups(map, markerLayer) {
-  markerLayer.on('click', function(e) {
-    var feature = e.layer.feature
-    var popupContent = '<h2>' + feature.opts.name + '</h2>' +
-                        '<h3>' + feature.opts.breed + '</h3>'
-    e.layer.bindPopup(popupContent,{closeButton: false,})
-  })
-}
-

You will edit the popupContent variable however you'd like your popups to look. To reference the data you sent to you geoJSON you'll use feature.opts and then one of the column headers you passed into createGeoJSON().

- -

Make a Table

- -
-

Example - Local Pet Friends

- - Clear - no matches -
-
- - -

Sheetsee.js supports making multiple tables or templates with IcanHas.js. The tables can have multiple inputs for searches and table headers can be used to sort the data in that column. For each of these you'll need a <div> in your html, a <script> template and a <script> that calls table functions.

-

Your HTML Placeholder <div>

-

This is as simple as an empty <div> with an id. This id should match the script tempate id in the next section.

-
 <div id="siteTable"></div>
-

Your <script> Template

-

Your template is the mockup of what you'd like your table to look like and what content it should show. Most of this is up to you but if you want users to be able to click on headers and sort that column you must make a table row with table headers with the class tHeader.

-

The variables inside the {{}} must match the column headers in your spreadsheet. Lowercase (?) and remember spaces are ommited, so "Place Name" will become "placename".

-
<script id="siteTable" type="text/html">
-    <table>
-    <tr><th class="tHeader">City</th><th class="tHeader">Place Name</th><th class="tHeader">Year</th><th class="tHeader">Image</th></tr>
-      {{#rows}}
-        <tr><td>{{city}}</td><td>{{placename}}</td><td>{{year}}</td><td>{{image}}</td></tr>
-      {{/rows}}
-  </table>
-</script>
-

Your <script> Execution

-
<script type="text/javascript">
-    document.addEventListener('DOMContentLoaded', function() {
-        Sheetsee.makeTable(gData, "#siteTable")
-        Sheetsee.initiateTableFilter(gData, "#tableFilter", "#siteTable")
-    })
-</script>
-

To create another table, simply repeat the steps with the corresponding data and divs.

-
<div id="secondTable"></div>
-<script id="secondTable"> // your table template here </script>
-<script>
-  Sheetsee.makeTable(otherData, "#secondTable")
-  Sheetsee.initiateTableFilter(otherData, "#secondFilter", "#secondTable")
-</script>
-
-

Learn more about the things you can do with mustache.js.

- -

Sheetsee.makeTable(data, targetDiv)

-

You'll call this to make a table out of a data and tell it what targetDiv in the html to render it in (this should also be the same id as your script template id).

-
Sheetsee.makeTable(gData, "#siteTable")
- -

Table Filter/Search

-

If you want to have an input to allow users to search/filter the data in the table, you'll add this to your html:

-
<input id="tableFilter" type="text" placeholder="filter by.."></input>
-<span class="clear button">Clear</span>
-<span class="noMatches">no matches</span>
- -

Sheetsee.initiateTableFilter(data, filterDiv, tableDiv)

-

You will then call this function to make that input live:

-
Sheetsee.initiateTableFilter(gData, "#TableFilter", "#siteTable")
- -

Make a Chart

-

Sheetsee.js comes with a d3.js bar, pie and line chart. Each requires your data be an array of objects, formatted to contain "label" and "units" keys. See the section above on Your Data to learn about formatting.

-

You'll have to experiement with the charts to find the correct size your <div> will need to be to hold the chart with your data in it nicely.

-

You can also make your own d3 chart in a separate .js file, link to that and pass your data on to it. I'd love to see people building some other charts that will work with Sheetsee.

- -

Bar Chart

- -
-
-
- -

To create a bar chart you'll need to add a placeholder <div> in your HTML with an id.

-
<div id="barChart"></div>
-

In your CSS, give it dimensions.

-
#barChart {height: 400px; max-width: 600px; background: #F8CDCD;}
-

In a <script> tag set up your options.

-
var barOptions = {labels: "name", units: "cuddleability", m: [60, 60, 30, 150], w: 600, h: 400, div: "#barChart", xaxis: "no. of pennies", hiColor: "#FF317D"}
-
    -
  • labels is a string, usually a column header, it's what you call what you're charting
  • -
  • units is a string, usually a column header, it's the value you're charting
  • -
  • m is margins: top, right, bottom, left
  • -
  • w and h are width and height, this should match your CSS specs
  • -
  • div is the id for the <div> in your HTML
  • -
  • xaxis is optional text label for your x axis
  • -
  • hiColor is the highlight color of your choosing!
  • -
-

Then call the d3BarChart() function with your data and options.

-
Sheetsee.d3BarChart(data, barOptions)
- -

Line Chart

- -
-
-
- -

To create a line chart you'll need to add a placeholder <div> in your html with an id.

-
<div id="lineChart"></div>
-

In your CSS, give it dimensions.

-
#lineChart {height: 400px; max-width: 600px; background: #F8CDCD;}
-

In a <script> tag set up your options.

-
var lineOptions = {labels: "name", units: "cuddleability", m: [80, 100, 120, 100], w: 600, h: 400, div: "#lineChart", yaxis: "no. of pennies", hiColor: "#14ECC8"}
-
    -
  • labels is a string, usually a column header, it's what you call what you're charting
  • -
  • units is a string, usually a column header, it's the value you're charting
  • -
  • m is your margins: top, right, bottom, left
  • -
  • w and h are width and height, this should match your CSS specs
  • -
  • div is the id for the <div> in your HTML
  • -
  • yaxis is optional text label for your y axis
  • -
  • hiColor is the highlight color of your choosing!
  • -
-

Then call the d3LineChart() function with your data and options.

-
Sheetsee.d3LineChart(data, lineOptions)
- -

Pie Chart

- -
-
-
- -

To create a bar chart you'll need to add a placeholder <div> in your html with an id.

-
<div id="pieChart"></div>
-

In your CSS, give it dimensions.

-
#pieChart {height: 400px; max-width: 600px; background: #F8CDCD;}
-

In a <script> tag set up your options. You must include labels and units, this tells it what you're charting. Because for the pie chart we're using data we got from getOccurance() and makeColorArrayofObject(), our units are already called units. If we were using original data, we might have units as "cuddleability" or something else.

-
var pieOptions = {labels: "kind", units: "units", m: [80, 80, 80, 80], w: 600, h: 400, div: "#pieChart", hiColor: "#14ECC8"}
-
    -
  • labels is a string, usually a column header, it's what you call what you're charting
  • -
  • units is a string, usually a column header, it's the value you're charting
  • -
  • m is your margins: top, right, bottom, left
  • -
  • w and h are width and height, this should match your CSS specs
  • -
  • div is the id for the <div> in your HTML
  • -
  • hiColor is the highlight color of your choosing!
  • -
-

Then call the d3PieChart() function with your data and options.

-
Sheetsee.d3PieChart(data, pieOptions)
- -

Don't forget, right click this page, select View Source and scroll to the bottom and see exactly how these charts were set up!

- - -

Big Time Thanks

-

Thanks to Code for America for providing the platform me to build the first version of sheetsee.js for Macon, Georga.

-

Thanks to Dan Sinker at Open News for having faith and getting things together to make this Code Sprint happen and thanks to Matt Green at WBEZ for being a willing partner.

-

Thanks to Max Ogden for emotional support, teaching me JavaScript and working on the harder parts of Sheetsee.js - especially for making Tabletop.js for Node.js.

-

Thanks to all the authors and contributors to Tabletop.js, Mapbox.js, Leaflet.js, jQuery, ICanHas.js and d3.js. Thanks to Google and the Internet for existing and to all those who've written tutorials or asked or answered a question on StackOverflow.

-

Thanks to Mom and Dad for getting a computer in 1996 and the mIRC scripts I started writing that I suppose would eventually lead me here.

- -

Licensed under BSD. East Bay represent!

- - - - - - - - - diff --git a/demos/demo-map.html b/demos/demo-map.html new file mode 100644 index 00000000..452079ab --- /dev/null +++ b/demos/demo-map.html @@ -0,0 +1,78 @@ + + + + + Sheetsee Maps Demo + + + + + + + + + + +
+

All Pennies Map

+

spreadsheet

+

Loading...
+

View Source // View Documentation

+ + +
+ + + + diff --git a/demos/demo-table.html b/demos/demo-table.html new file mode 100644 index 00000000..1ea8c79a --- /dev/null +++ b/demos/demo-table.html @@ -0,0 +1,89 @@ + + + + + Sheetsee Table Demo + + + + + + + + + +
+

All Pennies

+

spreadsheet

+ + Clear +

Loading...
+

View Source // View Documentation

+ + +
+ + + + + + diff --git a/docs/about.html b/docs/about.html new file mode 100644 index 00000000..1304750f --- /dev/null +++ b/docs/about.html @@ -0,0 +1,81 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

About

+

Sheetsee.js began as a part of a Code for America 2012 Fellowship project. The original idea was to make a way for cities to easily publish and maintain budget data themselves. Originally, the JavaScript was part of a WordPress theme that could be connected to a spreadsheet, allowing new pages to be created with charts, maps and tables automatically generated from the data.

+

In early 2013, after the CfA Fellowship and through a grant from Mozilla Open News, the JavaScript bits were pulled out to make it a standalone open source library: sheetsee.js.

+

Since then there have been a few updates to the library but it was not until 2017 when Sheetsee got it's next major upgrade.

+

In Spring of 2017 Sheetsee was cleaned up and downsized. Charting support and some dependencies were removed to make maintenance and overall size better.

+

Dependencies

+

Sheetsee comes into play after you use Tabletop.js, a library that handles the messy interactions with the Google Spreadsheets API for you and returns a lovely array of your data. At the end of the day, however, Sheetsee just wants an array of JSON data, if you have some on hand already, you can use Sheetsee too :)

+

Mustache, Leaflet

+

Sheetsee uses the Mustache.js library for templates in sheetsee-tables and map popups in sheetsee-maps. The maps are generated using the Leaflet.js library.

+

Hacked on Openly

+ +

Contact & Contribute

+

Issues with this website can be opened on the sheetsee.js repository. Otherwise, if your issue falls specifically with one of the modules, you can file it on its particular repo:

+ +

Thanks, y'all

+

Thanks to Code for America for providing the platform me to build the first version of sheetsee.js for Macon, Georgia.

+

Thanks to Dan Sinker at Open News for having faith and getting things together to make this Code Sprint happen and thanks to Matt Green at WBEZ for being a willing partner.

+

Thanks to Max Ogden for emotional support, teaching me JavaScript and answering lots of questions.

+

Thanks to all the authors and contributors to Tabletop.js, Leaflet.js and Mustache.js. Thanks to Google and the Internet for existing and to all those who've written tutorials or asked or answered a question on StackOverflow.

+

Thanks to Mom and Dad for getting a computer in 1996 and the mIRC scripts I started writing that I suppose would eventually lead me here.

+ + + +
+ + + diff --git a/docs/about.md b/docs/about.md new file mode 100644 index 00000000..95700b10 --- /dev/null +++ b/docs/about.md @@ -0,0 +1,40 @@ +# About + +Sheetsee.js began as a part of a [Code for America](http://www.codeforamerica.org) 2012 Fellowship project. The original idea was to make a way for cities to easily publish and maintain budget data themselves. Originally, the JavaScript was part of a WordPress theme that could be connected to a spreadsheet, allowing new pages to be created with charts, maps and tables automatically generated from the data. + +In early 2013, after the CfA Fellowship and through a grant from [Mozilla Open News](http://opennews.org), the JavaScript bits were pulled out to make it a standalone open source library: sheetsee.js. + +Since then there have been a few updates to the library but it was not until 2017 when Sheetsee got it's next major upgrade. + +In Spring of 2017 Sheetsee was cleaned up and downsized. Charting support and some dependencies were removed to make maintenance and overall size better. + +## Dependencies + +Sheetsee comes into play after you use [Tabletop.js](https://github.com/jsoma/tabletop), a library that handles the messy interactions with the Google Spreadsheets API for you and returns a lovely array of your data. At the end of the day, however, Sheetsee just wants an array of JSON data, if you have some on hand already, you can use Sheetsee too :) + +### Mustache, Leaflet + +Sheetsee uses the [Mustache.js](https://mustache.github.io) library for templates in `sheetsee-tables` and map popups in `sheetsee-maps`. The maps are generated using the [Leaflet.js](http://leafletjs.com) library. + +## Hacked on Openly +- Sheetsee.js is open source software with a [BSD license](docs/license.md). +- Sheetsee.js is a labor of love by [jlord](http://www.github.com/jlord) ([Twitter](http://www.twitter.com/jllord)) + +## Contact & Contribute +Issues with this website can be opened on the [sheetsee.js repository](https://github.com/jlord/sheetsee/issues/new). Otherwise, if your issue falls specifically with one of the modules, you can file it on its particular repo: + - [sheetsee (CLI)](http://www.github.com/jlord/sheetsee/issues/new) + - [sheetsee-core](http://www.github.com/jlord/sheetsee-core/issues/new) + - [sheetsee-tables](http://www.github.com/jlord/sheetsee-tables/issues/new) + - [sheetsee-maps](http://www.github.com/jlord/sheetsee-maps/issues/new) + +## Thanks, y'all + +Thanks to [Code for America](http://www.codeforamerica.org) for providing the platform me to build the first version of sheetsee.js for Macon, Georgia. + +Thanks to [Dan Sinker](http://www.twitter.com/dansinker) at [Open News](http://www.mozillaopennews.org/) for having faith and getting things together to make this Code Sprint happen and thanks to [Matt Green](https://twitter.com/whatsnewmedia) at WBEZ for being a willing partner. + +Thanks to [Max Ogden](http://www.twitter.com/maxogden) for emotional support, teaching me JavaScript and answering lots of questions. + +Thanks to all the authors and contributors to [Tabletop.js](https://github.com/jsoma/tabletop), [Leaflet.js](http://leafletjs.com) and [Mustache.js](https://mustache.github.io). Thanks to Google and the Internet for existing and to all those who've written tutorials or asked or answered a question on StackOverflow. + +Thanks to Mom and Dad for getting a computer in 1996 and the mIRC scripts I started writing that I suppose would eventually lead me here. diff --git a/docs/basics.html b/docs/basics.html new file mode 100644 index 00000000..84728a08 --- /dev/null +++ b/docs/basics.html @@ -0,0 +1,124 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

Spreadsheets as Databases

+

Spreadsheets are a great lightweight databases. Google Spreadsheets in particular are easy to work with and share, making this unlike most traditional database setups. That being said, traditional databases are great for bigger, more secure jobs. If you're storing lots and lots and lots of information, or storing sensitive or complex information—the spreadsheet is not for you. But if you're working on small to medium sized personal or community projects, try a spreadsheet!

+

The Short & Sweet

+
    +
  • Link to Sheetsee.js and Tabletop.js in your HTML head.
  • +
  • Link to sheetsee's default stylesheet, sss.css.
  • +
  • Create a place holder <div>, with id, in your HTML the map or table you want.
  • +
  • Create templates for tables in <script> tags with an id matching the <div> plus _template.
  • +
  • Inside of another <script> tag initialize Tabletop.js. Once it fetches your spreadsheet data, pass it onto Sheetsee.
  • +
+
document.addEventListener('DOMContentLoaded', function() {
+  var URL = 'YOURSPREADSHEETSKEYHERE'
+  Tabletop.init({key: URL, callback: callback, simpleSheet: true})
+})
+
+
    +
  • Define the function that Tabletop.js calls when it returns with the data. This function will contain all the Sheetsee.js methods you want to use.
  • +
+
function callback (data) {
+  // All the Sheetsee things you want to do!
+}
+
+
    +
  • Set it and forget. Now all you need to do is edit the spreadsheet and visitors will get the latest information every time they load the page.
  • +
+

Bare Minimum Setup

+

Ignoring some HTML things to conserve space, you get the point. This is a basic setup:

+
<html>
+  <head>
+    <meta charset="utf-8">
+    <script type="text/javascript" src="js/tabletop.js"></script>
+    <script type="text/javascript" src='js/sheetsee.js'></script>
+    <link rel="stylesheet" type="text/css" href="css/sss.css">
+  </head>
+  <body>
+  <div id="placeholder"></div>
+
+  <script id="placeholder" type="text/html">
+    // template if you so desire!
+  </script>
+
+  <script type="text/javascript">
+    document.addEventListener('DOMContentLoaded', function () {
+        var URL = 'YOURSPREADSHEETSKEYHERE'
+        Tabletop.init( { key: URL, callback: myData, simpleSheet: true } )
+    })
+    function myData (data) {
+      // All the sheetsee things you want to do!
+    }
+  </script>
+  </body>
+</html>
+
+

Your Data

+

sheetsee

+

Your Google Spreadsheet should be set up with row one as your column headers. Row two and beyond should be your data. Each header and row becomes an object in the final array that Tabletop.js delivers of your data.

+

sheetsee

+

There shouldn't be any breaks or horizontal organization in the spreadsheet. But, feel free to format the style of your spreadsheet as you wish; borders, fonts and colors and such do not transfer or affect your data exporting.

+
[{"name":"Coco","breed":"Teacup Maltese","kind":"Dog","cuddlability":"5","lat":"37.74832","long":"-122.402158","picurl":"http://distilleryimage8.s3.amazonaws.com/98580826813011e2bbe622000a9f1270_7.jpg","hexcolor":"#ECECEC","rowNumber":1}...]
+

Hexcolor

+

sheetsee

+

You can add a column to your spreadsheet with the heading hexcolor (case insensitive) and add colors to be used in maps. The color scheme is up to you, all you need to do is fill the column with hexidecimal color values. This color picker by Devin Hunt is really nice. #Funtip: Coloring the background of the cell it's hexcolor brings delight!

+

Geocoding

+

If you intend to map your data and only have addresses you'll need to geocode the addresses into lat/long coordinates. Mapbox built a plugin that does this for you in Google Docs. You can also use websites like latlong.net to get the coordinates and paste them into rows with column headers lat and long.

+

Publishing Your Spreadsheet

+

sheetsee

+

You need to do this in order to generate a unique key for your spreadsheet, which Tabletop.js will use to get your spreadsheet data. In your Google Spreadsheet, click File > Publish to the Web. Then in the next window click Start Publishing; it will then turn into a Stop Publishing button.

+

sheetsee

+

You should have an address in a box at the bottom, your key is the portion between the = and the &. You'll retrieve this later when you hook up your site to the spreadsheet. Actually, you technically can use the whole URL, but it's so long...

+

CSS

+

Sheetsee.js comes with a bare minimum stylesheet, sss.css, which contains elements you'll want to style when using the feature they correspond to. Use it if you want, or as a starting off point to create your own styles.

+ + + +
+ + + diff --git a/docs/basics.md b/docs/basics.md new file mode 100644 index 00000000..7e587a75 --- /dev/null +++ b/docs/basics.md @@ -0,0 +1,96 @@ +# Spreadsheets as Databases + +Spreadsheets are a great _lightweight_ databases. Google Spreadsheets in particular are easy to work with and share, making this unlike most traditional database setups. That being said, traditional databases are great for bigger, more secure jobs. If you're storing lots and lots and lots of information, or storing sensitive or complex information—the spreadsheet is not for you. But if you're working on small to medium sized personal or community projects, try a spreadsheet! + +## The Short & Sweet + +- Link to Sheetsee.js and [Tabletop.js](https://github.com/jsoma/tabletop) in your HTML head. +- Link to sheetsee's default stylesheet, `sss.css`. +- Create a place holder `
`, with `id`, in your HTML the map or table you want. +- Create templates for tables in ` + + + + +
+ + + + + + +``` + +## Your Data + +![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/spreadsheettodata.png) + +Your Google Spreadsheet should be set up with row one as your column headers. Row two and beyond should be your data. Each header and row becomes an object in the final array that [Tabletop.js](https://github.com/jsoma/tabletop) delivers of your data. + +![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/nonos.png) + +There shouldn't be any breaks or horizontal organization in the spreadsheet. But, feel free to format the style of your spreadsheet as you wish; borders, fonts and colors and such do not transfer or affect your data exporting. + + [{"name":"Coco","breed":"Teacup Maltese","kind":"Dog","cuddlability":"5","lat":"37.74832","long":"-122.402158","picurl":"http://distilleryimage8.s3.amazonaws.com/98580826813011e2bbe622000a9f1270_7.jpg","hexcolor":"#ECECEC","rowNumber":1}...] + +### Hexcolor + +![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/hexcolors.png) + +You can add a column to your spreadsheet with the heading _hexcolor_ (case insensitive) and add colors to be used in maps. The color scheme is up to you, all you need to do is fill the column with hexidecimal color values. This [color picker](http://color.hailpixel.com/) by [Devin Hunt](https://twitter.com/hailpixel) is really nice. #Funtip: Coloring the background of the cell it's hexcolor brings delight! + +### Geocoding + +If you intend to map your data and only have addresses you'll need to geocode the addresses into lat/long coordinates. Mapbox built a [plugin](http://mapbox.com/tilemill/docs/guides/google-docs/#geocoding) that does this for you in Google Docs. You can also use websites like [latlong.net](http://www.latlong.net) to get the coordinates and paste them into rows with column headers _lat_ and _long_. + +### Publishing Your Spreadsheet + +![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/publish.png) + +You need to do this in order to generate a unique key for your spreadsheet, which [Tabletop.js](https://github.com/jsoma/tabletop) will use to get your spreadsheet data. In your Google Spreadsheet, click _File_ > _Publish to the Web_. Then in the next window click _Start Publishing_; it will then turn into a _Stop Publishing_ button. + +![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/key.png) + +You should have an address in a box at the bottom, your key is the portion between the = and the &. You'll retrieve this later when you hook up your site to the spreadsheet. _Actually, you technically can use the whole URL, but it's so long..._ + +### CSS + +Sheetsee.js comes with a bare minimum stylesheet, `sss.css`, which contains elements you'll want to style when using the feature they correspond to. Use it if you want, or as a starting off point to create your own styles. diff --git a/docs/building.html b/docs/building.html new file mode 100644 index 00000000..13bc022e --- /dev/null +++ b/docs/building.html @@ -0,0 +1,77 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

Right-sizing

+

You can customize your Sheetsee build with just the parts you want to use, for example to only include the mapping module or only the tables module. If you want to just use the full version, you can grab it here at github.com/jlord/sheetsee.js.

+

All builds come with Mustache.js and Leaflet.js. Additionally, you'll need to link to Tabletop.js your HTML head like so:

+
<script src="https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js"></script>
+<script src="js/sheetsee.js"></script>
+
+

To build a custom Sheetsee you'll need Node.js on your computer familiarity with the command line.

+

Download Node.js from nodejs.org/download. For most users you can just download the Mac .pkg or Windows .msi. Follow the install instructions; both include npm. Then install sheetsee.

+

Install sheetsee from npm

+

The sheetsee (with no '.js') module is the tool for building custom Sheetsee builds. Install sheetsee globally and then run it within the folder of your soon-to-be Sheetsee project.

+

Install globally

+
npm install -g sheetsee
+
+

Run from within a project folder

+
sheetsee [options]
+
+

Here are the options for the different modules. If you want save the generated file as sheetsee.js then add the --save option.

+
    +
  • -m or -maps for maps
  • +
  • -t or -tables for tables
  • +
  • --save to write out the file*
  • +
+

* otherwise, defaults to standard out on your console which you can | pbcopy

+

So for instance, sheetsee -m --save will build you a Sheetsee with the basic data functions and the map section, leaving out the tables section. It will save it as a file named 'sheetsee.js'. Running sheetsee -m | pbcopy will save the output to your clipboard.

+ + + +
+ + + diff --git a/docs/building.md b/docs/building.md new file mode 100644 index 00000000..84c15cf1 --- /dev/null +++ b/docs/building.md @@ -0,0 +1,39 @@ +# Right-sizing + +You can customize your Sheetsee build with just the parts you want to use, for example to only include the mapping module or only the tables module. If you want to just use the full version, you can grab it here at [github.com/jlord/sheetsee.js](https://github.com/jlord/sheetsee.js/blob/master/js/sheetsee.js). + +All builds come with [Mustache.js](https://mustache.github.io) and [Leaflet.js](http://leafletjs.com). Additionally, you'll need to link to [Tabletop.js](https://github.com/jsoma/tabletop) your HTML head like so: + +```HTML + + +``` + +**To build a custom Sheetsee you'll need [Node.js](http://www.nodejs.org) on your computer familiarity with the command line.** + +Download Node.js from [nodejs.org/download](http://nodejs.org/download). For most users you can just download the Mac _.pkg_ or Windows _.msi_. Follow the install instructions; both include npm. Then install `sheetsee`. + +## Install `sheetsee` from npm +The `sheetsee` (with no '.js') module is the tool for building custom Sheetsee builds. Install `sheetsee` globally and then run it within the folder of your soon-to-be Sheetsee project. + +_Install globally_ + +```bash +npm install -g sheetsee +``` + +_Run from within a project folder_ + +```bash +sheetsee [options] +``` + +Here are the options for the different modules. If you want save the generated file as _sheetsee.js_ then add the `--save` option. + +- `-m` or `-maps` for maps +- `-t` or `-tables` for tables +- `--save` to write out the file* + +_* otherwise, defaults to standard out on your console which you can_ `| pbcopy` + +So for instance, `sheetsee -m --save` will build you a Sheetsee with the basic **data** functions and the **map** section, leaving out the tables section. It will save it as a file named '**sheetsee.js**'. Running `sheetsee -m | pbcopy` will save the output to your clipboard. diff --git a/docs/changelog.html b/docs/changelog.html new file mode 100644 index 00000000..57edebfc --- /dev/null +++ b/docs/changelog.html @@ -0,0 +1,92 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

March 2017 Sheetsee v4

+

sheetsee-core changes

+

Methods for charts have been removed:

+
    +
  • Sheetsee.makeColorArrayOfObject(data, colors)
  • +
  • Sheetsee.addUnitsLabels(arrayObj, oldLabel, oldUnits)
  • +
+

May 10, 2014, Sheetsee v3

+

Better Table Template Options

+

Updated sheetsee-tables to allow you to re-use a template (rather than duplicating it for each different table you wanted to create). Previously it assumed your HTML table div id matched your script template id. This means that you can pass in an extra key/value pair in your table options into Sheetsee.maketable(). The new pair it takes is: "templateID" : "yourtemplateid". Example below, full sheetsee-tables documentation here.

+
var tableOptions = {
+                    "data": gData,
+                    "pagination": 10,
+                    "tableDiv": "#fullTable",
+                    "filterDiv": "#fullTableFilter",
+                    "templateID": "tableTemplte"
+                    }
+Sheetsee.makeTable(tableOptions)
+
+

May 2014

+

Important Google Spreadsheets & Tabletop News

+

Google recently updated their Google Spreadsheets and the API. For a bit this was breaking things using the old API, including Tabletop. This has been fixed and the latest version of tabletop.js works on both old and new spreadsheets. Be sure to include at least version 1.3.4 in your project.

+

August 13, 2013

+

Charting Intake

+

D3 charts need an array of objects, and something to chart: the thing itself (aka labels) and the corresponding value (aka units). Your data usually contains more than D3 needs to make the chart, so you have to tell it what to chart from your data to chart.

+

Previously Sheetsee required you pass your data through a function, addUnitsAndLabels() which took in your data and the things you wanted to chart, reformatted your data for you so that you could pass it into one of the d3 charts. This is one more step than actually needs to happen.

+

Now Sheetsee just asks for what you want your labels and units to be in the options you give it when calling the chart function. It then sorts the data correctly on the inside of the chart function. Yay, easier!

+
var options = {
+  labels: "name",
+  units: "cuddleability",
+  m: [60, 60, 30, 150],
+  w: 600, h: 400,
+  div: "#barChart",
+  xaxis: "no. of pennies",
+  hiColor: "#FF317D"
+}
+
+

Thanks @maxogden for the help with this.

+

Started doing this changelong pretty late in the game.

+ + + +
+ + + diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 00000000..44685fbd --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,54 @@ +### March 2017 Sheetsee v4 + +sheetsee-core changes + +Methods for charts have been removed: +- `Sheetsee.makeColorArrayOfObject(data, colors)` +- `Sheetsee.addUnitsLabels(arrayObj, oldLabel, oldUnits)` + + +## May 10, 2014, Sheetsee v3 +### Better Table Template Options + +Updated `sheetsee-tables` to allow you to re-use a template (rather than duplicating it for each different table you wanted to create). Previously it assumed your HTML table `div` id matched your script template `id`. This means that you can pass in an extra key/value pair in your table options into `Sheetsee.maketable()`. The new pair it takes is: `"templateID" : "yourtemplateid"`. Example below, full `sheetsee-tables` documentation [here](docs/sheetsee-tables.html). + +```JavaScript +var tableOptions = { + "data": gData, + "pagination": 10, + "tableDiv": "#fullTable", + "filterDiv": "#fullTableFilter", + "templateID": "tableTemplte" + } +Sheetsee.makeTable(tableOptions) +``` + +## May 2014 +### Important Google Spreadsheets & Tabletop News + +Google recently updated their Google Spreadsheets and the API. For a bit this was breaking things using the old API, including Tabletop. This has been fixed and the latest version of tabletop.js works on both old and new spreadsheets. **Be sure to include at least version 1.3.4 in your project.** + +## August 13, 2013 +### Charting Intake + +D3 charts need an array of objects, and something to chart: the thing itself (aka labels) and the corresponding value (aka units). Your data usually contains more than D3 needs to make the chart, so you have to tell it what to chart from your data to chart. + +Previously Sheetsee required you pass your data through a function, `addUnitsAndLabels()` which took in your data and the things you wanted to chart, reformatted your data for you so that you could pass it into one of the d3 charts. This is one more step than actually needs to happen. + +Now Sheetsee just asks for what you want your _labels_ and _units_ to be in the options you give it when calling the chart function. It then sorts the data correctly on the inside of the chart function. Yay, easier! + +```javascript +var options = { + labels: "name", + units: "cuddleability", + m: [60, 60, 30, 150], + w: 600, h: 400, + div: "#barChart", + xaxis: "no. of pennies", + hiColor: "#FF317D" +} +``` + +Thanks @maxogden for the help with this. + +### Started doing this changelong pretty late in the game. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..575b3d49 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,46 @@ +![sheetseeimg](img/next-sheetsee.png) + +**Sheetsee.js** is a client-side library for connecting Google Spreadsheets to a website and visualizing the information in tables and maps. + +
+ +## Spreadsheets!? + +Google Spreadsheets can be used as simple and collaborative databases, they make getting a data driven site going much easier than traditional databases. [Read more](./docs/basics.md) about using spreadsheets for databases. + +## Modules + +Each of Sheetsee's functions are divided into modules. Use just the parts you need; see docs on [building](./docs/building.md). If you don't want to build your own, you can just use the full library which includes all modules, it's [here on GitHub](http://www.github.com/jlord/sheetsee.js). + +| Module | Contains | Docs | +| ------------------- | --------------------------------------------------------------------------------------------------- | ---------------------------- | +| **sheetsee** | Command line module for make a custom build of Sheetsee. | [Doc](./docs/building.md) | +| **sheetsee-core** | **Included in all builds**. Has helpful working-with-your-data functions. | [Doc](./docs/sheetsee-core.md) | +| **sheetsee-tables** | Contains everything you'll need to create a table including sortable columns, pagination and search.| [Doc](./docs/sheetsee-tables.md) | +| **sheetsee-maps** | For making maps with your point, line or polygon spreadsheet data. Built with Leaflet.js. | [Doc](./docs/sheetsee-maps.md) | + +
New News!
+ +## Get your Spreadsheet as JSON or Try Sheetsee with Glitch! + +The [spreadsheet.glitch.me](https://spreadsheet.glitch.me) site will give you an endpoint to use that will return your spreadsheet to you as JSON. The [sheetsee.glitch.me](https://sheetsee.glitch.me) site provides template to get started with Sheetsee; it's already set up with a server so that your data is backed up. + +### Or Fork a Site! + +There are site templates hooked up to Sheetsee that are ready to be forked on GitHub and used by you, check out the [Fork-n-go site](http://jlord.us/forkngo). + +## Sheetsee Updates + +Sheetsee has just been re-written and there are some breaking changes. Also some nice ones, like dependencies removed. The API for maps with Sheetsee have changed, [see the docs](https://github.com/jlord/sheetsee-maps#sheetseeloadmapoptions). + +
+ +## Resources & Documentation + +More resources on using Sheetsee: + +| Getting Started | Ideas | Demos | Use | +| --- | --- | --- | --- | +| [About Sheetsee](./docs/about.md) | [Templates](./docs/templates.md) | [Table Demo](./demos/demo-table.html) | [Sheetsee-core](./docs/sheetsee-core.md) | +| [Building Sheetsee](./docs/building.md) | [Tips!](./docs/tips.md) | [Map Demo](./demos/demo-map.html) | [Sheetsee-tables](./docs/sheetsee-tables.md) | +| [Basics](./docs/basics.md) | | | [Sheetsee-maps](./docs/sheetsee-maps.md) | diff --git a/docs/sheetsee-core.html b/docs/sheetsee-core.html new file mode 100644 index 00000000..e368e0e8 --- /dev/null +++ b/docs/sheetsee-core.html @@ -0,0 +1,149 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

sheetsee-core

+

This module is included in every Sheetsee build. It contains methods for basic data manipulation you might want to do.

+

Working With Your Data

+

Sheetsee pairs with Tabletop.js which will fetch the data from your spreadsheet and return it as an array of objects. You'll use these methods from Sheetsee after you have that data.

+

Methods

+

Here are the functions you can use!

+

Sheetsee.getKeywordCount(data, keyword)

+
    +
  • data array of objects
  • +
  • keyword string
  • +
  • Returns number
  • +
+

Given your data and keyword to search by, this function returns the number of times it occurs throughout all of the data.

+
getGroupCount(data, 'cat')
+// returns a number
+
+

Sheetsee.getKeyword(data, keyword)

+
    +
  • data array of objects
  • +
  • keyword string
  • +
  • Returns number
  • +
+

Given your data and a keyword to search by, this function returns every row which contains a match to the keyword.

+
getKeyword(data, 'cat')
+// returns array of objects
+
+

Sheetsee.getColumnTotal(data, column)

+
    +
  • data array of objects
  • +
  • column string
  • +
  • Returns number
  • +
+

Use only with columns of numbers

+

Given your data and column header, this function sums each cell in that column and returns the value.

+
getColumnTotal(data, 'cuddlability')
+// returns number
+
+

Sheetsee.getColumnAverage(data, column)

+
    +
  • data array of objects
  • +
  • column string
  • +
  • Returns number
  • +
+

Given your data and column header, this function returns the average value of every cell in the column.

+
getColumnAverage(data, 'cuddlability')
+// returns number
+
+

Sheetsee.getMin(data, column)

+
    +
  • data array of objects
  • +
  • column string
  • +
  • Returns array
  • +
+

Given your data and column header, this function returns an array of the rows with the lowest values within the specified column.

+
getMin(data, 'cuddlability')
+// returns array
+
+

Sheetsee.getMax(data, column)

+
    +
  • data array of objects
  • +
  • column string
  • +
  • Returns array
  • +
+

Given your data and column header, this function returns an array of the rows with the highest values within the specified column.

+
getMin(data, 'cuddlability')
+// returns array of objects
+
+

Sheetsee.getMatches(data, filter, column)

+
    +
  • data array of objects
  • +
  • filter string
  • +
  • column string
  • +
  • Returns array
  • +
+

Takes data, a filter term to search by within a column and returns every row that matches,

+
getMatches(data, 'dog', 'kind')
+// returns array of objects
+// [{'name': 'coco', 'kind': 'dog'...}, {'name': 'wolfgang', 'kind': 'dog'...},{'name': 'cooc', 'kind': 'dog'...} ]
+
+

Sheetsee.getOccurance(data, column)

+
    +
  • data array of objects
  • +
  • column string
  • +
  • Returns object
  • +
+

Takes data column header and returns an object with key/value pairs of how often an item occurs in the column.

+
getOccurance(data, 'kind')
+// Returns an object
+// {'dog': 3, 'cat': 3}
+
+

Math

+

Don't Forget JavaScript Math! Create variables that are the sums, differences, multiples and so forth of others. Lots of info on that here on MDN.

+
var profit09 = Sheetsee.getColumnTotal(data, '2009')
+var profit10 = Sheetsee.getColumnTotal(data, '2010')
+var difference = profit09 - profit10
+
+ + + +
+ + + diff --git a/docs/sheetsee-core.md b/docs/sheetsee-core.md new file mode 100644 index 00000000..d1be4772 --- /dev/null +++ b/docs/sheetsee-core.md @@ -0,0 +1,130 @@ +# sheetsee-core + +This module is included in every Sheetsee build. It contains methods for basic data manipulation you might want to do. + +## Working With Your Data + +Sheetsee pairs with [Tabletop.js](https://github.com/jsoma/tabletop) which will fetch the data from your spreadsheet and return it as an _array of objects_. You'll use these methods from Sheetsee after you have that data. + +## Methods + +Here are the functions you can use! + +### `Sheetsee.getKeywordCount(data, keyword)` + +- `data` _array of objects_ +- `keyword` _string_ +- Returns _number_ + +Given your **data** and **keyword** to search by, this function returns the number of times it occurs throughout all of the data. + +```javascript +getGroupCount(data, 'cat') +// returns a number +``` + +### `Sheetsee.getKeyword(data, keyword)` + +- `data` _array of objects_ +- `keyword` _string_ +- Returns _number_ + +Given your **data** and a **keyword** to search by, this function returns every row which contains a match to the keyword. + +```javascript +getKeyword(data, 'cat') +// returns array of objects +``` + +### `Sheetsee.getColumnTotal(data, column)` + +- `data` _array of objects_ +- `column` _string_ +- Returns _number_ + +_Use only with columns of numbers_ + +Given your **data** and **column** header, this function sums each cell in that column and returns the value. + +```javascript +getColumnTotal(data, 'cuddlability') +// returns number +``` + +### `Sheetsee.getColumnAverage(data, column)` + +- `data` _array of objects_ +- `column` _string_ +- Returns _number_ + +Given your **data** and **column** header, this function returns the average value of every cell in the column. + +```javascript +getColumnAverage(data, 'cuddlability') +// returns number +``` + +### `Sheetsee.getMin(data, column)` + +- `data` _array of objects_ +- `column` _string_ +- Returns _array_ + +Given your **data** and **column** header, this function returns an array of the rows with the lowest values within the specified column. + +```javascript +getMin(data, 'cuddlability') +// returns array +``` + +### `Sheetsee.getMax(data, column)` + +- `data` _array of objects_ +- `column` _string_ +- Returns _array_ + +Given your **data** and **column** header, this function returns an array of the rows with the highest values within the specified column. + +```javascript +getMin(data, 'cuddlability') +// returns array of objects +``` + +### `Sheetsee.getMatches(data, filter, column)` + +- `data` _array of objects_ +- `filter` _string_ +- `column` _string_ +- Returns _array_ + +Takes **data**, a **filter** term to search by within a **column** and returns every row that matches, + +```javascript +getMatches(data, 'dog', 'kind') +// returns array of objects +// [{'name': 'coco', 'kind': 'dog'...}, {'name': 'wolfgang', 'kind': 'dog'...},{'name': 'cooc', 'kind': 'dog'...} ] +``` + +### `Sheetsee.getOccurance(data, column)` + +- `data` _array of objects_ +- `column` _string_ +- Returns _object_ + +Takes **data** **column** header and returns an object with key/value pairs of how often an item occurs in the column. + +```JAVASCRIPT +getOccurance(data, 'kind') +// Returns an object +// {'dog': 3, 'cat': 3} +``` + +### Math + +Don't Forget JavaScript Math! Create variables that are the sums, differences, multiples and so forth of others. Lots of info on that [here on MDN](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math). + +```javascript +var profit09 = Sheetsee.getColumnTotal(data, '2009') +var profit10 = Sheetsee.getColumnTotal(data, '2010') +var difference = profit09 - profit10 +``` diff --git a/docs/sheetsee-maps.html b/docs/sheetsee-maps.html new file mode 100644 index 00000000..a8fe451d --- /dev/null +++ b/docs/sheetsee-maps.html @@ -0,0 +1,118 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

sheetsee-maps

+

Sheetsee uses this module to handle maps in your projects. This module uses (and includes) Leaflet.js to make maps of your points, polygons, lines or multipolygons (all coordinate based). Details on what that actually looks like here. It uses (and includes) Mustache.js templates for marker popups.

+

You'll need to include Leaflet's map CSS in your HTML's head:

+
<head>
+  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
+</head>
+
+

Maps: Polygons and Lines

+

Sheetsee-maps supports polygons and lines; so long as you have the correct coordinate structure in your cells. More details for coordinates of lines and polygons in geoJSON are here, but briefly:

+

Must use lowercase spreadsheet column headers: 'lat' and 'long'.

+

A linestring:

+
[-122.41722106933594, 37.7663045891584], [-122.40477561950684, 37.77695634643178]
+
+

A polygon:

+
[-122.41790771484375, 37.740381166384914], [-122.41790771484375, 37.74520008134973], [-122.40966796874999, 37.74520008134973],[-122.40966796874999, 37.740381166384914], [-122.41790771484375, 37.740381166384914]
+
+

A Multipolygon:

+
[[-122.431640625, 37.79106586542567], [-122.431640625, 37.797441398913286], [-122.42666244506835, 37.797441398913286],[-122.42666244506835, 37.79106586542567], [-122.431640625, 37.79106586542567]],
+[[-122.43352890014648, 37.78197638783258], [-122.43352890014648, 37.789031004883654], [-122.42443084716797, 37.789031004883654], [-122.42443084716797, 37.78197638783258], [-122.43352890014648, 37.78197638783258]]
+
+

To Use

+

This module is used as a part of Sheetsee.js. You can download the full version or build your own with a command line tool.

+

You'll create a little bit of HTML and then some JavaScript in your HTML to use this. You can customize marker color, popup content and enable/disable clustering in your map.

+

Methods

+

Here are the functions you can use!

+

Sheetsee.createGeoJSON(data, optionsJSON)

+
    +
  • data JSON array of data
  • +
  • optionsJSON array of strings, spreadsheet column title
  • +
+

If you'd like to just generate geoJSON from a spreadsheet you can use this method.

+

This takes in your spreadsheet data in JSON format (which you can get with Tabletop.js)and the parts of your data, optionsJSON, that you plan on including in your map's popups. These will be column headers in your spreadsheet in an array of strings.

+

If you're not going to have popups on your markers, don't worry about it then and just pass in your data (by default it will use all the row's information).

+
var optionsJSON = ['name', 'breed', 'cuddlability']
+var geoJSON = Sheetsee.createGeoJSON(data, optionsJSON)
+
+

It will return an array in the special geoJSON format that map making things love.

+

Sheetsee.loadMap(options)

+

This method will generate a map for you on the page (it also generates the geoJSON for the map).

+
    +
  • options object required
      +
    • data your spreadsheet data array required
    • +
    • mapDiv the id of the div in your HTML to contain the map required
    • +
    • geoJSONincludes array of strings of column headers to include in popups
    • +
    • template HTML/Mustache template for popups
    • +
    • cluster a true/false boolean, do you want your markers clustered
    • +
    • hexcolor pick one color for your markers
    • +
    +
  • +
+
var mapOptions = {
+  data: data, // required
+  mapDiv: 'map', //required
+  geoJSONincludes: ['Name', 'Animal', 'Rating'], // optional
+  template: '<p>{{Name}}—{{Animal}}—{{Rating}}</p>', // optional
+  cluster: true, // optional
+  hexcolor: '#e91e63' // optional
+}
+Sheetsee.loadMap(mapOptions)
+
+

Breaking Changes The latest version of Sheetsee replaces three methods ('loadMap', 'addTileLayer', 'addMarkerLayer') with one loadMap which takes in an object of map options.

+

Marker colors

+

If you create a column title hexcolor in your spreadsheet and fill each cell with hex color codes, those will be used to color your markers. If you define a color for hexcolor in the options you pass to your map it will override colors in the spreadsheet data.

+

View Demo +Visit Site

+ + + +
+ + + diff --git a/docs/sheetsee-maps.md b/docs/sheetsee-maps.md new file mode 100644 index 00000000..ee2bf7cb --- /dev/null +++ b/docs/sheetsee-maps.md @@ -0,0 +1,97 @@ +# sheetsee-maps + +Sheetsee uses this module to handle maps in your projects. This module uses (and includes) [Leaflet.js](http://leafletjs.com) to make maps of your **points**, **polygons**, **lines** or **multipolygons** (all coordinate based). Details on what that actually looks like [here](http://leafletjs.com/examples/geojson.html). It uses (and includes) [Mustache.js](https://mustache.github.io) templates for marker popups. + +You'll need to include Leaflet's map CSS in your HTML's head: + +```html + + + +``` + +## Maps: Polygons and Lines + +Sheetsee-maps supports polygons and lines; so long as you have the correct coordinate structure in your cells. More details for coordinates of lines and polygons in geoJSON are [here](http://leafletjs.com/examples/geojson.html), but briefly: + +**Must use lowercase spreadsheet column headers: 'lat' and 'long'.** + +**A linestring:** + +```text +[-122.41722106933594, 37.7663045891584], [-122.40477561950684, 37.77695634643178] +``` + +**A polygon:** + +```text +[-122.41790771484375, 37.740381166384914], [-122.41790771484375, 37.74520008134973], [-122.40966796874999, 37.74520008134973],[-122.40966796874999, 37.740381166384914], [-122.41790771484375, 37.740381166384914] +``` + +**A Multipolygon:** + +```text +[[-122.431640625, 37.79106586542567], [-122.431640625, 37.797441398913286], [-122.42666244506835, 37.797441398913286],[-122.42666244506835, 37.79106586542567], [-122.431640625, 37.79106586542567]], +[[-122.43352890014648, 37.78197638783258], [-122.43352890014648, 37.789031004883654], [-122.42443084716797, 37.789031004883654], [-122.42443084716797, 37.78197638783258], [-122.43352890014648, 37.78197638783258]] +``` + +## To Use + +This module is used as a part of [Sheetsee.js](http://jlord.us/sheetsee.js). You can download the [full version](https://github.com/jlord/sheetsee.js/blob/master/js/sheetsee.js) or build your own with a [command line tool](https://github.com/jlord/sheetsee). + +You'll create a little bit of HTML and then some JavaScript in your HTML to use this. You can customize marker color, popup content and enable/disable clustering in your map. + +## Methods + +Here are the functions you can use! + +### `Sheetsee.createGeoJSON(data, optionsJSON)` + +- **data** _JSON array_ of data +- **optionsJSON** _array_ of strings, spreadsheet column title + +If you'd like to just generate geoJSON from a spreadsheet you can use this method. + +This takes in your spreadsheet **data** in JSON format (which you can get with [Tabletop.js]())and the parts of your data, **optionsJSON**, that you plan on including in your map's popups. These will be column headers in your spreadsheet in an array of strings. + +If you're not going to have popups on your markers, don't worry about it then and just pass in your data (by default it will use all the row's information). + +```javascript +var optionsJSON = ['name', 'breed', 'cuddlability'] +var geoJSON = Sheetsee.createGeoJSON(data, optionsJSON) +``` + +It will return an _array_ in the special [geoJSON format](http://geojson.org) that map making things love. + +### `Sheetsee.loadMap(options)` + +This method will generate a map for you on the page (it also generates the geoJSON for the map). + +- **options** _object_ **required** + - `data` your spreadsheet data array **required** + - `mapDiv` the `id` of the `div` in your HTML to contain the map **required** + - `geoJSONincludes` array of strings of column headers to include in popups + - `template` HTML/[Mustache](https://mustache.github.io) template for popups + - `cluster` a true/false boolean, do you want your markers clustered + - `hexcolor` pick one color for your markers + +```js +var mapOptions = { + data: data, // required + mapDiv: 'map', //required + geoJSONincludes: ['Name', 'Animal', 'Rating'], // optional + template: '

{{Name}}—{{Animal}}—{{Rating}}

', // optional + cluster: true, // optional + hexcolor: '#e91e63' // optional +} +Sheetsee.loadMap(mapOptions) +``` + +**Breaking Changes** The latest version of Sheetsee replaces three methods ('loadMap', 'addTileLayer', 'addMarkerLayer') with one `loadMap` which takes in an object of map options. + +#### Marker colors + +If you create a column title `hexcolor` in your spreadsheet and fill each cell with hex color codes, those will be used to color your markers. If you define a color for `hexcolor` in the options you pass to your map it will override colors in the spreadsheet data. + +_[View Demo](http://jlord.us/sheetsee.js/demos/demo-maps.html)_ +_[Visit Site](http://jlord.us/sheetsee.js)_ diff --git a/docs/sheetsee-tables.html b/docs/sheetsee-tables.html new file mode 100644 index 00000000..7ee2c6ba --- /dev/null +++ b/docs/sheetsee-tables.html @@ -0,0 +1,148 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

sheetsee-tables

+

Sheetsee,js uses this module to make tables. With this module you can create tables with your spreadsheet data that are sortable, searchable and paginate-able.

+

You'll need a placeholder <div> in your html, a <script> with a Mustache.js template and a <script> that tells Sheetsee to build the table.

+

Your HTML Placeholder

+

This is as simple as an empty <div> with an id.

+

Your Template

+

Your template is the mockup of what you'd like your table to look like and what content it should show. The style is up to you! It is a mustache template inside of <script> tags.

+

The id of the template should be the same as the HTML placeholder it corresponds to but with "_template" on the end.

+

Sorting

+

If you want users to be able to click on headers and sort that column, your template must include table headers with the class tHeader.

+

You can then style .tHeader in your CSS to make them look how you want.

+

You must also make the inner text of your table headers have the same capitalization as in your spreadsheet. It's ok to have spaces in your table header but don't use spaces in your spreadsheet headers.

+
    +
  • Spreadsheet column name: 'PlaceName'
      +
    • OK table header: 'Place Name'
    • +
    • Not OK table header: 'PLACENAME', 'placename'
    • +
    +
  • +
+

Your Script

+

You'll want to set your table options and pass them into Sheetsee.makeTable(). If you want to add a search/filter, pass your options into Sheetsee.initiateTableFilter().

+

Methods

+

Functions for you to use! There are just two, woo!

+

Sheetsee.makeTable(tableOptions)

+

You pass in an object containing:

+
    +
  • data array your data from Tabletop.js required
  • +
  • pagination number how many rows displayed at one time, defaults to all
  • +
  • tableDiv string the <div> id placeholder in your HTML, includes the hash # required
  • +
  • filterDiv string the <div> id containing your <input> filter if using search, includes the hash # required if using filter
  • +
  • templateID string the id of your <script> tag with the template, defaults to assume it's the same as tableDiv + _template.
  • +
+
var tableOptions = {
+  "data": data,
+  "pagination": 10,
+  "tableDiv": "#fullTable",
+  "filterDiv": "#fullTableFilter",
+  "templateID": "fullTable_template"
+}
+Sheetsee.makeTable(tableOptions)
+
+

Pagination

+

If you do not put in a number for pagination, by default it will show all of the data at once. With pagination, HTML will be added at the bottom of your table for navigation, which you can style in your CSS:

+

HTML

+
<div id='Pagination' currentPage class='table-pagination'>
+  Showing page {{currentPage}} of {{totalPages}}
+  <a class='pagination-pre'>Previous</a><a class='pagination-next'>Next</a>
+</div>
+
+

CSS

+
#Pagination {}
+.pagination-next {}
+.pagination-pre {}
+.no-pag {}
+
+

Sheetsee.initiateTableFilter(tableOptions)

+

If you want to have an input to allow users to search/filter the data in the table, you'll add an input to your HTML. Give it an id and if you want add placeholder text. You'll also need to add a 'clear' button using the .clear CSS class.

+
<input id="tableFilter" type="text" placeholder="filter by.."></input>
+<a href="#" class=".clear">Clear</a>
+
+

Then you'll pass your tableOptions object into this method:

+
Sheetsee.initiateTableFilter(tableOptions)
+
+

Example

+

HTML

+
<input id="siteTableFilter" type="text"></input><a href="#" class=".clear">Clear</a>
+<div id="siteTable"></div>
+
+

Template

+
<script id="tableTemplate" type="text/html">
+    <table>
+    <tr><th class="tHeader">City</th><th class="tHeader">Place Name</th><th class="tHeader">Year</th><th class="tHeader">Image</th></tr>
+      {{#rows}}
+        <tr><td>{{city}}</td><td>{{placename}}</td><td>{{year}}</td><td>{{image}}</td></tr>
+      {{/rows}}
+  </table>
+</script>
+
+

JavaScript

+
<script type="text/javascript">
+  document.addEventListener('DOMContentLoaded', function() {
+    var tableOptions = {
+      "data": data,
+      "pagination": 10,
+      "tableDiv": "#siteTable",
+      "filterDiv": "#siteTableFilter",
+      "templateID": "siteTable_template"
+    }
+    Sheetsee.makeTable(tableOptions)
+    Sheetsee.initiateTableFilter(tableOptions)
+  })
+</script>
+
+

View Demo +Visit Site

+ + + +
+ + + diff --git a/docs/sheetsee-tables.md b/docs/sheetsee-tables.md new file mode 100644 index 00000000..0b6f702c --- /dev/null +++ b/docs/sheetsee-tables.md @@ -0,0 +1,136 @@ +# sheetsee-tables + +Sheetsee,js uses this module to make tables. With this module you can create tables with your spreadsheet data that are sortable, searchable and paginate-able. + +You'll need a placeholder `
` in your html, a ` +``` + +_JavaScript_ + +```javascript + +``` + +_[View Demo](http://jlord.us/sheetsee.js/demos/demo-table.html)_ +_[Visit Site](http://jlord.us/sheetsee.js)_ diff --git a/docs/templates.html b/docs/templates.html new file mode 100644 index 00000000..d425a83a --- /dev/null +++ b/docs/templates.html @@ -0,0 +1,78 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

Templates

+

Here are partially set up projects to get you going!

+

Glitch

+

+

The spreadsheet.glitch.me site will give you an endpoint to use that will return your spreadsheet to you as JSON. The sheetsee.glitch.me site provides template to get started with Sheetsee; it's already set up with a server so that your data is backed up.

+

Fork-n-Go

+

+

A Fork-n-Go project is a project on GitHub that in a few clicks, starting with a fork, gives another user a live website that they control with an easy to swap-for-your-own Google Spreadsheet database.

+

Two awesome things that make this possible: Forking, the tool on GitHub that allows you to copy a public repository onto your account, and GitHub Pages, GitHub's free web hosting service for every repository, account and organization.

+

I've built a whole other website on the idea with lots of examples: jlord.github.io/forkngo

+

How

+

To have a website for a repository hosted by GitHub Pages all you need is to have webfiles uploaded and to tell GitHub the name of the branch you want it to host (in your repository's settings).

+

So Sheetsee.js projects, hosted on GitHub, can easily be forked and connected to another spreadsheet giving another user a live website of their own—with data they control—really easily.

+

Example

+

A Fork-n-Go example from my blog post on the topic:

+

Hack Spots Fork-n-Go

+

I made this website to collect hack spots all over the world from friends and friends of friends (the spreadsheet is wide open, so you can add some, too!). It’s using sheetsee to power the table, map and other elements of the page. Its source is in this repo, with just a gh-pages branch. To create an instance of this site for yourself all you need to do:

+
    +
  • Create a Google spreadsheet with the same headers (just copy and paste header row from the original). Click File > Publish to Web, then Start Publishing.
  • +
  • Fork the original repository.
  • +
  • Edit the HTML file directly on GitHub.com to replace the original spreadsheet’s unique key with your spreadsheet’s key (found in your spreadsheet’s URL). +Commit your change.
  • +
+

Now you have the same site connected to a spreadsheet that you manage — it’s live and can be found at yourGitHubName.github.io/theReposName.

+

forkcommit

+ + + +
+ + + diff --git a/docs/templates.md b/docs/templates.md new file mode 100644 index 00000000..da0e0eae --- /dev/null +++ b/docs/templates.md @@ -0,0 +1,42 @@ +# Templates + +Here are partially set up projects to get you going! + +## Glitch + + + +The [spreadsheet.glitch.me](https://spreadsheet.glitch.me) site will give you an endpoint to use that will return your spreadsheet to you as JSON. The [sheetsee.glitch.me](https://sheetsee.glitch.me) site provides template to get started with Sheetsee; it's already set up with a server so that your data is backed up. + +## Fork-n-Go + + + +A Fork-n-Go project is a project on GitHub that in a few clicks, starting with a fork, gives another user a live website that they control with an easy to swap-for-your-own Google Spreadsheet database. + +Two awesome things that make this possible: **Forking**, the tool on GitHub that allows you to copy a public repository onto your account, and [**GitHub Pages**](http://pages.github.com), GitHub's free web hosting service for every repository, account and organization. + +I've built a whole other website on the idea with lots of examples: [jlord.github.io/forkngo](http://jlord.github.io/forkngo) + +### How + +To have a website for a repository hosted by GitHub Pages all you need is to have webfiles uploaded and to tell GitHub the name of the branch you want it to host (in your repository's settings). + +So Sheetsee.js projects, hosted on GitHub, can easily be forked and connected to another spreadsheet giving another user a live website of their own—with data they control—really easily. + +### Example + +A Fork-n-Go example from my [blog post](http://jlord.github.io/blog/fork-n-go) on the topic: + +#### Hack Spots Fork-n-Go + +I made this website to collect hack spots all over the world from friends and friends of friends (the spreadsheet is wide open, so you can add some, too!). It’s using sheetsee to power the table, map and other elements of the page. Its source is in this repo, with just a gh-pages branch. To create an instance of this site for yourself all you need to do: + +- Create a Google spreadsheet with the same headers (just copy and paste header row from the original). Click File > Publish to Web, then Start Publishing. +- Fork the original repository. +- Edit the HTML file directly on GitHub.com to replace the original spreadsheet’s unique key with your spreadsheet’s key (found in your spreadsheet’s URL). +Commit your change. + +Now you have the same site connected to a spreadsheet that you manage — it’s live and can be found at yourGitHubName.github.io/theReposName. + +![forkcommit](http://jlord.s3.amazonaws.com/wp-content/uploads/forkcommit1.png) diff --git a/docs/tips.html b/docs/tips.html new file mode 100644 index 00000000..fcf65646 --- /dev/null +++ b/docs/tips.html @@ -0,0 +1,113 @@ + + + + + Sheetsee.js + + + + + + + + + + + +
+

Tips

+

A few things to think about beyond maps and tables.

+

Mustache

+

You can use templates for more than just tables. Use them to create lists ol, ul; array of images... You'll need a placeholder <div> in your HTML, a <script> for your template. In your Tabletop.js callback use Mustache to pass your data into the template and add it to the DOM.

+

HTML

+
<div id="divID"></div>
+
+

Template

+
<script id="divID_template" type="text/html">
+  {{#rows}}
+    <div><img class="photo" src="{{some-variable}}"></div>
+  {{/rows}}
+</script>
+
+

Script

+
<script type="text/html">
+  document.addEventListener('DOMContentLoaded', function() {
+    var URL = 'YOURSPREADSHEETSKEYHERE'
+    Tabletop.init({key: URL, callback: showData, simpleSheet: true})
+  })
+
+  function showData (data) {
+    var template = document.querySelector('divID_template').innerHTML
+    var html = Sheetsee.Mustache.render(template, {'rows': data})
+    document.getElementByID('divID').innerHTML = html
+  }
+</script>
+
+

non-table example

+

lib

+

Query Strings

+

If your spreadsheet contains address information, using templates (Sheetsee uses Mustache.js), you can embed those elements into a query string (aka a search URL) like Google Maps URL or Yelp. If you search for a location in Google Maps, you'll notice it creates a URL for that search.

+

So, if you have information in your spreadsheet that would go inside a query string, make a template for inserting them into a link on your page.

+

The basic elements are: a spreadsheet with address info + HTML template to create the query string.

+

The Sheetsee Hack-Spots is an example that does such a thing. Here is the spreadsheet, with address information:

+

img

+

In the HTML template for the table on the Hack-Spots page, the button’s links look like this:

+
<a class="button" href="https://maps.google.com/maps?q={{address}},{{city}},{{state}}" target="_blank">View in Google Maps</a>
+<a class="button" href="http://www.yelp.com/search?find_desc={{name}}&find_loc={{city}},{{state}}" target="_blank">Find on Yelp</a>
+
+

Above we're inserting the address, city, and state details from the spreadsheet into the structure of a query string for Google maps and Yelp. You can figure out the query string of a service by just using it (type in an address in Google Maps) and looking at the resulting URL.

+

With a some CSS and such, the resulting website has a table with the hack spots and a button for viewing in Google Maps or Yelp:

+

img

+

When the page builds, it creates the correct link for each row. When someone clicks on the buttons it takes them directly to the Google Map search result for that address. BAM!

+

IFTTT

+

Ifttt.com offers lots of options sending data from your actions (Twitter, Instagram, GitHub, Pocket...) to Google Spreadsheets.

+

Row Numbers

+

When Tabletop.js returns your spreadsheet data, it adds a key/value of rownumber. This is great to use when you need to uniquely match or find a row in your data.

+

Images

+

Your spreadsheet can contain URLs to images which you can use to display the images on the page you build. Your template would look something like this:

+
<img src='{{imgurl}}'/>
+
+

Data as Classes

+

You can use your data as classes to style with CSS. For instance, if you had data about recipes and a column called 'Taste' that contained either 'savory' or 'sweet'. In a table of the recipes you could do something like:

+
<tr><td class="{{taste}}"></tr>
+
+

Then in your CSS:

+
td .savory {}
+td .sweet {}
+
+ + + +
+ + + diff --git a/docs/tips.md b/docs/tips.md new file mode 100644 index 00000000..3d3b3925 --- /dev/null +++ b/docs/tips.md @@ -0,0 +1,102 @@ +# Tips + +A few things to think about beyond maps and tables. + +## Mustache + +You can use templates for more than just tables. Use them to create lists `ol`, `ul`; array of images... You'll need a placeholder `
` in your HTML, a ` +``` + +_Script_ + +```JavaScript + +``` + +_non-table example_ + +![lib](http://jlord.s3.amazonaws.com/wp-content/uploads/lending-ss.png) + +## Query Strings + +If your spreadsheet contains address information, using templates (Sheetsee uses Mustache.js), you can embed those elements into a query string (aka a search URL) like Google Maps URL or Yelp. If you search for a location in Google Maps, you'll notice it creates a URL for that search. + +So, if you have information in your spreadsheet that would go inside a query string, make a template for inserting them into a link on your page. + +The basic elements are: a spreadsheet with address info + HTML template to create the query string. + +The Sheetsee [Hack-Spots](jlord.github.io/hack-spots) is an example that does such a thing. Here is the spreadsheet, with address information: + +![img](http://jlord.s3.amazonaws.com/wp-content/uploads/Screen-Shot-2013-09-15-at-6.49.19-PM.png) + +In the HTML template for the table on the [Hack-Spots](jlord.github.io/hack-spots) page, the button’s links look like this: + +```HTML +View in Google Maps +Find on Yelp +``` + +Above we're inserting the address, city, and state details from the spreadsheet into the structure of a query string for Google maps and Yelp. You can figure out the query string of a service by just using it (type in an address in Google Maps) and looking at the resulting URL. + +With a some CSS and such, the resulting website has a table with the hack spots and a button for viewing in Google Maps or Yelp: + +![img](http://jlord.s3.amazonaws.com/wp-content/uploads/Screen-Shot-2013-09-15-at-6.43.54-PM.png) + +When the page builds, it creates the correct link for each row. When someone clicks on the buttons it takes them directly to the Google Map search result for that address. BAM! + +## IFTTT + +[Ifttt.com](http://www.ifttt.com) offers lots of options sending data from your actions (Twitter, Instagram, GitHub, Pocket...) to Google Spreadsheets. + +## Row Numbers + +When Tabletop.js returns your spreadsheet data, it adds a key/value of `rownumber`. This is great to use when you need to uniquely match or find a row in your data. + +## Images + +Your spreadsheet can contain URLs to images which you can use to display the images on the page you build. Your template would look something like this: + +```HTML + +``` + +## Data as Classes + +You can use your data as classes to style with CSS. For instance, if you had data about recipes and a column called 'Taste' that contained either 'savory' or 'sweet'. In a table of the recipes you could do something like: + +```HTML + +``` + +Then in your CSS: + +```CSS +td .savory {} +td .sweet {} +``` diff --git a/favicon.png b/favicon.png new file mode 100644 index 00000000..09e96887 Binary files /dev/null and b/favicon.png differ diff --git a/img/glitch.png b/img/glitch.png new file mode 100644 index 00000000..738f7b96 Binary files /dev/null and b/img/glitch.png differ diff --git a/img/next-sheetsee.png b/img/next-sheetsee.png new file mode 100644 index 00000000..a053bdc8 Binary files /dev/null and b/img/next-sheetsee.png differ diff --git a/index.html b/index.html index 27151c7a..13407362 100644 --- a/index.html +++ b/index.html @@ -1,39 +1,134 @@ + - - Yo, yo, yo! - - - - - - - - - - - - - + + + Sheetsee.js + + + + + + + + + + + +
+

sheetseeimg

+

Sheetsee.js is a client-side library for connecting Google Spreadsheets to a website and visualizing the information in tables and maps.

+
- - - +

Spreadsheets!?

+

Google Spreadsheets can be used as simple and collaborative databases, they make getting a data driven site going much easier than traditional databases. Read more about using spreadsheets for databases.

+

Modules

+

Each of Sheetsee's functions are divided into modules. Use just the parts you need; see docs on building. If you don't want to build your own, you can just use the full library which includes all modules, it's here on GitHub.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModuleContainsDocs
sheetseeCommand line module for make a custom build of Sheetsee.Doc
sheetsee-coreIncluded in all builds. Has helpful working-with-your-data functions.Doc
sheetsee-tablesContains everything you'll need to create a table including sortable columns, pagination and search.Doc
sheetsee-mapsFor making maps with your point, line or polygon spreadsheet data. Built with Leaflet.js.Doc
+
New News!
- +

Get your Spreadsheet as JSON or Try Sheetsee with Glitch!

+

The spreadsheet.glitch.me site will give you an endpoint to use that will return your spreadsheet to you as JSON. The sheetsee.glitch.me site provides template to get started with Sheetsee; it's already set up with a server so that your data is backed up.

+

Or Fork a Site!

+

There are site templates hooked up to Sheetsee that are ready to be forked on GitHub and used by you, check out the Fork-n-go site.

+

Sheetsee Updates

+

Sheetsee has just been re-written and there are some breaking changes. Also some nice ones, like dependencies removed. The API for maps with Sheetsee have changed, see the docs.

+
- - \ No newline at end of file +

Resources & Documentation

+

More resources on using Sheetsee:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Getting StartedIdeasDemosUse
About SheetseeTemplatesTable DemoSheetsee-core
Building SheetseeTips!Map DemoSheetsee-tables
BasicsSheetsee-maps
+ + + +
+ + + diff --git a/js/ICanHaz.js b/js/ICanHaz.js deleted file mode 100644 index 25a14ac6..00000000 --- a/js/ICanHaz.js +++ /dev/null @@ -1,542 +0,0 @@ -/*! -ICanHaz.js version 0.10 -- by @HenrikJoreteg -More info at: http://icanhazjs.com -*/ -(function () { -/* - mustache.js — Logic-less templates in JavaScript - - See http://mustache.github.com/ for more info. -*/ - -var Mustache = function () { - var _toString = Object.prototype.toString; - - Array.isArray = Array.isArray || function (obj) { - return _toString.call(obj) == "[object Array]"; - } - - var _trim = String.prototype.trim, trim; - - if (_trim) { - trim = function (text) { - return text == null ? "" : _trim.call(text); - } - } else { - var trimLeft, trimRight; - - // IE doesn't match non-breaking spaces with \s. - if ((/\S/).test("\xA0")) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; - } else { - trimLeft = /^\s+/; - trimRight = /\s+$/; - } - - trim = function (text) { - return text == null ? "" : - text.toString().replace(trimLeft, "").replace(trimRight, ""); - } - } - - var escapeMap = { - "&": "&", - "<": "<", - ">": ">", - '"': '"', - "'": ''' - }; - - function escapeHTML(string) { - return String(string).replace(/&(?!\w+;)|[<>"']/g, function (s) { - return escapeMap[s] || s; - }); - } - - var regexCache = {}; - var Renderer = function () {}; - - Renderer.prototype = { - otag: "{{", - ctag: "}}", - pragmas: {}, - buffer: [], - pragmas_implemented: { - "IMPLICIT-ITERATOR": true - }, - context: {}, - - render: function (template, context, partials, in_recursion) { - // reset buffer & set context - if (!in_recursion) { - this.context = context; - this.buffer = []; // TODO: make this non-lazy - } - - // fail fast - if (!this.includes("", template)) { - if (in_recursion) { - return template; - } else { - this.send(template); - return; - } - } - - // get the pragmas together - template = this.render_pragmas(template); - - // render the template - var html = this.render_section(template, context, partials); - - // render_section did not find any sections, we still need to render the tags - if (html === false) { - html = this.render_tags(template, context, partials, in_recursion); - } - - if (in_recursion) { - return html; - } else { - this.sendLines(html); - } - }, - - /* - Sends parsed lines - */ - send: function (line) { - if (line !== "") { - this.buffer.push(line); - } - }, - - sendLines: function (text) { - if (text) { - var lines = text.split("\n"); - for (var i = 0; i < lines.length; i++) { - this.send(lines[i]); - } - } - }, - - /* - Looks for %PRAGMAS - */ - render_pragmas: function (template) { - // no pragmas - if (!this.includes("%", template)) { - return template; - } - - var that = this; - var regex = this.getCachedRegex("render_pragmas", function (otag, ctag) { - return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + ctag, "g"); - }); - - return template.replace(regex, function (match, pragma, options) { - if (!that.pragmas_implemented[pragma]) { - throw({message: - "This implementation of mustache doesn't understand the '" + - pragma + "' pragma"}); - } - that.pragmas[pragma] = {}; - if (options) { - var opts = options.split("="); - that.pragmas[pragma][opts[0]] = opts[1]; - } - return ""; - // ignore unknown pragmas silently - }); - }, - - /* - Tries to find a partial in the curent scope and render it - */ - render_partial: function (name, context, partials) { - name = trim(name); - if (!partials || partials[name] === undefined) { - throw({message: "unknown_partial '" + name + "'"}); - } - if (!context || typeof context[name] != "object") { - return this.render(partials[name], context, partials, true); - } - return this.render(partials[name], context[name], partials, true); - }, - - /* - Renders inverted (^) and normal (#) sections - */ - render_section: function (template, context, partials) { - if (!this.includes("#", template) && !this.includes("^", template)) { - // did not render anything, there were no sections - return false; - } - - var that = this; - - var regex = this.getCachedRegex("render_section", function (otag, ctag) { - // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder - return new RegExp( - "^([\\s\\S]*?)" + // all the crap at the beginning that is not {{*}} ($1) - - otag + // {{ - "(\\^|\\#)\\s*(.+)\\s*" + // #foo (# == $2, foo == $3) - ctag + // }} - - "\n*([\\s\\S]*?)" + // between the tag ($2). leading newlines are dropped - - otag + // {{ - "\\/\\s*\\3\\s*" + // /foo (backreference to the opening tag). - ctag + // }} - - "\\s*([\\s\\S]*)$", // everything else in the string ($4). leading whitespace is dropped. - - "g"); - }); - - - // for each {{#foo}}{{/foo}} section do... - return template.replace(regex, function (match, before, type, name, content, after) { - // before contains only tags, no sections - var renderedBefore = before ? that.render_tags(before, context, partials, true) : "", - - // after may contain both sections and tags, so use full rendering function - renderedAfter = after ? that.render(after, context, partials, true) : "", - - // will be computed below - renderedContent, - - value = that.find(name, context); - - if (type === "^") { // inverted section - if (!value || Array.isArray(value) && value.length === 0) { - // false or empty list, render it - renderedContent = that.render(content, context, partials, true); - } else { - renderedContent = ""; - } - } else if (type === "#") { // normal section - if (Array.isArray(value)) { // Enumerable, Let's loop! - renderedContent = that.map(value, function (row) { - return that.render(content, that.create_context(row), partials, true); - }).join(""); - } else if (that.is_object(value)) { // Object, Use it as subcontext! - renderedContent = that.render(content, that.create_context(value), - partials, true); - } else if (typeof value == "function") { - // higher order section - renderedContent = value.call(context, content, function (text) { - return that.render(text, context, partials, true); - }); - } else if (value) { // boolean section - renderedContent = that.render(content, context, partials, true); - } else { - renderedContent = ""; - } - } - - return renderedBefore + renderedContent + renderedAfter; - }); - }, - - /* - Replace {{foo}} and friends with values from our view - */ - render_tags: function (template, context, partials, in_recursion) { - // tit for tat - var that = this; - - var new_regex = function () { - return that.getCachedRegex("render_tags", function (otag, ctag) { - return new RegExp(otag + "(=|!|>|&|\\{|%)?([^#\\^]+?)\\1?" + ctag + "+", "g"); - }); - }; - - var regex = new_regex(); - var tag_replace_callback = function (match, operator, name) { - switch(operator) { - case "!": // ignore comments - return ""; - case "=": // set new delimiters, rebuild the replace regexp - that.set_delimiters(name); - regex = new_regex(); - return ""; - case ">": // render partial - return that.render_partial(name, context, partials); - case "{": // the triple mustache is unescaped - case "&": // & operator is an alternative unescape method - return that.find(name, context); - default: // escape the value - return escapeHTML(that.find(name, context)); - } - }; - var lines = template.split("\n"); - for(var i = 0; i < lines.length; i++) { - lines[i] = lines[i].replace(regex, tag_replace_callback, this); - if (!in_recursion) { - this.send(lines[i]); - } - } - - if (in_recursion) { - return lines.join("\n"); - } - }, - - set_delimiters: function (delimiters) { - var dels = delimiters.split(" "); - this.otag = this.escape_regex(dels[0]); - this.ctag = this.escape_regex(dels[1]); - }, - - escape_regex: function (text) { - // thank you Simon Willison - if (!arguments.callee.sRE) { - var specials = [ - '/', '.', '*', '+', '?', '|', - '(', ')', '[', ']', '{', '}', '\\' - ]; - arguments.callee.sRE = new RegExp( - '(\\' + specials.join('|\\') + ')', 'g' - ); - } - return text.replace(arguments.callee.sRE, '\\$1'); - }, - - /* - find `name` in current `context`. That is find me a value - from the view object - */ - find: function (name, context) { - name = trim(name); - - // Checks whether a value is thruthy or false or 0 - function is_kinda_truthy(bool) { - return bool === false || bool === 0 || bool; - } - - var value; - - // check for dot notation eg. foo.bar - if (name.match(/([a-z_]+)\./ig)) { - var childValue = this.walk_context(name, context); - if (is_kinda_truthy(childValue)) { - value = childValue; - } - } else { - if (is_kinda_truthy(context[name])) { - value = context[name]; - } else if (is_kinda_truthy(this.context[name])) { - value = this.context[name]; - } - } - - if (typeof value == "function") { - return value.apply(context); - } - if (value !== undefined) { - return value; - } - // silently ignore unkown variables - return ""; - }, - - walk_context: function (name, context) { - var path = name.split('.'); - // if the var doesn't exist in current context, check the top level context - var value_context = (context[path[0]] != undefined) ? context : this.context; - var value = value_context[path.shift()]; - while (value != undefined && path.length > 0) { - value_context = value; - value = value[path.shift()]; - } - // if the value is a function, call it, binding the correct context - if (typeof value == "function") { - return value.apply(value_context); - } - return value; - }, - - // Utility methods - - /* includes tag */ - includes: function (needle, haystack) { - return haystack.indexOf(this.otag + needle) != -1; - }, - - // by @langalex, support for arrays of strings - create_context: function (_context) { - if (this.is_object(_context)) { - return _context; - } else { - var iterator = "."; - if (this.pragmas["IMPLICIT-ITERATOR"]) { - iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; - } - var ctx = {}; - ctx[iterator] = _context; - return ctx; - } - }, - - is_object: function (a) { - return a && typeof a == "object"; - }, - - /* - Why, why, why? Because IE. Cry, cry cry. - */ - map: function (array, fn) { - if (typeof array.map == "function") { - return array.map(fn); - } else { - var r = []; - var l = array.length; - for(var i = 0; i < l; i++) { - r.push(fn(array[i])); - } - return r; - } - }, - - getCachedRegex: function (name, generator) { - var byOtag = regexCache[this.otag]; - if (!byOtag) { - byOtag = regexCache[this.otag] = {}; - } - - var byCtag = byOtag[this.ctag]; - if (!byCtag) { - byCtag = byOtag[this.ctag] = {}; - } - - var regex = byCtag[name]; - if (!regex) { - regex = byCtag[name] = generator(this.otag, this.ctag); - } - - return regex; - } - }; - - return({ - name: "mustache.js", - version: "0.4.0", - - /* - Turns a template and view into HTML - */ - to_html: function (template, view, partials, send_fun) { - var renderer = new Renderer(); - if (send_fun) { - renderer.send = send_fun; - } - renderer.render(template, view || {}, partials); - if (!send_fun) { - return renderer.buffer.join("\n"); - } - } - }); -}(); -/*! - ICanHaz.js -- by @HenrikJoreteg -*/ -/*global */ -(function () { - function trim(stuff) { - if (''.trim) return stuff.trim(); - else return stuff.replace(/^\s+/, '').replace(/\s+$/, ''); - } - var ich = { - VERSION: "0.10", - templates: {}, - - // grab jquery or zepto if it's there - $: (typeof window !== 'undefined') ? window.jQuery || window.Zepto || null : null, - - // public function for adding templates - // can take a name and template string arguments - // or can take an object with name/template pairs - // We're enforcing uniqueness to avoid accidental template overwrites. - // If you want a different template, it should have a different name. - addTemplate: function (name, templateString) { - if (typeof name === 'object') { - for (var template in name) { - this.addTemplate(template, name[template]); - } - return; - } - if (ich[name]) { - console.error("Invalid name: " + name + "."); - } else if (ich.templates[name]) { - console.error("Template \"" + name + " \" exists"); - } else { - ich.templates[name] = templateString; - ich[name] = function (data, raw) { - data = data || {}; - var result = Mustache.to_html(ich.templates[name], data, ich.templates); - return (ich.$ && !raw) ? ich.$(result) : result; - }; - } - }, - - // clears all retrieval functions and empties cache - clearAll: function () { - for (var key in ich.templates) { - delete ich[key]; - } - ich.templates = {}; - }, - - // clears/grabs - refresh: function () { - ich.clearAll(); - ich.grabTemplates(); - }, - - // grabs templates from the DOM and caches them. - // Loop through and add templates. - // Whitespace at beginning and end of all templates inside - - - - - - - - - -
- - - -``` - -## Awesome Possibilities - -1. Small newsrooms with data for stories but small dev teams. -2. Friends or groups collaborating on data for a website/project. -3. Using [iftt.com](http://www.ifttt.com) to auto populate spreadsheets which are hooked to a website with Sheetsee.js. - -## Examples -1. [Hack Spots](http://jlord.github.io/hack-spots) -2. [James Sconfitto](https://twitter.com/jugglingnutcase) make a [map of his relationship](https://github.com/jugglingnutcase/katiejamie) with his wife <3 - -## Getting Started - -This bit is the same for both client-side and server-side versions. - -### Your Data - -![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/spreadsheettodata.png) - -Your Google Spreadsheet should be set up with row one as your column headers. Row two and beyond should be your data. Each header and row becomes an oject in the final array that Tabletop.js delivers of your data. - -![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/nonos.png) - -There shouldn't be any breaks or horizontal organization in the spreadsheet. But, feel free to format the style of your spreadsheet as you wish; borders, fonts and colors and such do not transfer or affect your data exporting. - - [{"name":"Coco","breed":"Teacup Maltese","kind":"Dog","cuddlability":"5","lat":"37.74832","long":"-122.402158","picurl":"http://distilleryimage8.s3.amazonaws.com/98580826813011e2bbe622000a9f1270_7.jpg","hexcolor":"#ECECEC","rowNumber":1}...] - -#### Hexcolor - -![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/hexcolors.png) - -You must add a column to your spreadsheet with the heading _hexcolor_ (case insensitive). The maps, charts and such use colors and this is the easiest way to standardize that. The color scheme is up to you, all you need to do is fill the column with hexidecimal color values. This [color picker](http://color.hailpixel.com/) by [Devin Hunt](https://twitter.com/hailpixel) is really nice. #Funtip: Coloring the background of the cell it's hexcolor brings delight! - -#### Geocoding - -If you intend to map your data and only have addresses you'll need to geocode the addresses into lat/long coordinates. Mapbox built a [plugin](http://mapbox.com/tilemill/docs/guides/google-docs/#geocoding) - that does this for you in Google Docs. You can also use websites like [latlong.net](http://www.latlong.net/) to get the coordinates and paste them into rows with column headers _lat_ and _long_. - -> image of lat and long column headers - -#### Publishing Your Spreadsheet - -![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/publish.png) - -You need to do this in order to generate a unique key for your spreadsheet, which Tabletop.js will use to get your spreadsheet data. In your Google Spreadsheet, click _File_ > _Publish to the Web_. Then in the next window click _Start Publishing_; it will then turn into a _Stop Publishing_ button. - -![sheetsee](https://raw.github.com/jllord/sheetsee-cache/master/img/key.png) - -You should have an address in a box at the bottom, your key is the portion between the = and the &. You'll retrieve this later when you hook up your site to the spreadsheet. - -### Your Website - -Before you get started with Sheetsee.js you should plan out your website. Design it, create the basic markup and stylesheet. - -For now, create empty `div` placeholders for the map, chart and tables you plan on including. - -## Hooking Up Your Data - -Here the paths diverge: - -### Client-side Hookup - -For client-siders, all you need to do is include the dependencies and sheetsee in your HTML `` and then in a script tag at the bottom of your page, right before the `` tag, you'll include this: - -``` html - -``` - -The **URL** variable is the key from your spreadsheet's longer URL, explained above. `Tabletop.init()` takes that URL and execute's Tabletop, when it's done generating the table it executes the callback `showInfo` function. It's inside of this function that you'll then use your spreadsheet data, **gData**, to do all the Sheetsee.js goodness with. - -### Server-side Hookup - -The server-side version is in the repo [sheetsee-cache](http://www.github.com/jllord/sheetsee-cache). It uses [Node.js](http://www.nodejs.org) to go to Google, get the spreadsheet data (with a Node.js version of [Tabletop.js](http://npmjs.org/tabletop), thanks Max Ogden!) and save it on the server. This means every user that visits the page doesn't have to wait on Google's response to load the charts from the data. - -When the server builds your page, it will build in your data as the variable gData. All you need to do is add your scripts to the bottom of the page. For the tables/templating you'll need to wrap them in an event listener so that it doesn't try and build them before the data has settled. - -``` html - -``` - -#### Running Locally - -You can run this locally and it will check your internet connection - if you're not online it will use the last saved data allowing you to develop offline, yay! - -Once you [clone the repo](http://www.github.com/jllord/sheetsee-cache), navigate there in Terminal, install the node modules and launch the server. - -``` sh -cd sheetsee-cache -npm install -node server.js -``` - -This will launch a local server you can visit and develop locally with in your browser. - -## Working With Your Data - -Tabletop.js will return all of your data and it will be passed into your site as an _array of objects_ called **gData**. Sheetsee.js has functions built in to help you filter or use that data in other ways if you'd like. - -### Sheetsee.getKeyword(data, keyword) - -This takes in your data, an _array of objects_, and searches for a _string_, **keyword**, in each piece of your **data** (formerly the cells of your spreadsheet). It returns an array of each element containing a **keyword** match. Similarly, using `getKeywordCount(data, "keyword)` will return the just the number of times the **keyword** occured. - -``` js -getKeyword(gData, "cat") -// returns [{breed: "Fat", kind: "cat", hexcolor: "#CDCF83"...}, {breed: "Grey", kind: "cat", hexcolor: "#9C9B9A"...}, {breed: "Creepy", kind: "cat", hexcolor: "#918376"...}] -``` - -### Sheetsee.getColumnTotal(data, column) - -Given your **data**, an _array of objects_ and a _string_ **column** header, this functions sums each cell in that column, so they best be numbers. - -``` js -getColumnTotal(gData, "cuddlability") -// returns 11 -``` - -### Sheetsee.getAveragefromColumn(data, column) - -A really simple function that builds on `getColumnTotal()` by returning the average number in a **column** of numbers. - -``` js -getColumnAverage(gData, "cuddlability") -// returns 1.8333333333333333 -``` - -### Sheetsee.getMin(data, column) - -This will return an _array_ of _object_ or _objects_ (if there is a tie) of the element with the lowest number value in the **column** you specify from your **data**. - -``` js -getMin(gData, "cuddlability") -// returns [{breed: "Fat", cuddlability: "0", hexcolor: "#CDCF83"...}, {breed: "Grey", cuddlability: "0", hexcolor: "#9C9B9A"...}, {breed: "Creepy", cuddlability: "0", hexcolor: "#918376"...}] -``` - -### Sheetsee.getMax(data, column) - -This will return an _array_ of _object_ or _objects_ (if there is a tie) of the element with the highest number value in the **column** you specify from your **data**. - -``` js -getMax(gData, "cuddlability") -// returns {breed: "Teacup Maltese", cuddlability: "5", hexcolor: "#ECECEC", kind: "Dog", lat: "37.74832", long: "-122.402158", name: "Coco"...} -``` - -### Don't Forget JavaScript Math - -Create variables that are the sums, differences, multiples and so forth of others. Lots of info on that [here on MDN](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math). - -``` js -var profit09 = Sheetsee.getColumnTotal(gData, "2009") -var profit10 = Sheetsee.getColumnTotal(gData, "2010") -var difference = profit09 - profit10 -``` - -#### What These Little Bits are Good For - -You don't have to just create tables of your data. You can have other portions of your page that show things like, "The difference taco consumption between last week and this week is..." These are easy to create with javascirpt math functions and knowing a little bit more about [icanhas.js](http://icanhazjs.com/). View source on this page to see how I created "Most Cuddlable". - -### Sheetsee.getMatches(data, filter, category) - -Takes **data** as an _array of objects_, a _string_ you'd like to **filter** and a _string_ of the **category** you want it to look in (a column header from your spreadsheet). - -``` js -getMatches(gData, "dog", "kind") -``` - -Returns an _array of objects_ matching the category's filter. - -``` js -[{"name": "coco", "kind": "dog"...}, {"name": "wolfgang", "kind": "dog"...},{"name": "cooc", "kind": "dog"...} ] -``` - - -### Sheetsee.getOccurance(data, category) - -Takes **data** as an _array of objects_ and a _string_ for **category** (a column header from your spreadsheet) you want tally how often an element occured. - -``` js -getOccurance(gData, "kind") -``` - -Returns an object with keys and values for each variation of the category and its occurance. - -``` js -{"dog": 3, "cat": 3} -``` - -### Sheetsee.makeColorArrayOfObject(data, colors) - -If you use `getOccurance()` and want to then chart that data with d3.js, you'll need to make it into an _array_ (instead of an object) and add colors back in (since the hexcolor column applies to the datapoints in your original dataset and not this new dataset). - -This function takes in your data, as an _object_, and an _array_ of hexidecimal color strings which you define. - -``` js -var kinds = getOccurance(gData, "kind") -var kindColors = ["#ff00ff", "#DCF13C"] - -var kindData = makeColorArrayOfObjects(mostPopBreeds, kindColors) -``` - -It will return an array of objects formatted to go directly into a d3 chart with the appropriate _units_ and _label keys_, like so: - -``` js -[{"label": "dog", "units": 2, "hexcolor": "#ff00ff"}, {"label": "cat", "units": 3, "hexcolor": "#DCF13C"}] -``` - -If you pass in an array of just one color it will repeat that color for all items. If you pass fewer colors than data elements it will repeat the sequences of colors for the remainder elements. - -## Make a Map - -Sheetsee.js uses [Mapbox.js](http://mapbox.com/mapbox.js), a [Leaflet.js](http://leafletjs.com/) plugin, to make maps. - -Create an empty `
` in your HTML, with an id. - -``` html -
-``` - -Next you'll need to create geoJSON out of your data so that it can be mapped. - -### Sheetsee.createGeoJSON(data, optionsJSON) - -This takes in your **data** and the parts of your data, **optionsJSON**, that you plan in your map's popups. If you're not going to have popups on your markers, don't worry about it then and just pass in your data. - -``` js -var optionsJSON = ["name", "breed", "cuddlability"] -var geoJSON = Sheetsee.createGeoJSON(gData, optionsJSON) -``` - -It will return an _array_ in the special geoJSON format that map making things love. - -``` js -[{ - "geometry": {"type": "Point", "coordinates": [long, lat]}, - "properties": { - "marker-size": "small", - "marker-color": lineItem.hexcolor - }, - "opts": {the options you pass in}, -}} -``` - - -### Sheetsee.loadMap(mapDiv) - -To create a simple map, with no data, you simply call `.loadMap() and pass in a _string_ of the **mapDiv** (with no #) from your HTML. - -``` js -var map = Sheetsee.loadMap("map") -``` - -### Sheetsee.addTileLayer(map, tileLayer) - -To add a tile layer, aka a custom map scheme/design/background, you'll use this function which takes in your **map** and the source of the **tileLayer**. This source can be a Mapbox id, a URL to a TileJSON or your own generated TileJSON. See [Mapbox's Documentation](http://mapbox.com/mapbox.js/api/v1.0.2/#L.mapbox.tileLayer) for more information. - -``` js -Sheetsee.addTileLayer(map, 'examples.map-20v6611k') -``` - -You can add tiles from awesome mapmakers like [Stamen](examples.map-20v6611k) or create your own in Mapbox's [Tilemill](http://www.mapbox.com/tilemill) or [online](https://tiles.mapbox.com/newmap#3.00/0.00/0.00). - -### Sheetsee.addMarkerLayer(geoJSON, map, zoomLevel) - -To add makers to your map, use this function and pass in your **geoJSON** so that it can get the coordinates, your **map** so that it places the markers there and a **zoom level**. - -``` js -var markerLayer = Sheetsee.addMarkerLayer(geoJSON, map, 11) -``` - -### Sheetsee.addPopups(map, markerLayer) - -To customize the marker popup content in your map you'll need to use this entire function on your website. - -``` js -function addPopups(map, markerLayer) { - markerLayer.on('click', function(e) { - var feature = e.layer.feature - var popupContent = '

' + feature.opts.name + '

' + - '

' + feature.opts.breed + '

' - e.layer.bindPopup(popupContent,{closeButton: false,}) - }) -} -``` - -You will edit the **popupContent** variable however you'd like your popups to look. To reference the data you sent to you geoJSON you'll use `feature.opts` and then one of the column headers you passed into `createGeoJSON().` - -## Make a Table - -Sheetsee.js supports making multiple tables or templates with IcanHas.js. The tables can have multiple inputs for filtering and table headers can be used to sort the data in that column. For each of these you'll need a `
` in your html, a ` -``` - -#### Your ` -``` - -To create another table, simply repeat the steps. - -``` html -
- - -``` - - Learn more about the things you can do with [mustache.js](http://mustache.github.io/). - - -### Sheetsee.makeTable(data, targetDiv) - -You'll call this to make a table out of a **data** and tell it what **targetDiv** in the html to render it in (this should also be the same id as your script template id). - -``` js -Sheetsee.makeTable(gData, "#siteTable") -``` - -## Table Filter/Search - -If you want to have an input to allow users to search/filter the data in the table, you'll add this to your html: - -``` html - -Clear -no matches -``` - -### Sheetsee.initiateTableFilter(data, filterDiv, tableDiv) - -You will then call this function to make that input live: - -``` js -Sheetsee.initiateTableFilter(gData, "#TableFilter", "#siteTable") -``` - -## Make a Chart - -Sheetsee.js comes with a d3.js bar, pie and line chart. Each requires your data be an _array of objects_, formatted to contain "label" and "units" keys. See the section above on Your Data to learn about formatting. - -You'll have to experiement with the charts to find the correct size your `
` will need to be to hold the chart with your data in it nicely. - -You can also make your own d3 chart in a separate .js file, link to that and pass your data on to it. I'd love to see people building some other charts that will work with Sheetsee. - -### Bar Chart - -To create a bar chart you'll need to add a placeholder `
` in your HTML with an id. - -``` html -
-``` - -In your CSS, give it dimensions. - -``` css -#barChart {height: 400px; max-width: 600px; background: #F8CDCD;} -``` - -In a ` + + + + + + +
+ {{{content}}} + + +
+ + +