Created
February 22, 2012 06:21
-
-
Save thisismattmiller/1882090 to your computer and use it in GitHub Desktop.
Client for visualMOA.org
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vmoa = { | |
searchMainTerm: null, //the inital search term | |
searchSecondTerm: null, //the refined search term | |
searchSecondType: null, //the refined part of speach of that search term | |
searchThirdYear: null, //the year selected from the n-Gram | |
searchThirdTerm: null, //the connected term selected from the ngram page (like the top 10 word) | |
searchThirdType: null, //the part of speach of the seelcted connected word | |
searchMainCount: 0, | |
authorNetworkObject: null, //the data object | |
authorNetworkD3Force: null, //the d3 objects to interact with the network graph | |
authorNetworkD3Vis: null, //the d3 vis element | |
authorNetworkD3Nodes: null, //the d3 nodes | |
authorNetworkD3Links: null, // ' ' links | |
authorNetworkScale: null, // the d3 scale function to size the nodes | |
words100k: [], //holds the 100k words | |
awsURI: "", //the url to the aws instance | |
ocrToolSkip: 0, | |
History: null, //holds the nav object | |
//lookup table for the journals | |
journals: [ | |
{id: "amis", title : "American Missionary", dates : "1878 - 1901"}, | |
{id: "amwh", title : "American Whig Review", dates: "1845 - 1852"}, | |
{id: "atla", title : "Atlantic Monthly", dates: "1857 - 1901"}, | |
{id: "bays", title : "Bay State Monthly", dates: "1884 - 1886"}, | |
{id: "cent", title : "The Century", dates: "1881 - 1899"}, | |
{id: "cont", title : "Continental Monthly", dates: "1862 - 1864"}, | |
{id: "gala", title : "The Galaxy", dates: "1866 - 1878"}, | |
{id: "harp", title : "Harper's New Monthly Magazine", dates: "1850 - 1899"}, | |
{id: "intr", title : "International Monthly Magazine", dates: "1850 - 1852"}, | |
{id: "newe", title : "The New England Magazine", dates: "1886 - 1900"}, | |
{id: "nwen", title : "The New-England Magazine", dates: "1831 - 1835"}, | |
{id: "livn", title : "The Living Age", dates: "1844 - 1900"}, | |
{id: "manu", title : "Manufacturer and Builder", dates: "1869 - 1894"}, | |
{id: "nwng", title : "New Englander", dates: "1843 - 1892"}, | |
{id: "nora", title : "North American Review", dates: "1815 - 1900"}, | |
{id: "oldg", title : "The Old Guard", dates: "1863 - 1867"}, | |
{id: "punc", title : "Punchinello", dates: "1870"}, | |
{id: "putn", title : "Putnam's Monthly", dates: "1853 - 1870"}, | |
{id: "scia", title : "Scientific American", dates: "1846 - 1869"}, | |
{id: "scmo", title : "Scribner's Monthly", dates: "1870 - 1881", wiki: "http://en.wikipedia.org/wiki/Scribner's_Monthly"}, | |
{id: "scri", title : "Scribner's Magazine", dates: "1887 - 1896", wiki: "http://en.wikipedia.org/wiki/Scribner's_Magazine"}, | |
{id: "usde", title : "The United States Democratic Review", dates: "1837 - 1859", wiki: "http://en.wikipedia.org/wiki/The_United_States_Magazine_and_Democratic_Review"} | |
], | |
months: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"], | |
/*--------------------------- | |
Updates the db with the user reply | |
-----------------------------*/ | |
ocrToolUpdate: function(word, review, incorrect, correct){ | |
if (typeof correct == 'undefined'){correct='null';} | |
if (typeof incorrect == 'undefined'){incorrect='null';} | |
//review: 1= needs review 2= its okay, 3 = incorrect, correct and incorrect are supplied | |
var req = $.getJSON( "/ocrToolUpdate/" + word + "/" + review + "/" + incorrect + "/" + correct) | |
.done(function(json) { | |
vmoa.ocrToolNext(); | |
}) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/*--------------------------- | |
display and setup the ocr tool | |
-----------------------------*/ | |
ocrToolInit: function(){ | |
vmoa.History.pushState({state:8}, "VisualMOA | OCR Correct", "?ocr"); | |
this.ocrToolNext(); | |
}, | |
/*--------------------------- | |
loads the next OCR problem and display it | |
-----------------------------*/ | |
ocrToolNext: function(){ | |
this.toggleWorking(true); | |
var req = $.getJSON( "/ocrToolNext/" + vmoa.ocrToolSkip) | |
.done(function(json) { | |
$('#ocrToolErrors').hide('fast'); | |
$('#ocrToolIncorrect').val(json[0]._id) | |
$('#ocrToolCorrect').val("") | |
$('#ocrToolWord').text(json[0]._id); | |
var sentence = json[0].sentence; | |
sentence= sentence.replace(json[0]._id,'<span style="text-decoration:underline">' + json[0]._id + '</span>'); | |
sentence= sentence.replace(vmoa.capitaliseFirstLetter(json[0]._id),'<span style="text-decoration:underline">' + json[0]._id + '</span>'); | |
$('#ocrToolSentence').html(sentence); | |
vmoa.toggleWorking(false); | |
}) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/*--------------------------- | |
Start of the 100k word freq | |
-----------------------------*/ | |
int100kWords: function(){ | |
this.toggleWorking(true); | |
vmoa.History.pushState({state:7}, "VisualMOA | 100K Words", "?100k"); | |
//load the big json file for all the words, this is not the most optimal way to do it but I rather put | |
//the load of servering a larger file from the satic server (a lot of bandwidth) than 100s requests to the node server | |
var script = document.createElement("script"); | |
script.type = "text/javascript"; | |
script.src = "http://www.visualmoa.org/js/words.js"; // use this for linked script | |
document.body.appendChild(script); | |
}, | |
/*--------------------------- | |
Start of the 100k word freq | |
-----------------------------*/ | |
build100kWords: function(){ | |
//this.toggleWorking(true); | |
//$("#authorsList").empty(); | |
//$("#authorsNetworkChart svg").remove(); | |
$(document).keydown(function(e){ | |
if (e.keyCode == 37) { | |
if (parseInt($("#wordFreqRange").val())>0){ | |
$("#wordFreqRange").val(parseInt($("#wordFreqRange").val())-1); | |
$("#wordFreqRange").change(); | |
} | |
return false; | |
} | |
if (e.keyCode == 39) { | |
if (parseInt($("#wordFreqRange").val())<100000){ | |
$("#wordFreqRange").val(parseInt($("#wordFreqRange").val())+1); | |
$("#wordFreqRange").change(); | |
} | |
return false; | |
} | |
}); | |
$("#wordFreqContextLink").on("click",function(event){ | |
var req = $.getJSON( "/wordContext/" + encodeURIComponent($("#wordFreqActiveWord").text())) | |
.done(function(json) { | |
var sentence = json[0].sentence; | |
//clean it up a little | |
sentence = sentence.replace(/ /g," "); | |
sentence = sentence.replace(/_/g,""); | |
//wont catach upper case but ehhh... | |
sentence = sentence.replace($("#wordFreqActiveWord").text(),'<span style="text-decoration:underline">' + $("#wordFreqActiveWord").text() + "</span>"); | |
sentence = sentence.replace(vmoa.capitaliseFirstLetter($("#wordFreqActiveWord").text()),'<span style="text-decoration:underline">' + $("#wordFreqActiveWord").text() + "</span>"); | |
sentence = sentence.replace($("#wordFreqActiveWord").text().toUpperCase(),'<span style="text-decoration:underline">' + $("#wordFreqActiveWord").text() + "</span>"); | |
$("#wordFreqContext").html(sentence); | |
$("#wordFreqContext").show('fast'); | |
}) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
event.preventDefault(); | |
return false; | |
}); | |
$("#wordFreqFilter").on("keyup",function(){ | |
if (vmoa.words100k.indexOf($(this).val())!=-1){ | |
$("#wordFreqRange").val(parseInt(vmoa.words100k.indexOf($(this).val()))); | |
$("#wordFreqRange").change(); | |
} | |
}); | |
$("#wordFreqRange").on("change",function(){ | |
$("#wordFreqContext").hide('fast'); | |
$("#wordFreqPlace").text(vmoa.numberWithCommas(parseInt($(this).val())) + vmoa.returnOrdinal(parseInt($(this).val())) ); | |
$("#wordFreqPreviousWord").text(vmoa.words100k[parseInt($(this).val())-1]); | |
$("#wordFreqPreviousWord").css("left", -1*parseInt($("#wordFreqPreviousWord").width())+175); | |
$("#wordFreqActiveWord").text(vmoa.words100k[parseInt($(this).val())]); | |
$("#wordFreqNextWord").text(vmoa.words100k[parseInt($(this).val())+1]); | |
}); | |
$("#wordFreqRange").change(); | |
this.toggleWorking(false); | |
}, | |
/*--------------------------- | |
Loads and displays the authors articles | |
-----------------------------*/ | |
authorNetworkBuildArticles: function(author, terms){ | |
//make it csv | |
terms = terms.join(","); | |
$("#authorsNetworkArticlesBody").empty(); | |
$("#authorsNetworkArticles").show('fast'); | |
$("#authorsNetworkArticlesHeader").html('Articles by ' + author + ' about : <span>' + terms.replace(/,/g,', ') + '</span>'); | |
var req = $.getJSON( "/authors/filter/" +author+'/'+terms) | |
.done(function(json) { | |
for (article in json){ | |
$("#authorsNetworkArticlesBody").append( | |
$("<div>") | |
.addClass('authorsNetworkArticlesHolder') | |
.click(function(){ | |
$($(this).children()[2]).show('fast'); | |
$($(this).children()[3]).show('fast'); | |
}) | |
.append( | |
//the journal and the year | |
$("<div>") | |
.addClass('authorsNetworkArticlesMeta') | |
.text(vmoa.returnJournalData(json[article].journal).title + ' - ' + json[article].year), | |
//the title of the article | |
$("<div>") | |
.addClass('authorsNetworkArticlesTitle') | |
.text(json[article].title), | |
$("<div>") | |
.addClass('authorsNetworkArticlesTerms') | |
.text('Article is about: ' + json[article].terms.join(", ")), | |
$("<div>") | |
.addClass('authorsNetworkArticlesSentence') | |
.html(function(){ | |
searchTerms = encodeURIComponent(json[article].title); //make it url safe | |
//try to grab the last name of the author | |
var lastName = author.split(' ')[author.split(' ').length-1]; | |
var query = "http://ebooks.library.cornell.edu/cgi/t/text/text-idx?ALLSELECTED=1&xc=1&g=moagrp&type=simple&rgn=full+text&q1=" + searchTerms + "&Submit=Search&c=" + vmoa.returnJournalData(json[article].journal).id + "&cite1=" + lastName + "&cite1restrict=author&cite2=" + searchTerms + "&cite2restrict=title" ; | |
return "Core Sentence:<br>" + json[article].sentence + '<br><a href="' + query + '" target="_target">Search for article in MOA archive</a>'; | |
}) | |
) | |
); | |
} | |
}) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/*--------------------------- | |
Start of the author network | |
name = the name of the author to add to the network | |
onlyOneTerm = if populated it means that the author will only be added for that one term | |
addMoreIcon = if true it will add a plus symbol node to allow for more authors to be added to a term. | |
-----------------------------*/ | |
authorNetworkAddAuthor: function(name,onlyOneTerm,addMoreIcon){ | |
if (typeof onlyOneTerm == 'undefined'){onlyOneTerm=false;} | |
if (typeof addMoreIcon == 'undefined'){addMoreIcon=false;} | |
//is it already added? | |
for (aNode in this.authorNetworkD3Nodes){ | |
//if this is only one term req then we want to add duplicate authors to the network because they can appear off of multiple subjects | |
if (onlyOneTerm){ | |
//we never want to add the same author that was just linked to this subject, so make sure this is not the root author node | |
if (this.authorNetworkD3Nodes[aNode].id==name && this.authorNetworkD3Nodes[aNode].term == false){return false;} | |
//now dont add anyone again who is already attached to this node | |
if (this.authorNetworkD3Nodes[aNode].id==name && this.authorNetworkD3Nodes[aNode].term == onlyOneTerm){return false;} | |
}else{ | |
//otherwise do not add duplicate authors | |
if (this.authorNetworkD3Nodes[aNode].id==name){return false;} | |
} | |
} | |
//find it in the data obj | |
for (author in this.authorNetworkObject){ | |
if (this.authorNetworkObject[author]._id==name){ | |
var newAuthorNode = {id: this.authorNetworkObject[author]._id, type : "author", size : this.authorNetworkObject[author].value, term: onlyOneTerm, connectedTerms : []}; | |
vmoa.authorNetworkD3Nodes.push(newAuthorNode); | |
//now loop through all the topics and see if they are added and link them | |
var index = -1; | |
for (aTerm in this.authorNetworkObject[author].terms){ | |
if (onlyOneTerm){ | |
if (onlyOneTerm!=this.authorNetworkObject[author].terms[aTerm]){ | |
continue; | |
} | |
} | |
var newSubjectNode = {id: this.authorNetworkObject[author].terms[aTerm], type : "subject"}; | |
index = -1; | |
for (aNode in this.authorNetworkD3Nodes){ | |
if (this.authorNetworkD3Nodes[aNode].id == this.authorNetworkObject[author].terms[aTerm]){ | |
index = aNode; | |
} | |
} | |
if (index==-1){ | |
//not yet added, | |
vmoa.authorNetworkD3Nodes.push(newSubjectNode); | |
vmoa.authorNetworkD3Links.push({target : newAuthorNode, source : newSubjectNode}); | |
}else{ | |
//already in here | |
vmoa.authorNetworkD3Links.push({target : this.authorNetworkD3Nodes[index], source : newAuthorNode}); | |
} | |
//push this term into the authors terms | |
vmoa.authorNetworkD3Nodes[vmoa.authorNetworkD3Nodes.indexOf(newAuthorNode)].connectedTerms.push(this.authorNetworkObject[author].terms[aTerm]); | |
} | |
if(addMoreIcon){ | |
var addMore = {id: "more " + this.authorNetworkD3Nodes[index].id, term : this.authorNetworkD3Nodes[index].id, type : "more", size : 5}; | |
vmoa.authorNetworkD3Nodes.push(addMore); | |
vmoa.authorNetworkD3Links.push({target : this.authorNetworkD3Nodes[index], source : addMore}); | |
addMoreIcon=false; | |
} | |
this.authorNetworkRedraw(); | |
} | |
} | |
}, | |
/*--------------------------- | |
redraw the nodes and links | |
-----------------------------*/ | |
authorNetworkRedraw: function(){ | |
var link = vmoa.authorNetworkD3Vis.selectAll("line.link") | |
.data(vmoa.authorNetworkD3Links, function(d) { return d.source.id + "-" + d.target.id; }); | |
link.enter().insert("svg:line", "g.node") | |
.style("stroke","#C8C891") | |
.attr("class", "link"); | |
link.exit().remove(); | |
var node = vmoa.authorNetworkD3Vis.selectAll("g.node") | |
.data(vmoa.authorNetworkD3Nodes, function(d) { return d.id;}); | |
var nodeEnter = node.enter().append("svg:g") | |
.attr("class", "node") | |
.style("fill", "#444") | |
.on("mouseover", function(d, i){d3.select(this).style('fill',"#e3774f") ;}) | |
.on("mouseout", function(d, i){d3.select(this).style("fill", "#444");}) | |
.on("dblclick",function(d){ | |
//if it is a author then load related articles | |
if (d.type=='author'){ | |
vmoa.authorNetworkBuildArticles(d.id, d.connectedTerms); | |
} | |
}) | |
.on("click",function(d){ | |
var total = 0; | |
//we need to know how many there are to begin with | |
for (author in vmoa.authorNetworkObject){ | |
if (vmoa.authorNetworkObject[author].terms.indexOf(d.id) != -1){ total++; } | |
} | |
if (d.type=='author'){ | |
if (d3.event.shiftKey){ | |
//we want to disconnect this author node from the subjects and re-add it | |
for (aNode in vmoa.authorNetworkD3Nodes){ | |
if(vmoa.authorNetworkD3Nodes[aNode].id==d.id && d.term != false){ | |
var removedNode = vmoa.authorNetworkD3Nodes.splice(aNode,1); | |
//now remove the link | |
for (aLink in vmoa.authorNetworkD3Links){ | |
if (vmoa.authorNetworkD3Links[aLink].source.id == d.id){ | |
vmoa.authorNetworkD3Links.splice(aLink,1); | |
} | |
} | |
vmoa.authorNetworkRedraw(); | |
//add back in | |
vmoa.authorNetworkAddAuthor(d.id); | |
return; | |
} | |
} | |
} | |
} | |
//if it is a more, add a plus sign load some more authors node | |
if (d.type=='more'){ | |
alreadyAuthors = []; | |
//loop through all the nodes and find the authors that are already dispalyed for this term | |
for (aNode in vmoa.authorNetworkD3Nodes){ | |
if (vmoa.authorNetworkD3Nodes[aNode].term==d.term){ | |
alreadyAuthors.push(vmoa.authorNetworkD3Nodes[aNode].id); | |
} | |
} | |
//now loop through and add it if it is not already added | |
var count = 1; | |
var totalCount = 1; | |
for (author in vmoa.authorNetworkObject){ | |
if (count>6){break;} | |
//does it have this term in it? | |
if (vmoa.authorNetworkObject[author].terms.indexOf(d.term)!=-1){ | |
totalCount=totalCount+1; | |
//make sure it is not already on there | |
if (alreadyAuthors.indexOf(vmoa.authorNetworkObject[author]._id)==-1){ | |
//add it to the graph | |
if (count<6){ | |
vmoa.authorNetworkAddAuthor(vmoa.authorNetworkObject[author]._id,d.term,false); | |
}else{ | |
//if there are more add the load more node | |
if (total > 11){ | |
vmoa.authorNetworkAddAuthor(vmoa.authorNetworkObject[author]._id,d.term,true); | |
}else{ | |
vmoa.authorNetworkAddAuthor(vmoa.authorNetworkObject[author]._id,d.term,false); | |
} | |
} | |
count++; | |
} | |
} | |
} | |
} | |
//if it is a subject expand other authors | |
if (d.type=='subject'){ | |
var count = 1; | |
for (author in vmoa.authorNetworkObject){ | |
//console.log(vmoa.authorNetworkObject[author]); | |
if (count>6){break;} | |
//does it have this term in it? | |
if (vmoa.authorNetworkObject[author].terms.indexOf(d.id)!=-1){ | |
//add it to the graph | |
if (count<6){ | |
vmoa.authorNetworkAddAuthor(vmoa.authorNetworkObject[author]._id,d.id); | |
}else{ | |
//if there are more add the load more node | |
if (total > 6){ | |
vmoa.authorNetworkAddAuthor(vmoa.authorNetworkObject[author]._id,d.id,true); | |
}else{ | |
vmoa.authorNetworkAddAuthor(vmoa.authorNetworkObject[author]._id,d.id); | |
} | |
} | |
count++; | |
} | |
} | |
} | |
}) | |
.call(vmoa.authorNetworkD3Force.drag); | |
nodeEnter.append("svg:image") | |
.attr("class", "circle") | |
.attr("cursor","pointer") | |
.attr("xlink:href", function(d){ | |
if (d.type=="subject"){return "http://www.visualmoa.org/img/book.png";} | |
if (d.type=="author"){return "http://www.visualmoa.org/img/author.png";} | |
if (d.type=="more"){return "http://www.visualmoa.org/img/plus.png";} | |
}) | |
.attr("x", function(d){ | |
if (d.type=="author"){return vmoa.authorNetworkScale(d.size) / 2 * -1;} | |
if (d.type=="subject"){return -13.3775;} | |
if (d.type=="more"){return -12.5;} | |
}) | |
.attr("y", function(d){ | |
if (d.type=="author"){return vmoa.authorNetworkScale(d.size) / 1.25 * -1;} | |
if (d.type=="subject"){return -7.5;} | |
if (d.type=="more"){return -12.5;} | |
}) | |
.attr("height", function(d){ | |
if (d.type=="author"){return vmoa.authorNetworkScale(d.size);} | |
if (d.type=="subject"){return 15;} | |
if (d.type=="more"){return 25;} | |
}) | |
.attr("width", function(d){ | |
if (d.type=="author"){return vmoa.authorNetworkScale(d.size);} | |
if (d.type=="subject"){return 26.755;} | |
if (d.type=="more"){return 25;} | |
}); | |
//.attr("width", "16px") | |
//.attr("height", "16px"); | |
nodeEnter.append("title") | |
.text(function(d) { | |
if (d.type=="more"){return "Click to load more authors for this subject.";} | |
}); | |
nodeEnter.append("svg:text") | |
.attr("class", "nodetext") | |
.style("font-size", 12) | |
.attr("cursor","pointer") | |
.style("font-weight",function(d){ | |
if (d.type=="author"){return "bold";} | |
}) | |
.attr("dx", function(d){return d.id.length * 2.8 * -1; }) | |
.attr("dy", 20) | |
.text(function(d) { | |
if (d.type=="more"){return "";} | |
return d.id | |
}); | |
node.exit().remove(); | |
vmoa.authorNetworkD3Force.start(); | |
}, | |
/*--------------------------- | |
Start of the author network | |
-----------------------------*/ | |
buildAuthorNetwork: function(){ | |
this.toggleWorking(true); | |
//$("#authorsList").empty(); | |
//$("#authorsNetworkChart svg").remove(); | |
vmoa.History.pushState({state:6}, "VisualMOA | Author Network", "?authorNetwork"); | |
//if it is alreadt running don't re make it | |
if ($("#authorsList").children().length!=0){this.toggleWorking(false); return;} | |
var req = $.getJSON( "/authors/") | |
.done(function(json) { | |
$('#suthorsNetworkHelpClose').click(); | |
vmoa.authorNetworkObject = json; | |
//console.log(json); | |
//create the list of people | |
maxMinRange = []; | |
for (author in json){ | |
maxMinRange.push(json[author].value); | |
$("#authorsList").append( | |
$("<div>") | |
.addClass('authorListDivHolder') | |
.append( | |
$("<div>") | |
.text(json[author]._id) | |
.addClass('authorListDiv') | |
.data("_id",json[author]._id) | |
.click(function(){ | |
vmoa.authorNetworkAddAuthor($(this).data('_id')); | |
$('#authorsNetworkHelp').hide('fast'); | |
}) | |
.mouseover(function(){ | |
var domEle = $(this).parent().children()[1]; | |
$(domEle).css('visibility','visible'); | |
}) | |
.mouseout(function(){ | |
var domEle = $(this).parent().children()[1]; | |
$(domEle).css('visibility','hidden'); | |
}) | |
).append( | |
$("<div>") | |
.text('') | |
.addClass('authorWikiLinkDiv') | |
.mouseover(function(){ | |
$(this).css('visibility','visible'); | |
}) | |
.mouseout(function(){ | |
$(this).css('visibility','hidden'); | |
}).append( | |
$("<a>") | |
.attr('target','_blank') | |
.attr('href','http://www.google.com/search?q=' + json[author]._id.split(' ').join('+') + '+writer+wikipedia&btnI') | |
.attr('title','Try a Wikipedia search for this author') | |
.append( | |
$("<img>") | |
.attr("src","http://www.visualmoa.org/img/wikipedia-icon.gif") | |
.attr("border","0") | |
.css('height','18px').css('width','auto') | |
) | |
) | |
) | |
); | |
} | |
vmoa.authorNetworkScale = d3.scale.linear() | |
.domain([d3.min(maxMinRange), d3.max(maxMinRange)]) | |
.range([15, 50]); | |
$("#authorsNetwork").css("height", $(window).height() - 63 + "px"); | |
$("#authorsList").css("height", $(window).height() - 63 + "px"); | |
$("#authorsNetworkChart").css("height", $(window).height() - 63 + "px"); | |
$("#authorsNetworkArticles").css("height", $(window).height() - 63 + "px"); | |
//inilaize the network graph stuff | |
var w = $("#authorsNetworkChart").width(), | |
h = $("#authorsNetworkChart").height(); | |
vmoa.authorNetworkD3Force = d3.layout.force() | |
.gravity(0.05) | |
.distance(110) | |
.charge(-220) | |
.size([w, h]); | |
vmoa.authorNetworkD3Nodes = vmoa.authorNetworkD3Force.nodes(); | |
vmoa.authorNetworkD3Links = vmoa.authorNetworkD3Force.links(); | |
vmoa.authorNetworkD3Vis = d3.select("#authorsNetworkChart").append("svg:svg") | |
.attr("width", w) | |
.attr("height", h); | |
vmoa.authorNetworkD3Force.on("tick", function() { | |
vmoa.authorNetworkD3Vis.selectAll("g.node") | |
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
vmoa.authorNetworkD3Vis.selectAll("line.link") | |
.attr("x1", function(d) { return d.source.x; }) | |
.attr("y1", function(d) { return d.source.y; }) | |
.attr("x2", function(d) { return d.target.x; }) | |
.attr("y2", function(d) { return d.target.y; }); | |
}); | |
vmoa.toggleWorking(false); | |
}) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/* | |
when there are no results. | |
*/ | |
noResults: function(spanDOM){ | |
History.back(); | |
$(spanDOM).fadeIn('slow', function() { | |
$(spanDOM).fadeOut(4000); | |
}); | |
}, | |
/*--------------------------- | |
starts off the article network tool | |
-----------------------------*/ | |
searchArticles: function(){ | |
this.toggleWorking(true); | |
if ($('#inputSearchArticle').val().length==0){return false;} | |
$("#articleNetworkChart").empty(); | |
$("#articleNetworkInfoTitle").empty(); | |
$("#articleNetworkInfoTerms").empty(); | |
$("#articleNetworkInfoSentence").empty(); | |
$("#articleNetworkInfoJournal").empty(); | |
this.toggleWorking(true); | |
//hide the search stuff | |
$('#search').fadeOut(100); | |
vmoa.History.pushState({state:5}, "VisualMOA | Article Tree", "?articleTree"); | |
this.searchMainTerm = $.trim($('#inputSearchArticle').val()); | |
var req = $.getJSON( "/articles/" + this.searchMainTerm.toLowerCase() ) | |
.done(function(json) { | |
if (json.children.length==0){ | |
vmoa.toggleWorking(false); | |
vmoa.noResults('#noResultsAT'); | |
return false; | |
} | |
$('#articleNetworkInfo').fadeIn('slow'); | |
$('#articleNetworkInstructions').css('display','block'); | |
var m = [0, 120, 0, 120], | |
w = 1280 - m[1] - m[3], | |
h = (json.children.length*20) - m[0] - m[2], | |
i = 0, | |
duration = 500, | |
root; | |
var tree = d3.layout.tree() | |
.size([h, w]); | |
var diagonal = d3.svg.diagonal() | |
.projection(function(d) { return [d.y, d.x]; }); | |
var vis = d3.select("#articleNetworkChart").append("svg") | |
.attr("width", w + m[1] + m[3]) | |
.attr("height", h + m[0] + m[2]) | |
.append("g") | |
.attr("transform", "translate(" + m[3] + "," + m[0] + ")"); | |
root = json; | |
root.x0 = h / 2; | |
root.y0 = 0; | |
function collapse(d) { | |
if (d.children) { | |
d._children = d.children; | |
d._children.forEach(collapse); | |
d.children = null; | |
} | |
} | |
root.children.forEach(collapse); | |
update(root); | |
function update(source) { | |
// Compute the new tree layout. | |
var nodes = tree.nodes(root).reverse(); | |
// Normalize for fixed-depth. | |
nodes.forEach(function(d) { d.y = d.depth * 190; }); | |
// Update the nodes… | |
var node = vis.selectAll("g.artTree") | |
.data(nodes, function(d) { return d.id || (d.id = ++i); }); | |
// Enter any new nodes at the parent's previous position. | |
var nodeEnter = node.enter().append("g") | |
.attr("class", "artTree") | |
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) | |
.on("click", click); | |
nodeEnter.append("circle") | |
.attr("r", 1e-6) | |
.style("fill", function(d) { return d._children ? "#C8C891" : "#fff"; }); | |
nodeEnter.append("text") | |
.attr("x", function(d) { return d.children || d._children ? -10 : 10; }) | |
.attr("dy", ".25em") | |
.attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) | |
.text(function(d) { return d.name; }) | |
.style("fill-opacity", 1e-6) | |
//provide a little handel to mouse over | |
nodeEnter.append("rect") | |
.attr("x", function(d) { return -5; }) | |
.attr("y", function(d) { return -5; }) | |
.attr("height", 10) | |
.attr("cursor","pointer") | |
.attr("width",100) | |
.style("fill-opacity", 0) | |
.attr("visibility", function(d) { return d._children ? "hidden" : "visible"; }) | |
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }) | |
.on("mouseover", function(d){ | |
if (typeof d.sentence == "string"){ | |
$('#articleNetworkInstructions').css('display','none'); | |
$('#articleNetworkInfoTitle').text(d.name + " (" + d.year + ")"); | |
$('#articleNetworkInfoTerms').empty(); | |
$('#articleNetworkInfoTerms').html("This article is about:<br>") | |
var terms = d.terms.split(","); | |
for (term in terms){ | |
$('#articleNetworkInfoTerms').append( | |
$("<a>") | |
.attr("href","#") | |
.text(terms[term]) | |
.data("term",terms[term]) | |
.click(function(event){ | |
$('#inputSearchArticle').val($(this).data('term')); | |
vmoa.searchArticles(); | |
event.preventDefault(); | |
return false; | |
}) | |
).append( | |
$("<span>").text(" ") | |
); | |
} | |
$('#articleNetworkInfoSentence').html("Core Sentence:<br>"); | |
$('#articleNetworkInfoSentence').append( | |
$("<span>").text(d.sentence) | |
); | |
$('#articleNetworkInfoJournal') | |
.text("Journal: " + vmoa.returnJournalData(d.journal).title) | |
.append("<br>") | |
.append( | |
$("<a>") | |
.text("View article at MOA Archive") | |
.attr("target", "_blank") | |
.attr('href', function(){ | |
searchTerms = encodeURIComponent(d.name); //make it url safe | |
var query = "http://ebooks.library.cornell.edu/cgi/t/text/text-idx?ALLSELECTED=1&xc=1&g=moagrp&type=simple&rgn=full+text&q1=" + searchTerms + "&cite1=&cite1restrict=author&cite2=" + searchTerms + "&cite2restrict=title&Submit=Search&c=" + vmoa.returnJournalData(d.journal).id; | |
return query; | |
}) | |
); | |
//$('#articleNetworkInfo').text(d.sentence); | |
} | |
}); | |
// Transition nodes to their new position. | |
var nodeUpdate = node.transition() | |
.duration(duration) | |
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); | |
nodeUpdate.select("circle") | |
.attr("r", 4.5) | |
.style("fill", function(d) { return d._children ? "#C8C891" : "#fff"; }); | |
nodeUpdate.select("text") | |
.style("fill-opacity", 1); | |
// Transition exiting nodes to the parent's new position. | |
var nodeExit = node.exit().transition() | |
.duration(duration) | |
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) | |
.remove(); | |
nodeExit.select("circle") | |
.attr("r", 1e-6); | |
nodeExit.select("text") | |
.style("fill-opacity", 1e-6); | |
// Update the links… | |
var link = vis.selectAll("path.link") | |
.data(tree.links(nodes), function(d) { return d.target.id; }); | |
// Enter any new links at the parent's previous position. | |
link.enter().insert("path", "g") | |
.attr("class", "link") | |
.attr("d", function(d) { | |
var o = {x: source.x0, y: source.y0}; | |
return diagonal({source: o, target: o}); | |
}) | |
.transition() | |
.duration(duration) | |
.attr("d", diagonal); | |
// Transition links to their new position. | |
link.transition() | |
.duration(duration) | |
.attr("d", diagonal); | |
// Transition exiting nodes to the parent's new position. | |
link.exit().transition() | |
.duration(duration) | |
.attr("d", function(d) { | |
var o = {x: source.x, y: source.y}; | |
return diagonal({source: o, target: o}); | |
}) | |
.remove(); | |
// Stash the old positions for transition. | |
nodes.forEach(function(d) { | |
d.x0 = d.x; | |
d.y0 = d.y; | |
}); | |
} | |
// Toggle children on click. | |
function click(d) { | |
if (d.children) { | |
d._children = d.children; | |
d.children = null; | |
} else { | |
d.children = d._children; | |
d._children = null; | |
} | |
update(d); | |
} | |
vmoa.toggleWorking(false); | |
} | |
) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/*--------------------------- | |
Builds the page view box inline with the quotes | |
vol = the meta id for the journal ready to be sent to the server | |
image = a int of the "IMG", a way to narrow down the selction, it needs to be in the formated later to make sure it is padded, etc, see below | |
holder = a int of the div id where we should put everything, format it as '#quote' + holder | |
md5 = a hash of the sentence being expanded so we can easily compare and highlight the expanded sentence in the text | |
-----------------------------*/ | |
buildPageView: function(vol,image,holder, md5){ | |
this.toggleWorking(true); | |
$('#quote' + holder).empty(); | |
//pad the img number to meet the format on the server | |
padded_image = vmoa.padNumber(image,5); | |
//get the data | |
var req = $.getJSON( "/page/"+vol+"/"+padded_image ) | |
.done(function(data) { | |
//create a place to hold the results | |
$('#quote' + holder).append( | |
$("<div>") | |
.addClass("pageViewer") | |
); | |
for (aSentence in data.results){ | |
//if the title is blank it is a continuation of the article, if it isnt then we need to announce what artcile we are looking at | |
if (data.results[aSentence].title!=""){ | |
$('#quote' + holder + " div").append( | |
$("<span>") | |
.text(data.results[aSentence].title) | |
.addClass("pageViewerTitle") | |
); | |
$('#quote' + holder + " div").append( | |
$("<br>") | |
); | |
} | |
var useClass = "pageViewerBody"; | |
//emphisize the sentence in context | |
if (md5==vmoa.MD5(data.results[aSentence].sentence)){useClass = "pageViewerBodyHighLight";} | |
$('#quote' + holder + " div").append( | |
$("<span>") | |
.text(data.results[aSentence].sentence + " ") | |
.addClass(useClass) | |
); | |
} | |
//build the nav buttons at the bottom | |
$('#quote' + holder + " div").append( | |
$("<hr>") | |
); | |
$('#quote' + holder + " div").append( | |
$("<div>") | |
.addClass("quoteButtons") | |
.append( | |
$("<button>") | |
.addClass("btn") | |
.html("← Previous Page") | |
.click(function(){ | |
vmoa.buildPageView(vol,image-1,holder,md5); | |
}) | |
) | |
.append( | |
$("<button>") | |
.addClass("btn") | |
.html("Close") | |
.click(function(){ | |
$('#quote' + holder).animate({ | |
height: 0, | |
}, 300, function() { | |
$('#quote' + holder).empty(); | |
$('#quote' + holder).css("height","auto"); | |
}); | |
}) | |
) | |
.append( | |
$("<button>") | |
.addClass("btn") | |
.html("Next Page →") | |
.click(function(){vmoa.buildPageView(vol,image+1,holder,md5); }) | |
) | |
); | |
var offset = $('#quote' + holder).offset(); | |
$('html, body').animate({scrollTop:offset.top-20}, 'fast'); | |
vmoa.toggleWorking(false); | |
} | |
) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/*--------------------------- | |
builds/displays the quotes from connected words from the nGram | |
-----------------------------*/ | |
buildQuotes: function(){ | |
this.toggleWorking(true); | |
$('#quotesHolderList').empty(); | |
this.History.pushState({state:4}, "VisualMOA | Connected Quotes", "?quotes"); | |
//hide the previous pge | |
$('#ngramHolder').fadeOut('fast'); | |
var sentences=[]; | |
//colllect the data | |
var req = $.getJSON( "/text/" + vmoa.searchThirdYear + "/" + vmoa.searchSecondTerm.toLowerCase() + "/" + vmoa.searchSecondType + "/" + vmoa.searchThirdTerm.toLowerCase() + "/" + vmoa.searchThirdType) | |
.done(function(data) { | |
//we want to group the quotes by journal and then by article if possible | |
for (quote in data.results){ | |
var journal=vmoa.returnJournalData(data.results[quote].page); | |
var idSafeDate = data.results[quote].date.replace(".",""); //we use this to make IDs so strip out the period | |
//is this jounal added to the page yet? | |
if (!$('#journalHolder' + journal.id).length){ | |
//nope | |
$('#quotesHolderList').append( | |
$('<div>') | |
.attr("id", 'journalHolder' + journal.id) | |
); | |
//add the title and links and stuff | |
$('#journalHolder' + journal.id).append( | |
$('<h4>') | |
.text(journal.title) | |
.attr("title","Journal Title : " + journal.title + " (" + journal.dates + ")") | |
); | |
//TODO | |
} | |
//is there already a section for this article? | |
if (!$('#articleHolder' + journal.id + idSafeDate + vmoa.MD5(data.results[quote].title)).length){ | |
//nope | |
$('#journalHolder' + journal.id).append( | |
$("<div>") | |
.attr("id",'articleHolder' + journal.id + idSafeDate + vmoa.MD5(data.results[quote].title)) | |
.addClass("articleHolder") | |
); | |
//var articleDate = Date.parse("1-" + data.results[quote].date.split(".")[1] + "-" + data.results[quote].date.split(".")[0]); | |
var articleDate = new Date(data.results[quote].date.split(".")[0] + '-' + data.results[quote].date.split(".")[1] + '-015') | |
//console.log(vmoa.months[articleDate.getMonth()] + " " + articleDate.getMonth() + " " + data.results[quote].date) | |
//add the title of the article | |
$('#articleHolder' + journal.id + idSafeDate + vmoa.MD5(data.results[quote].title)).append( | |
$('<h6>') | |
.text(data.results[quote].title + " (" + vmoa.months[articleDate.getMonth()] + " " + articleDate.getFullYear() +")") | |
.attr("title","Article Title") | |
); | |
} | |
//not sure if to enable this.... | |
//if ($.inArray(vmoa.MD5(journal.id+data.results[quote].sentence), sentences)==-1){ //this bit just makes sure we aren't repeating setences | |
//we want to emphisize the matched words | |
var sentence = data.results[quote].sentence; | |
if (sentence.indexOf(vmoa.searchSecondTerm)!=-1){ | |
sentence = sentence.replace(vmoa.searchSecondTerm,'<span class="quoteText' + vmoa.searchSecondType + '">'+ vmoa.searchSecondTerm +'</span>'); | |
}else if (sentence.indexOf(vmoa.capitaliseFirstLetter(vmoa.searchSecondTerm))!=-1){ | |
//take care of upper | |
sentence = sentence.replace(vmoa.capitaliseFirstLetter(vmoa.searchSecondTerm),'<span class="quoteText' + vmoa.searchSecondType + '">'+ vmoa.searchSecondTerm +'</span>'); | |
}else if (sentence.indexOf(vmoa.searchSecondTerm.toLowerCase())!=-1){ | |
//take care of lowercased | |
sentence = sentence.replace(vmoa.searchSecondTerm.toLowerCase(),'<span class="quoteText' + vmoa.searchSecondType + '">'+ vmoa.searchSecondTerm +'</span>'); | |
} | |
if (sentence.indexOf(vmoa.searchThirdTerm)!=-1){ | |
sentence = sentence.replace(vmoa.searchThirdTerm,'<span class="quoteText' + vmoa.searchThirdType + '">'+ vmoa.searchThirdTerm +'</span>'); | |
}else if (sentence.indexOf(vmoa.capitaliseFirstLetter(vmoa.searchThirdTerm))!=-1){ | |
//take care of upper | |
sentence = sentence.replace(vmoa.capitaliseFirstLetter(vmoa.searchThirdTerm),'<span class="quoteText' + vmoa.searchThirdType + '">'+ vmoa.capitaliseFirstLetter(vmoa.searchThirdTerm) +'</span>'); | |
}else if (sentence.indexOf(vmoa.searchThirdTerm.toLowerCase())!=-1){ | |
//take care of lowercased | |
sentence = sentence.replace(vmoa.searchThirdTerm.toLowerCase(),'<span class="quoteText' + vmoa.searchThirdType + '">'+ vmoa.searchThirdTerm +'</span>'); | |
} | |
//add the text into the article | |
$('#articleHolder' + journal.id + idSafeDate + vmoa.MD5(data.results[quote].title)).append( | |
$("<div>") | |
.html(sentence) | |
.addClass("quoteText") | |
.append( | |
$("<a>") | |
.text("[expand context]") | |
.css("padding","0px 2px 0px 2px") | |
.css("color","#444444") | |
.attr("title","Expand this sentence, view more of the article") | |
.data("vol", data.results[quote].page.replace(/\//g,"|")) | |
.data("image", parseInt(data.results[quote].image.replace(/img/ig,""),10)) | |
.data("holder", quote) | |
.data("md5", vmoa.MD5(data.results[quote].sentence)) | |
.attr("href","#") | |
.click(function(event){ | |
//so we want to build the preview box, but not here, tooo many nested functionnnnnsssss | |
vmoa.buildPageView($(this).data("vol"),$(this).data("image"),$(this).data("holder"),$(this).data("md5")); | |
event.preventDefault(); | |
return false; | |
}) | |
) | |
.append( | |
$("<a>") | |
.attr("target", "_blank") | |
.text("[search MOA]") | |
.css("color","#444444") | |
.css("padding","0px 2px 0px 2px") | |
.attr("title","Attempt to view this sentence on the MOA website") | |
.attr("href", function(){ | |
var maxChar = data.results[quote].sentence.length; | |
if (maxChar>101){maxChar=101;} //the MOA site cuts it off | |
var searchTerms = data.results[quote].sentence.substring(0,maxChar) | |
//the MOA site does not like half formed words, so break it up by word and drop the last one | |
var words = searchTerms.split(" "); | |
searchTerms = ""; | |
for (i=0;i<words.length-1;i++){ | |
searchTerms = searchTerms + " " + words[i]; | |
} | |
searchTerms = encodeURIComponent(searchTerms); //make it url safe | |
var query = "http://ebooks.library.cornell.edu/cgi/t/text/text-idx?ALLSELECTED=1&xc=1&g=moagrp&type=simple&rgn=full+text&q1=" + searchTerms + "&cite1=&cite1restrict=author&cite2=&cite2restrict=author&Submit=Search&c=" + journal.id; | |
return query; | |
}) | |
) | |
); | |
$('#articleHolder' + journal.id + idSafeDate + vmoa.MD5(data.results[quote].title)).append( | |
$("<div>") | |
.attr("id","quote" + quote) | |
); | |
//} | |
//not being used right now but maybe should be. | |
sentences.push(vmoa.MD5(journal.id+data.results[quote].sentence)); | |
} | |
$('#quotesHolder').fadeIn('fast'); | |
vmoa.toggleWorking(false); | |
} | |
) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/*--------------------------- | |
builds the details for the year for the diffrent parts of speach | |
-----------------------------*/ | |
buildNgramDetails: function(useYear){ | |
//build for the three typess | |
var types = ['np','nn','vb']; | |
this.toggleWorking(true); | |
for (x in types){ | |
//empty out any current graphs | |
$("#ngramDetails" + types[x] + 'Chart').empty(); | |
$("#ngramDetails" + types[x] + 'OverflowChart').empty(); | |
$(".title").css("display","none"); | |
//colllect the data | |
var req = $.getJSON( "/filter/" + vmoa.searchThirdYear + "/" + vmoa.searchSecondTerm.toLowerCase() + "/" + types[x] + "/" + vmoa.searchSecondType + "/") | |
.done(function(data) { | |
$(".title").css("display","block"); | |
//this is just to figure out what the type of speach we are looking up,the this.url refers | |
//to the url of the json req which has the type in it. | |
var useType = this.url.substring(this.url.length-6,this.url.length-4); | |
//grab the data | |
var results = {"name":"results", "children" : []}; | |
var resultsOverflow = {"name":"overflow", "children" : []}; | |
var counter=0; | |
var maxSize = []; | |
//process the data | |
for (aType in data.children){ | |
//set the type for the bubble bilder to know the color to use | |
data.children[aType].type = useType; | |
//bubles are hard to read, so only have the top 5 results, then list the rest below the graph | |
if (counter<10){ | |
results.children.push(data.children[aType]); | |
counter++; | |
}else{ | |
maxSize.push(parseInt(data.children[aType].size)); | |
resultsOverflow.children.push(data.children[aType]); | |
} | |
} | |
//build the chart | |
var r = ($(document).width()/3)-75; | |
$('#ngramDetails' + useType + 'Chart').css('width',r+'px'); | |
//the lastR holds the size of the last bubble, we uuse it below | |
var lastR = vmoa.buildBubble(results,'ngramDetails' + useType + 'Chart',r); | |
//now new need to list the over flow results below the chart | |
var currentCY = 0; | |
var getCY = function(plus){ | |
currentCY = currentCY + (plus*2); | |
return currentCY; | |
} | |
var rad = d3.scale.linear() | |
.domain([0, d3.max(maxSize)]) | |
.range([0, 30]); | |
//the margin to use | |
var m = 5; | |
//make the intial CY a line up at the top | |
currentCY = (rad(d3.max(maxSize))-10) * -1; | |
var vis = d3.select('#ngramDetails' + useType + 'OverflowChart').append("svg") | |
.attr("width", r) | |
.attr("height", r) | |
.attr("id","ngramOverflow" + useType + "Chart") | |
.attr("class", "bubble"); | |
//add in a rect behind the label text to facilitate clicking | |
vis.selectAll(".ngramOverflowLabelRect") | |
.data(resultsOverflow.children) | |
.enter().append("rect") | |
.attr("width", function(d) { return r; }) | |
.attr("height", function(d) { return rad(d.size)*2; }) | |
.attr("y", function(d, i){return(getCY(rad(d.size)+m) - rad(d.size));}) | |
.attr("x", function() {return rad(d3.max(maxSize));}) | |
.style("cursor", "pointer") | |
.attr("opacity", 0.0) | |
.on("mouseover", function(d, i){d3.select("#" + useType + i).style("stroke-width", 1).style("stroke", "#444444");}) | |
.on("mouseout", function(d, i) {d3.select("#" + useType + i).style("stroke-width", 0.000005)}) | |
.on("click", function(d){ | |
vmoa.searchThirdType=d.type; | |
vmoa.searchThirdTerm=d.name.toLowerCase(); | |
vmoa.buildQuotes(); | |
}); | |
//reset the CY | |
currentCY = (rad(d3.max(maxSize))-10) * -1; | |
vis.selectAll(".circle") | |
.data(resultsOverflow.children) | |
.enter().append("circle") | |
.attr("r", function(d) { return rad(d.size); }) | |
.attr("id", function(d, i) {return useType + i;}) | |
.attr("cy", function(d, i){return(getCY(rad(d.size)+m));}) | |
.attr("cx", function() {return rad(d3.max(maxSize));}) | |
.style("cursor", "pointer") | |
.style("fill", function(d) { | |
if (d.type=='nn'){ | |
return "#66c499" | |
}else if (d.type=='np'){ | |
return "#e3774f"; | |
}else{ | |
return "#e47598"; | |
} | |
}) | |
.on("mouseover", function(d, i){d3.select(this).style("stroke-width", 1).style("stroke", "#444444");}) | |
.on("mouseout", function(d, i) {d3.select(this).style("stroke-width", 0.000005)}) | |
.on("click", function(d){ | |
}); | |
//reset the CY | |
currentCY = (rad(d3.max(maxSize))-10) * -1; | |
vis.selectAll(".ngramOverflowLabelSize") | |
.data(resultsOverflow.children) | |
.enter() | |
.append("text") | |
.attr("x", function() {return rad(d3.max(maxSize));}) | |
.attr("y", function(d){ return( getCY(rad(d.size)+m)) }) | |
.attr("text-anchor", "middle") | |
.attr("dy", ".3em") | |
.attr("font-size", "14") | |
.style("fill","#444444") | |
.attr("pointer-events", "none") | |
.style("font-family", "Helvetica, Arial, sans-serif") | |
.text(function(d){ return d.size;}); | |
//reset the CY | |
currentCY = (rad(d3.max(maxSize))-10) * -1; | |
vis.selectAll(".ngramOverflowLabelText") | |
.data(resultsOverflow.children) | |
.enter() | |
.append("text") | |
.attr("x", function() {return rad(d3.max(maxSize))*2 + m;}) | |
.attr("y", function(d){ return( getCY(rad(d.size)+m)) }) | |
.attr("text-anchor", "right") | |
.attr("dy", ".3em") | |
.attr("font-size", "15") | |
.attr("pointer-events", "none") | |
.style("fill","#444444") | |
.style("font-family", "Helvetica, Arial, sans-serif") | |
.text(function(d){ return d.name;}); | |
//make sure the svg is big enough | |
d3.select("#ngramOverflow" + useType + "Chart").attr("height", function(){ return getCY(0) + rad(d3.max(maxSize))} ); | |
//turn off the working spinner if this is the last one called "vb" | |
(useType == "vb") ? vmoa.toggleWorking(false) : null; | |
} | |
) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
} | |
}, | |
/*--------------------------- | |
builds the ngram chart | |
id = the mongodb object _id string | |
-----------------------------*/ | |
buildNgram: function(id){ | |
this.toggleWorking(true); | |
this.History.pushState({state:3}, "VisualMOA | n-gram view", "?ngram"); | |
//hide the search stuff | |
$('#mainSearchPartialOverflow').fadeOut('fast'); | |
$('#mainSearchChartHolder').fadeOut('fast'); | |
//clear out any old charts | |
$('#ngramChart').empty(); | |
//make sure the old details are gone too | |
$("#ngramDetails" + "nn" + 'Chart').empty(); | |
$("#ngramDetails" + "nn" + 'OverflowChart').empty(); | |
$("#ngramDetails" + "np" + 'Chart').empty(); | |
$("#ngramDetails" + "np" + 'OverflowChart').empty(); | |
$("#ngramDetails" + "vb" + 'Chart').empty(); | |
$("#ngramDetails" + "vb" + 'OverflowChart').empty(); | |
$(".title").css("display","none"); | |
nGram = []; | |
//colllect the data | |
var req = $.getJSON( "/ngram/" + id) | |
.done(function(data) { | |
//build the data object | |
//there is an array of number that corospond to a year 1800-1901, so the x+1800 basiclly is the year | |
for (x in data[0].data){ | |
nGram.push({"year" : ( 1800 + parseInt(x)),"size" : data[0].data[x]}); | |
} | |
//get an array of the size to getthe max of the Y axis | |
var maxH = []; | |
var total = 0; | |
for (x in nGram){ | |
maxH.push(nGram[x].size); | |
total = total + nGram[x].size; | |
} | |
$('#ngramTitle').text("Found " + total + " results for '" + vmoa.searchSecondTerm + "', click a year to expand"); | |
//figure out how wide the bars can be based on the screen width. | |
var w = (Math.floor(($(document).width()-100)/101)+0.5); | |
$("#ngramChart").css("width",(w*101)+10); | |
//a helper function to move the label of the year around the chart | |
var showLabel = function(d,pos){ | |
//console.log(pos); | |
var posText = pos; | |
if (d.year > 1897){posText = pos - ((d.year - 1897)*8);} | |
if (d.year < 1805){posText = pos + ((1805 - d.year)*8);} | |
d3.select("#ngramLabelYear").attr("x", posText - (w*3.3)).text(d.year); | |
d3.select("#ngramLabelSize").attr("x", posText + 5).text(vmoa.numberWithCommas(d.size)); | |
d3.select("#ngramLabelLine").attr("x1", pos).attr("x2", pos); | |
}; | |
var h = 200, | |
m = 10; | |
var x = d3.scale.linear() | |
.domain([1800, 1901]) | |
.range([0, w * nGram.length]); | |
var y = d3.scale.linear() | |
.domain([0, d3.max(maxH)+35]) | |
.rangeRound([0, h]); | |
var chart = d3.select("#ngramChart").append("svg") | |
.attr("class", "chart") | |
.attr("id","ngramsvg") | |
.attr("width", (w * nGram.length - 1) + (m * 2)) | |
.attr("height", h + (m*2)) | |
.on("mouseover", function(d){ | |
d3.select("#ngramLabelYear").attr("visibility", "visible"); | |
d3.select("#ngramLabelSize").attr("visibility", "visible"); | |
d3.select("#ngramLabelLine").attr("visibility", "visible"); | |
}) | |
.on("mouseout", function(d){ | |
d3.select("#ngramLabelYear").attr("visibility", "hidden"); | |
d3.select("#ngramLabelSize").attr("visibility", "hidden"); | |
d3.select("#ngramLabelLine").attr("visibility", "hidden"); | |
}); | |
//add in the bars for the data | |
chart.selectAll("rect") | |
.data(nGram) | |
.enter().append("rect") | |
.attr("x", function(d, i) { return x(d.year); })//return x(i) - .5; }) | |
.attr("y", function(d) { return h - y(d.size) - .5; }) | |
.attr("width", w) | |
.style("fill", '#4a8fbf') | |
.attr("id",function(d) {return "rect" + d.year}) //used to ref back to it when mouse over the trans bar | |
.style("stroke", '#444444') | |
.attr("visibility", "hidden") | |
.attr("height", function(d) { return y(d.size); }); | |
//have them appear in a cascade effect | |
d3.selectAll("rect").transition() | |
.attr("visibility", "visible") | |
.delay(function(d,i) { return i * 7 }) | |
.duration(3000) | |
.ease("elastic", 10, .45); | |
//now add in full size transparent bars that allow the user to click on a bar without having to click exactly on the bar | |
//so they can be above the acutal end of the bar and still have it seelcted, | |
chart.selectAll(".rect") | |
.data(nGram) | |
.enter().append("rect") | |
.attr("x", function(d, i) { return x(d.year); })//return x(i) - .5; }) | |
.attr("y", function(d) { return 0; }) | |
.attr("width", w) | |
.style("fill", '#4a8fbf') | |
.style("stroke", 'white') | |
.style("cursor", "pointer") | |
.attr("opacity", 0.0) | |
.on("mouseover", function(d){ | |
d3.select("#rect" + d.year).style("fill", "#fff"); | |
showLabel(d, x(d.year)); | |
}) | |
.on("mouseout", function(d){ | |
d3.select("#rect" + d.year).style("fill", "#4a8fbf"); | |
}) | |
.on("click", function(d){ | |
if (d.size==0){return false;} | |
vmoa.searchThirdYear=d.year; | |
vmoa.buildNgramDetails(d.year); | |
}) | |
.attr("height", function(d) { return 200; }); | |
chart.append("line") | |
.attr("x1", 0) | |
.attr("x2", (w * nGram.length) + m + 0.5) | |
.attr("y1", h - .5) | |
.attr("y2", h - .5) | |
.style("stroke", "#444444"); | |
chart.selectAll("line") | |
.data(x.ticks(10)) | |
.enter().append("line") | |
.attr("x1", x) | |
.attr("x2", x) | |
.attr("y1", 0) | |
.attr("y2", 200) | |
.attr("stroke-dasharray", "1, 3") | |
.style("stroke", "#ccc"); | |
chart.selectAll(".rule") | |
.data(x.ticks(10)) | |
.enter().append("text") | |
.attr("x", x) | |
.attr("y", 215) | |
.style("fill","#444444") | |
.style("font-family", "Helvetica, Arial, sans-serif") | |
.attr("text-anchor", "left") | |
.attr("pointer-events", "none") | |
.text(function(d){return d}); | |
chart.selectAll(".ngramLabelYear") | |
.data([0]) | |
.enter() | |
.append("text") | |
.attr("class", "rule") | |
.attr("id","ngramLabelYear") | |
.attr("x", 20) | |
.attr("y", 15) | |
.attr("font-size", "17") | |
.attr("pointer-events", "none") | |
.style("fill","#444444") | |
.attr("visibility", "hidden") | |
.attr("dy", -3) | |
.style("font-family", "Helvetica, Arial, sans-serif") | |
.attr("text-anchor", "right"); | |
chart.selectAll(".ngramLabelSize") | |
.data([0]) | |
.enter() | |
.append("text") | |
.attr("class", "rule") | |
.attr("id","ngramLabelSize") | |
.attr("x", 20) | |
.attr("y", 12) | |
.attr("font-size", "12") | |
.style("fill","#444444") | |
.attr("visibility", "hidden") | |
.attr("pointer-events", "none") | |
.attr("dy", -3) | |
.style("font-family", "Helvetica, Arial, sans-serif") | |
.attr("text-anchor", "right"); | |
chart.append("line") | |
.attr("x1", 100) | |
.attr("x2", 100) | |
.attr("y1", 0) | |
.attr("visibility", "hidden") | |
.attr("y2", h) | |
.attr("id","ngramLabelLine") | |
.style("stroke", "#444444"); | |
vmoa.toggleWorking(false); | |
}) | |
.fail(function() { alert("error"); }) //TODO | |
.always(function() { } //TODO | |
); | |
}, | |
/*--------------------------- | |
A reuseable bubble builder | |
data = array of objects epxteded to be in the layout format | |
container = string of the id of the container for the chart | |
r = the radius in px of the chart | |
-----------------------------*/ | |
buildBubble: function (data,container,r){ | |
var lastR = 0; | |
var format = d3.format(",d"); | |
var bubble = d3.layout.pack() | |
.sort(null) | |
.size([r, r]); | |
var vis = d3.select("#"+container).append("svg") | |
.attr("width", r) | |
.attr("height", r) | |
.attr("class", "bubble"); | |
var node = vis.selectAll("g.node") | |
.data(bubble.nodes(vmoa.classes(data)) | |
.filter(function(d) { return !d.children; })) | |
.enter().append("g") | |
.attr("class", "node") | |
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
node.append("title") | |
.text(function(d) { return d.className + ": " + format(d.value); }); | |
node.append("circle") | |
.attr("r", function(d) { lastR = d.r; return d.r; }) | |
.style("cursor", "pointer") | |
.style("fill", function(d) { | |
if (d.type=='nn'){ | |
return "#66c499" | |
}else if (d.type=='np'){ | |
return "#e3774f"; | |
}else{ | |
return "#e47598"; | |
} | |
}) | |
.on("mouseover", function(){d3.select(this).style("stroke-width", 1).style("stroke", "#444444");}) | |
.on("mouseout", function() {d3.select(this).style("stroke-width", 0.000005)}) | |
.on("click", function(d){ | |
//the main search bubble behavior | |
if (d.packageName == "matches" || d.packageName == "partials"){ | |
vmoa.searchSecondTerm=d.className; | |
vmoa.buildNgram(d.id); | |
vmoa.searchSecondType=d.type; | |
} | |
//the ngram details bubble; | |
if (d.packageName == "results"){ | |
vmoa.searchThirdType=d.type; | |
vmoa.searchThirdTerm=d.className.toLowerCase(); | |
vmoa.buildQuotes(); | |
} | |
}); | |
node.append("text") | |
.attr("text-anchor", "middle") | |
.attr("dy", ".3em") | |
.style("cursor", "pointer") | |
.attr("fill","#444444") | |
.attr("pointer-events", "none") | |
.attr("font-size", "11px") | |
.text(function(d) { return d.className.substring(0, d.r / 3); }); | |
//we use this in the buildNgramDetails function, we want to know the last size of the bubble so we can pick up with that size for the | |
//overflow list of results | |
return lastR; | |
}, | |
/*--------------------------- | |
handles the history changes as a navigation method. | |
-----------------------------*/ | |
route: function(){ | |
var State = History.getState(); | |
//History.log(State.data.state, State.title, State.url); | |
switch(State.data.state){ | |
case 100: //State 100: the main search page, eg the home page | |
$('#mainSearchChartHolder').fadeOut(1); | |
$('#articleNetworkHolder').fadeOut(1); | |
$('#articleNetworkInfo').fadeOut(1); | |
$('#authorsNetwork').fadeOut(1); | |
$("#wordFreqHolder").fadeOut(1); | |
$("#ocrToolHolder").fadeOut(1); | |
$('#search').fadeIn('slow'); | |
//get rid of the bindings to the keys for the 100k word freq | |
$(document).off("keydown"); | |
break; | |
case 1: //State 1: the main search results bubble chart | |
$('#mainSearchPartialOverflow').fadeOut(1); | |
$('#search').fadeOut(1); | |
$('#ngramHolder').fadeOut(1) | |
$('#mainSearchChartHolder').fadeIn('slow'); | |
break | |
case 2: //State 2: the list of the overflow partial matches | |
$('#mainSearchChartHolder').fadeOut(1); | |
$('#ngramHolder').fadeOut(1) | |
$('#mainSearchPartialOverflow').fadeIn('slow'); | |
break | |
case 3: //State 3: the n gram viewer | |
$('#mainSearchChartHolder').fadeOut(1) | |
$('#mainSearchPartialOverflow').fadeOut(1) | |
$('#quotesHolder').fadeOut(1); | |
$('#ngramHolder').fadeIn('slow'); | |
break | |
case 4: //State 3: the quotes page | |
$('#mainSearchChartHolder').fadeOut(1) | |
$('#mainSearchPartialOverflow').fadeOut(1) | |
$('#ngramHolder').fadeOut(1); | |
$('#quotesHolder').fadeIn('slow'); | |
break | |
case 5: //State 5: the article tree | |
$('#search').fadeOut(1) | |
$('#ngramHolder').fadeOut(1); | |
$('#articleNetworkInfo').fadeIn(1); | |
$('#articleNetworkHolder').fadeIn('slow'); | |
break | |
case 6: //State 5: the author Tree | |
$('#search').fadeOut(1) | |
$('#ngramHolder').fadeOut(1); | |
$('#articleNetworkInfo').fadeIn(1); | |
$('#authorsNetwork').fadeIn('slow'); | |
break | |
case 7: //State n: the 100k word freq | |
$('#search').fadeOut(1) | |
$('#ngramHolder').fadeOut(1); | |
$('#authorsNetwork').fadeOut(1); | |
$('#articleNetworkInfo').fadeIn(1); | |
$("#wordFreqHolder").fadeIn('fast'); | |
break | |
case 8: //State n: ocr correct tool | |
$('#search').fadeOut(1) | |
$('#ngramHolder').fadeOut(1); | |
$('#authorsNetwork').fadeOut(1); | |
$('#articleNetworkInfo').fadeOut(1); | |
$("#ocrToolHolder").fadeIn('fast'); | |
break | |
default: | |
} | |
}, | |
/*--------------------------- | |
The main search action | |
-----------------------------*/ | |
searchMain: function (){ | |
if ($('#inputSearch').val().length==0){return false;} | |
this.toggleWorking(true); | |
this.searchMainTerm = $.trim($('#inputSearch').val()); | |
this.searchMainCount =0; | |
//hide the search stuff | |
$('#search').fadeOut(500); | |
//clear out any old charts | |
$('#mainSearchChartMatchesChart').empty(); | |
$('#mainSearchChartPartialsChart').empty(); | |
var resultsMatchs = {"name":"matches", "children" : []}; | |
var resultsPartials = {"name":"partials", "children" : []}; | |
var resultsPartialsOverflow = {"name":"partialsOverflow", "children" : []}; | |
//colllect the data | |
var req = $.getJSON( "/search/" + this.searchMainTerm.toLowerCase()) | |
.done(function(data) { | |
vmoa.History.pushState({state:1}, "VisualMOA | Sentence Search Results", "?ssResults"); | |
if (data.children.length==0){ | |
vmoa.toggleWorking(false); | |
vmoa.noResults('#noResultsSS'); | |
return; | |
} | |
var counter=0; | |
//process the data | |
//sort if they are a direct matach or just a partial | |
for (x in data.children){ | |
vmoa.searchMainCount=vmoa.searchMainCount + parseInt(data.children[x].size); | |
if (data.children[x].name.toLowerCase()==vmoa.searchMainTerm.toLowerCase()){ | |
resultsMatchs.children.push(data.children[x]); | |
}else{ | |
//if it is not a direct match then it shows up in the partials, but there might be a lot. so filter it to overflow into | |
//another object to display as text, only show the top xx (they are being served from the server DESC) | |
if (counter<13){ | |
resultsPartials.children.push(data.children[x]); | |
counter++; | |
}else{ | |
resultsPartialsOverflow.children.push(data.children[x]); | |
} | |
} | |
} | |
var r1 = ($(document).width()/2)-300; | |
var r2 = ($(document).width()/2)-225; | |
$('#mainSearchChartMatchesChart').css('width',r1+'px'); | |
$('#mainSearchChartPartialsChart').css('width',r2+'px'); | |
vmoa.buildBubble(resultsMatchs,'mainSearchChartMatchesChart',r1); | |
vmoa.buildBubble(resultsPartials,'mainSearchChartPartialsChart',r2); | |
//update some labels | |
$('#mainSearchChartHolderHeaderCount').text("Found " + vmoa.numberWithCommas(vmoa.searchMainCount) + " results, click a term to refine."); | |
//the link to show the over flow text | |
$("#mainSearchChartPartialsMoreLabel").empty(); | |
if (resultsPartialsOverflow.children.length>0){ | |
$("#mainSearchChartPartialsMoreLabel").append( | |
$('<span>') | |
.text('Found ' + vmoa.numberWithCommas(resultsPartialsOverflow.children.length) + ' other partial matches: ') | |
.append( | |
$('<a>') | |
.text('View') | |
.attr('href','#') | |
.click(function(event){ | |
vmoa.History.pushState({state:2}, "VisualMOA | Sentence Search Results", "?sentenceResults"); | |
event.preventDefault(); | |
return false; | |
}) | |
) | |
); | |
} | |
//build the table of the overflow partial mataches | |
$("#mainSearchPartialOverflowList").empty(); | |
for (x in resultsPartialsOverflow.children){ | |
var color = (resultsPartialsOverflow.children[x].type == 'nn') ? "#66c499" : "#e3774f"; | |
$("#mainSearchPartialOverflowList").append( | |
$('<tr>') | |
.append( | |
$('<td>') | |
.addClass('tableBubble') | |
.append( | |
$('<div>') | |
.addClass('mainSearchLegendBubble') | |
.css('background-color',color) | |
) | |
) | |
.append( | |
$('<td>') | |
.addClass('tableCount') | |
.text(resultsPartialsOverflow.children[x].size) | |
) | |
.append( | |
$('<td>') | |
.append( | |
$("<a>") | |
.attr("href","#") | |
.text(resultsPartialsOverflow.children[x].name) | |
.data("name",resultsPartialsOverflow.children[x].name) | |
.data("type",resultsPartialsOverflow.children[x].type) | |
.data("id",resultsPartialsOverflow.children[x].id) | |
.click(function(event){ | |
vmoa.searchSecondTerm=$(this).data("name"); | |
vmoa.searchSecondType=$(this).data("type"); | |
vmoa.buildNgram($(this).data("id")); | |
event.preventDefault(); | |
return false; | |
}) | |
) | |
) | |
); | |
} | |
//show the charts | |
vmoa.toggleWorking(false); | |
//$('#mainSearchChartHolder').fadeIn('slow'); | |
}) | |
.fail(function() { }) //TODO | |
.always(function() { }); //TODO | |
}, | |
/*--------------------------- | |
Displays the working spinner or not | |
-----------------------------*/ | |
toggleWorking: function(show){ | |
if (show){$('#working').css('display','block');}else{$('#working').css('display','none');} | |
}, | |
/*--------------------------- | |
Makes sure we have everything we need for the app to work | |
-----------------------------*/ | |
runChecks: function(){ | |
//no SVG support, uh oh. | |
if(!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")){ | |
$('#errorNoSVG').css('display','block'); | |
} | |
}, | |
/*--------------------------- | |
Binds the dom elements using jquery | |
-----------------------------*/ | |
bindControls: function(){ | |
//turn off working spinner | |
this.toggleWorking(false); | |
//Main search controls | |
$('#inputSearch').keypress( | |
function(event){ | |
if (event.keyCode === 13){ | |
vmoa.searchMain(); | |
} | |
} | |
); | |
$('#inputSearchArticle').keypress( | |
function(event){ | |
if (event.keyCode === 13){ | |
vmoa.searchArticles(); | |
} | |
} | |
); | |
//generic back buttons | |
$('.btnBack').click(function(event){ | |
History.back(); | |
event.preventDefault(); | |
return false; | |
}) | |
//the close link on the author network article viwer | |
$('#authorsNetworkArticlesClose a').click(function(event){ | |
$('#authorsNetworkArticles').hide('fast'); | |
event.preventDefault(); | |
return false; | |
}) | |
//the reset button | |
$('.btnNetworkReset').click(function(){ | |
vmoa.authorNetworkD3Nodes.splice(0, vmoa.authorNetworkD3Nodes.length); | |
vmoa.authorNetworkD3Links.splice(0, vmoa.authorNetworkD3Links.length); | |
vmoa.authorNetworkRedraw(); | |
}); | |
//the launch button | |
$('#authorNetworkLaunch').click(function(){ | |
vmoa.buildAuthorNetwork(); | |
}); | |
$('#words100kLaunch').click(function(){ | |
vmoa.int100kWords(); | |
}); | |
//the help button for the network | |
$('.btnNetworkHelp, #suthorsNetworkHelpClose').click(function(event){ | |
if ($("#authorsNetworkHelp").css("display")=="none"){ | |
$("#authorsNetworkHelp").show('fast'); | |
}else{ | |
$("#authorsNetworkHelp").hide('fast'); | |
} | |
event.preventDefault(); | |
return false; | |
}) | |
//ocr tools | |
$('#ocrToolOkay').click(function(){ | |
vmoa.ocrToolUpdate($('#ocrToolWord').text(),2); | |
}); | |
$('#ocrToolSkip').click(function(){ | |
vmoa.ocrToolSkip++; | |
vmoa.ocrToolNext(); | |
}); | |
$('#ocrToolError').click(function(){ | |
$('#ocrToolErrors').show('fast'); | |
}); | |
$('#ocrToolSave').click(function(){ | |
vmoa.ocrToolUpdate($('#ocrToolWord').text(),3,$('#ocrToolIncorrect').val(),$('#ocrToolCorrect').val()); | |
}); | |
$('#ocrToolLaunch').click(function(){ | |
vmoa.ocrToolInit(); | |
}); | |
//main launch button | |
$('#launchVMOA').click(function(){ | |
window.location = vmoa.awsURI; | |
}); | |
//the history controls | |
this.History = window.History; | |
this.History.Adapter.bind(window,'statechange',function(){ | |
vmoa.route(); | |
}); | |
this.History.pushState({state:100}, "Home", "?home"); | |
}, | |
/*--------------------------- | |
utilty functions | |
-----------------------------*/ | |
numberWithCommas: function (x) { | |
return x.toString().replace(/\B(?=(?:\d{3})+(?!\d))/g, ","); | |
}, | |
capitaliseFirstLetter: function(string){ | |
//return string.charAt(0).toUpperCase() + string.slice(1); | |
return string.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } ); | |
}, | |
MD5: function(e){function h(a,b){var c,d,e,f,g;e=a&2147483648;f=b&2147483648;c=a&1073741824;d=b&1073741824;g=(a&1073741823)+(b&1073741823);return c&d?g^2147483648^e^f:c|d?g&1073741824?g^3221225472^e^f:g^1073741824^e^f:g^e^f}function i(a,b,c,d,e,f,g){a=h(a,h(h(b&c|~b&d,e),g));return h(a<<f|a>>>32-f,b)}function j(a,b,c,d,e,f,g){a=h(a,h(h(b&d|c&~d,e),g));return h(a<<f|a>>>32-f,b)}function k(a,b,d,c,e,f,g){a=h(a,h(h(b^d^c,e),g));return h(a<<f|a>>>32-f,b)}function l(a,b,d,c,e,f,g){a=h(a,h(h(d^(b|~c), | |
e),g));return h(a<<f|a>>>32-f,b)}function m(a){var b="",d="",c;for(c=0;3>=c;c++)d=a>>>8*c&255,d="0"+d.toString(16),b+=d.substr(d.length-2,2);return b}var f=[],n,o,p,q,a,b,c,d,e=function(a){for(var a=a.replace(/\r\n/g,"\n"),b="",d=0;d<a.length;d++){var c=a.charCodeAt(d);128>c?b+=String.fromCharCode(c):(127<c&&2048>c?b+=String.fromCharCode(c>>6|192):(b+=String.fromCharCode(c>>12|224),b+=String.fromCharCode(c>>6&63|128)),b+=String.fromCharCode(c&63|128))}return b}(e),f=function(b){var a,c=b.length;a= | |
c+8;for(var d=16*((a-a%64)/64+1),e=Array(d-1),f=0,g=0;g<c;)a=(g-g%4)/4,f=8*(g%4),e[a]|=b.charCodeAt(g)<<f,g++;a=(g-g%4)/4;e[a]|=128<<8*(g%4);e[d-2]=c<<3;e[d-1]=c>>>29;return e}(e);a=1732584193;b=4023233417;c=2562383102;d=271733878;for(e=0;e<f.length;e+=16)n=a,o=b,p=c,q=d,a=i(a,b,c,d,f[e+0],7,3614090360),d=i(d,a,b,c,f[e+1],12,3905402710),c=i(c,d,a,b,f[e+2],17,606105819),b=i(b,c,d,a,f[e+3],22,3250441966),a=i(a,b,c,d,f[e+4],7,4118548399),d=i(d,a,b,c,f[e+5],12,1200080426),c=i(c,d,a,b,f[e+6],17,2821735955), | |
b=i(b,c,d,a,f[e+7],22,4249261313),a=i(a,b,c,d,f[e+8],7,1770035416),d=i(d,a,b,c,f[e+9],12,2336552879),c=i(c,d,a,b,f[e+10],17,4294925233),b=i(b,c,d,a,f[e+11],22,2304563134),a=i(a,b,c,d,f[e+12],7,1804603682),d=i(d,a,b,c,f[e+13],12,4254626195),c=i(c,d,a,b,f[e+14],17,2792965006),b=i(b,c,d,a,f[e+15],22,1236535329),a=j(a,b,c,d,f[e+1],5,4129170786),d=j(d,a,b,c,f[e+6],9,3225465664),c=j(c,d,a,b,f[e+11],14,643717713),b=j(b,c,d,a,f[e+0],20,3921069994),a=j(a,b,c,d,f[e+5],5,3593408605),d=j(d,a,b,c,f[e+10],9,38016083), | |
c=j(c,d,a,b,f[e+15],14,3634488961),b=j(b,c,d,a,f[e+4],20,3889429448),a=j(a,b,c,d,f[e+9],5,568446438),d=j(d,a,b,c,f[e+14],9,3275163606),c=j(c,d,a,b,f[e+3],14,4107603335),b=j(b,c,d,a,f[e+8],20,1163531501),a=j(a,b,c,d,f[e+13],5,2850285829),d=j(d,a,b,c,f[e+2],9,4243563512),c=j(c,d,a,b,f[e+7],14,1735328473),b=j(b,c,d,a,f[e+12],20,2368359562),a=k(a,b,c,d,f[e+5],4,4294588738),d=k(d,a,b,c,f[e+8],11,2272392833),c=k(c,d,a,b,f[e+11],16,1839030562),b=k(b,c,d,a,f[e+14],23,4259657740),a=k(a,b,c,d,f[e+1],4,2763975236), | |
d=k(d,a,b,c,f[e+4],11,1272893353),c=k(c,d,a,b,f[e+7],16,4139469664),b=k(b,c,d,a,f[e+10],23,3200236656),a=k(a,b,c,d,f[e+13],4,681279174),d=k(d,a,b,c,f[e+0],11,3936430074),c=k(c,d,a,b,f[e+3],16,3572445317),b=k(b,c,d,a,f[e+6],23,76029189),a=k(a,b,c,d,f[e+9],4,3654602809),d=k(d,a,b,c,f[e+12],11,3873151461),c=k(c,d,a,b,f[e+15],16,530742520),b=k(b,c,d,a,f[e+2],23,3299628645),a=l(a,b,c,d,f[e+0],6,4096336452),d=l(d,a,b,c,f[e+7],10,1126891415),c=l(c,d,a,b,f[e+14],15,2878612391),b=l(b,c,d,a,f[e+5],21,4237533241), | |
a=l(a,b,c,d,f[e+12],6,1700485571),d=l(d,a,b,c,f[e+3],10,2399980690),c=l(c,d,a,b,f[e+10],15,4293915773),b=l(b,c,d,a,f[e+1],21,2240044497),a=l(a,b,c,d,f[e+8],6,1873313359),d=l(d,a,b,c,f[e+15],10,4264355552),c=l(c,d,a,b,f[e+6],15,2734768916),b=l(b,c,d,a,f[e+13],21,1309151649),a=l(a,b,c,d,f[e+4],6,4149444226),d=l(d,a,b,c,f[e+11],10,3174756917),c=l(c,d,a,b,f[e+2],15,718787259),b=l(b,c,d,a,f[e+9],21,3951481745),a=h(a,n),b=h(b,o),c=h(c,p),d=h(d,q);return(m(a)+m(b)+m(c)+m(d)).toLowerCase()}, | |
returnOrdinal: function(number){ | |
var n = number % 100; | |
var suffix = ['th', 'st', 'nd', 'rd', 'th']; | |
var ord = n < 21 ? (n < 4 ? suffix[n] : suffix[0]) : (n % 10 > 4 ? suffix[0] : suffix[n % 10]); | |
return ord; | |
}, | |
returnJournalData: function(name){ | |
for (x in this.journals){ | |
if (name.indexOf(this.journals[x].id)!=-1){return this.journals[x];} | |
} | |
}, | |
padNumber: function(number, length) { | |
var str = '' + number; | |
while (str.length < length) { | |
str = '0' + str; | |
} | |
return str; | |
}, | |
/*--------------------------- | |
d3 functions | |
-----------------------------*/ | |
classes: function(root) { | |
var classes = []; | |
function recurse(name, node) { | |
if (node.children) node.children.forEach(function(child) { recurse(node.name, child); }); | |
else classes.push({packageName: name, className: node.name, value: node.size, type: node.type, id: node.id}); | |
} | |
recurse(null, root); | |
return {children: classes}; | |
} | |
} | |
//init things when ready | |
$(document).ready(function(){ | |
vmoa.runChecks(); | |
vmoa.bindControls(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment