diff --git a/deploy.properties b/deploy.properties
new file mode 100644
index 00000000..20a0df93
--- /dev/null
+++ b/deploy.properties
@@ -0,0 +1,77 @@
+# -----------------------------------------------------------------------------
+#
+# VIVO deployment properties
+#
+# This file is provided as example.deploy.properties.
+#
+# Save a copy of this file as deploy.properties, and edit the properties as
+# needed for your deployment.
+#
+# -----------------------------------------------------------------------------
+
+#
+# This namespace will be used when generating URIs for objects created in the
+# editor. Change it to reflect your own domain. For example, Cornell's
+# namespace is http://vivo.cornell.edu/individual/
+#
+# Note: it is essential that this namespace end with a trailing slash.
+#
+Vitro.defaultNamespace = http://vivo-trunk.indiana.edu/individual/
+
+#
+# Where is the Vitro core directory?
+# In most deployments, this is set to ./vitro-core, but internal developers may
+# prefer to set it to ../vitro
+# Examples:
+# vitro.core.dir = ./vitro-core
+# vitro.core.dir = ../vitro
+# vitro.core.dir = /usr/local/vitro/trunk
+vitro.core.dir = /usr/local/home/bkoniden/eclipse-workspace/bkoniden-vitro-post-1.1
+
+#
+# The base install directory for your Tomcat server. The VIVO application
+# will be deployed in the /webapps directory below this base.
+#
+tomcat.home = /usr/local/tomcat
+
+#
+# The name of the VIVO application. This will be used as the name of the
+# subdirectory within your Tomcat server's /webapps directory. It also appears
+# in the URL for the application. For example, http://my.vivo.server/vivo
+#
+webapp.name = vivo1
+
+#
+# The location where the VIVO application will store uploaded files
+# (usually images). You should arrange for these files to be backed up in some
+# way.
+#
+upload.directory = /usr/local/vivo1/data-vivo-updated/uploads
+
+#
+# The location where the VIVO application will create its Lucene search
+# index.
+#
+LuceneSetup.indexDir = /usr/local/vivo1/data-vivo-updated/luceneIndex
+
+#
+# SMTP host which the "Contact Us" form can use to send mail. If this is left
+# empty, the "Contact Us" form will be disabled.
+#
+Vitro.smtpHost =
+
+#
+# The basic parameters for a MySQL database connection. Change the end of the
+# URL to reflect your database name (if it is not "vitro"). Change the username
+# and password to match the authorized user you created in MySQL.
+#
+VitroConnection.DataSource.url = jdbc:mysql://localhost/vivo1
+VitroConnection.DataSource.username = vivouser1
+VitroConnection.DataSource.password = vivo123
+
+#
+# The name of your first admin user for the VIVO application. The password for
+# for this user is initially set to "defaultAdmin", but you will be asked to
+# change the password the first time you login.
+#
+initialAdminUser = defaultAdmin
\ No newline at end of file
diff --git a/deployVIVOInstance b/deployVIVOInstance
new file mode 100755
index 00000000..e9180286
--- /dev/null
+++ b/deployVIVOInstance
@@ -0,0 +1,2 @@
+sudo /usr/local/tomcat/bin/shutdown.sh
+ant clean deploy
diff --git a/example.deploy.properties b/example.deploy.properties
index 38034236..b4629b1a 100644
--- a/example.deploy.properties
+++ b/example.deploy.properties
@@ -14,7 +14,7 @@
# editor. Change it to reflect your own domain. For example, Cornell's
# namespace is http://vivo.cornell.edu/individual/
#
-# Note: it is essential that this namespace end with a trailing slash.
+# Note: it is essential that this namespace end with a trailing slash.
#
Vitro.defaultNamespace = http://vivo.mydomain.edu/individual/
diff --git a/productMods/WEB-INF/visualization/visualizations-beans-injection.xml b/productMods/WEB-INF/visualization/visualizations-beans-injection.xml
index 23de8763..a3b7c4c7 100644
--- a/productMods/WEB-INF/visualization/visualizations-beans-injection.xml
+++ b/productMods/WEB-INF/visualization/visualizations-beans-injection.xml
@@ -1,6 +1,5 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/productMods/WEB-INF/web.xml b/productMods/WEB-INF/web.xml
index 10d79824..0b5527fa 100644
--- a/productMods/WEB-INF/web.xml
+++ b/productMods/WEB-INF/web.xml
@@ -1221,7 +1221,6 @@
/admin/sparqlquery
-
+
+
VisualizationController
diff --git a/productMods/js/visualization/entityComparison/constants.js b/productMods/js/visualization/entityComparison/constants.js
new file mode 100644
index 00000000..e867617d
--- /dev/null
+++ b/productMods/js/visualization/entityComparison/constants.js
@@ -0,0 +1,75 @@
+
+//Hard coded color constants
+var TURQUOISE = "#8DD3C7";
+var LIGHT_YELLOW = "#FFFFB3";
+var LIGHT_VIOLET = "#BEBADA";
+var LIGHT_RED = "#FB8072";
+var SKY_BLUE = "#80B1D3";
+var ORANGE = "#FDB462";
+var LIGHT_GREEN = "#B3DE69";
+var LIGHT_PINK = "#FCCDE5";
+var LIGHT_GREY = "#D9D9D9";
+var PURPLE = "#BC80BD";
+
+var colorConstantQueue =
+ [
+ TURQUOISE, LIGHT_YELLOW, LIGHT_VIOLET, LIGHT_RED,
+ SKY_BLUE, ORANGE, LIGHT_GREEN, LIGHT_PINK, LIGHT_GREY,
+ PURPLE
+ ];
+
+var freeColors = [
+ TURQUOISE, LIGHT_YELLOW, LIGHT_VIOLET, LIGHT_RED,
+ SKY_BLUE, ORANGE, LIGHT_GREEN, LIGHT_PINK, LIGHT_GREY,
+ PURPLE
+ ];
+
+var year = {
+ min: 1998,
+ max: 2018,
+ globalMin: 1995,
+ globalMax: 2025
+};
+
+var colors = {};
+var prevColor = {};
+var colorToAssign, colorToRemove;
+var renderedObjects = [];
+var labelToEntityRecord = {};
+var setOfLabels = [];
+var labelToCheckedEntities = {};
+var stopWordsToCount = {};
+
+var graphContainer;
+var tableDiv;
+var entityLevel;
+
+//options for Flot
+var FlotOptions = {
+ legend : {
+ show : false
+ },
+ lines : {
+ show : true
+ },
+ points : {
+ show : false
+ },
+ xaxis : {
+ tickDecimals : 0,
+ tickSize : 10
+ },
+ series : {
+ lines : {
+ lineWidth : 7
+ }
+ },
+ yaxis : {
+ tickSize : 1,
+ tickDecimals : 0,
+ min : 0
+ }
+};
+
+FlotOptions.colors = colorConstantQueue;
+
diff --git a/productMods/js/visualization/entityComparison/util.js b/productMods/js/visualization/entityComparison/util.js
new file mode 100644
index 00000000..c4fe3a4a
--- /dev/null
+++ b/productMods/js/visualization/entityComparison/util.js
@@ -0,0 +1,1032 @@
+/**
+ * init sets some initial options for the default graph. i.e for when the page
+ * is initially loaded or when its refreshed or when all the checkboxes on the
+ * page are unchecked.
+ *
+ * @param graphContainer
+ * is the div that contains the main graph.
+ */
+function init(graphContainer) {
+
+ var optionSelected = $("select.comparisonValues option:selected").val();
+ // TODO: make use of the id on the select field instead of a generic one.
+ $("#comparisonParameter").text("Total Number of " + $("select.comparisonValues option:selected").val());
+ $('#yaxislabel').html("Number of " + optionSelected).mbFlipText(false);
+ $("span#paramdesc").text($("select.comparisonValues option:selected").val() + ' (desc)');
+ $("span#paramasc").text($("select.comparisonValues option:selected").val() + ' (asc)');
+
+ var defaultFlotOptions = {
+ xaxis : {
+ min : 1996,
+ max : 2008,
+ tickDecimals : 0,
+ tickSize : 2
+ },
+ yaxis: {
+ tickDecimals : 0,
+ min : 0,
+ max: 5
+ }
+ };
+
+ /*
+ * [[]] is an empty 2D array object. $.plot is passed this for the default
+ * behavior. Ex.When the page initially loads, or when no graphs are present
+ * on the webpage.
+ */
+
+ var initialDataObject = [ [] ];
+ $.plot(graphContainer, initialDataObject, defaultFlotOptions);
+}
+
+/**
+ * unStuffZerosFromLineGraphs removes the previously stuffed zero values. r is
+ * the current data object. s is the current min and max {year} values. All the
+ * datapoints < curr_min{year} && > > curr_max{year} are removed, so that they
+ * don't show up on the graph
+ *
+ * @param {Object}
+ * jsonObject
+ * @param {Object}
+ * arrayOfMinAndMaxYears
+ * @returns jsonObject with modified data points.
+ */
+
+//TODO: side-effect year.
+function unStuffZerosFromLineGraphs(jsonObject, year) {
+
+ calcZeroLessMinAndMax(jsonObject, year);
+ var currentMinYear = year.globalMin, currentMaxYear = year.globalMax;
+
+ $
+ .each(
+ jsonObject,
+ function(key, val) {
+ var i = 0;
+ for (i = 0; i < val.data.length; i++) {
+ if (((val.data[i][0] < currentMinYear) || (val.data[i][0] > currentMaxYear))
+ && val.data[i][1] == 0) {
+
+ val.data.splice(i, 1);
+ i--;
+ } else {
+ continue;
+ }
+ }
+ });
+}
+
+/**
+ * while unStuffZerosFromLineGraphs is for a group of data objects,
+ * unStuffZerosFromLineGraph is for a single data object. It removes zeroes from
+ * the single object passed as parameter.
+ *
+ * @param {Object}
+ * jsonObject
+ */
+function unStuffZerosFromLineGraph(jsonObject) {
+ var i = 0;
+ for (i = 0; i < jsonObject.data.length; i++) {
+ if (jsonObject.data[i][1] == 0) {
+ jsonObject.data.splice(i, 1);
+ i--;
+ }
+ }
+}
+
+/**
+ * stuffZerosIntoLineGraphs is used to fill discontinuities in data points. For
+ * example, if a linegraph has the following data points [1990,
+ * 2],[1992,3],[1994, 5],[1996,5],[2000,4],[2001,1]. stuffZerosIntoLineGraphs
+ * inserts [1991,0],[1993,0],1995,0]..and so on. It also inserts zeroes at the
+ * beginning and the end if the max and min{year} of the current linegraph fall
+ * in between the global max and min{year}
+ *
+ * @param {Object}
+ * jsonObject
+ * @param {Object}
+ * arrayOfMinAndMaxYears
+ * @returns jsonObject with stuffed data points.
+ */
+function stuffZerosIntoLineGraphs(jsonObject, year) {
+
+ calcZeroLessMinAndMax(jsonObject, year);
+
+ var arrayOfMinAndMaxYears = [ year.globalMin, year.globalMax ];
+
+ $
+ .each(
+ jsonObject,
+ function(key, val) {
+ var position = arrayOfMinAndMaxYears[0], i = 0;
+
+ for (i = 0; i < (arrayOfMinAndMaxYears[1] - arrayOfMinAndMaxYears[0]) + 1; i++) {
+
+ if (val.data[i]) {
+
+ if (val.data[i][0] != position
+ && position <= arrayOfMinAndMaxYears[1]) {
+ val.data.splice(i, 0, [ position, 0 ]);
+ }
+ }
+
+ else {
+ val.data.push( [ position, 0 ]);
+ }
+ position++;
+ }
+ });
+}
+/**
+ * During runtime, when the user checks/unchecks a checkbox, the zeroes have to
+ * be inserted and removed dynamically. This function calculates the max{year}
+ * and min{year} among all the linegraphs present on the graph at a particular
+ * instance in time .
+ *
+ * @param {Object}
+ * jsonObject
+ * @returns an array of current min and max years.
+ */
+function calcZeroLessMinAndMax(jsonObject, year) {
+
+ var globalMinYear = 5000, globalMaxYear = 0, minYear, maxYear, i = 0;
+
+ $.each(jsonObject, function(key, val) {
+
+ for (i = 0; i < val.data.length; i++) {
+ if (val.data[i][1] != 0) {
+ minYear = val.data[i][0];
+ break;
+ }
+ }
+
+ for (i = val.data.length - 1; i >= 0; i--) {
+ if (val.data[i][1] != 0 && val.data[i][0] != -1) {
+ maxYear = val.data[i][0];
+ break;
+ }
+
+ }
+ if (globalMinYear > minYear)
+ globalMinYear = minYear;
+ if (globalMaxYear < maxYear)
+ globalMaxYear = maxYear;
+
+ });
+
+ year.globalMin = globalMinYear;
+ year.globalMax = globalMaxYear;
+}
+
+/**
+ * z is an an object with two properties label and data. data is of the form
+ * [year,value] This function returns the min and max values of all such years.
+ *
+ * @param {Object}
+ * jsonObject
+ * @returns [minYear, maxYear]
+ */
+function calcMinandMaxYears(jsonObject, year) {
+ var minYear = 5000, maxYear = 0;
+ $.each(jsonObject, function(key, val) {
+ if (minYear > val.data[0][0]) {
+ minYear = val.data[0][0];
+ }
+ if (maxYear < val.data[val.data.length - 1][0]
+ && val.data[val.data.length - 1][0] != -1){
+ maxYear = val.data[val.data.length - 1][0];
+ }else {
+ if(val.data.length != 1){
+ maxYear = val.data[val.data.length - 2][0];
+ }
+ }
+ });
+
+ year.min = minYear;
+ year.max = maxYear;
+}
+
+/**
+ * y is an an object with two properties label and data. data is of the form
+ * [year,value] This function returns the max of all values.
+ *
+ * @param {Object}
+ * jsonObject
+ * @returns maxCount
+ */
+function calcMaxOfComparisonParameter(jsonObject) {
+ var sum = 0, i = 0, maxCount = 0;
+
+ $.each(jsonObject, function(key, val) {
+ for (i = 0; i < val.data.length; i++)
+ sum += val.data[i][1];
+
+ if (maxCount < sum)
+ maxCount = sum;
+
+ sum = 0;
+ });
+
+// console.log('returning max value' + maxCount);
+ return maxCount;
+}
+
+function calcMaxWithinComparisonParameter(jsonObject){
+
+ var value = 0, i = 0, maxCount = 0;
+
+ $.each(jsonObject, function(key, val) {
+ for (i = 0; i < val.data.length; i++){
+ value = val.data[i][1];
+ // console.log(val.data[i][1]);
+
+ if (maxCount < value){
+ maxCount = value;
+ }
+ }
+ });
+
+ //console.log('max value: ' + maxCount);
+ return maxCount;
+}
+
+/**
+ * x is an object and it has two properties label and data. data is a two
+ * dimensional array of the form [year, value] This function returns the sum of
+ * all the values.
+ *
+ * @param {Object}
+ * jsonObject
+ * @returns sum{values}.
+ */
+function calcSumOfComparisonParameter(jsonObject) {
+
+ var sum = 0, i = 0;
+ for (i = 0; i < jsonObject.data.length; i++) {
+ sum += jsonObject.data[i][1];
+ }
+
+ // sum += jsonObject.publicationCount;
+ return sum;
+}
+
+/**
+ * A simple function to see if the passed
+ *
+ * @param {array}
+ * objectArray
+ * @param {Object}
+ * object
+ * @returns a flag - 0/1 - indicating whether a contains b.
+ */
+function contains(objectArray, object) {
+ var i = 0, flag = 0;
+ for (i = 0; i < objectArray.length; i++) {
+ if (objectArray[i] == object)
+ flag = i;
+ }
+ return flag;
+}
+
+/**
+ * Dynamically change the linewidth and ticksize based on input year range.
+ *
+ * @param {Object}
+ * yearRange
+ */
+function setLineWidthAndTickSize(yearRange, flotOptions) {
+
+ if (yearRange > 0 && yearRange < 15) {
+ flotOptions.series.lines.lineWidth = 3;
+ flotOptions.xaxis.tickSize = 1;
+ } else if (yearRange > 15 && yearRange < 70) {
+ flotOptions.series.lines.lineWidth = 2;
+ flotOptions.xaxis.tickSize = 4;
+ } else {
+ flotOptions.series.lines.lineWidth = 1;
+ flotOptions.xaxis.tickSize = 10;
+ }
+
+}
+
+/**
+ * Dynamically change the ticksize of y-axis.
+ */
+function setTickSizeOfYAxis(maxValue, flotOptions){
+
+ if (maxValue > 0 && maxValue <= 5) {
+ flotOptions.yaxis.tickSize = 1;
+ } else if (maxValue > 5 && maxValue <= 10) {
+ flotOptions.yaxis.tickSize = 2;
+ } else if (maxValue > 10 && maxValue <= 15) {
+ flotOptions.yaxis.tickSize = 3;
+ } else if (maxValue > 15 && maxValue <= 70) {
+ flotOptions.yaxis.tickSize = maxValue/5;
+ } else {
+ flotOptions.yaxis.tickSize = maxValue/7;
+ }
+}
+/**
+ * Create a div that represents the rectangular bar A hidden input class that is
+ * used to pass the value and a label beside the checkbox.
+ *
+ * @param {Object}
+ * entityLabel
+ */
+function createGraphic(entity, bottomDiv) {
+
+ var parentP = $('
');
+ parentP.attr('id', slugify(entity.label));
+
+ var labelDiv = $('