diff --git a/demo/basic.html b/demo/basic.html new file mode 100755 index 0000000..61a22f7 --- /dev/null +++ b/demo/basic.html @@ -0,0 +1,59 @@ + + + + + + +StackView Basic + + + + + + + + + + + + + + +
+ + + + + \ No newline at end of file diff --git a/demo/documentation.html b/demo/documentation.html new file mode 100755 index 0000000..cc85d68 --- /dev/null +++ b/demo/documentation.html @@ -0,0 +1,270 @@ + + + + + + +Stack View Documentation + + + + + + + + + + + + + + + + + + Fork me on GitHub +

Stack View Documentation

+ +
+
+

Requirements

+

Stack View requires jQuery and two additional plugins to enable further functionality. These plugins are bundled with jquery.stackview.min.js and do not need to be included separately.

+ +

A small set of images is also necessary for drawing the stack. They can be found in the lib/images directory.

+ +

How to Use

+

You can start by looking at the most basic demo.

+

After including the required files, place a div in your html code where you would like Stack View to appear.

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

In your javascript, create some data for Stack View to use.

+
+var data = {
+    "start": "-1", // -1 start value signifies the end of a stack
+    "limit": "0",
+    "num_found": "2",
+    "docs": [
+        {
+            "title": "Blankets",
+            "creator": [
+                "Craig Thompson"
+            ],
+            "measurement_page_numeric": 582,
+            "measurement_height_numeric": 25,
+            "shelfrank": 13,
+            "pub_date": "2003",
+            "link": "http://holliscatalog.harvard.edu/?itemid=|library/m/aleph|009189638"
+        },
+        {
+            "title": "Persepolis",
+            "creator": [
+                "Marjane Satrapi"
+            ],
+            "measurement_page_numeric": 153,
+            "measurement_height_numeric": 24,
+            "shelfrank": 64,
+            "pub_date": "2003",
+            "link": "http://holliscatalog.harvard.edu/?itemid=|library/m/aleph|009098946"
+        }
+    ]
+};
+		
+

Then call the Stack View plugin using a jQuery selector.

+
+		$('#stackview').stackView({data: data});
+		
+

Alternately, you can give Stack View a url. The url should point to a JSON file with data formatted as above or a script that accepts a callback and a start parameter and returns a JSON object. A script is useful for continually feeding Stack View new data as the user scrolls. Basically Stack View's version of paging.

+
+		$('#stackview').stackView({url: 'data.php'});
+		
+

This is the most basic example using PHP. +

+		$start = $_GET['start'];
+		
+		$docs = '[
+		    {
+            "title": "Blankets",
+            "creator": [
+                "Craig Thompson"
+            ],
+            "measurement_page_numeric": 582,
+            "measurement_height_numeric": 25,
+            "shelfrank": 13,
+            "pub_date": "2003",
+            "link": "http://holliscatalog.harvard.edu/?itemid=|library/m/aleph|009189638"
+            }
+        ]';
+        
+        if($start > 0) {
+            echo "{'start': '-1', 'num_found': '0', 'limit': '0', 'docs': ''}";
+        }
+        else {
+            echo "{'start': '0', 'limit': '0', 'num_found': '1', 'docs': $docs}"; 
+        }
+		
+

Available Stack View Options

+

data

+

A JSON object used to construct a static stack. Stack View requires either a data object or a url, but not both.

+

url

+

The URL should point to a JSON file or a script that accepts a callback and start parameter and then provides Stack View with JSON formatted data. Stack View requires either a data object or a url, but not both.

+

jsonp

+

This option, when set to true, tells Stack View to send a JSONP request to the url specified. If using JSONP, make sure that the specified url accepts a callback and includes that callback as part of the JSONP response. +
Default is false.

+

books_per_page

+

How many books will be requested. +
Default is 10.

+

threshold

+

How much screen space to fill with books. +
Default is 1000.

+

page_multiple

+

Pixels per page. +
Default is 0.11.

+

height_multiple

+

Pixels per centimeter. +
Default is 12.

+

search_type

+

The type of search that the script from your url parameter should perform if a search is necessary. +
Default is keyword.

+

query

+

The query that the script from your url should use if performing a search. +
Default is nothing.

+

ribbon

+

The text that will appear in the ribbon at the top of the stack. +
Default is Stack View.

+
+
+ + + + + + + \ No newline at end of file diff --git a/demo/examples.html b/demo/examples.html new file mode 100755 index 0000000..834fdd0 --- /dev/null +++ b/demo/examples.html @@ -0,0 +1,311 @@ + + + + + + +Stack View Examples + + + + + + + + + + + + + + + + + + Fork me on GitHub +

Stack View Examples

+ +
+ +
+ +
+ + + +
+

Amazon stack

+

A stack made up of book search results from the Amazon API. The amazon.php file performs the search, formats and feeds the results to Stack View.

+

Each book's Amazon Sales Rank is roughly sorted into one of ten groups that make up the heatmapping.

+

Include an empty div in the page.

+
+		<div id="amazon-stack"></div>
+		
+

Then call the Stack View plugin using a jQuery selector.

+
+		$('#amazon-stack').stackView({
+			url: 'php/amazon.php', 
+			query: 'memory', 
+			ribbon: 'Amazon search for "memory"'
+		});
+		
+

To use Stack View with the Amazon API, save a copy of the file keys.php.example as keys.php and fill in the required API keys.

+

Note that Amazon's API now limits to 100 results.

+
+ +
+ +
+ +
+ + + +
+

WorldCat stack

+

A keyword search using the WorldCat API. The worldcat.php file performs the search, formats and feeds the results to Stack View.

+

The number of libraries that hold each book is roughly sorted into one of ten groups that make up the heatmapping. This operation is very slow.

+

Include an empty div in the page.

+
+		<div id="worldcat-stack"></div>
+		
+

Then call the Stack View plugin using a jQuery selector.

+
+		$('#worldcat-stack').stackView({
+			url: 'php/worldcat.php', 
+			jsonp: true,
+			query: 'modern pirates', 
+			ribbon: 'WorldCat search for "modern pirates"'
+		});
+		
+

This example utilizes JSONP. See the associated worldcat.php script for code that will return a JSONP response.

+

To use Stack View with the WorldCat API, save a copy of the file keys.php.example as keys.php and fill in the required API key.

+
+ +
+ +
+ +
+ + + +
+

Google stack

+

A keyword search using the Google API. The google.php file performs the search, formats and feeds the results to Stack View.

+

The user ratings are roughly sorted into one of ten groups that make up the heatmapping. Since Google rarely provides the height of the book, these are mostly randomized.

+

Include an empty div in the page.

+
+		<div id="google-stack"></div>
+		
+

Then call the Stack View plugin using a jQuery selector.

+
+		$('#google-stack').stackView({
+			url: 'php/google.php',
+			query: 'time travel', 
+			ribbon: 'Google search for "time travel"'
+		});
+		
+

Note that, according to Google Books API documentation, the totalItems count is an estimate. This causes the Stack View items count to change as the user scrolls.

+

To use Stack View with the Google API, save a copy of the file keys.php.example as keys.php and fill in the required API key.

+
+ +
+ +
+ +
+ + + +
+

DPLA stack

+

A keyword search using the DPLA API. The dpla.php file performs the search, formats and feeds the results to Stack View.

+

Checkouts are roughly sorted into one of ten groups that make up the heatmapping.

+

Include an empty div in the page.

+
+		<div id="dpla-stack"></div>
+		
+

Then call the Stack View plugin using a jQuery selector.

+
+		$('#dpla-stack').stackView({
+			url: 'php/dpla.php',
+			query: 'history', 
+			ribbon: 'DPLA search for "history"'
+		});
+		
+

