API Docs for:
Show:

File: tree.js

/* tree.js - Functions for index.html that handle tree creation*/
/*Functions that handle details and important taxon members*/ 
/**
 * Methods for creating the tree.
 *
 * @module Tree
 */
 
/**
* Executed when somebody clicks on a details button.
* Gets greek name translation and execute an ajax request for the node summary 
* after a time delay to ensure that greekName was passed to sessionStorage. 
* Sets sessionStorage variables in case the user wants to read the full article. 
* Sets title and image in modal window. 
*
* @class $(document).on()
* @constructor
* @param {event} "click" The click event
* @param {string} ".details" A node with class "details"
* @param {function} function 
*/
$(document).on("click", ".details", function() {
    var name = getName($(this)); //Get name of node that was clicked

    getGreekName(name, "index"); //Finds greek name and stores in sessionStorage
    var button = $(this);


    setTimeout(function() {
        var rank = getRank(button);
        var img_url = button.closest('.thumbnail').find('img').attr('data-src');
        img_url = getImg300(img_url);

        sessionStorage.setItem('name', name);
        sessionStorage.setItem('rank', rank);
        if (sessionStorage.getItem('lang') == 'en') {
            $(".modal-title").text(name);
        } else {
            $(".modal-title").text(sessionStorage.getItem('greekName'));
        }

        prevRank = getPrevRank(rank);
        var selected = $("#" + prevRank).find(".selected");

        sessionStorage.setItem('prevRankName', selected.find('p[caption]').attr('caption'));


        $(".article").attr('onclick', 'showArticle("' + name + '")');
        $('#modalThumb img').hide();
        $('#modalThumb img').attr('src', img_url);
        time = prettyLoadRank($('#modalThumb img'), 'null', 900);
        $('#membersList').html(''); //Clear memberlist data
        startLoading('#modalSum');

        var query = getSummaryQuery(name);
        $.ajax({
            dataType: "jsonp",
            url: query,
            rank: rank,
            img_url: img_url,
            name: name,
            success: summarySuccess,
            error: ajaxError
        });
    }, 1000)


});

/**
* Callback for ajax request in details click event. 
* Adds the summary to the modal window.  
*
* @class summarySuccess
* @constructor
* @param {object} _data Ajax request response that contains node summary 
*/
function summarySuccess(_data) {
    var results = _data.query.pages;
    for (var j in results) {
        if (results[j].extract !== undefined) {
            var sum = results[j].extract;

            if (sum.length > 1000) sum = sum.substr(0, 1000) + '...';
        } else {
            var sum = '<span name="lbl" caption="noSummary"></span>';

        }
    }
    stopLoading('#modalSum');
    $('#modalSum').hide();
    $('#modalSum').html(sum);
    var time = prettyLoadRank($('#modalSum'), 'null', 700);
    startLoading('#membersList');
    getMembers(this.rank, this.name, "index");
}

/**
* Makes ajax request to get important members of node.  
*
* @class getMembers
* @constructor
* @param {string} rank Rank of node 
* @param {string} name Name of node
* @param {string} page The page from where the function was called, either index or article 
*/
function getMembers(rank, name, page) {
    if (page != "article") {
        var success = importantMembersSuccess;
    } else {
        var success = membersSuccess;
    }
    var query = getImportantQuery(rank, name.replace(' ', "_"));

    checkUrl();
    var queryUrl = encodeURI(url + "?query=" + query + "&format=json");
    $.ajax({
        dataType: "jsonp",
        url: queryUrl,

        success: success,
        error: ajaxError,
    });
}

/**
* Callback of getMembers ajax request called when the page is article.
* Creates member thumbnails and loads them under article  
*
* @class membersSuccess
* @constructor
* @param {object} _data Ajax request response that contains all members of rank species of a node
*/
function membersSuccess(_data) {
    animals_html = "";

    var dbpedia_results = _data.results.bindings;

    for (var i in dbpedia_results) { //pass all dbpedia results in array for easier understanding
        var src = dbpedia_results[i].name.value;
        var name = nameFromUrl(src);
        name = name.replace("_", ' ');
        thumb_url = getThumbUrl(dbpedia_results[i].thumb);


        animals_html = animals_html + " <li> <div class='thumbnail'><img src='assets/Timer.gif' data-src='" + thumb_url + "'width='50px' > <div class='caption'><p caption='" + name + "'>" + name + "</p></div></div></li>";
    }

    $('#membersList').html(animals_html);
    $("#membersList .thumbnail").hide();
    var $thumbnails = $("#membersList .thumbnail");
    var time2 = $thumbnails.length * 250;
    setTimeout(function() {
        var time = prettyLoadRank($thumbnails, 'null', 250);
        $("img").unveil();
    }, 800)
    changeLanguage(sessionStorage.getItem('lang'), '#membersList');
    $("img").unveil();

}
/**
* Callback of getMembers ajax request called when the page is index.
* Gets up to 8 most important members of rank species of a node.   
*
* @class importantMembersSuccess
* @constructor
* @param {object} _data Ajax request response that contains all members of rank species of a node
*/ 
  
function importantMembersSuccess(_data) {
    animals_html = "";
    var k = 0;
    var dbArray = [];
    var dbpedia_results = _data.results.bindings;

    var wikirankResults = [wikirank0, wikirank1, wikirank2, wikirank3,
        wikirank4, wikirank5, wikirank6, wikirank7, wikirank8,
        wikirank9
    ]
    for (var j in dbpedia_results) { //pass all dbpedia results in array for easier understanding
        var src = dbpedia_results[j].name.value;
        var name = nameFromUrl(src);
        dbArray[j] = name;
    }
    if (dbArray.length <= 8) { //Skip the wikirank part if rank has 8 or fewer members
        for (var i in dbArray) {
            thumb_url = getThumbUrl(dbpedia_results[i].thumb);
            src = dbArray[i];
            animals_html = animals_html + getMemberHtml(thumb_url, src);
        }
    } else {

        for (var i in wikirankResults) { //Traverse wikirank data, compare each element to dbpedia results and if it exists add to animal list
            var wikiArray = wikirankResults[i].split(',');
            for (var j in wikiArray) {
                src = wikiArray[j];
                if ($.inArray(src, dbArray) > -1) {
                    k++;
                    var thumb_url = getThumbUrl(dbpedia_results[$.inArray(src, dbArray)].thumb);
                    animals_html = animals_html + getMemberHtml(thumb_url, src);
                }
                if (k > 7) break;
            }
            if (k > 7) break;
        }
    }
    stopLoading('#membersList');
    $('#membersList').html(animals_html);
    $("#membersList .thumbnail").hide();
    var $thumbnails = $("#membersList .thumbnail");
    var time2 = $thumbnails.length * 250;
    setTimeout(function() {
        var time = prettyLoadRank($thumbnails, 'null', 250);
        $("img").unveil();
    }, 800)
    changeLanguage(sessionStorage.getItem('lang'), '#myModal');

    $("img").unveil();
}
  /*End of details functions*/
  /*Functions that make the tree*/
/**
* Executed when somebody clicks on an open button.
* Sets variables and calls function that creates next rank of tree.
*
* @class $(document).on()
* @constructor
* @param {event} "click" The click event
* @param {string} ".open" A node with class "open"
* @param {function} function 
*/
  
$(document).on("click", ".open", function() {
    $('button').prop('disabled', true);
    var name = getName($(this));
    sessionStorage.setItem('prevRankName', name);

    var rank = getRank($(this));
    console.log("rank " + rank);
    selectRank($(this), rank); //Make clicked node selected
    var next_rank = getNextRank(rank); //get the next rank
    clearNextRanks(rank); //Clear data of next ranks
    startLoading('#' + next_rank + '>div');
    var query = getOpenQuery(name, rank, next_rank);

    executeOpenQuery(query, next_rank, "open");

});


  /*Functions that make the tree*/

