";
+ if (heatMap.isSaveAllowed()) {
+ buttons = buttons + "
";
+ }
+ setTableRow(prefButtons,[""]);
+ rowCtr++;
+ prefprefs.appendChild(prefButtons);
+
+ //Add prefspanel table to the main preferences DIV and set position and display
+ prefspanel.appendChild(prefContents);
+ prefspanel.style.position = "absolute";
+ prefspanel.style.top = e.offsetTop + 15;
+ prefspanel.style.display="inherit";
+
+ //maxRows has been loaded with a count of the datalayer/class panel with the most rows
+ //add to this the number of rows added during construction of prefspanel table.
+ maxRows = maxRows+rowCtr;
+ //Retrieve maximum row height size used in various preferences DIVs
+ helpRowSize = parseFloat(getStyle(prefspanel, 'font-size' ), 10)*1.45;
+ //Use the two above numbers to apply sizing to all of the preferences DIVs.
+ setPrefsDivSizing();
+ prefspanel.style.left = e.offsetLeft - parseInt(layerprefs.style.width,10);
+
+ //If errors exist and they are NOT on the currently visible DIV (dataLayer1),
+ //hide the dataLayers DIV, set the tab to "Covariates", and open the appropriate
+ //covariate bar DIV.
+ showDendroSelections();
+ setShowAll();
+ if ((errorMsg != null) && (errorMsg[1] === "classPrefs")) {
+ showClassBreak(errorMsg[0]);
+ showClassPrefs();
+ } else if ((errorMsg != null) && (errorMsg[1] === "layerPrefs")){
+ showLayerPrefs();
+ } else if (searchPerformed){
+ searchPerformed = false;
+ showClassPrefs();
+ } else {
+ showRowsColsPrefs();
+ }
+
+}
+
+/**********************************************************************************
+ * FUNCTION - setPrefsDivSizing: The purpose of this function is to resize the
+ * various DIVs inside the preferences dialog. It is called when the dialog is
+ * first opened and whenever data layer breakpoints are added (if necessary).
+ **********************************************************************************/
+//TODO - This can be improved as the current sizing is not exact.
+function setPrefsDivSizing() {
+ var rowsColsprefs = document.getElementById("rowsColsPrefs");
+ var layerprefs = document.getElementById("layerPrefs");
+ var classprefs = document.getElementById("classPrefs");
+ var helprefs = document.getElementById("prefsPanel");
+ var prefHeight = maxRows*helpRowSize;
+ var prefWidth = 380;
+ rowsColsprefs.style.width = prefWidth;
+ rowsColsprefs.style.height = prefHeight;
+ layerprefs.style.width = prefWidth;
+ layerprefs.style.height = prefHeight;
+ classprefs.style.width = prefWidth;
+ classprefs.style.height = prefHeight;
+}
+
+/**********************************************************************************
+ * FUNCTION - showLayerPrefs: The purpose of this function is to perform the
+ * processing for the preferences tab when the user selects the "Data Layers" tab.
+ **********************************************************************************/
+function showRowsColsPrefs() {
+ //Turn off all tabs
+ hideAllPrefs();
+ //Turn on layer prefs tab
+ var rowsColsBtn = document.getElementById("prefRowsCols_btn");
+ rowsColsBtn.setAttribute('src', staticPath + 'images/rowsColsOn.png');
+ var rowsColsDiv = document.getElementById("rowsColsPrefs");
+ rowsColsDiv.style.display="block";
+}
+
+
+/**********************************************************************************
+ * FUNCTION - showLayerPrefs: The purpose of this function is to perform the
+ * processing for the preferences tab when the user selects the "Data Layers" tab.
+ **********************************************************************************/
+function showLayerPrefs() {
+ //Turn off all tabs
+ hideAllPrefs();
+ //Turn on layer prefs tab
+ var layerBtn = document.getElementById("prefLayer_btn");
+ layerBtn.setAttribute('src', staticPath + 'images/dataLayersOn.png');
+ var layerDiv = document.getElementById("layerPrefs");
+ layerDiv.style.display="block";
+}
+
+/**********************************************************************************
+ * FUNCTION - showClassPrefs: The purpose of this function is to perform the
+ * processing for the preferences tab when the user selects the "Covariates" tab.
+ **********************************************************************************/
+function showClassPrefs() {
+ //Turn off all tabs
+ hideAllPrefs();
+ //Turn on classification prefs tab
+ var classBtn = document.getElementById("prefClass_btn");
+ classBtn.setAttribute('src', staticPath + 'images/covariateBarsOn.png');
+ var classDiv = document.getElementById("classPrefs");
+ classDiv.style.display="block";
+}
+
+/**********************************************************************************
+ * FUNCTION - hideAllPrefs: The purpose of this function is to set all tabs off. It
+ * is called whenever a tab is clicked. All tabs are set to hidden with their
+ * image set to the "off" image.
+ **********************************************************************************/
+function hideAllPrefs() {
+ var classBtn = document.getElementById("prefClass_btn");
+ classBtn.setAttribute('src', staticPath + 'images/covariateBarsOff.png');
+ var classDiv = document.getElementById("classPrefs");
+ classDiv.style.display="none";
+ var layerBtn = document.getElementById("prefLayer_btn");
+ layerBtn.setAttribute('src', staticPath + 'images/dataLayersOff.png');
+ var layerDiv = document.getElementById("layerPrefs");
+ layerDiv.style.display="none";
+ var rowsColsBtn = document.getElementById("prefRowsCols_btn");
+ rowsColsBtn.setAttribute('src', staticPath + 'images/rowsColsOff.png');
+ var rowsColsDiv = document.getElementById("rowsColsPrefs");
+ rowsColsDiv.style.display="none";
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsCancelButton: The purpose of this function is to perform all processing
+ * necessary to exit the user preferences dialog WITHOUT applying or saving any
+ * changes made by the user when the Cancel button is pressed on the ColorMap
+ * preferences dialog. Since the dataLayer colormap must be edited to add/delete
+ * breakpoints, the backup colormap (saved when preferences are first opened) is re-
+ * applied to the colorMapManager. Then the preferences DIV is retrieved and removed.
+ **********************************************************************************/
+function prefsCancelButton() {
+ if (bkpColorMap !== null) {
+ var colorMapMgr = heatMap.getColorMapManager();
+ colorMapMgr.setColorMap("dl1", bkpColorMap);
+ }
+ var prefspanel = document.getElementById('prefsPanel');
+ if (prefspanel){
+ prefspanel.remove();
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsApplyButton: The purpose of this function is to perform all processing
+ * necessary to reconfigure the "current" presentation of the heat map in the
+ * viewer when the Apply button is pressed on the ColorMap Preferences Dialog.
+ * First validations are performed. If errors are found, preference
+ * changes are NOT applied and the user is re-presented with the preferences dialog
+ * and the error found. If no errors are found, all changes are applied to the heatmap
+ * and the summary panel, detail panel, and covariate bars are redrawn. However,
+ * these changes are not yet permanently saved to the JSON files that are used to
+ * configure heat map presentation.
+ **********************************************************************************/
+function prefsApplyButton() {
+ //Perform validations of all user-entered data layer and covariate bar
+ //preference changes.
+ var errorMsg = prefsValidate();
+ prefsApply();
+ if (errorMsg !== null) {
+ prefsError(errorMsg);
+ } else {
+ prefsSuccess();
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsSaveButton: The purpose of this function is to perform all processing
+ * necessary to permanently save user preference changes. This will result in
+ * changes to the JSON files that are used to configure heat map presentation.
+ **********************************************************************************/
+function prefsSaveButton() {
+ var mode = heatMap.mode;
+ var errorMsg = prefsValidate();
+ prefsApply();
+ if (errorMsg !== null) {
+ prefsError(errorMsg);
+ } else {
+ var success = heatMap.saveHeatMapProperties();
+ if (success === "false") {
+ prefsError(["dl1", "layerPrefs", "ERROR: Preferences failed to save. Use Apply or Cancel to continue."]);
+ } else {
+ prefsSuccess();
+ }
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsSuccess: The purpose of this function perform the functions
+ * necessary when preferences are determined to be valid. It is shared by the
+ * Apply and Save buttons.
+ **********************************************************************************/
+function prefsSuccess() {
+ filterVal = null;
+ //Remove the backup color map (used to reinstate colors if user cancels)
+ //and formally apply all changes to the heat map, re-draw, and exit preferences.
+ bkpColorMap = null;
+ summaryInit();
+ detailInit();
+ changeMode('NORMAL');
+ prefsCancelButton();
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsError: The purpose of this function perform the functions
+ * necessary when preferences are determined to be invalid. It is shared by the
+ * Apply and Save buttons.
+ **********************************************************************************/
+function prefsError(errorMsg) {
+ //If a validation error exists, re-present the user preferences
+ //dialog with the error message displayed in red.
+ var prefspanel = document.getElementById('prefsPanel');
+ if (prefspanel){
+ prefspanel.remove();
+ }
+ editPreferences(document.getElementById('gear_btn'),errorMsg);
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsSuccess: The purpose of this function is to apply all user
+ * ColorMap preferences settings. It is shared by the Apply and Save buttons.
+ **********************************************************************************/
+function prefsApply() {
+ // Apply Row & Column Preferences
+ var dendrogram = heatMap.getDendrogram();
+ var rowLabels = heatMap.getRowLabels();
+ var rowOrder = rowLabels['order_method'];
+ if (rowOrder === "Hierarchical") {
+ var rowDendroShowVal = document.getElementById("rowDendroShowPref").value;
+ dendrogram['row_dendro_show'] = rowDendroShowVal;
+ dendrogram['row_dendro_height'] = document.getElementById("rowDendroHeightPref").value;
+ }
+ var colLabels = heatMap.getColLabels();
+ var colOrder = colLabels['order_method'];
+ if (colOrder === "Hierarchical") {
+ var colDendroShowVal = document.getElementById("colDendroShowPref").value;
+ dendrogram['col_dendro_show'] = colDendroShowVal;
+ dendrogram['col_dendro_height'] = document.getElementById("colDendroHeightPref").value;
+ }
+ // Apply Covariate Bar Preferences
+ var classBars = heatMap.getClassifications();
+ for (var key in classBars){
+ var showElement = document.getElementById(key+"_showPref");
+ var heightElement = document.getElementById(key+"_heightPref");
+ if (filterShow(key)) {
+ heatMap.setClassificationPrefs(key,showElement.checked,heightElement.value);
+ } else {
+ heatMap.setClassificationPrefs(key,false,15);
+ }
+ prefsApplyBreaks(classBars[key].colorScheme,"covariate",filterShow(key));
+ }
+ // Apply Data Layer Preferences
+ //TODO - Future loop for data layers
+ prefsApplyBreaks("dl1","datalayer",true);
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsValidate: The purpose of this function is to validate all user
+ * changes to the heatmap properties. When the very first error is found, an error
+ * message (string array containing error information) is created and returned to
+ * the prefsApply function.
+ **********************************************************************************/
+function prefsValidate() {
+ var classBars = heatMap.getClassifications();
+ var errorMsg = null;
+ //Loop thru all covariate classfication bars validating all break colors
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var showElement = document.getElementById(key+"_showPref");
+ var heightElement = document.getElementById(key+"_heightPref");
+ errorMsg = prefsValidateBreakColors(classBars[key].colorScheme,"classPrefs");
+ if (errorMsg !== null) break;
+ }
+ }
+ //Validate all breakpoints and colors for the main data layer
+ if (errorMsg === null) {
+ //TODO: currently only processing for data layer 1. This will require modification
+ // when new data layers (e.g. flicks) are added to the heatmap.
+ errorMsg = prefsValidateBreakPoints("dl1","layerPrefs");
+ if (errorMsg === null) {
+ errorMsg = prefsValidateBreakColors("dl1","layerPrefs");
+ }
+ }
+ return errorMsg;
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsValidateBreakPoints: The purpose of this function is to validate
+ * all user breakpoint and color changes to heatmap data layer properties. When the
+ * first error is found, an error message (string array containing error information)
+ * is created and returned to the prefsApply function.
+ **********************************************************************************/
+function prefsValidateBreakPoints(colorMapName,prefPanel) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var dupeBreak = false;
+ var breakOrder = false;
+ var prevBreakValue = -99999;
+ var errorMsg = null;
+ //Loop thru colormap thresholds and validate for order and duplicates
+ for (var i = 0; i < thresholds.length; i++) {
+ var breakElement = document.getElementById(colorMapName+"_breakPt"+i+"_breakPref");
+ //If current breakpoint is not greater than previous, throw order error
+ if (parseInt(breakElement.value) < prevBreakValue) {
+ breakOrder = true;
+ break;
+ }
+ //Loop thru thresholds, skipping current element, searching for a match to the
+ //current selection. If found, throw duplicate error
+ for (var j = 0; j < thresholds.length; j++) {
+ var be = document.getElementById(colorMapName+"_breakPt"+j+"_breakPref");
+ if (i != j) {
+ if (breakElement.value === be.value) {
+ dupeBreak = true;
+ break;
+ }
+ }
+ }
+ }
+ if (breakOrder) {
+ errorMsg = [colorMapName, prefPanel, "ERROR: Data layer breakpoints must be in order"];
+ }
+ if (dupeBreak) {
+ errorMsg = [colorMapName, prefPanel, "ERROR: Duplicate data layer breakpoint found above"];
+ }
+ return errorMsg;
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsValidateBreakColors: The purpose of this function is to validate
+ * all user color changes to heatmap classification and data layer properties. When the
+ * first error is found, an error message (string array containing error information)
+ * is created and returned to the prefsApply function.
+ **********************************************************************************/
+function prefsValidateBreakColors(colorMapName,prefPanel) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var dupeColor = false;
+ for (var i = 0; i < colors.length; i++) {
+ var colorElement = document.getElementById(colorMapName+"_color"+i+"_colorPref");
+ for (var j = 0; j < thresholds.length; j++) {
+ var ce = document.getElementById(colorMapName+"_color"+j+"_colorPref");
+ if (i != j) {
+ if (colorElement.value === ce.value) {
+ dupeColor = true;
+ break;
+ }
+ }
+ }
+ }
+ if (dupeColor) {
+ return [colorMapName, prefPanel, "ERROR: Duplicate color setting found above"];
+ }
+ return null;
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsApplyBreaks: The purpose of this function is to apply all
+ * user entered changes to colors and breakpoints.
+ **********************************************************************************/
+function prefsApplyBreaks(colorMapName, colorMapType, show) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ if (show) {
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var newColors = getNewBreakColors(colorMapName);
+ colorMap.setColors(newColors);
+ if (colorMapType === "datalayer") {
+ var newThresholds = getNewBreakThresholds(colorMapName);
+ colorMap.setThresholds(newThresholds);
+ }
+ var missingElement = document.getElementById(colorMapName+"_missing_colorPref");
+ colorMap.setMissingColor(missingElement.value);
+ var colorMapMgr = heatMap.getColorMapManager();
+ colorMapMgr.setColorMap(colorMapName, colorMap);
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - getNewBreakColors: The purpose of this function is to grab all user
+ * color entries for a given colormap and place them on a string array. It will
+ * iterate thru the screen elements, pulling the current color entry for each
+ * element, placing it in a new array, and returning that array. This function is
+ * called by the prefsApplyBreaks function. It is ALSO called from the data layer
+ * addLayerBreak and deleteLayerBreak functions with parameters passed in for
+ * the position to add/delete and the action to be performed (add/delete).
+ **********************************************************************************/
+function getNewBreakColors(colorMapName, pos, action) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var newColors = [];
+ for (var j = 0; j < thresholds.length; j++) {
+ var colorElement = document.getElementById(colorMapName+"_color"+j+"_colorPref");
+ //If being called from addLayerBreak or deleteLayerBreak
+ if (typeof pos !== 'undefined') {
+ if (action === "add") {
+ newColors.push(colorElement.value);
+ if (j === pos) {
+ newColors.push(colorElement.value);
+ }
+ } else {
+ if (j !== pos) {
+ newColors.push(colorElement.value);
+ }
+ }
+ } else {
+ newColors.push(colorElement.value);
+ }
+ }
+ return newColors;
+}
+
+/**********************************************************************************
+ * FUNCTION - getNewBreakThresholds: The purpose of this function is to grab all user
+ * data layer breakpoint entries for a given colormap and place them on a string array.
+ * It will iterate thru the screen elements, pulling the current breakpoint entry for each
+ * element, placing it in a new array, and returning that array. This function is
+ * called by the prefsApplyBreaks function (only for data layers). It is ALSO called
+ * from the data layer addLayerBreak and deleteLayerBreak functions with parameters
+ * passed in for the position to add/delete and the action to be performed (add/delete).
+ **********************************************************************************/
+function getNewBreakThresholds(colorMapName, pos, action) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var newThresholds = [];
+ for (var j = 0; j < thresholds.length; j++) {
+ var breakElement = document.getElementById(colorMapName+"_breakPt"+j+"_breakPref");
+ if (typeof pos !== 'undefined') {
+ if (action === "add") {
+ newThresholds.push(breakElement.value);
+ if (j === pos) {
+ newThresholds.push(breakElement.value);
+ }
+ } else {
+ if (j !== pos) {
+ newThresholds.push(breakElement.value);
+ }
+ }
+ } else {
+ newThresholds.push(breakElement.value);
+ }
+ }
+ return newThresholds;
+}
+
+/*===================================================================================
+ * DATA LAYER PREFERENCE PROCESSING FUNCTIONS
+ *
+ * The following functions are utilized to present heat map data layer
+ * configuration options:
+ * - setupLayerPrefs
+ * - setupLayerBreaks
+ * - setupLayerPrefs
+ * - addLayerBreak
+ * - deleteLayerBreak
+ * - reloadLayerBreaksColorMap
+ =================================================================================*/
+
+/**********************************************************************************
+ * FUNCTION - setupLayerPrefs: The purpose of this function is to construct a DIV
+ * panel containing all data layer preferences. A dropdown list containing all
+ * data layers is presented and individual DIVs for each data layer, containing
+ * breakpoints/colors, are added.
+ **********************************************************************************/
+function setupLayerPrefs(e, prefprefs){
+ var layerprefs = getDivElement("layerPrefs");
+ var prefContents = document.createElement("TABLE");
+ var colorMapName = "dl1";
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ // TODO Future: primary and flick data layers in dropdown
+ var dlSelect = ""
+ setTableRow(prefContents,["Data Layer: ", dlSelect]);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ layerprefs.appendChild(prefContents);
+ var breakprefs = setupLayerBreaks(e, colorMapName, colorMapName);
+ breakprefs.style.display="block";
+ breakprefs.style.width = 300;
+ layerprefs.appendChild(breakprefs);
+ maxRows = maxRows+3;
+ // TODO Future: loop for primary and flick data layers
+ return layerprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - setupLayerBreaks: The purpose of this function is to construct a DIV
+ * containing a list of breakpoints/colors for a given matrix data layer.
+ **********************************************************************************/
+function setupLayerBreaks(e, mapName, barName, barType){
+ var classBars = heatMap.getClassifications();
+ var colorMap = heatMap.getColorMapManager().getColorMap(mapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var helpprefs = getDivElement("breakPrefs_"+mapName);
+ var prefContents = document.createElement("TABLE");
+ var rowCtr = 0;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Breakpoint", ""+"Color"+""," "]);
+ rowCtr++;
+ for (var j = 0; j < thresholds.length; j++) {
+ var threshold = thresholds[j];
+ var color = colors[j];
+ var threshId = mapName+"_breakPt"+j;
+ var colorId = mapName+"_color"+j;
+ var breakPtInput = "";
+ var colorInput = "";
+ var addButton = "
"
+ var delButton = "
"
+ if (j === 0) {
+ setTableRow(prefContents, [breakPtInput, colorInput, addButton]);
+ } else {
+ setTableRow(prefContents, [breakPtInput, colorInput, addButton, delButton]);
+ }
+ rowCtr++;
+ }
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Missing Color:", ""]);
+ rowCtr++;
+ if (rowCtr > maxRows) {
+ maxRows = rowCtr;
+ }
+ helpprefs.style.height = rowCtr;
+ helpprefs.style.width = 30;
+ helpprefs.appendChild(prefContents);
+ return helpprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - addLayerBreak: The purpose of this function is to add a breakpoint
+ * row to a data layer colormap. A new row is created using the preceding row as a
+ * template (i.e. breakpt value and color same as row clicked on).
+ **********************************************************************************/
+function addLayerBreak(pos,colorMapName) {
+ //Retrieve colormap for data layer
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var newThresholds = getNewBreakThresholds(colorMapName, pos,"add");
+ var newColors = getNewBreakColors(colorMapName, pos,"add");
+ //Calculate new size of data layers panel and reset size of the
+ // entire preferences dialog (if necessary)
+ var layerRows = newThresholds.length+helpRowSize;
+ maxRows = Math.max(maxRows,layerRows);
+ setPrefsDivSizing();
+ //Apply new arrays for thresholds and colors to the datalayer
+ //and reload the colormap.
+ colorMap.setThresholds(newThresholds);
+ colorMap.setColors(newColors);
+ reloadLayerBreaksColorMap(colorMapName, colorMap);
+}
+
+/**********************************************************************************
+ * FUNCTION - deleteLayerBreak: The purpose of this function is to remove a breakpoint
+ * row from a data layer colormap.
+ **********************************************************************************/
+function deleteLayerBreak(pos,colorMapName) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var newThresholds = getNewBreakThresholds(colorMapName, pos,"delete");
+ var newColors = getNewBreakColors(colorMapName, pos,"delete");
+ //Apply new arrays for thresholds and colors to the datalayer
+ //and reload the colormap.
+ colorMap.setThresholds(newThresholds);
+ colorMap.setColors(newColors);
+ reloadLayerBreaksColorMap(colorMapName, colorMap);
+}
+
+/**********************************************************************************
+ * FUNCTION - reloadLayerBreaksColorMap: The purpose of this function is to reload
+ * the colormap for a given data layer. The add/deleteLayerBreak methods call
+ * this common function. The layerPrefs DIV is retrieved and the setupLayerBreaks
+ * method is called, passing in the newly edited colormap.
+ **********************************************************************************/
+function reloadLayerBreaksColorMap(colorMapName, colorMap) {
+ var e = document.getElementById('gear_btn')
+ var colorMapMgr = heatMap.getColorMapManager();
+ colorMapMgr.setColorMap(colorMapName, colorMap);
+ var breakPrefs = document.getElementById('breakPrefs_'+colorMapName);
+ if (breakPrefs){
+ breakPrefs.remove();
+ }
+ var layerprefs = getDivElement("layerPrefs");
+ var breakPrefs = setupLayerBreaks(e, colorMapName, colorMapName);
+ breakPrefs.style.display="block";
+ breakPrefs.style.width = 300;
+ layerPrefs.appendChild(breakPrefs);
+}
+
+/*===================================================================================
+ * COVARIATE CLASSIFICATION PREFERENCE PROCESSING FUNCTIONS
+ *
+ * The following functions are utilized to present heat map covariate classfication
+ * bar configuration options:
+ * - setupClassPrefs
+ * - setupClassBreaks
+ * - setupAllClassesPrefs
+ * - showAllBars
+ * - setShowAll
+ =================================================================================*/
+
+/**********************************************************************************
+ * FUNCTION - setupClassPrefs: The purpose of this function is to construct a DIV
+ * panel containing all covariate bar preferences. A dropdown list containing all
+ * covariate classification bars is presented and individual DIVs for each data layer,
+ * containing breakpoints/colors, are added. Additionally, a "front panel" DIV is
+ * created for "ALL" classification bars that contains preferences that are global
+ * to all of the individual bars.
+ **********************************************************************************/
+function setupClassPrefs(e, prefprefs){
+ var classBars = heatMap.getClassifications();
+ var classprefs = getDivElement("classPrefs");
+ var prefContents = document.createElement("TABLE");
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var filterInput = "";
+ var filterButton = "
";
+ if (filterVal != null) {
+ var filterInput = "";
+ var filterButton = "
";
+ }
+ var searchClasses = filterInput+" "+filterButton;
+ setTableRow(prefContents,[searchClasses], 4, 'right');
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var classSelect = ""
+ setTableRow(prefContents,["Covariate Bar: ", classSelect]);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ classprefs.appendChild(prefContents);
+ var i = 0;
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var breakprefs = setupClassBreaks(e, classBars[key].colorScheme, key);
+ breakprefs.style.display="none";
+ breakprefs.style.width = 300;
+ classprefs.appendChild(breakprefs);
+ }
+ i++;
+ }
+ // Append a DIV panel for all of the covariate class bars
+ var allPrefs = setupAllClassesPrefs(e);
+ allPrefs.style.display="block";
+ classprefs.appendChild(allPrefs);
+ return classprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - setupClassBreaks: The purpose of this function is to construct a DIV
+ * containing a list of all covariate bars with informational data and user preferences
+ * that are common to all bars (show/hide and size).
+ **********************************************************************************/
+function setupAllClassesPrefs(e){
+ var allprefs = getDivElement("breakPrefs_ALL");
+ var prefContents = document.createElement("TABLE");
+ var rowCtr = 0;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var colShowAll = " ";
+ setTableRow(prefContents,[""+"Classification"+"", ""+"Position"+"", colShowAll+""+"Show"+"", ""+"Height"+""]);
+ rowCtr=2;
+ var classBars = heatMap.getClassifications();
+ var checkState = true;
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var colShow = " ";
+ var colHeight = "";
+ setTableRow(prefContents,[key,toTitleCase(classBars[key].position),colShow,colHeight]);
+ rowCtr++;
+ }
+ }
+ allprefs.appendChild(prefContents);
+ if (rowCtr > maxRows) {
+ maxRows = rowCtr;
+ }
+ return allprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - setupClassBreaks: The purpose of this function is to construct a DIV
+ * containing a set informational data and a list of categories/colors for a given
+ * covariate classfication bar.
+ **********************************************************************************/
+function setupClassBreaks(e, mapName, barName){
+ var classBars = heatMap.getClassifications();
+ var colorMap = heatMap.getColorMapManager().getColorMap(mapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var helpprefs = getDivElement("breakPrefs_"+mapName);
+ var prefContents = document.createElement("TABLE");
+ var rowCtr = 0;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var colShow = "";
+ var colHeight = "";
+ var pos = toTitleCase(classBars[barName].position);
+ var typ = toTitleCase(colorMap.getType());
+ if (classBars[barName].position == "row") {
+ pos = "Row";
+ }
+ setTableRow(prefContents,["Bar Position: ",""+pos+""]);
+ setTableRow(prefContents,["Bar Type: ",""+typ+""]);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr = rowCtr+4;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Category", ""+"Color"+""]);
+ rowCtr++;
+ for (var j = 0; j < thresholds.length; j++) {
+ var threshold = thresholds[j];
+ var color = colors[j];
+ var threshId = mapName+"_breakPt"+j;
+ var colorId = mapName+"_color"+j;
+ var colorInput = "";
+ setTableRow(prefContents, [threshold, colorInput]);
+ rowCtr++;
+ }
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Missing Color:", ""]);
+ rowCtr++;
+ if (rowCtr > maxRows) {
+ maxRows = rowCtr;
+ }
+ helpprefs.style.height = rowCtr;
+ helpprefs.style.width = 30;
+ helpprefs.appendChild(prefContents);
+ return helpprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - showAllBars: The purpose of this function is to set the condition of
+ * the "show" checkbox for all covariate bars on the covariate bars tab of the user
+ * preferences dialog. These checkboxes are located on the DIV that is visible when
+ * the ALL entry of the covariate dropdown is selected. Whenever a user checks the
+ * show all box, all other boxes are checked.
+ **********************************************************************************/
+function showAllBars(){
+ var classBars = heatMap.getClassifications();
+ var showAllBox = document.getElementById('all_showPref');
+ var checkState = false;
+ if (showAllBox.checked) {
+ checkState = true;
+ }
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var colShow = document.getElementById(key+'_showPref');
+ colShow.checked = checkState;
+ }
+ }
+ return;
+}
+
+/**********************************************************************************
+ * FUNCTION - setShowAll: The purpose of this function is to set the condition of
+ * the "show all" checkbox on the covariate bars tab of the user preferences dialog.
+ * This checkbox is located on the DIV that is visible when the ALL entry of the
+ * covariate dropdown is selected. If a user un-checks a single box in the list of
+ * covariate bars, the show all box is un-checked. Conversely, if a user checks a box
+ * resulting in all of the boxes being selected, the show all box will be checked.
+ **********************************************************************************/
+function setShowAll(){
+ var classBars = heatMap.getClassifications();
+ var checkState = true;
+ for (var key in classBars){
+ var colShow = document.getElementById(key+'_showPref');
+ if (filterShow(key)) {
+ if (!colShow.checked) {
+ checkState = false;
+ break;
+ }
+ }
+ }
+ var showAllBox = document.getElementById('all_showPref');
+ showAllBox.checked = checkState;
+ return;
+}
+
+
+/**********************************************************************************
+ * FUNCTION - showClassBreak: The purpose of this function is to show the
+ * appropriate classification bar panel based upon the user selection of the
+ * covariate dropdown on the covariates tab of the preferences screen. This
+ * function is also called when an error is trappped, opening the covariate DIV
+ * that contains the erroneous data entry.
+ **********************************************************************************/
+function showClassBreak(selClass) {
+ var classBtn = document.getElementById("classPref_list");
+ if (typeof selClass != 'undefined') {
+ classBtn.value = selClass;
+ }
+ for (var i=0; i
";
+ if (heatMap.isSaveAllowed()) {
+ buttons = buttons + "
";
+ }
+ setTableRow(prefButtons,[""]);
+ rowCtr++;
+ prefprefs.appendChild(prefButtons);
+
+ //Add prefspanel table to the main preferences DIV and set position and display
+ prefspanel.appendChild(prefContents);
+ prefspanel.style.position = "absolute";
+ prefspanel.style.top = e.offsetTop + 15;
+ prefspanel.style.display="inherit";
+
+ //maxRows has been loaded with a count of the datalayer/class panel with the most rows
+ //add to this the number of rows added during construction of prefspanel table.
+ maxRows = maxRows+rowCtr;
+ //Retrieve maximum row height size used in various preferences DIVs
+ helpRowSize = parseFloat(getStyle(prefspanel, 'font-size' ), 10)*1.45;
+ //Use the two above numbers to apply sizing to all of the preferences DIVs.
+ setPrefsDivSizing();
+ prefspanel.style.left = e.offsetLeft - parseInt(layerprefs.style.width,10);
+
+ //If errors exist and they are NOT on the currently visible DIV (dataLayer1),
+ //hide the dataLayers DIV, set the tab to "Covariates", and open the appropriate
+ //covariate bar DIV.
+ showDendroSelections();
+ setShowAll();
+ if ((errorMsg != null) && (errorMsg[1] === "classPrefs")) {
+ showClassBreak(errorMsg[0]);
+ showClassPrefs();
+ } else if ((errorMsg != null) && (errorMsg[1] === "layerPrefs")){
+ showLayerPrefs();
+ } else if (searchPerformed){
+ searchPerformed = false;
+ showClassPrefs();
+ } else {
+ showRowsColsPrefs();
+ }
+
+}
+
+/**********************************************************************************
+ * FUNCTION - setPrefsDivSizing: The purpose of this function is to resize the
+ * various DIVs inside the preferences dialog. It is called when the dialog is
+ * first opened and whenever data layer breakpoints are added (if necessary).
+ **********************************************************************************/
+//TODO - This can be improved as the current sizing is not exact.
+function setPrefsDivSizing() {
+ var rowsColsprefs = document.getElementById("rowsColsPrefs");
+ var layerprefs = document.getElementById("layerPrefs");
+ var classprefs = document.getElementById("classPrefs");
+ var helprefs = document.getElementById("prefsPanel");
+ var prefHeight = maxRows*helpRowSize;
+ var prefWidth = 380;
+ rowsColsprefs.style.width = prefWidth;
+ rowsColsprefs.style.height = prefHeight;
+ layerprefs.style.width = prefWidth;
+ layerprefs.style.height = prefHeight;
+ classprefs.style.width = prefWidth;
+ classprefs.style.height = prefHeight;
+}
+
+/**********************************************************************************
+ * FUNCTION - showLayerPrefs: The purpose of this function is to perform the
+ * processing for the preferences tab when the user selects the "Data Layers" tab.
+ **********************************************************************************/
+function showRowsColsPrefs() {
+ //Turn off all tabs
+ hideAllPrefs();
+ //Turn on layer prefs tab
+ var rowsColsBtn = document.getElementById("prefRowsCols_btn");
+ rowsColsBtn.setAttribute('src', staticPath + 'images/rowsColsOn.png');
+ var rowsColsDiv = document.getElementById("rowsColsPrefs");
+ rowsColsDiv.style.display="block";
+}
+
+
+/**********************************************************************************
+ * FUNCTION - showLayerPrefs: The purpose of this function is to perform the
+ * processing for the preferences tab when the user selects the "Data Layers" tab.
+ **********************************************************************************/
+function showLayerPrefs() {
+ //Turn off all tabs
+ hideAllPrefs();
+ //Turn on layer prefs tab
+ var layerBtn = document.getElementById("prefLayer_btn");
+ layerBtn.setAttribute('src', staticPath + 'images/dataLayersOn.png');
+ var layerDiv = document.getElementById("layerPrefs");
+ layerDiv.style.display="block";
+}
+
+/**********************************************************************************
+ * FUNCTION - showClassPrefs: The purpose of this function is to perform the
+ * processing for the preferences tab when the user selects the "Covariates" tab.
+ **********************************************************************************/
+function showClassPrefs() {
+ //Turn off all tabs
+ hideAllPrefs();
+ //Turn on classification prefs tab
+ var classBtn = document.getElementById("prefClass_btn");
+ classBtn.setAttribute('src', staticPath + 'images/covariateBarsOn.png');
+ var classDiv = document.getElementById("classPrefs");
+ classDiv.style.display="block";
+}
+
+/**********************************************************************************
+ * FUNCTION - hideAllPrefs: The purpose of this function is to set all tabs off. It
+ * is called whenever a tab is clicked. All tabs are set to hidden with their
+ * image set to the "off" image.
+ **********************************************************************************/
+function hideAllPrefs() {
+ var classBtn = document.getElementById("prefClass_btn");
+ classBtn.setAttribute('src', staticPath + 'images/covariateBarsOff.png');
+ var classDiv = document.getElementById("classPrefs");
+ classDiv.style.display="none";
+ var layerBtn = document.getElementById("prefLayer_btn");
+ layerBtn.setAttribute('src', staticPath + 'images/dataLayersOff.png');
+ var layerDiv = document.getElementById("layerPrefs");
+ layerDiv.style.display="none";
+ var rowsColsBtn = document.getElementById("prefRowsCols_btn");
+ rowsColsBtn.setAttribute('src', staticPath + 'images/rowsColsOff.png');
+ var rowsColsDiv = document.getElementById("rowsColsPrefs");
+ rowsColsDiv.style.display="none";
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsCancelButton: The purpose of this function is to perform all processing
+ * necessary to exit the user preferences dialog WITHOUT applying or saving any
+ * changes made by the user when the Cancel button is pressed on the ColorMap
+ * preferences dialog. Since the dataLayer colormap must be edited to add/delete
+ * breakpoints, the backup colormap (saved when preferences are first opened) is re-
+ * applied to the colorMapManager. Then the preferences DIV is retrieved and removed.
+ **********************************************************************************/
+function prefsCancelButton() {
+ if (bkpColorMap !== null) {
+ var colorMapMgr = heatMap.getColorMapManager();
+ colorMapMgr.setColorMap("dl1", bkpColorMap);
+ }
+ var prefspanel = document.getElementById('prefsPanel');
+ if (prefspanel){
+ prefspanel.remove();
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsApplyButton: The purpose of this function is to perform all processing
+ * necessary to reconfigure the "current" presentation of the heat map in the
+ * viewer when the Apply button is pressed on the ColorMap Preferences Dialog.
+ * First validations are performed. If errors are found, preference
+ * changes are NOT applied and the user is re-presented with the preferences dialog
+ * and the error found. If no errors are found, all changes are applied to the heatmap
+ * and the summary panel, detail panel, and covariate bars are redrawn. However,
+ * these changes are not yet permanently saved to the JSON files that are used to
+ * configure heat map presentation.
+ **********************************************************************************/
+function prefsApplyButton() {
+ //Perform validations of all user-entered data layer and covariate bar
+ //preference changes.
+ var errorMsg = prefsValidate();
+ prefsApply();
+ if (errorMsg !== null) {
+ prefsError(errorMsg);
+ } else {
+ prefsSuccess();
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsSaveButton: The purpose of this function is to perform all processing
+ * necessary to permanently save user preference changes. This will result in
+ * changes to the JSON files that are used to configure heat map presentation.
+ **********************************************************************************/
+function prefsSaveButton() {
+ var mode = heatMap.mode;
+ var errorMsg = prefsValidate();
+ prefsApply();
+ if (errorMsg !== null) {
+ prefsError(errorMsg);
+ } else {
+ var success = heatMap.saveHeatMapProperties();
+ if (success === "false") {
+ prefsError(["dl1", "layerPrefs", "ERROR: Preferences failed to save. Use Apply or Cancel to continue."]);
+ } else {
+ prefsSuccess();
+ }
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsSuccess: The purpose of this function perform the functions
+ * necessary when preferences are determined to be valid. It is shared by the
+ * Apply and Save buttons.
+ **********************************************************************************/
+function prefsSuccess() {
+ filterVal = null;
+ //Remove the backup color map (used to reinstate colors if user cancels)
+ //and formally apply all changes to the heat map, re-draw, and exit preferences.
+ bkpColorMap = null;
+ summaryInit();
+ detailInit();
+ changeMode('NORMAL');
+ prefsCancelButton();
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsError: The purpose of this function perform the functions
+ * necessary when preferences are determined to be invalid. It is shared by the
+ * Apply and Save buttons.
+ **********************************************************************************/
+function prefsError(errorMsg) {
+ //If a validation error exists, re-present the user preferences
+ //dialog with the error message displayed in red.
+ var prefspanel = document.getElementById('prefsPanel');
+ if (prefspanel){
+ prefspanel.remove();
+ }
+ editPreferences(document.getElementById('gear_btn'),errorMsg);
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsSuccess: The purpose of this function is to apply all user
+ * ColorMap preferences settings. It is shared by the Apply and Save buttons.
+ **********************************************************************************/
+function prefsApply() {
+ // Apply Row & Column Preferences
+ var dendrogram = heatMap.getDendrogram();
+ var rowLabels = heatMap.getRowLabels();
+ var rowOrder = rowLabels['order_method'];
+ if (rowOrder === "Hierarchical") {
+ var rowDendroShowVal = document.getElementById("rowDendroShowPref").value;
+ dendrogram['row_dendro_show'] = rowDendroShowVal;
+ dendrogram['row_dendro_height'] = document.getElementById("rowDendroHeightPref").value;
+ }
+ var colLabels = heatMap.getColLabels();
+ var colOrder = colLabels['order_method'];
+ if (colOrder === "Hierarchical") {
+ var colDendroShowVal = document.getElementById("colDendroShowPref").value;
+ dendrogram['col_dendro_show'] = colDendroShowVal;
+ dendrogram['col_dendro_height'] = document.getElementById("colDendroHeightPref").value;
+ }
+ // Apply Covariate Bar Preferences
+ var classBars = heatMap.getClassifications();
+ for (var key in classBars){
+ var showElement = document.getElementById(key+"_showPref");
+ var heightElement = document.getElementById(key+"_heightPref");
+ if (filterShow(key)) {
+ heatMap.setClassificationPrefs(key,showElement.checked,heightElement.value);
+ } else {
+ heatMap.setClassificationPrefs(key,false,15);
+ }
+ prefsApplyBreaks(classBars[key].colorScheme,"covariate",filterShow(key));
+ }
+ // Apply Data Layer Preferences
+ //TODO - Future loop for data layers
+ prefsApplyBreaks("dl1","datalayer",true);
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsValidate: The purpose of this function is to validate all user
+ * changes to the heatmap properties. When the very first error is found, an error
+ * message (string array containing error information) is created and returned to
+ * the prefsApply function.
+ **********************************************************************************/
+function prefsValidate() {
+ var classBars = heatMap.getClassifications();
+ var errorMsg = null;
+ //Loop thru all covariate classfication bars validating all break colors
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var showElement = document.getElementById(key+"_showPref");
+ var heightElement = document.getElementById(key+"_heightPref");
+ errorMsg = prefsValidateBreakColors(classBars[key].colorScheme,"classPrefs");
+ if (errorMsg !== null) break;
+ }
+ }
+ //Validate all breakpoints and colors for the main data layer
+ if (errorMsg === null) {
+ //TODO: currently only processing for data layer 1. This will require modification
+ // when new data layers (e.g. flicks) are added to the heatmap.
+ errorMsg = prefsValidateBreakPoints("dl1","layerPrefs");
+ if (errorMsg === null) {
+ errorMsg = prefsValidateBreakColors("dl1","layerPrefs");
+ }
+ }
+ return errorMsg;
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsValidateBreakPoints: The purpose of this function is to validate
+ * all user breakpoint and color changes to heatmap data layer properties. When the
+ * first error is found, an error message (string array containing error information)
+ * is created and returned to the prefsApply function.
+ **********************************************************************************/
+function prefsValidateBreakPoints(colorMapName,prefPanel) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var dupeBreak = false;
+ var breakOrder = false;
+ var prevBreakValue = -99999;
+ var errorMsg = null;
+ //Loop thru colormap thresholds and validate for order and duplicates
+ for (var i = 0; i < thresholds.length; i++) {
+ var breakElement = document.getElementById(colorMapName+"_breakPt"+i+"_breakPref");
+ //If current breakpoint is not greater than previous, throw order error
+ if (parseInt(breakElement.value) < prevBreakValue) {
+ breakOrder = true;
+ break;
+ }
+ //Loop thru thresholds, skipping current element, searching for a match to the
+ //current selection. If found, throw duplicate error
+ for (var j = 0; j < thresholds.length; j++) {
+ var be = document.getElementById(colorMapName+"_breakPt"+j+"_breakPref");
+ if (i != j) {
+ if (breakElement.value === be.value) {
+ dupeBreak = true;
+ break;
+ }
+ }
+ }
+ }
+ if (breakOrder) {
+ errorMsg = [colorMapName, prefPanel, "ERROR: Data layer breakpoints must be in order"];
+ }
+ if (dupeBreak) {
+ errorMsg = [colorMapName, prefPanel, "ERROR: Duplicate data layer breakpoint found above"];
+ }
+ return errorMsg;
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsValidateBreakColors: The purpose of this function is to validate
+ * all user color changes to heatmap classification and data layer properties. When the
+ * first error is found, an error message (string array containing error information)
+ * is created and returned to the prefsApply function.
+ **********************************************************************************/
+function prefsValidateBreakColors(colorMapName,prefPanel) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var dupeColor = false;
+ for (var i = 0; i < colors.length; i++) {
+ var colorElement = document.getElementById(colorMapName+"_color"+i+"_colorPref");
+ for (var j = 0; j < thresholds.length; j++) {
+ var ce = document.getElementById(colorMapName+"_color"+j+"_colorPref");
+ if (i != j) {
+ if (colorElement.value === ce.value) {
+ dupeColor = true;
+ break;
+ }
+ }
+ }
+ }
+ if (dupeColor) {
+ return [colorMapName, prefPanel, "ERROR: Duplicate color setting found above"];
+ }
+ return null;
+}
+
+/**********************************************************************************
+ * FUNCTION - prefsApplyBreaks: The purpose of this function is to apply all
+ * user entered changes to colors and breakpoints.
+ **********************************************************************************/
+function prefsApplyBreaks(colorMapName, colorMapType, show) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ if (show) {
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var newColors = getNewBreakColors(colorMapName);
+ colorMap.setColors(newColors);
+ if (colorMapType === "datalayer") {
+ var newThresholds = getNewBreakThresholds(colorMapName);
+ colorMap.setThresholds(newThresholds);
+ }
+ var missingElement = document.getElementById(colorMapName+"_missing_colorPref");
+ colorMap.setMissingColor(missingElement.value);
+ var colorMapMgr = heatMap.getColorMapManager();
+ colorMapMgr.setColorMap(colorMapName, colorMap);
+ }
+}
+
+/**********************************************************************************
+ * FUNCTION - getNewBreakColors: The purpose of this function is to grab all user
+ * color entries for a given colormap and place them on a string array. It will
+ * iterate thru the screen elements, pulling the current color entry for each
+ * element, placing it in a new array, and returning that array. This function is
+ * called by the prefsApplyBreaks function. It is ALSO called from the data layer
+ * addLayerBreak and deleteLayerBreak functions with parameters passed in for
+ * the position to add/delete and the action to be performed (add/delete).
+ **********************************************************************************/
+function getNewBreakColors(colorMapName, pos, action) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var newColors = [];
+ for (var j = 0; j < thresholds.length; j++) {
+ var colorElement = document.getElementById(colorMapName+"_color"+j+"_colorPref");
+ //If being called from addLayerBreak or deleteLayerBreak
+ if (typeof pos !== 'undefined') {
+ if (action === "add") {
+ newColors.push(colorElement.value);
+ if (j === pos) {
+ newColors.push(colorElement.value);
+ }
+ } else {
+ if (j !== pos) {
+ newColors.push(colorElement.value);
+ }
+ }
+ } else {
+ newColors.push(colorElement.value);
+ }
+ }
+ return newColors;
+}
+
+/**********************************************************************************
+ * FUNCTION - getNewBreakThresholds: The purpose of this function is to grab all user
+ * data layer breakpoint entries for a given colormap and place them on a string array.
+ * It will iterate thru the screen elements, pulling the current breakpoint entry for each
+ * element, placing it in a new array, and returning that array. This function is
+ * called by the prefsApplyBreaks function (only for data layers). It is ALSO called
+ * from the data layer addLayerBreak and deleteLayerBreak functions with parameters
+ * passed in for the position to add/delete and the action to be performed (add/delete).
+ **********************************************************************************/
+function getNewBreakThresholds(colorMapName, pos, action) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var newThresholds = [];
+ for (var j = 0; j < thresholds.length; j++) {
+ var breakElement = document.getElementById(colorMapName+"_breakPt"+j+"_breakPref");
+ if (typeof pos !== 'undefined') {
+ if (action === "add") {
+ newThresholds.push(breakElement.value);
+ if (j === pos) {
+ newThresholds.push(breakElement.value);
+ }
+ } else {
+ if (j !== pos) {
+ newThresholds.push(breakElement.value);
+ }
+ }
+ } else {
+ newThresholds.push(breakElement.value);
+ }
+ }
+ return newThresholds;
+}
+
+/*===================================================================================
+ * DATA LAYER PREFERENCE PROCESSING FUNCTIONS
+ *
+ * The following functions are utilized to present heat map data layer
+ * configuration options:
+ * - setupLayerPrefs
+ * - setupLayerBreaks
+ * - setupLayerPrefs
+ * - addLayerBreak
+ * - deleteLayerBreak
+ * - reloadLayerBreaksColorMap
+ =================================================================================*/
+
+/**********************************************************************************
+ * FUNCTION - setupLayerPrefs: The purpose of this function is to construct a DIV
+ * panel containing all data layer preferences. A dropdown list containing all
+ * data layers is presented and individual DIVs for each data layer, containing
+ * breakpoints/colors, are added.
+ **********************************************************************************/
+function setupLayerPrefs(e, prefprefs){
+ var layerprefs = getDivElement("layerPrefs");
+ var prefContents = document.createElement("TABLE");
+ var colorMapName = "dl1";
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ // TODO Future: primary and flick data layers in dropdown
+ var dlSelect = ""
+ setTableRow(prefContents,["Data Layer: ", dlSelect]);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ layerprefs.appendChild(prefContents);
+ var breakprefs = setupLayerBreaks(e, colorMapName, colorMapName);
+ breakprefs.style.display="block";
+ breakprefs.style.width = 300;
+ layerprefs.appendChild(breakprefs);
+ maxRows = maxRows+3;
+ // TODO Future: loop for primary and flick data layers
+ return layerprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - setupLayerBreaks: The purpose of this function is to construct a DIV
+ * containing a list of breakpoints/colors for a given matrix data layer.
+ **********************************************************************************/
+function setupLayerBreaks(e, mapName, barName, barType){
+ var classBars = heatMap.getClassifications();
+ var colorMap = heatMap.getColorMapManager().getColorMap(mapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var helpprefs = getDivElement("breakPrefs_"+mapName);
+ var prefContents = document.createElement("TABLE");
+ var rowCtr = 0;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Breakpoint", ""+"Color"+""," "]);
+ rowCtr++;
+ for (var j = 0; j < thresholds.length; j++) {
+ var threshold = thresholds[j];
+ var color = colors[j];
+ var threshId = mapName+"_breakPt"+j;
+ var colorId = mapName+"_color"+j;
+ var breakPtInput = "";
+ var colorInput = "";
+ var addButton = "
"
+ var delButton = "
"
+ if (j === 0) {
+ setTableRow(prefContents, [breakPtInput, colorInput, addButton]);
+ } else {
+ setTableRow(prefContents, [breakPtInput, colorInput, addButton, delButton]);
+ }
+ rowCtr++;
+ }
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Missing Color:", ""]);
+ rowCtr++;
+ if (rowCtr > maxRows) {
+ maxRows = rowCtr;
+ }
+ helpprefs.style.height = rowCtr;
+ helpprefs.style.width = 30;
+ helpprefs.appendChild(prefContents);
+ return helpprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - addLayerBreak: The purpose of this function is to add a breakpoint
+ * row to a data layer colormap. A new row is created using the preceding row as a
+ * template (i.e. breakpt value and color same as row clicked on).
+ **********************************************************************************/
+function addLayerBreak(pos,colorMapName) {
+ //Retrieve colormap for data layer
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var newThresholds = getNewBreakThresholds(colorMapName, pos,"add");
+ var newColors = getNewBreakColors(colorMapName, pos,"add");
+ //Calculate new size of data layers panel and reset size of the
+ // entire preferences dialog (if necessary)
+ var layerRows = newThresholds.length+helpRowSize;
+ maxRows = Math.max(maxRows,layerRows);
+ setPrefsDivSizing();
+ //Apply new arrays for thresholds and colors to the datalayer
+ //and reload the colormap.
+ colorMap.setThresholds(newThresholds);
+ colorMap.setColors(newColors);
+ reloadLayerBreaksColorMap(colorMapName, colorMap);
+}
+
+/**********************************************************************************
+ * FUNCTION - deleteLayerBreak: The purpose of this function is to remove a breakpoint
+ * row from a data layer colormap.
+ **********************************************************************************/
+function deleteLayerBreak(pos,colorMapName) {
+ var colorMap = heatMap.getColorMapManager().getColorMap(colorMapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var newThresholds = getNewBreakThresholds(colorMapName, pos,"delete");
+ var newColors = getNewBreakColors(colorMapName, pos,"delete");
+ //Apply new arrays for thresholds and colors to the datalayer
+ //and reload the colormap.
+ colorMap.setThresholds(newThresholds);
+ colorMap.setColors(newColors);
+ reloadLayerBreaksColorMap(colorMapName, colorMap);
+}
+
+/**********************************************************************************
+ * FUNCTION - reloadLayerBreaksColorMap: The purpose of this function is to reload
+ * the colormap for a given data layer. The add/deleteLayerBreak methods call
+ * this common function. The layerPrefs DIV is retrieved and the setupLayerBreaks
+ * method is called, passing in the newly edited colormap.
+ **********************************************************************************/
+function reloadLayerBreaksColorMap(colorMapName, colorMap) {
+ var e = document.getElementById('gear_btn')
+ var colorMapMgr = heatMap.getColorMapManager();
+ colorMapMgr.setColorMap(colorMapName, colorMap);
+ var breakPrefs = document.getElementById('breakPrefs_'+colorMapName);
+ if (breakPrefs){
+ breakPrefs.remove();
+ }
+ var layerprefs = getDivElement("layerPrefs");
+ var breakPrefs = setupLayerBreaks(e, colorMapName, colorMapName);
+ breakPrefs.style.display="block";
+ breakPrefs.style.width = 300;
+ layerPrefs.appendChild(breakPrefs);
+}
+
+/*===================================================================================
+ * COVARIATE CLASSIFICATION PREFERENCE PROCESSING FUNCTIONS
+ *
+ * The following functions are utilized to present heat map covariate classfication
+ * bar configuration options:
+ * - setupClassPrefs
+ * - setupClassBreaks
+ * - setupAllClassesPrefs
+ * - showAllBars
+ * - setShowAll
+ =================================================================================*/
+
+/**********************************************************************************
+ * FUNCTION - setupClassPrefs: The purpose of this function is to construct a DIV
+ * panel containing all covariate bar preferences. A dropdown list containing all
+ * covariate classification bars is presented and individual DIVs for each data layer,
+ * containing breakpoints/colors, are added. Additionally, a "front panel" DIV is
+ * created for "ALL" classification bars that contains preferences that are global
+ * to all of the individual bars.
+ **********************************************************************************/
+function setupClassPrefs(e, prefprefs){
+ var classBars = heatMap.getClassifications();
+ var classprefs = getDivElement("classPrefs");
+ var prefContents = document.createElement("TABLE");
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var filterInput = "";
+ var filterButton = "
";
+ if (filterVal != null) {
+ var filterInput = "";
+ var filterButton = "
";
+ }
+ var searchClasses = filterInput+" "+filterButton;
+ setTableRow(prefContents,[searchClasses], 4, 'right');
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var classSelect = ""
+ setTableRow(prefContents,["Covariate Bar: ", classSelect]);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ classprefs.appendChild(prefContents);
+ var i = 0;
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var breakprefs = setupClassBreaks(e, classBars[key].colorScheme, key);
+ breakprefs.style.display="none";
+ breakprefs.style.width = 300;
+ classprefs.appendChild(breakprefs);
+ }
+ i++;
+ }
+ // Append a DIV panel for all of the covariate class bars
+ var allPrefs = setupAllClassesPrefs(e);
+ allPrefs.style.display="block";
+ classprefs.appendChild(allPrefs);
+ return classprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - setupClassBreaks: The purpose of this function is to construct a DIV
+ * containing a list of all covariate bars with informational data and user preferences
+ * that are common to all bars (show/hide and size).
+ **********************************************************************************/
+function setupAllClassesPrefs(e){
+ var allprefs = getDivElement("breakPrefs_ALL");
+ var prefContents = document.createElement("TABLE");
+ var rowCtr = 0;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var colShowAll = " ";
+ setTableRow(prefContents,[""+"Classification"+"", ""+"Position"+"", colShowAll+""+"Show"+"", ""+"Height"+""]);
+ rowCtr=2;
+ var classBars = heatMap.getClassifications();
+ var checkState = true;
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var colShow = " ";
+ var colHeight = "";
+ setTableRow(prefContents,[key,toTitleCase(classBars[key].position),colShow,colHeight]);
+ rowCtr++;
+ }
+ }
+ allprefs.appendChild(prefContents);
+ if (rowCtr > maxRows) {
+ maxRows = rowCtr;
+ }
+ return allprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - setupClassBreaks: The purpose of this function is to construct a DIV
+ * containing a set informational data and a list of categories/colors for a given
+ * covariate classfication bar.
+ **********************************************************************************/
+function setupClassBreaks(e, mapName, barName){
+ var classBars = heatMap.getClassifications();
+ var colorMap = heatMap.getColorMapManager().getColorMap(mapName);
+ var thresholds = colorMap.getThresholds();
+ var colors = colorMap.getColors();
+ var helpprefs = getDivElement("breakPrefs_"+mapName);
+ var prefContents = document.createElement("TABLE");
+ var rowCtr = 0;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ var colShow = "";
+ var colHeight = "";
+ var pos = toTitleCase(classBars[barName].position);
+ var typ = toTitleCase(colorMap.getType());
+ if (classBars[barName].position == "row") {
+ pos = "Row";
+ }
+ setTableRow(prefContents,["Bar Position: ",""+pos+""]);
+ setTableRow(prefContents,["Bar Type: ",""+typ+""]);
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr = rowCtr+4;
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Category", ""+"Color"+""]);
+ rowCtr++;
+ for (var j = 0; j < thresholds.length; j++) {
+ var threshold = thresholds[j];
+ var color = colors[j];
+ var threshId = mapName+"_breakPt"+j;
+ var colorId = mapName+"_color"+j;
+ var colorInput = "";
+ setTableRow(prefContents, [threshold, colorInput]);
+ rowCtr++;
+ }
+ prefContents.insertRow().innerHTML = formatBlankRow();
+ rowCtr++;
+ setTableRow(prefContents, ["Missing Color:", ""]);
+ rowCtr++;
+ if (rowCtr > maxRows) {
+ maxRows = rowCtr;
+ }
+ helpprefs.style.height = rowCtr;
+ helpprefs.style.width = 30;
+ helpprefs.appendChild(prefContents);
+ return helpprefs;
+}
+
+/**********************************************************************************
+ * FUNCTION - showAllBars: The purpose of this function is to set the condition of
+ * the "show" checkbox for all covariate bars on the covariate bars tab of the user
+ * preferences dialog. These checkboxes are located on the DIV that is visible when
+ * the ALL entry of the covariate dropdown is selected. Whenever a user checks the
+ * show all box, all other boxes are checked.
+ **********************************************************************************/
+function showAllBars(){
+ var classBars = heatMap.getClassifications();
+ var showAllBox = document.getElementById('all_showPref');
+ var checkState = false;
+ if (showAllBox.checked) {
+ checkState = true;
+ }
+ for (var key in classBars){
+ if (filterShow(key)) {
+ var colShow = document.getElementById(key+'_showPref');
+ colShow.checked = checkState;
+ }
+ }
+ return;
+}
+
+/**********************************************************************************
+ * FUNCTION - setShowAll: The purpose of this function is to set the condition of
+ * the "show all" checkbox on the covariate bars tab of the user preferences dialog.
+ * This checkbox is located on the DIV that is visible when the ALL entry of the
+ * covariate dropdown is selected. If a user un-checks a single box in the list of
+ * covariate bars, the show all box is un-checked. Conversely, if a user checks a box
+ * resulting in all of the boxes being selected, the show all box will be checked.
+ **********************************************************************************/
+function setShowAll(){
+ var classBars = heatMap.getClassifications();
+ var checkState = true;
+ for (var key in classBars){
+ var colShow = document.getElementById(key+'_showPref');
+ if (filterShow(key)) {
+ if (!colShow.checked) {
+ checkState = false;
+ break;
+ }
+ }
+ }
+ var showAllBox = document.getElementById('all_showPref');
+ showAllBox.checked = checkState;
+ return;
+}
+
+
+/**********************************************************************************
+ * FUNCTION - showClassBreak: The purpose of this function is to show the
+ * appropriate classification bar panel based upon the user selection of the
+ * covariate dropdown on the covariates tab of the preferences screen. This
+ * function is also called when an error is trappped, opening the covariate DIV
+ * that contains the erroneous data entry.
+ **********************************************************************************/
+function showClassBreak(selClass) {
+ var classBtn = document.getElementById("classPref_list");
+ if (typeof selClass != 'undefined') {
+ classBtn.value = selClass;
+ }
+ for (var i=0; i