Note that much of the data from DPLA is currently dummy data.

+
+ +
+ +
+ +
+ + + +
+

Static stack

+

A manually created static stack. The static.json file feeds a JSON object to Stack View. The heatmapping is manually entered here (a digit from 1 to 100).

+

Note that you can also start with the most basic demo.

+

Include an empty div in the page.

+
+		<div id="static-stack"></div>
+		
+

Then call the Stack View plugin using a jQuery selector.

+
+		$('#static-stack').stackView({
+			url: 'json/static.json', 
+			ribbon: 'Static stack'
+		});
+		
+

Example JSON

+
+{
+    "start": "-1",
+    "limit": "0",
+    "num_found": "2",
+    "docs": [
+        {
+            "title": "Blankets",
+            "creator": [
+                "Craig Thompson"
+            ],
+            "measurement_page_numeric": 582,
+            "measurement_height_numeric": 25,
+            "shelfrank": 13,
+            "pub_date": "2003",
+            "link": "http://holliscatalog.harvard.edu/?itemid=|library/m/aleph|009189638"
+        },
+        {
+            "title": "Persepolis",
+            "creator": [
+                "Marjane Satrapi"
+            ],
+            "measurement_page_numeric": 153,
+            "measurement_height_numeric": 24,
+            "shelfrank": 64,
+            "pub_date": "2003",
+            "link": "http://holliscatalog.harvard.edu/?itemid=|library/m/aleph|009098946"
+        }
+    ]
+}
+        
+
+ + + + + + + + \ No newline at end of file diff --git a/demo/index.html b/demo/index.html new file mode 100755 index 0000000..ffc5151 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,200 @@ + + + + + + +Stack View + + + + + + + + + + + + + + + + + + + + + Fork me on GitHub +

Stack View

+ +
+ +
+ +
+ +
+

A virtual shelf

+

Stack View is a book visualization and browsing tool. This jQuery plugin turns metadata into a browsable stack of books.

+

Stack View is drawn with CSS. When possible, the height of the book is based on the actual height of the object and the width is calculated using the page count. The color can be based on any data from ratings and rankings to library checkouts or holdings. The darker the color the higher the rating.

+

JSON data

+
+        {
+            "title": "Blankets",
+            "creator": [
+                "Craig Thompson"
+            ],
+            "measurement_page_numeric": 582,
+            "measurement_height_numeric": 25,
+            "shelfrank": 13,
+            "pub_date": "2003",
+            "link": "http://holliscatalog.harvard.edu/?itemid=|library/m/aleph|009189638"
+        }
+		
+

Becomes a virtual object