/**
* Makes ajax request that gets the next rank of the tree.   
*
* @class executeOpenQuery
* @constructor
* @param {string} query Ajax request query
* @param {string} rank The rank
* @param {string} func Variable that determines if function was called for a search or open
* @param {string} selectedName Used for search function
*/ 
function executeOpenQuery(query, rank, func, selectedName) {

    if (selectedName === undefined) {
        selectedName = '';
    }
    checkUrl();
    var queryUrl = encodeURI(url + "?query=" + query + "&format=json");

    $.ajax({
        type: "GET",
        dataType: "jsonp",
        url: queryUrl,
        rank: rank,
        selectedName: selectedName,
        success: openSuccess,
        func: func,
        error: ajaxError
    });
}
/**
* Callback of executeOpenQuery. Loads rank thumbnails in page.  
*
* @class openSuccess
* @constructor
* @param {object} _data Response of ajax request query that contains members of rank
*/ 
function openSuccess(_data) {

    var item = '';
    var thumb_url = "";
    var rank = this.rank;
    var results = _data.results.bindings;
    if (results.length > 0) { //if there are any results
        for (var i in results) {

            var src = results[i].taxon.value;

            var name = nameFromUrl(src);
            var html = thumbHtml(name, results[i].thumb, rank, this.selectedName);
            var item = item + html;


            stopLoading('#' + rank + '>div');

        }
        $(item).hide();

        $("#" + rank).append(item);

        var contents = $("#" + rank + " .selected").detach();
        $('#' + rank + ">.rankHead").after(contents);

        var $thumbnails = $("#" + rank + " .thumbnail");
        var time = prettyLoadRank($thumbnails, rank);


        setTimeout(function() {

            $("#" + rank + " .counter").html(" " + $thumbnails.length);
            $thumbnails.show();
            $('.thumbnail>button').prop('disabled', true);
            sessionStorage.setItem('treePage', $('#tree_container').html());


            $("img").unveil();

        }, time + 100)

    } else {
        stopLoading('#' + rank + '>div');

        if (this.func == "open") {
            $("#" + rank).append('<span name="lbl" caption="noResults"></span>');
        }
    }
    $('button').prop('disabled', false);
    ChangeDiv($(window).width()); //Does changes related to screen size
    changeLanguage(sessionStorage.getItem('lang'), "#" + rank); //does text translation for selected language
}
  /* Functions that make the Search Tree*/
