1. Changed layout per Katy's suggestion for Temporal Graph Vis.

2. Refactored javascript code for Temporal graph vis.
3. Fixed couple of bugs including the one in which an entity had only one publication the line graph showed weird behavior.
4. Modified the behavior of the temporal linear graph to always try to display last 10 years at least on the line graph.
This commit is contained in:
cdtank 2011-01-19 23:47:52 +00:00
parent 239b6d40d7
commit 6af3fee6b1
5 changed files with 127 additions and 48 deletions

View file

@ -13,17 +13,25 @@
} }
a.temporalGraphLinks { a.temporalGraphLinks {
margin-top: 10px;
/*float:right;*/ /*float:right;*/
height: 20px; background-color: #2485AE;
text-decoration: none; color: white;
width: 30%;
/*margin: 0 1% 0 1%;*/
background-color: #EAEAEA;
text-align: center;
padding: 3px;
padding-top: 4px;
cursor: pointer; cursor: pointer;
font-weight: bold;
height: 20px;
margin-top: 10px;
padding: 4px 3px 3px;
text-align: center;
text-decoration: none;
}
#paginated-table-footer {
margin-top: 10px;
text-align: right;
}
#legend-row-header a {
background-color: #878787;
} }
#reset-search { #reset-search {
@ -98,6 +106,8 @@ a.temporalGraphLinks {
.small-arrows { .small-arrows {
font-size: 0.9em; font-size: 0.9em;
padding: 0 !important; padding: 0 !important;
text-decoration: none;
vertical-align: top;
} }
#header-entity-label { #header-entity-label {

View file

@ -10,6 +10,7 @@ var LIGHT_RED = "#FB8072";
var DARK_RED = "#520000"; var DARK_RED = "#520000";
var SKY_BLUE = "#80B1D3"; var SKY_BLUE = "#80B1D3";
var DARK_BLUE = "#80B1D3"; var DARK_BLUE = "#80B1D3";
var NAVY_BLUE = "#003366";
var LIGHT_BLUE = "#3399FF"; var LIGHT_BLUE = "#3399FF";
var ORANGE = "#FDB462"; var ORANGE = "#FDB462";
var DARK_ORANGE = "#FF9900"; var DARK_ORANGE = "#FF9900";
@ -21,21 +22,22 @@ var LIGHT_GREY = "#D9D9D9";
var PURPLE = "#BC80BD"; var PURPLE = "#BC80BD";
var DARK_PURPLE = "#6600CC"; var DARK_PURPLE = "#6600CC";
var PINK_PURPLE = "#CC00CC"; var PINK_PURPLE = "#CC00CC";
var HOT_PINK = "#FF00B4";
var MEHENDI_GREEN = "#7A7900";
var colorConstantQueue = [ DARK_BLUE, DARK_TURQUOISE, var colorConstantQueue = [ LIGHT_BLUE, DARK_ORANGE, VIBRANT_GREEN,
LIGHT_BLUE, DARK_GREEN, NAVY_BLUE, RED, PINK_PURPLE,
VIBRANT_GREEN, DARK_PURPLE, DARK_TURQUOISE, MEHENDI_GREEN, HOT_PINK,
PINK_PURPLE, DARK_ORANGE, DARK_RED ];
DARK_RED, RED ];
var freeColors = colorConstantQueue.slice(); var freeColors = colorConstantQueue.slice();
var globalDateObject = new Date(); var globalDateObject = new Date();
var year = { var year = {
min: globalDateObject.getFullYear() - 10, min: globalDateObject.getFullYear() - 9,
max: globalDateObject.getFullYear(), max: globalDateObject.getFullYear(),
globalMin: globalDateObject.getFullYear() - 10, globalMin: globalDateObject.getFullYear() - 9,
globalMax: globalDateObject.getFullYear() globalMax: globalDateObject.getFullYear()
}; };

View file

@ -1,25 +1,36 @@
@CHARSET "UTF-8"; @CHARSET "UTF-8";
.filterInfo { .filterInfo {
/*font-size: 0.9em;*/ float:left;
display: inline-block; margin-top: 15px;
}
.filterInfo div {
font-weight: bold;
} }
.paginate_button { .paginate_button {
text-decoration: underline; /*text-decoration: underline;*/
} }
.paginatedtabs { .paginatedtabs {
/* border-top: 1px #3D454E solid; /* border-top: 1px #3D454E solid;
text-align: center;*/ text-align: center;*/
margin-bottom: 10px; margin-bottom: 10px;
padding-top: 10px;
font-size: 0.9em; font-size: 0.9em;
/*display: inline-block;*/
float:right;
margin-top: 15px;
} }
.paginatedtabs span { .paginatedtabs span {
padding-right: 5px; padding-right: 5px;
cursor: pointer; cursor: pointer;
color: #2485AE;
}
.paginate-nav-text {
text-decoration: underline;
} }
.datatablewrapper td, th { .datatablewrapper td, th {
@ -41,6 +52,10 @@
text-align: left; text-align: left;
} }
.table-separator {
clear: both;
}
.datatablewrapper th { .datatablewrapper th {
border-top: 1px #3D454E solid; border-top: 1px #3D454E solid;
background:#F1F2ee; background:#F1F2ee;

View file

@ -7,9 +7,9 @@ $.fn.dataTableExt.oPagination.gmail_style = {
"fnInit": function ( oSettings, nPaging, fnCallbackDraw ) "fnInit": function ( oSettings, nPaging, fnCallbackDraw )
{ {
//var nInfo = document.createElement( 'div' );
var nFirst = document.createElement( 'span' ); var nFirst = document.createElement( 'span' );
var nPrevious = document.createElement( 'span' ); var nPrevious = document.createElement( 'span' );
var nInfo = document.createElement( 'div' );
var nNext = document.createElement( 'span' ); var nNext = document.createElement( 'span' );
var nLast = document.createElement( 'span' ); var nLast = document.createElement( 'span' );
@ -20,10 +20,10 @@ $.fn.dataTableExt.oPagination.gmail_style = {
nLast.innerHTML = oSettings.oLanguage.oPaginate.sLast; nLast.innerHTML = oSettings.oLanguage.oPaginate.sLast;
*/ */
nFirst.innerHTML = "<span class='small-arrows'><<</span> First"; nFirst.innerHTML = "<span class='small-arrows'>&laquo;</span> <span class='paginate-nav-text'>First</span>";
nPrevious.innerHTML = "<span class='small-arrows'><</span> Prev"; nPrevious.innerHTML = "<span class='small-arrows'>&lsaquo;</span> <span class='paginate-nav-text'>Prev</span>";
nNext.innerHTML = "Next <span class='small-arrows'>></span>"; nNext.innerHTML = "<span class='paginate-nav-text'>Next</span><span class='small-arrows'>&rsaquo;</span>";
nLast.innerHTML = "Last <span class='small-arrows'>>></span>"; nLast.innerHTML = "<span class='paginate-nav-text'>Last</span><span class='small-arrows'>&raquo;</span>";
var oClasses = oSettings.oClasses; var oClasses = oSettings.oClasses;
nFirst.className = oClasses.sPageButton+" "+oClasses.sPageFirst; nFirst.className = oClasses.sPageButton+" "+oClasses.sPageFirst;
@ -31,9 +31,9 @@ $.fn.dataTableExt.oPagination.gmail_style = {
nNext.className= oClasses.sPageButton+" "+oClasses.sPageNext; nNext.className= oClasses.sPageButton+" "+oClasses.sPageNext;
nLast.className = oClasses.sPageButton+" "+oClasses.sPageLast; nLast.className = oClasses.sPageButton+" "+oClasses.sPageLast;
//nPaging.appendChild( nInfo );
nPaging.appendChild( nFirst ); nPaging.appendChild( nFirst );
nPaging.appendChild( nPrevious ); nPaging.appendChild( nPrevious );
nPaging.appendChild( nInfo );
nPaging.appendChild( nNext ); nPaging.appendChild( nNext );
nPaging.appendChild( nLast ); nPaging.appendChild( nLast );
@ -76,7 +76,7 @@ $.fn.dataTableExt.oPagination.gmail_style = {
nPaging.setAttribute( 'id', oSettings.sTableId+'_paginate' ); nPaging.setAttribute( 'id', oSettings.sTableId+'_paginate' );
nFirst.setAttribute( 'id', oSettings.sTableId+'_first' ); nFirst.setAttribute( 'id', oSettings.sTableId+'_first' );
nPrevious.setAttribute( 'id', oSettings.sTableId+'_previous' ); nPrevious.setAttribute( 'id', oSettings.sTableId+'_previous' );
nInfo.setAttribute( 'id', 'infoContainer' ); //nInfo.setAttribute( 'id', 'infoContainer' );
nNext.setAttribute( 'id', oSettings.sTableId+'_next' ); nNext.setAttribute( 'id', oSettings.sTableId+'_next' );
nLast.setAttribute( 'id', oSettings.sTableId+'_last' ); nLast.setAttribute( 'id', oSettings.sTableId+'_last' );
} }
@ -239,8 +239,8 @@ function init(graphContainer) {
var defaultFlotOptions = { var defaultFlotOptions = {
xaxis : { xaxis : {
min : 1996, min : globalDateObject.getFullYear() - 9,
max : 2008, max : globalDateObject.getFullYear(),
tickDecimals : 0, tickDecimals : 0,
tickSize : 2 tickSize : 2
}, },
@ -283,12 +283,14 @@ function unStuffZerosFromLineGraphs(jsonObject, year) {
calcZeroLessMinAndMax(jsonObject, year); calcZeroLessMinAndMax(jsonObject, year);
var currentMinYear = year.globalMin, currentMaxYear = year.globalMax; var currentMinYear = year.globalMin, currentMaxYear = year.globalMax;
var normalizedYearRange = getNormalizedYearRange();
$.each(jsonObject, $.each(jsonObject,
function(key, val) { function(key, val) {
var i = 0; var i = 0;
for (i = 0; i < val.data.length; i++) { for (i = 0; i < val.data.length; i++) {
if (((val.data[i][0] < currentMinYear) || (val.data[i][0] > currentMaxYear)) if (((val.data[i][0] < normalizedYearRange.normalizedMinYear) || (val.data[i][0] > normalizedYearRange.normalizedMaxYear))
&& val.data[i][1] == 0) { && val.data[i][1] == 0) {
val.data.splice(i, 1); val.data.splice(i, 1);
@ -318,6 +320,43 @@ function unStuffZerosFromLineGraph(jsonObject) {
} }
} }
/**
* This is used to normalize the year range for the currently selected entities to always
* display the last 10 years worth of data points.
*
*/
function getNormalizedYearRange() {
/*
* This is done to make sure that at least last 10 years worth of data points
* can be displayed.
* */
if (globalDateObject.getFullYear() < year.globalMax) {
inferredMaxYear = year.globalMax;
} else {
inferredMaxYear = globalDateObject.getFullYear();
}
if (globalDateObject.getFullYear() - 9 > year.globalMin) {
inferredMinYear = year.globalMin;
} else {
inferredMinYear = globalDateObject.getFullYear() - 9;
}
return {
normalizedMinYear: inferredMinYear,
normalizedMaxYear: inferredMaxYear,
normalizedRange: inferredMaxYear - inferredMinYear
};
}
/** /**
* stuffZerosIntoLineGraphs is used to fill discontinuities in data points. For * stuffZerosIntoLineGraphs is used to fill discontinuities in data points. For
* example, if a linegraph has the following data points [1990, * example, if a linegraph has the following data points [1990,
@ -336,22 +375,22 @@ function stuffZerosIntoLineGraphs(jsonObject, year) {
calcZeroLessMinAndMax(jsonObject, year); calcZeroLessMinAndMax(jsonObject, year);
var arrayOfMinAndMaxYears = [ year.globalMin, year.globalMax ]; var normalizedYearRange = getNormalizedYearRange();
$.each(jsonObject, $.each(jsonObject,
function(key, val) { function(key, val) {
var position = arrayOfMinAndMaxYears[0], i = 0; var position = normalizedYearRange.normalizedMinYear, i = 0;
//console.log(key, val, position, (arrayOfMinAndMaxYears[1] - arrayOfMinAndMaxYears[0]) + 1); //console.log(key, val, position, (arrayOfMinAndMaxYears[1] - arrayOfMinAndMaxYears[0]) + 1);
for (i = 0; i < (arrayOfMinAndMaxYears[1] - arrayOfMinAndMaxYears[0]) + 1; i++) { for (i = 0; i < normalizedYearRange.normalizedRange + 1; i++) {
//console.log("val.data[i]", val.data[i]); //console.log("val.data[i]", val.data[i]);
if (val.data[i]) { if (val.data[i]) {
if (val.data[i][0] != position if (val.data[i][0] != position
&& position <= arrayOfMinAndMaxYears[1]) { && position <= normalizedYearRange.normalizedMaxYear) {
val.data.splice(i, 0, [ position, 0 ]); val.data.splice(i, 0, [ position, 0 ]);
} }
} }
@ -525,6 +564,9 @@ function setLineWidthAndTickSize(yearRange, flotOptions) {
} else if (yearRange > 15 && yearRange < 70) { } else if (yearRange > 15 && yearRange < 70) {
flotOptions.series.lines.lineWidth = 2; flotOptions.series.lines.lineWidth = 2;
flotOptions.xaxis.tickSize = 5; flotOptions.xaxis.tickSize = 5;
} else if (yearRange == 0 ) {
flotOptions.series.lines.lineWidth = 3;
flotOptions.xaxis.tickSize = 1;
} else { } else {
flotOptions.series.lines.lineWidth = 1; flotOptions.series.lines.lineWidth = 1;
flotOptions.xaxis.tickSize = 10; flotOptions.xaxis.tickSize = 10;
@ -800,12 +842,13 @@ function removeEntityUnChecked(renderedObjects, entity){
//remove the entity that is unchecked //remove the entity that is unchecked
var ii = 0; var ii = 0;
while (ii < renderedObjects.length) { while (ii < renderedObjects.length) {
if (renderedObjects[ii].label == entity.label) { if (renderedObjects[ii].label == entity.label) {
unStuffZerosFromLineGraph(renderedObjects[ii]); unStuffZerosFromLineGraph(renderedObjects[ii]);
renderedObjects.splice(ii, 1); renderedObjects.splice(ii, 1);
} else { } else {
ii++; ii++;
} }
} }
unStuffZerosFromLineGraphs(renderedObjects, year); unStuffZerosFromLineGraphs(renderedObjects, year);
@ -868,16 +911,23 @@ function updateCounter(){
} }
function displayLineGraphs(){ function displayLineGraphs(){
//plot all we got //plot all we got
if (renderedObjects.length == 0) { if (renderedObjects.length == 0) {
init(graphContainer); init(graphContainer);
} else { } else {
removeUnknowns(renderedObjects); removeUnknowns(renderedObjects);
$.plot(graphContainer, renderedObjects, FlotOptions); $.plot(graphContainer, renderedObjects, FlotOptions);
insertBackUnknowns(renderedObjects); insertBackUnknowns(renderedObjects);
} }
} }
function removeCheckBoxFromGlobalSet(checkbox){ function removeCheckBoxFromGlobalSet(checkbox){
//remove checkbox object from the globals //remove checkbox object from the globals
var value = $(checkbox).attr("value"); var value = $(checkbox).attr("value");
@ -966,7 +1016,7 @@ function prepareTableForDataTablePagination(jsonData){
var searchBarParentContainerDIVClass = "searchbar"; var searchBarParentContainerDIVClass = "searchbar";
var entityListTable = $('#datatable').dataTable({ var entityListTable = $('#datatable').dataTable({
"sDom": '<"' + searchBarParentContainerDIVClass + '"f><"filterInfo"i><"paginatedtabs"p><"datatablewrapper"t>', "sDom": '<"' + searchBarParentContainerDIVClass + '"f><"filterInfo"i><"paginatedtabs"p><"table-separator"><"datatablewrapper"t>',
"aaSorting": [ "aaSorting": [
[2, "desc"] [2, "desc"]
], ],
@ -974,7 +1024,7 @@ function prepareTableForDataTablePagination(jsonData){
"iDisplayLength": 10, "iDisplayLength": 10,
"bInfo": true, "bInfo": true,
"oLanguage": { "oLanguage": {
"sInfo": "_START_ - _END_ of _TOTAL_", "sInfo": "Records _START_ - _END_ of _TOTAL_",
"sInfoEmpty": "No matching entities found", "sInfoEmpty": "No matching entities found",
"sInfoFiltered": "", "sInfoFiltered": "",
}, },
@ -999,8 +1049,10 @@ function prepareTableForDataTablePagination(jsonData){
entityListTable.fnFilter(""); entityListTable.fnFilter("");
}); });
/*
var filterInfo = $(".filterInfo").detach(); var filterInfo = $(".filterInfo").detach();
$("#infoContainer").append(filterInfo); $("#infoContainer").append(filterInfo);
*/
} }
@ -1108,8 +1160,6 @@ function enableUncheckedEntities(){
function checkIfColorLimitIsReached(){ function checkIfColorLimitIsReached(){
// console.log(getSize(labelToCheckedEntities));
if (getSize(labelToCheckedEntities) >= 10) { if (getSize(labelToCheckedEntities) >= 10) {
disableUncheckedEntities(); disableUncheckedEntities();
} else { } else {
@ -1126,10 +1176,8 @@ function setTickSizeOfAxes(){
checkedLabelToEntityRecord[index] = labelToEntityRecord[index]; checkedLabelToEntityRecord[index] = labelToEntityRecord[index];
}); });
//calcMinandMaxYears(checkedLabelToEntityRecord, year); var normalizedYearRange = getNormalizedYearRange();
//yearRange = (year.max - year.min);
yearRange = (year.globalMax - year.globalMin);
setLineWidthAndTickSize(yearRange, FlotOptions); setLineWidthAndTickSize(normalizedYearRange.normalizedRange, FlotOptions);
setTickSizeOfYAxis(calcMaxWithinComparisonParameter(checkedLabelToEntityRecord), FlotOptions); setTickSizeOfYAxis(calcMaxWithinComparisonParameter(checkedLabelToEntityRecord), FlotOptions);
} }

View file

@ -248,7 +248,7 @@ var organizationLabel = '${organizationLabel}';
*/ */
$.each($("input.if_clicked_on_school"), function(index, checkbox) { $.each($("input.if_clicked_on_school"), function(index, checkbox) {
if (index > 0) { if (index > 2) {
return false; return false;
} }
@ -306,8 +306,9 @@ var organizationLabel = '${organizationLabel}';
</div> </div>
<h3>Who do you want to compare?</h3> <h3>Who do you want to compare?</h3>
<div id="paginatedTable"></div> <div id="paginatedTable"></div>
<br /> <div id="paginated-table-footer">
<a id="csv" href="${TemporalGraphDownloadFile}" class="temporalGraphLinks">Save as CSV</a> <a id="csv" href="${TemporalGraphDownloadFile}" class="temporalGraphLinks">Save as CSV</a>
</div>
</div> </div>
<#-- <#--
<div id = "stopwordsdiv"> <div id = "stopwordsdiv">
@ -329,8 +330,11 @@ var organizationLabel = '${organizationLabel}';
<div id="bottom"> <div id="bottom">
<h3><span id="comparisonParameter"></span></h3> <h3><span id="comparisonParameter"></span></h3>
<p class="displayCounter">You have selected <span id="counter">0</span> of a maximum <p class="displayCounter">You have selected <span id="counter">0</span> of a maximum
<span id="total">10</span> <span id="entityleveltext"> schools</span> to compare. <span id="total">10</span> <span id="entityleveltext"> schools</span> to compare.
<a id="clear" class="temporalGraphLinks">Clear</a></p> <span id="legend-row-header">
<a id="clear" class="temporalGraphLinks">Clear</a>
</span>
</p>
</div> </div>
</div> </div>