+ +
+ + + + + + + \ No newline at end of file diff --git a/demo/liblabstamp.png b/demo/liblabstamp.png new file mode 100755 index 0000000..853b8d1 Binary files /dev/null and b/demo/liblabstamp.png differ diff --git a/json/README.md b/json/README.md index 9fc0e4d..a0ada69 100644 --- a/json/README.md +++ b/json/README.md @@ -33,7 +33,7 @@ var data = { ] }; -$('#stackview').stackview({ data: data }); +$('#stackview').stackView({ data: data }); ``` ...or passed as a URL to a static file... diff --git a/lib/jquery.stackview.min.js b/lib/jquery.stackview.min.js index 47e5ff4..7e8b000 100644 --- a/lib/jquery.stackview.min.js +++ b/lib/jquery.stackview.min.js @@ -12,4 +12,4 @@ Dual licensed under MIT and GPL. */ -(function(g,f,a,h){var d,e="stackview",c,b={};d={init:"stackview.init",page_load:"stackview.pageload"};b.get_heat=function(i){return i===100?10:Math.floor(i/10)+1};b.get_height=function(l,m){var k=parseInt(m.measurement_height_numeric,10),n=l.options.min_item_height,j=l.options.max_item_height,i=l.options.height_multiple;k=Math.min(Math.max(k,n),j)*i;return k+"px"};b.get_thickness=function(k,l){var n=parseInt(l.measurement_page_numeric,10),m=k.options.min_pages,j=k.options.max_pages,i=k.options.page_multiple;n=Math.min(Math.max(n,m),j)*i;return n+"px"};b.normalize_link=function(i){return i.title_link_friendly?"../shelflife/book/"+i.title_link_friendly+"/"+i.id:i.link};b.get_author=function(j){var i=j.creator&&j.creator.length?j.creator[0]:"";if(/^([^,]*)/.test(i)){i=i.match(/^[^,]*/)}return i};b.render_items=function(i,m,j){var k=j?"after":"append",l=j?j:i.$element.find(i.options.selectors.item_list);g.each(m,function(o,p){var n=g(tmpl(c.templates.book,{heat:b.get_heat(p.shelfrank),book_height:b.get_height(i,p),book_thickness:b.get_thickness(i,p),link:b.normalize_link(p),title:p.title,author:b.get_author(p),year:p.pub_date}));n.data("stackviewItem",p);l[k](n)});if(j){j.remove()}};b.calculate_params=function(i){var k={start:i.page*i.options.items_per_page,limit:i.options.items_per_page,search_type:i.options.search_type,query:i.options.query},j,l;if(k.search_type==="loc_sort_order"){k.start="-1";if(i.page===0){k.query=["[",i.options.id-Math.floor(i.options.items_per_page/2),"%20TO%20",i.options.id+Math.floor(i.options.items_per_page/2),"]"].join("")}else{if(i.direction==="down"){j=i.$element.find(i.options.selectors.item).last();l=j.data("stackviewItem").loc_sort_order[0]+1;k.query=["[",l,"%20TO%20",l+i.options.items_per_page,"]"].join("")}else{if(i.direction==="up"){j=i.$element.find(i.options.selectors.item).first();l=j.data("stackviewItem").loc_sort_order[0]+1;k.query=["[",l-i.options.items_per_page,"%20TO%20",l,"]"].join("")}}}}return k};b.fetch_page=function(j,m){var l=b.calculate_params(j),k,i;if(j.options.jsonp){l.callback="?"}i=g.param(l);j.page++;k=f.stackCache.get(j.options.url+i);if(k){m(k)}else{g.getJSON(j.options.url,i,function(n){f.stackCache.set(j.options.url+l,n,j.options.cache_ttl);m(n)})}};b.reverse_flow=function(j){var m=j.$element.find(j.options.selectors.item);for(var k=m.length-1,l=0;k>=0;k--,l++){m.eq(k).css("z-index",l)}};c=function(j,i){this.element=j;this.$element=g(j);this.options=g.extend({},c.defaults,i);this.page=0;this.finished={up:false,down:false};this.loc_sort_order=h;this.direction="down";this.init()};g.extend(c,{defaults:{url:"basic.json",data:"",jsonp:false,items_per_page:10,threshold:1000,page_multiple:0.2,height_multiple:12.5,search_type:"keyword",query:"",ribbon:"Stack View",id:null,min_pages:200,max_pages:540,min_item_height:20,max_item_height:39,cache_ttl:60,selectors:{item:".stack-item",item_list:".stack-items",ribbon:".ribbon"}}});g.extend(true,c.prototype,{init:function(){var i=this;this.$element.html(tmpl(c.templates.scaffold,{ribbon:this.options.ribbon})).addClass(e).bind(d.page_load,function(){b.reverse_flow(i)});this.$element.data("stackviewObject",this);this.$element.trigger(d.init);this.next_page()},next_page:function(){var i=g(tmpl(c.templates.placeholder,{})),k=this,j=this.options;if(this.finished.down){return}this.direction="down";if(j.data){b.render_items(this,j.data.docs?j.data.docs:j.data);this.finished.down=true;this.$element.trigger(d.page_load,[j.data])}else{if(j.url){this.$element.find(j.selectors.item_list).append(i);b.fetch_page(this,function(l){b.render_items(k,l.docs,i);if(parseInt(l.start,10)===-1){k.finished.down=true}console.log(d.page_load);k.$element.trigger(d.page_load,[l])})}}},prev_page:function(){var i=g(tmpl(c.templates.placeholder,{})),k=this.options,j=this;if(k.search_type!=="loc_sort_order"||this.finished.up){return}this.direction="up";this.$element.find(k.selectors.item_list).prepend(i);b.fetch_page(this,function(l){var m=j.$element.find(k.selectors.item).first();b.render_items(j,l.docs,i);if(page>1){j.$element.find(k.selectors.item_list).animate({scrollTop:"+="+m.position().top},0)}if(parseInt(l.start,10)===-1){j.finished.up=true}j.$element.trigger(d.page_load,[l])})}});g.fn[e]=function(k){var i,j=Array.prototype.slice.call(arguments,1);this.each(function(m,o){var l=g(o),p=l.data("stackviewObject");if(!p){new c(o,k)}else{if(p[k]){var n=p[k](j);if(i===h&&n!==h){i=n}}}});return i===h?this:i};f.StackView=c})(jQuery,window,document);(function(c,d){var a=c(document),b;c.extend(StackView.defaults,{infiniteScrollDistance:100});b=function(f){var l=c(f.target),m=l.data("stackviewObject"),j,e,g,i,h,k;if(!m){return}e=m.options;j=l.find(e.selectors.item_list);g=j.find(e.selectors.item).last().position().top;g+=j.scrollTop();i=g-l.height()-e.infiniteScrollDistance;h=function(){if(j.scrollTop()>=i){j.unbind("scroll.stackview",h);l.stackview("next_page")}};k=function(){if(j.scrollTop()<=e.infiniteScrollDistance){j.unbind("scroll.stackview",k);l.stackview("prev_page")}};j.bind("scroll.stackview",h);j.bind("scroll.stackview",k);h();k()};a.delegate(".stackview","stackview.pageload",b)})(jQuery);(function(c,d){var b=c(document),a=window.StackView;c.extend(true,a.defaults,{transitionDuration:200,navigationPercent:80,selectors:{downstream:".downstream",upstream:".upstream",num_items:".num-found span"}});b.delegate(".stackview","stackview.init",function(f){var g=c(f.target),e=g.data("stackviewObject"),i=g.find(e.options.selectors.item_list),h=g.height()*e.options.navigationPercent/100;g.prepend(tmpl(a.templates.navigation,{}));g.delegate(e.options.selectors.downstream,"click",function(){i.animate({scrollTop:"+="+h},e.options.transitionDuration);return false}).delegate(e.options.selectors.upstream,"click",function(){i.animate({scrollTop:"-="+h},e.options.transitionDuration);return false})}).delegate(".stackview","stackview.pageload",function(g,h){var i=c(g.target),e=i.data("stackviewObject"),f=h.num_found?h.num_found:h.length;i.find(e.options.selectors.num_items).text(f)})})(jQuery);window.stackCache=(function(d,f){var b={},e=d.JSON&&(function(){try{return("localStorage" in d)&&d.localStorage!==null}catch(h){return false}})();return{set:g,get:c,remove:a};function g(j,k,h){var i=h&&new Date(+new Date()+h*1000),m={expires:+i,value:k};if(e){try{localStorage[j]=JSON.stringify(m)}catch(l){return l}}else{b[j]=m}}function c(h){var i,j;if(e){i=localStorage[h];if(i){i=JSON.parse(i)}}else{i=b[h]}if(i){if(i.expires&&i.expires<+new Date()){a(h)}else{j=i.value}}return j}function a(h){if(e){localStorage.removeItem(h)}else{delete b[h]}}})(window);(function(a){StackView.templates={scaffold:'
<%= ribbon %>