/**
* Gets search term from search box and makes query to find rank of search term.   
*
* @class getSearchRank
* @constructor
* @param {string} func Article or index
*/ 
function getSearchRank(func) {

    //TODO-αν το search term ειναι στα ελληνικά (δηλαδή αν η γλώσσα είναι ελληνικά)να το μεταφράζει. Έχω ετοιμάσει το query στο  returnOneEnglishNameQuery(name)
    $('button').prop('disabled', true);
    //An einai plant h Animal na paravlepetai to query
    if (func == "article") {

        var callback = articleRankSuccess;
    } else {
        var callback = makeSearchTree;
    }
    var name = $('#searchBox').val();
    if (name == '') {
        name = $('#searchBoxMobile').val();
    }
    name = name.replace(' ', "_");
    name = capitalizeFirstLetter(name);

    var query = getSearchRankQuery(name);
    console.log(query);
    checkUrl();
    var queryUrl = encodeURI(url + "?query=" + query + "&format=json");
    $.ajax({
        dataType: "jsonp",
        url: queryUrl,
        name: name,
        success: callback,
        error: ajaxError
    });
}
/**
* Callback from getSearchRank. Finds rank of search term and makes ajax request to make search tree. 
* The rank for the search term is the one with the highest count.    
*
* @class getSearchRank
* @constructor
* @param {object} _data Response of ajax request query that contains count for each rank
*/ 
function makeSearchTree(_data) {
    var values = ['', '', '', '', '']
    var checkValue = 0;
    //find rank of searched term
    var results = _data.results.bindings[0];
    values[0] = results.countphylum.value;
    values[1] = results.countclass.value;
    values[2] = results.countorder.value;
    values[3] = results.countfamily.value;
    values[4] = results.countgenus.value;
    for (var i in values) {
        if (values[i] != 0) checkValue = values[i];
    }

    //Find index of max value, and add 1 to use with rankArray  
    if (checkValue == 0) {
        index = 6; //Search term is species	
    } else {
        maxValue = Math.max.apply(this, values);
        var index = $.inArray(maxValue.toString(), values) + 1;
    }

    var query = getSearchQuery(this.name, rankArray[index]);
    console.log(query);
    checkUrl();
    var queryUrl = encodeURI(url + "?query=" + query + "&format=json");
    $.ajax({
        dataType: "jsonp",
        url: queryUrl,
        index: index,
        name: this.name,
        success: makeSearchTreeSuccess,
        error: ajaxError
    });
}
/**
* Callback from makeSearchTree. Gets members of all ranks up to the search term and calls
* executeopenquery for each one.    
*
* @class getSearchRank
* @constructor
* @param {object} _data Response of ajax request query that contains count for each rank
*/ 
function makeSearchTreeSuccess(_data) {
    var name = this.name;
    clearNextRanks("kingdom"); //Clear data of all ranks
    var kingdomType = '';
    var results = _data.results.bindings;
    console.log
    var maxValue = [0, 0, 0, 0, 0, 0];
    var values = ['', '', '', '', '', ''];
    var tempName = '';

    for (var i in results) {
        if (results[i].countkingdom !== undefined) {
            if (parseInt(results[i].countkingdom.value) > maxValue[0]) {
                maxValue[0] = parseInt(results[i].countkingdom.value);
                tempName = nameFromUrl(results[i].kingdom.value);

                values[0] = tempName.replace(' ', "_");
            }
        }
        if (results[i].countphylum !== undefined) {
            if (parseInt(results[i].countphylum.value) > maxValue[1]) {
                maxValue[1] = parseInt(results[i].countphylum.value);
                tempName = nameFromUrl(results[i].phylum.value);

                values[1] = tempName.replace(' ', "_");
            }
        }
        if (results[i].countclassis !== undefined) {
            if (parseInt(results[i].countclassis.value) > maxValue[2]) {
                maxValue[2] = parseInt(results[i].countclassis.value);
                tempName = nameFromUrl(results[i].classis.value);

                values[2] = tempName.replace(' ', "_");
            }
        }
        if (results[i].countorder !== undefined) {
            if (parseInt(results[i].countorder.value) > maxValue[3]) {
                maxValue[3] = parseInt(results[i].countorder.value);
                tempName = nameFromUrl(results[i].order.value);

                values[3] = tempName.replace(' ', "_");
            }
        }
        if (results[i].countfamily !== undefined) {
            if (parseInt(results[i].countfamily.value) > maxValue[4]) {
                maxValue[4] = parseInt(results[i].countfamily.value);
                tempName = nameFromUrl(results[i].family.value);

                values[4] = tempName.replace(' ', "_");
            }
        }
        if (results[i].countgenus !== undefined) {
            if (parseInt(results[i].countgenus.value) > maxValue[5]) {
                maxValue[5] = parseInt(results[i].countgenus.value);
                tempName = nameFromUrl(results[i].genus.value);

                values[5] = tempName.replace(' ', "_");
            }
        }



    }
    if (values[0] == 'Animal' || values[0] == 'Animalia') values[0] = "Animal";
    if (values[0] == 'Plant' || values[0] == 'Plantae') values[0] = "Plant";
    if (values[0] == 'Animal' || values[0] == 'Plant') { //Only make tree if kingdom is plant or animal
        //TODO add species 
        for (i = 0; i < this.index; i++) {
            var query = getOpenQuery(values[i], rankArray[i], rankArray[i + 1]);
            startLoading('#' + rankArray[i + 1] + '>div');
            if (values[i + 1] == '') {
                values[i + 1] = name;
            }
            executeOpenQuery(query, rankArray[i + 1], "tree", values[i + 1]);
        }
        selectRank($('p[caption="' + values[0] + '"]'), rankArray[0]);
    }

    $('button').prop('disabled', false);

}
/*End of tree functions*/
  /*Helper functions*/
  
/**
* Creates html for thumbnail. 
*
* @class thumbHtml
* @constructor
* @param {string} name Name of node
* @param {string} thumb Image url for node
* @param {string} rank Rank of node
* @param {string} selectedName Used for search tree where node is selected automatically and not by the user 
*/ 

function thumbHtml(name, thumb, rank, selectedName) {
    thumb_url = getThumbUrl(thumb);
    name = name.replace("_", " ");
    if (selectedName == name) {
        select = "selected";
    } else {
        select = "";
    }
    if (rank != "species") {
        return '   <div class="thumbnail clearfix ' + select + '">' + '<img class="img-rounded" src="assets/Timer.gif" data-src=\"' + thumb_url + '\" alt=\"...\"><div class=\"caption\">' + '<p caption=\"' + name + '\"></p>' + '<div class="btn-group" role="group" aria-label="..."> <button name="lbl" caption="details" class="btn btn-info details"data-target="#myModal" data-toggle="modal" type="button"></button>  <button type="button"class="btn btn-default open "><span class="glyphicon glyphicon-menu-right" aria-hidden="true"></span></button></div>' + '</div>   ' + '</div>';
    } else {
        return '   <div class=\"thumbnail clearfix ' + select + '">' + '<img class="img-rounded" src="assets/Timer.gif" data-src=\"' + thumb_url + '\" alt=\"...\">' + '<div class=\"caption\"><p caption="' + name + '">' + '</p> <button name="lbl" caption="details" class="btn btn-info details" data-target="#myModal" data-toggle="modal"type="button"></button>' + '</div>   ' + '</div>';
    }
}
/**
* Clears next ranks of data to insert new nodes. 
*
* @class clearNextRanks
* @constructor
* @param {string} rank Rank of node
*/ 
function clearNextRanks(rank) {
    var rank_index = rankArray.indexOf(rank);
    for (i = rank_index + 1; i < rankArray.length; i++) {
        $("#" + rankArray[i] + '>.thumbnail').remove(); //remove thumbnail divs
        $("#" + rankArray[i] + '>span').remove(); //remove spans with text 
        contents = $("#" + rankArray[i]).detach();
        $("#" + rankArray[i - 1]).after(contents);
        $("#" + rankArray[i] + ' .counter').html("");
    }
}
/**
* Returns shrinked thumbnail url or placeholder image if image doesn't exist. 
*
* @class getThumbUrl
* @constructor
* @param {string} thumb Thumbnail url
*/ 
function getThumbUrl(thumb) {
    if (thumb === undefined) { //replace with placeholder image if image doesn't exist
        return "assets/no_img_thumb.jpg"
    } else {
        return shrinkImg200(thumb.value);
    }
}

/**
* Returns name by reading caption closest to object.  
*
* @class getName
* @constructor
* @param {object} obj Dom object, usually thumbnail
*/ 
function getName(obj) {
    return obj.closest('.thumbnail').find('.caption>p[caption]').attr('caption');
}

/**
* Returns rank of thumbnail.  
*
* @class getName
* @constructor
* @param {object} obj Dom object, usually thumbnail
*/ 
function getRank(obj) {

    var rank = obj.parents('div:eq(3)').attr('id');

    return rank;
}

/**
* Returns html for member thumbnail.  
*
* @class getName
* @constructor
* @param {string} thumb_url Url of image
* @param {string} src Name of member
*/ 
function getMemberHtml(thumb_url, src) {
    return " <li> <div class='thumbnail'><img src='" + thumb_url + "'  data-src='" + thumb_url + "'width='50px' > <div class='caption'><p caption='" + src + "'>" + src + "</p></div></div></li>";
}
/**
* Make a node selected. 
*
* @class getName
* @constructor
* @param {obj} button Button that was clicked
* @param {string} rank Name of rank
*/ 
function selectRank(button, rank) {
    var selected = button.closest('.thumbnail');

    $('#' + rank + ' .thumbnail').removeClass('selected');
    selected.addClass('selected');
    //selected.insertAfter($('#' + rank + '>.rankHead')); //TODO return to original position when unselected
}
/**
* Adds loading span when something starts loading.  
*
* @class startLoading
* @constructor
* @param {obj} container Container to add loading span
*/ 
function startLoading(container) {
 $(container).after("<span><span class='glyphicon glyphicon-refresh glyphicon-refresh-animate'></span> Loading...</span>");
}
/**
* Removes loading span when something stops loading.  
*
* @class stopLoading
* @constructor
* @param {obj} container Container to remove loading span from
*/ 
function stopLoading(container) {
  $(container).next("span").remove();
}
/**
* Returns image with width of 150 pixels.  
*
* @class shrinkImg200
* @constructor
* @param {string} thumb_url Url of image
*/ 
function shrinkImg200(thumb_url) {
  var shrinkedImg = thumb_url.replace('width=300', 'width=150');
  return shrinkedImg;
}
/**
* Returns image with width of 300 pixels.  
*
* @class shrinkImg300
* @constructor
* @param {string} thumb_url Url of image
*/ 
function getImg300(thumb_url) {
  var bigImg = thumb_url.replace('width=150', 'width=300');
  return bigImg;
}
/**
* Toggle hiding and showing of divs. 
*
* @class hideShowDivs
* @constructor
*
*/ 
function hideShowDivs() {
    for (i = 1; i < rankArray.length; i++) {
        if ($('#' + rankArray[i] + '>*').length == 1) {
            $('#' + rankArray[i]).hide();
        } else {
            $('#' + rankArray[i]).show();
        }
    }
}
/**
* Show all divs.
*
* @class showAllDivs
* @constructor
*
*/ 
function showAllDivs() {
    for (i = 1; i < rankArray.length; i++) {
        $('#' + rankArray[i]).show();
    }
}
/**
* Rearrange divs for mobile. 
*
* @class divsForMobile
* @constructor
*
*/ 
function divsForMobile() {
  for (i = 0; i < rankArray.length - 1; i++) {
    if ($('#' + rankArray[i]).find('.selected').length) {
      var contents = $('#' + rankArray[i + 1]).detach();
      $('#' + rankArray[i]).find('.selected').after(contents);
    }
  }
}
/**
* Rearrange divs for normal page. 
*
* @class normalDivs
* @constructor
*
*/ 
function normalDivs() {
  for (i = 0; i < rankArray.length - 1; i++) {
    var contents = $('#' + rankArray[i + 1]).detach();
    $('#' + rankArray[i]).after(contents);
  }
}
/**
* Change divs according to width. 
*
* @class ChangeDiv
* @constructor
* @param {number} width Width of browser window
*/ 
function ChangeDiv(width) {
    if (width <= 480) {
        //put img in button
        $(".col-sm-1>.thumbnail>img").wrap('<button class="btn btn-info details" data-target="#myModal" data-toggle="modal" type="button"> </button>');
        $(".glyphicon-menu-right").addClass("glyphicon-plus-sign");
        $(".glyphicon-menu-right").removeClass("glyphicon-menu-right");
        divsForMobile();
        hideShowDivs();
    } else {
        //remove img from button
        $("button>.img-rounded").unwrap();
        $(".glyphicon-plus-sign").addClass("glyphicon-menu-right");
        $(".glyphicon-plus-sign").removeClass("glyphicon-plus-sign");
        normalDivs();
        showAllDivs();
    }
}
/**
* Capitalize first letter of string. 
*
* @class capitalizeFirstLetter
* @constructor
* @param {string} string A string
*/ 
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

  /*End of helper functions*/