/*!
mason_viewer.js
github.com/yeastrc/mason
The Mason Viewer is created by calling MasonViewer.createMasonViewer = function ( $rootDiv, requestParams, configParams, callbackFunctionsObj ) {
where MasonViewer is an object at window.MasonViewer.
configParams is merged with the following parameters
MasonViewerPerInstanceRenderOnPage.prototype.configDisplayOptionDefaults = {
TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE : 2,
LABEL_FONT_SIZE : 12,
ROW_HEIGHT : 15, // Adjust the ROW_HEIGHT to accommodate the height of the label
BLOCK_HEIGHT : 14, // Adjust the BLOCK_HEIGHT to accommodate the height of the label
LABEL_WIDTH : 100, // Adjust the LABEL_WIDTH to accommodate the width of the longest label
ICON_EXPAND_ROW_STARTING_POSITION : 1,
ICON_EXPAND_ROW_WIDTH : 15,
ICON_EXPAND_ROW_SPACE_AFTER : 2,
ROW_TOTALS_BAR_RIGHT_MAX_WIDTH : 30,
ROW_TOTAL_BLOCK_MINIMUM_SIZE : 1,
ROW_TOTALS_BAR_RIGHT_SPACE_FROM_MAIN_GRID : 10,
ROW_TOTALS_BAR_RIGHT_SPACE_FROM_RIGHT_EDGE : 4,
BORDER_COLOR : "black",
BORDER_WIDTH : 1,
FOOTER_HEIGHT : 2,
// Tool tip text
CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT_PREFIX : "Click to hide individual ",
CLICK_TO_EXPAND_TO_SHOW_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT_PREFIX : "Click to show individual ",
blockTypeLabelPlural : "blocks",
BLOCK_HIGHLIGHT_BORDER_COLOR : "pink",
BLOCK_HIGHLIGHT_BORDER_WIDTH : 2,
createCombinedLineOnly : undefined, // set to true to only create combined line
skipCreateCombinedLine : undefined, // set to true to skip create combined line
combinedLineLabel : "Combined", // label on left for combined line
combinedLineTooltipHTML : undefined, // tool tip for label on left for combined line
ALIGNMENT_LINE_COLOR : "black",
ALIGNMENT_LINE_WIDTH : 2
};
*/
// mason_viewer_05_start_outer_enclosing_function.js
// !!!!!!!! IMPORTANT, only include this file when building the combined file !!!!!!!!!!!!!!!!!!!!!!!!!
// This file is expected to get a compile error.
// The matching closing "}" is in the file mason_viewer_95_end_outer_enclosing_function.js
// All the files: mason_viewer_01 thru mason_viewer_95 are to be included in the order they are numbered
// If including directly into the page for testing, skip mason_viewer_01 and mason_viewer_95
(function( window ) {
// masonViewerMain.js
// This is the main class to call to create a MasonViewer
// Depends on jquery, wtootip.js, Modernizr SVG support detection
// and particularly svg.js
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
////////////////////////////////////////////
// Constructor
var MasonViewer = function () {
};
MasonViewer.prototype.instanceCounter = 0;
// create a new Mason Viewer object
MasonViewer.prototype.createMasonViewer = function ( $rootDiv, requestParams, configParams, callbackFunctionsObj ) {
if ( $rootDiv === undefined || $rootDiv === null ) {
throw "$rootDiv is missing or null";
}
if ( requestParams === undefined || requestParams === null ) {
throw "requestParams is missing or null";
}
if ( configParams === undefined || configParams === null ) {
throw "configParams is missing or null";
}
if ( callbackFunctionsObj === undefined || callbackFunctionsObj === null ) {
throw "callbackFunctionsObj is missing or null";
}
var rootDivLength = $rootDiv.length;
if ( rootDivLength != 1 ) {
throw "Error calling 'MasonViewer.createMasonViewer': $rootDiv must contain exactly one element";
}
var svgSupport = Modernizr.svg;
if ( ! svgSupport ) { // is false if SVG not supported
throw "SVG not supported";
}
this.instanceCounter++;
var internalParams = { masonViewerMain: this, instanceCounter: this.instanceCounter };
var masonViewerInstance = new MasonViewerPerInstance ( $rootDiv, requestParams, configParams, callbackFunctionsObj, internalParams );
return masonViewerInstance;
};
// Get the "label" used to store the MasonViewer object in the DOM object
MasonViewer.prototype.getDataElement = function() {
return "MasonViewer";
};
// Get the "class" used to store the MasonViewer object in the DOM object of the root div
MasonViewer.prototype.getProtCovObjectStorageClassName = function() {
return "ProtCovObjectStorageClass";
};
var MasonViewer = new MasonViewer(); // Declare MasonViewer namespace
// assign to window in preparation for when surround with overall function to hide everything else
window.MasonViewer = MasonViewer;
// mason_viewer_constants.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
//
//MasonViewerPerInstance.prototype.CONSTANTS.COLOR_MIN() = function() {
//
// return 0;
//};
//
//MasonViewerPerInstance.prototype.CONSTANTS.COLOR_MAX() = function() {
//
// return 255;
//};
// mason_viewer_per_instance.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
////////////////////////////////////////////
// Constructor
// internal "class" constructor to create actual stored instance object
var MasonViewerPerInstance = function ( $rootDiv, requestParams, configParams, callbackFunctionsObj, internalParams ) {
var objectThis = this; // copy for use in local functions
var rootDivLength = $rootDiv.length;
if ( rootDivLength != 1 ) {
throw "Error calling 'MasonViewer.createMasonViewer': $rootDiv must contain exactly one element";
}
var masonViewerMain = internalParams.masonViewerMain;
////////////////////////////////////////
// The following code is not in a function. It runs immediately when the constructor is run.
// Add a sub div to the DOM to attach this instance to.
// By attaching this instance to a sub div, calling jquery.empty() on the $rootDiv will release this instance for garbage collection
var protCovObjectStorageNodeHTML = '
';
// Still call the .appendTo for the change to $rootDiv, just not save the result
// var $protCovObjectStorageNodeHTML =
$( protCovObjectStorageNodeHTML ).appendTo( $rootDiv );
// Look up the node this way to ensure it is findable since use the same technique for other operations
var protCovObjectStorageNodeSelector = "." + masonViewerMain.getProtCovObjectStorageClassName();
var $protCovObjectStorageNode = $rootDiv.children( protCovObjectStorageNodeSelector );
if ( $protCovObjectStorageNode.size() === 0 ) {
throw "Unable to find protCovObjectStorageNode under $rootDiv, protCovObjectStorageNodeSelector = " + protCovObjectStorageNodeSelector;
}
// attach the newly created object to the DOM object that is a child of the id provided
$protCovObjectStorageNode.data( masonViewerMain.getDataElement(), this );
// create the viewer and render it on the page
// create MasonViewer Instance
// var startTimeTracking = (new Date).getTime();
var dataReformattedToInternalFormat = objectThis.reformatDataToInternalFormat( requestParams );
// var timeTrackingDiffReformatToInternalFormat = (new Date).getTime() - startTimeTracking;
var computedRepresentation = objectThis.computeRepresentation( $rootDiv, dataReformattedToInternalFormat, requestParams, configParams );
// var timeTrackingDiffComputedRepresentation = (new Date).getTime() - startTimeTracking;
objectThis.renderViewerOnThePage( $rootDiv, computedRepresentation, requestParams, configParams, callbackFunctionsObj, internalParams );
// var timeTrackingDiffRenderViewerOnThePage = (new Date).getTime() - startTimeTracking;
// alert( "timeTrackingDiffReformatToInternalFormat: " + timeTrackingDiffReformatToInternalFormat +
// ", timeTrackingDiffComputedRepresentation: " + timeTrackingDiffComputedRepresentation +
// ", timeTrackingDiffRenderViewerOnThePage: " + timeTrackingDiffRenderViewerOnThePage );
};
MasonViewerPerInstance.prototype.renderViewerOnThePage =
function( $rootDiv, data, requestParams, configParams,
callbackFunctionsObj, internalParams ) {
var objectThisMasonViewerPerInstanceCopy = this; // copy for use in local functions
this.masonViewerPerInstanceRenderOnPage = new MasonViewerPerInstanceRenderOnPage( $rootDiv, data, requestParams, configParams,
callbackFunctionsObj, internalParams, objectThisMasonViewerPerInstanceCopy );
this.masonViewerPerInstanceRenderOnPage.renderViewerOnThePageMain();
};
//////////////////////////////////
MasonViewerPerInstance.prototype.MESSAGE_TYPE_RENDER_ON_PAGE = "RENDER_ON_PAGE";
MasonViewerPerInstance.prototype.hideVerticalDataLines = function( ) {
this.masonViewerPerInstanceRenderOnPage.hideVerticalDataLines();
};
MasonViewerPerInstance.prototype.showVerticalDataLines = function( ) {
this.masonViewerPerInstanceRenderOnPage.showVerticalDataLines();
};
MasonViewerPerInstance.prototype.deleteViewer = function( ) {
this.masonViewerPerInstanceRenderOnPage.deleteViewer();
};
// Accept a message from MasonViewerRegistry
MasonViewerPerInstance.prototype.acceptMessage = function( message ) {
if ( message.type === MasonViewerPerInstance.prototype.MESSAGE_TYPE_RENDER_ON_PAGE ) {
this.masonViewerPerInstanceRenderOnPage.acceptMessage( message.data );
} else {
throw "unknown type in message at 'MasonViewerPerInstance.prototype.acceptMessage'. type: " + message.type;
}
};
// TODO maybe rename this method
MasonViewerPerInstance.prototype.registerBlockHoverListener = function( params ) {
this.masonViewerPerInstanceRenderOnPage.registerBlockHoverListener( params );
};
// mason_viewer_compute_representation.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
// Input:
// requestParams
// = {
// };
//
// var dataReformattedToInternalFormat
// = { "maxSequenceLength": 255,
// "rowItems": [
// {"label":"BBpilabel1",
// "blockItems": [
// {
// "blockDataItems": [ {"level":42,"id":85,"otherData":"TheOtherData"} ],
// "blockStartPos":25,
// "blockEndPos":37
// }
// ]
// }
// ]
// }
// Output
// computedData
// = { outputRows:
// [
// { label: "",
// splitAnyEntries: true or false,
// blockItems: [ as copied from input ],
// mainLineBlocks:
// [
// {
// blockStartPos: 10,
// blockEndPos: 15,
// blockDataItems: [ {"id":85,"otherData":"TheOtherData"} ]
// }
// ]
// }
// ]
// };
// An element of outputRows is one row in the output including the label, main line of blocks or overlapping blocks, and hidden blocks
// Take the input params and compute an output to be rendered on the page
MasonViewerPerInstance.prototype.computeRepresentation = function( $rootDiv, dataReformattedToInternalFormat, requestParams, configParams ) {
var objectThis = this; // copy for use in local functions
var computedData = { outputRows: [] };
var outputRows = computedData.outputRows;
var inputData = dataReformattedToInternalFormat;
var rowItems = inputData.rowItems;
for ( var rowItemsIndex = 0; rowItemsIndex < rowItems.length; rowItemsIndex++ ) {
var rowItem = rowItems[ rowItemsIndex ];
var blockItems = rowItem.blockItems;
var splitOutput = objectThis.combineOverlapsProteinPositionBased( blockItems );
var mainLineBlocks = splitOutput.outputList;
var outputRow = { label: rowItem.label , mainLineBlocks: mainLineBlocks, blockItems: blockItems,
splitAnyEntries: splitOutput.splitAnyEntries, inputRowItem: rowItem.inputRowItem, vertLinesItems: rowItem.vertLinesItems };
outputRows.push( outputRow );
}
return computedData;
};
// mason_viewer_35_process_overlapping_blocks.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
/*
* Sort by start position ascending then end position descending
*/
MasonViewerPerInstance.prototype.combineOverlaps_Z_compareForSortBlocks = function( a, b ) {
if ( a.blockStartPos === b.blockStartPos ) {
return b.blockEndPos - a.blockEndPos;
}
return a.blockStartPos - b.blockStartPos;
};
/*
* Shallow Copy Array
*/
MasonViewerPerInstance.prototype.copyArray = function( inputArray ) {
var outputArray = inputArray.concat();
return outputArray;
};
/*
* Shallow Concat Two Arrays
*/
MasonViewerPerInstance.prototype.concatArrays = function( inputArray1, inputArray2 ) {
var outputArray = inputArray1.concat( inputArray2 );
return outputArray;
};
/////////////////////////////////////////////////////////////////
MasonViewerPerInstance.prototype.combineOverlapsProteinPositionBased = function( blockItemsInputParam ) {
var splitAnyEntries = false;
var splitAnEntryThisIterationOfLoop = true;
var numTimesSplitAnEntryLoop = 0;
var blockItemListInput = null;
// combine entries first to simplify later processing
var blockItemListOutput = this.combineEntriesProteinPositionBased( numTimesSplitAnEntryLoop, blockItemsInputParam );
while ( splitAnEntryThisIterationOfLoop ) {
numTimesSplitAnEntryLoop++;
if ( numTimesSplitAnEntryLoop > 200 ) {
var errorMsg = "combineOverlapsProteinPositionBased(...): numTimesSplitAnEntryLoop > 200 so throwing exception. ";
throw errorMsg;
}
// While entries have been split
splitAnEntryThisIterationOfLoop = false;
blockItemListInput = blockItemListOutput;
blockItemListOutput = [];
// Split entries
blockItemListInput.sort( this.combineOverlaps_Z_compareForSortBlocks );
var index = -1;
while ( ( ++index ) < blockItemListInput.length ) {
var blockItem = blockItemListInput[ index ];
if ( index === ( blockItemListInput.length - 1 ) ) {
// if is last entry( and not processed yet below ), put in output list.
blockItemListOutput.push( blockItem );
} else {
var blockItemNext = blockItemListInput[ index + 1 ];
if ( blockItem.blockEndPos < blockItemNext.blockStartPos ) {
// if not overlap next entry, put in output list.
blockItemListOutput.push( blockItem );
} else {
splitAnEntryThisIterationOfLoop = true;
splitAnyEntries = true;
if ( blockItem.blockStartPos === blockItemNext.blockStartPos ) {
// If same start point, the current entry is longer so split to end of next and what is left
// Split current entry to before next next entry and starts at next entry
var blockItemSplitBefore
= {
blockDataItems: this.copyArray( blockItem.blockDataItems ),
blockStartPos: blockItem.blockStartPos,
blockEndPos: blockItemNext.blockEndPos
};
var blockItemSplitAfter
= {
blockDataItems: this.copyArray( blockItem.blockDataItems ),
blockStartPos: blockItemNext.blockEndPos + 1,
blockEndPos: blockItem.blockEndPos
};
blockItemListOutput.push( blockItemSplitBefore );
blockItemListOutput.push( blockItemSplitAfter );
} else {
// Split current entry to before next entry and starts at next entry
var blockItemSplitBefore
= {
blockDataItems: this.copyArray( blockItem.blockDataItems ),
blockStartPos: blockItem.blockStartPos,
blockEndPos: ( blockItemNext.blockStartPos - 1 )
};
var blockItemSplitAfter
= {
blockDataItems: this.copyArray( blockItem.blockDataItems ),
blockStartPos: blockItemNext.blockStartPos,
blockEndPos: blockItem.blockEndPos
};
blockItemListOutput.push( blockItemSplitBefore );
blockItemListOutput.push( blockItemSplitAfter );
}
}
}
}
blockItemListOutput = this.combineEntriesProteinPositionBased( numTimesSplitAnEntryLoop, blockItemListOutput);
}
var finalOutput = { splitAnyEntries: splitAnyEntries, outputList: blockItemListOutput };
return finalOutput;
};
///////////////////////////////////////////////////
MasonViewerPerInstance.prototype.combineEntriesProteinPositionBased = function( numTimesSplitAnEntryLoop, blockItemListInput ) {
var blockItemListOutput = [];
var index;
blockItemListInput.sort( this.combineOverlaps_Z_compareForSortBlocks );
index = -1;
while ( ( ++index ) < blockItemListInput.length ) {
var blockItem = blockItemListInput[ index ];
if ( index === ( blockItemListInput.length - 1 ) ) {
// if is last entry( and not processed yet below ), put in output list.
blockItemListOutput.push( blockItem );
} else {
var indexNext = index;
while ( ( ++indexNext ) < blockItemListInput.length ) {
var blockItemNext = blockItemListInput[ indexNext ];
if ( blockItem.blockStartPos === blockItemNext.blockStartPos
&& blockItem.blockEndPos === blockItemNext.blockEndPos ) {
index = indexNext;
blockItem.blockDataItems = this.concatArrays( blockItem.blockDataItems, blockItemNext.blockDataItems );
} else {
break;
}
}
blockItemListOutput.push( blockItem );
}
}
return blockItemListOutput;
};
// mason_viewer_reformat_data_to_internal_format.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// Input format
//
// var inputData
// = {"maxSequenceLength": 255,
// "rowItems": [
// {"label":"BBpilabel1",
// "blockItems": [
// {
// "blockData":{"level":42,"id":85"},
// "startPos":25,
// "endPos":37
// }
// ]
// }
// ]
// }
// Output format - move "blockData" to be an element of "blockDataItems" copy positions to new names
//
// var inputData
// = { "maxSequenceLength": 255,
// "rowItems": [
// {"label":"BBpilabel1",
// "blockItems": [
// {
// "blockDataItems": [ {"level":42,"id":85} ],
// "blockStartPos":25,
// "blockEndPos":37
// }
// ]
// }
// ]
// }
/*
* reformat the provided data to the internal format
*/
MasonViewerPerInstance.prototype.reformatDataToInternalFormat = function( requestParams ) {
var inputData = requestParams.inputData;
if ( ! inputData ) {
throw "requestParams.inputData is missing or null";
}
if ( inputData.maxSequenceLength === undefined || inputData.maxSequenceLength === null || typeof inputData.maxSequenceLength !== 'number' ) {
throw "requestParams.inputData.maxSequenceLength is missing or null or is not a number";
}
var outputRowItems = [];
var inputDataReformatted = { maxSequenceLength: inputData.maxSequenceLength, rowItems: outputRowItems, vertLinesAllRowsItems: inputData.vertLinesAllRowsItems };
var rowItems = inputData.rowItems;
if ( ! inputData.rowItems ) {
throw "requestParams.inputData.rowItems is missing or null";
}
if ( inputData.rowItems.length === 0 ) {
throw "requestParams.inputData.rowItems is empty";
}
for ( var rowItemsIdx = 0; rowItemsIdx < rowItems.length; rowItemsIdx++ ) {
var rowItem = rowItems[ rowItemsIdx ];
if ( rowItem.label === undefined || rowItem.label === null || rowItem.label === "" ) {
throw "requestParams.inputData.rowItems.rowItem[ index ].label is missing or null or is empty for index = " + rowItemsIdx;
}
var outputBlockItems = [];
var blockItems = rowItem.blockItems;
if ( ! blockItems ) {
throw "requestParams.inputData.rowItems.rowItem[ index ].blockItems is missing or null for index = " + rowItemsIdx;
}
for ( var blockItemsIdx = 0; blockItemsIdx < blockItems.length; blockItemsIdx++ ) {
var blockItem = blockItems[ blockItemsIdx ];
if ( blockItem.startPos === undefined ) {
throw "requestParams.inputData.rowItems.rowItem[ rowItemsIdx ].blockItem[ blockItemsIdx ] is missing property 'startPos' rowItemsIdx = "
+ rowItemsIdx + ", and blockItemsIdx = " + blockItemsIdx;
}
if ( blockItem.endPos === undefined ) {
throw "requestParams.inputData.rowItems.rowItem[ rowItemsIdx ].blockItem[ blockItemsIdx ] is missing property 'endPos' rowItemsIdx = "
+ rowItemsIdx + ", and blockItemsIdx = " + blockItemsIdx;
}
if ( blockItem.blockData === undefined ) {
throw "requestParams.inputData.rowItems.rowItem[ rowItemsIdx ].blockItem[ blockItemsIdx ] is missing property 'blockData' rowItemsIdx = "
+ rowItemsIdx + ", and blockItemsIdx = " + blockItemsIdx;
}
var outputBlockItem = { blockStartPos: blockItem.startPos, blockEndPos: blockItem.endPos, blockDataItems: [ blockItem.blockData ] };
outputBlockItems.push( outputBlockItem );
}
var outputRowItem = { label: rowItem.label, blockItems: outputBlockItems, inputRowItem: rowItem, vertLinesItems: rowItem.vertLinesItems };
outputRowItems.push( outputRowItem );
}
return inputDataReformatted;
};
// mason_viewer_ProgramaticDataStorage.js
// This is a part of MasonViewer
// Used in the class MasonViewerPerInstanceRenderOnPage
// This file contains the classes ProgramaticDataStorage and ProgramaticDataStorageGroupOfRows
// ProgramaticDataStorage is a class containing data for a given row in the viewer
// ProgramaticDataStorageGroupOfRows is a class containing data for a group of rows
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
//////////////////////////////////////
// Constructor for ProgramaticDataStorageGroupOfRows
// This class contains data for a group of rows in the viewer
var ProgramaticDataStorageGroupOfRows = function () {
this.SVGGroup = undefined; // The SVG JS Group associated with this object
this.firstOutputRowSVGGroup = undefined; // Top level SVG JS object for the top level output row within this group
this.nextProgramaticDataStorageGroupOfRows = undefined; // The ProgramaticDataStorageGroupOfRows object that holds the next group of rows
};
////////
// "getter" and "setter" methods for this class
ProgramaticDataStorageGroupOfRows.prototype.getSVGGroup = function() {
return this.SVGGroup;
};
ProgramaticDataStorageGroupOfRows.prototype.setSVGGroup = function( SVGGroup_ ) {
this.SVGGroup = SVGGroup_;
};
ProgramaticDataStorageGroupOfRows.prototype.getFirstOutputRowSVGGroup = function() {
return this.firstOutputRowSVGGroup;
};
ProgramaticDataStorageGroupOfRows.prototype.setFirstOutputRowSVGGroup = function( firstOutputRowSVGGroup_ ) {
this.firstOutputRowSVGGroup = firstOutputRowSVGGroup_;
};
ProgramaticDataStorageGroupOfRows.prototype.getNextProgramaticDataStorageGroupOfRows = function() {
return this.nextProgramaticDataStorageGroupOfRows;
};
ProgramaticDataStorageGroupOfRows.prototype.setNextProgramaticDataStorageGroupOfRows = function( nextProgramaticDataStorageGroupOfRows_ ) {
this.nextProgramaticDataStorageGroupOfRows = nextProgramaticDataStorageGroupOfRows_;
};
//////////////////////////////////////
// Constructor for ProgramaticDataStorage
// This class contains data for a given row of the viewer
var ProgramaticDataStorage = function () {
this.outputRow = undefined;
this.rowIdx = undefined;
this.rowOffset = undefined;
this.createHiddenBlocksIfNotCreatedCallback = undefined; // calback function
this.SVGRowXmainBlocksGROUP = undefined;
this.groupToMoveForExpansion = undefined;
this.hiddenBlocksVisible = false;
this.hiddenBlocksForRowSet = undefined;
this.hiddenBlocksHeight = 0;
this.SVGGroupExpansionIcon = undefined;
this.mainBlocksBoxUnderEachRow = undefined;
this.hiddenBlocksBoxUnderEachRow = undefined;
this.toolTipHTML = undefined;
};
////////
// "getter" and "setter" methods for this class
ProgramaticDataStorage.prototype.getCreateHiddenBlocksIfNotCreatedCallback = function() {
return this.createHiddenBlocksIfNotCreatedCallback;
};
ProgramaticDataStorage.prototype.setCreateHiddenBlocksIfNotCreatedCallback = function( createHiddenBlocksIfNotCreatedCallback_ ) {
this.createHiddenBlocksIfNotCreatedCallback = createHiddenBlocksIfNotCreatedCallback_;
};
ProgramaticDataStorage.prototype.getOutputRow = function() {
return this.outputRow;
};
ProgramaticDataStorage.prototype.setOutputRow = function( outputRow_ ) {
this.outputRow = outputRow_;
};
ProgramaticDataStorage.prototype.getRowOffset = function() {
return this.rowOffset;
};
ProgramaticDataStorage.prototype.setRowOffset = function( rowOffset_ ) {
this.rowOffset = rowOffset_;
};
ProgramaticDataStorage.prototype.getRowIdx = function() {
return this.rowIdx;
};
ProgramaticDataStorage.prototype.setRowIdx = function( rowIdx_ ) {
this.rowIdx = rowIdx_;
};
ProgramaticDataStorage.prototype.getSVGRowXmainBlocksGROUP = function() {
return this.SVGRowXmainBlocksGROUP;
};
ProgramaticDataStorage.prototype.setSVGRowXmainBlocksGROUP = function( SVGRowXmainBlocksGROUP_ ) {
this.SVGRowXmainBlocksGROUP = SVGRowXmainBlocksGROUP_;
};
ProgramaticDataStorage.prototype.getGroupToMoveForExpansion = function() {
return this.groupToMoveForExpansion;
};
ProgramaticDataStorage.prototype.setGroupToMoveForExpansion = function( groupToMoveForExpansion_ ) {
this.groupToMoveForExpansion = groupToMoveForExpansion_;
};
ProgramaticDataStorage.prototype.getHiddenBlocksVisible = function() {
return this.hiddenBlocksVisible;
};
ProgramaticDataStorage.prototype.setHiddenBlocksVisible = function( hiddenBlocksVisible_ ) {
this.hiddenBlocksVisible = hiddenBlocksVisible_;
};
ProgramaticDataStorage.prototype.getHiddenBlocksForRowSet = function () {
return this.hiddenBlocksForRowSet;
};
ProgramaticDataStorage.prototype.setHiddenBlocksForRowSet = function ( hiddenBlocksForRowSet_ ) {
this.hiddenBlocksForRowSet = hiddenBlocksForRowSet_;
};
ProgramaticDataStorage.prototype.getHiddenBlocksHeight = function () {
return this.hiddenBlocksHeight;
};
ProgramaticDataStorage.prototype.setHiddenBlocksHeight = function ( hiddenBlocksHeight_ ) {
this.hiddenBlocksHeight = hiddenBlocksHeight_;
};
ProgramaticDataStorage.prototype.getSVGGroupExpansionIcon = function () {
return this.SVGGroupExpansionIcon;
};
ProgramaticDataStorage.prototype.setSVGGroupExpansionIcon = function ( SVGGroupExpansionIcon_ ) {
this.SVGGroupExpansionIcon = SVGGroupExpansionIcon_;
};
ProgramaticDataStorage.prototype.getMainBlocksBoxUnderEachRow = function ( ) {
return this.mainBlocksBoxUnderEachRow;
};
ProgramaticDataStorage.prototype.setMainBlocksBoxUnderEachRow = function ( mainBlocksBoxUnderEachRow_ ) {
this.mainBlocksBoxUnderEachRow = mainBlocksBoxUnderEachRow_;
};
ProgramaticDataStorage.prototype.getHiddenBlocksBoxUnderEachRow = function ( ) {
return this.hiddenBlocksBoxUnderEachRow;
};
ProgramaticDataStorage.prototype.setHiddenBlocksBoxUnderEachRow = function ( hiddenBlocksBoxUnderEachRow ) {
this.hiddenBlocksBoxUnderEachRow = hiddenBlocksBoxUnderEachRow;
};
ProgramaticDataStorage.prototype.getToolTipHTML = function ( ) {
return this.toolTipHTML;
};
ProgramaticDataStorage.prototype.setToolTipHTML = function ( toolTipHTML ) {
this.toolTipHTML = toolTipHTML;
};
// mason_viewer_render_on_page.js
// This is a part of MasonViewer
////////////// !!!!!!!!!!!!! Order of calling "precompute" call backs.
/////// For the Main blocks and the Hidden blocks, the precompute is called for each block right before the call to get the color
/////// For the Totals Per Row blocks on the right, the precompute is called for all the rows before the get color and size is called for each block
////// For the Totals Row, the precompute is called for all the rows before the get color is called for each block
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// Visible as attributes in the DOM
// blockBlockSVG.data( "label", { d1: 12, d4: "wwww"} );
// NOT Visible as attributes in the DOM
// blockBlockSVG.remember('oldBBox', { d1: 12, d4: "wwww"} );
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
// computedData
// = { outputRows:
// [
// { label: "",
// splitAnyEntries: true or false,
// blockItems: [ as copied from input ],
// mainLineBlocks:
// [
// {
// blockStartPos: 10,
// blockEndPos: 15,
// blockDataItems: [ {"id":85,"otherData":"TheOtherData"} ]
// }
// ]
// }
// ]
// };
// Add to that datastructure in this code:
// outputRows[ x ].callbackDataStorage
// mainLineBlocks[ x ].callbackDataStorage
// Take the computed data and put it on the page
// Create new class for Render on Page
// Constructor
var MasonViewerPerInstanceRenderOnPage =
function( $rootDiv, data, requestParams, configParams,
callbackFunctionsObj, internalParams, objectThisMasonViewerPerInstance ) {
// this.constructorParams = {
// this.constructorParams.$rootDiv: $rootDiv,
// this.constructorParams.data: data,
// this.constructorParams.requestParams: requestParams,
// this.constructorParams.configParams: configParams,
// this.constructorParams.callbackFunctionsObj: callbackFunctionsObj,
// this.constructorParams.internalParams: internalParams,
// this.constructorParams.objectThisMasonViewerPerInstance: objectThisMasonViewerPerInstance
// };
this.constructorParams = {
$rootDiv: $rootDiv,
data: data,
requestParams: requestParams,
configParams: configParams,
callbackFunctionsObj: callbackFunctionsObj,
internalParams: internalParams,
objectThisMasonViewerPerInstance: objectThisMasonViewerPerInstance
};
this.configDisplayOptions = {};
$.extend( this.configDisplayOptions, MasonViewerPerInstanceRenderOnPage.prototype.configDisplayOptionDefaults, configParams );
// Set additional info on this.configDisplayOptions, derived from other values
this.configDisplayOptions.LABEL_STARTING_POSITION = this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH + this.configDisplayOptions.ICON_EXPAND_ROW_SPACE_AFTER;
this.configDisplayOptions.MAIN_BOX_STARTING_POSITION = this.configDisplayOptions.LABEL_STARTING_POSITION + this.configDisplayOptions.LABEL_WIDTH;
this.configDisplayOptions.CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT = this.configDisplayOptions.CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT_PREFIX + this.configDisplayOptions.blockTypeLabelPlural;
this.configDisplayOptions.CLICK_TO_EXPAND_TO_SHOW_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT = this.configDisplayOptions.CLICK_TO_EXPAND_TO_SHOW_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT_PREFIX + this.configDisplayOptions.blockTypeLabelPlural;
this.GLOBALS = {
masonViewerSVG: undefined,
overallWidth: undefined,
sequenceWidth: undefined,
sequenceMultiplier: undefined,
rowsPerGroup: undefined,
viewerHeightInsideTheBox: undefined,
arrayOfcurrentSVGgroupOfRowXandBelow: [],
setSVGVerticalDataLines: undefined,
setSVGVerticalDataFullHeightLines: undefined,
showVerticalDataLines: true
};
this.GLOBALS.MAIN_BOX_STARTING_POSITION = this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;
};
////////////////////////////////////////
// Main Entry Point Function for this class, called to render the viewer data onto the page
MasonViewerPerInstanceRenderOnPage.prototype. renderViewerOnThePageMain = function( ) {
// var objectThis = this;
this.createSVG_Lib_Instance();
this.putDataOnThePageMain();
this.resizeOverallImageLength();
};
/////////////////////////////
/// Create the SVG object and the root in the DOM
MasonViewerPerInstanceRenderOnPage.prototype. createSVG_Lib_Instance = function( ) {
// var objectThis = this;
var overallWidth = this.constructorParams.$rootDiv.width();
// get the HTML element from jQuery
var masonViewerRootHTML_Element = this.constructorParams.$rootDiv[0];
try {
// Create the SVG main object ( from svg.js file ) which will create the root object on the DOM
this.GLOBALS.masonViewerSVG = SVG( masonViewerRootHTML_Element ).size( overallWidth, 5 ); // TODO Hard coded starting height
} catch ( e ) {
var stracktrace = e.stack;
throw "Exception creating SVG. " + stracktrace;
}
this.GLOBALS.setSVGVerticalDataLines = this.GLOBALS.masonViewerSVG.set();
this.GLOBALS.overallWidth = overallWidth;
this.GLOBALS.rowTotalsBarRightStartingPoint = overallWidth - ( this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_MAX_WIDTH + this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_SPACE_FROM_RIGHT_EDGE );
this.GLOBALS.sequenceWidth = overallWidth - ( this.configDisplayOptions.LABEL_STARTING_POSITION + this.configDisplayOptions.LABEL_WIDTH ) -
( this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_MAX_WIDTH + this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_SPACE_FROM_MAIN_GRID + this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_SPACE_FROM_RIGHT_EDGE );
// this.GLOBALS.sequenceMultiplier = this.GLOBALS.sequenceWidth / ( this.constructorParams.requestParams.inputData.maxSequenceLength - 1),
this.GLOBALS.sequenceMultiplier = this.GLOBALS.sequenceWidth / ( this.constructorParams.requestParams.inputData.maxSequenceLength ),
this.GLOBALS.leftLineX = this.configDisplayOptions.MAIN_BOX_STARTING_POSITION - 0.5;
this.GLOBALS.rightLineX = this.configDisplayOptions.MAIN_BOX_STARTING_POSITION + this.GLOBALS.sequenceWidth + 0.5;
var outputRowsLength = this.constructorParams.data.outputRows.length;
this.GLOBALS.rowsPerGroup = Math.floor( Math.sqrt( outputRowsLength ) );
if ( this.GLOBALS.rowsPerGroup < MasonViewerPerInstanceRenderOnPage.prototype.CONSTANTS.MIN_MAX_VALUES.MINIMUM_ROWS_PER_GROUP ) {
this.GLOBALS.rowsPerGroup = MasonViewerPerInstanceRenderOnPage.prototype.CONSTANTS.MIN_MAX_VALUES.MINIMUM_ROWS_PER_GROUP;
}
if ( MasonViewerPerInstanceRenderOnPage.prototype.CONSTANTS.MIN_MAX_VALUES.MAXIMUM_ROWS_PER_GROUP ) {
if ( this.GLOBALS.rowsPerGroup > MasonViewerPerInstanceRenderOnPage.prototype.CONSTANTS.MIN_MAX_VALUES.MAXIMUM_ROWS_PER_GROUP ) {
this.GLOBALS.rowsPerGroup = MasonViewerPerInstanceRenderOnPage.prototype.CONSTANTS.MIN_MAX_VALUES.MAXIMUM_ROWS_PER_GROUP;
}
}
};
/////////////////////////////
/// Process the data, putting it in the in the DOM
MasonViewerPerInstanceRenderOnPage.prototype. putDataOnThePageMain = function( ) {
// var objectThis = this;
var outputRows = this.constructorParams.data.outputRows;
this.add_callbackDataStorage_ToElementsIn_outputRows( outputRows );
var SVGrootGroupInsideBoundingBox = this.GLOBALS.masonViewerSVG.group();
SVGrootGroupInsideBoundingBox.attr("label", "SVGrootGroupInsideBoundingBox");
// Create a group for a group of rows.
var currentGroupOfRowsSVGgroup = this.GLOBALS.masonViewerSVG.group();
this.setupGroupOfRows( currentGroupOfRowsSVGgroup );
var currentGroupOfRowsSVGgroupProgramaticStorage = this.getProgramaticDataStorageFromSVG_js_Item( currentGroupOfRowsSVGgroup );
SVGrootGroupInsideBoundingBox.add( currentGroupOfRowsSVGgroup );
// Create a group for the row and all rows below it will be enclosed in it
var currentSVGgroupOfRowXandBelow = this.GLOBALS.masonViewerSVG.group();
this.setupRootGroupForEachRow( currentSVGgroupOfRowXandBelow );
var currentSVGgroupOfRowXandBelowProgramaticDataStorage = this.getProgramaticDataStorageFromSVG_js_Item( currentSVGgroupOfRowXandBelow );
currentSVGgroupOfRowXandBelowProgramaticDataStorage._type = "currentSVGgroupOfRowXandBelow";
currentSVGgroupOfRowXandBelowProgramaticDataStorage._attachedTo = currentSVGgroupOfRowXandBelow;
// Only need to add the top level currentSVGgroupOfRowXandBelow for each currentGroupOfRowsSVGgroup
currentGroupOfRowsSVGgroup.add( currentSVGgroupOfRowXandBelow );
currentGroupOfRowsSVGgroupProgramaticStorage.setFirstOutputRowSVGGroup( currentSVGgroupOfRowXandBelow );
var rowOffsetMainArea = 0;
// create totals row at top area
// create only if:
// this.constructorParams.callbackFunctionsObjcallbackFunctionsObj.combinedRow_callbackFunctions is defined
// more than 1 output row or configDisplayOptions.createCombinedLineOnly is true
// configDisplayOptions.skipCreateCombinedLine is false
if ( this.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions &&
( outputRows.length > 1 || this.configDisplayOptions.createCombinedLineOnly ) &&
! this.configDisplayOptions.skipCreateCombinedLine ) {
this.processCombinedRow( outputRows, 0 /* rowCount */, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
// Create group for bottom line and scale
nextSVGgroupOfRowXandBelow = this.GLOBALS.masonViewerSVG.group(); // Create a group for the row and all rows below it will be enclosed in it
nextSVGgroupOfRowXandBelow.attr("label", "nextSVGgroupOfRowXandBelow");
currentSVGgroupOfRowXandBelow.add( nextSVGgroupOfRowXandBelow );
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setGroupToMoveForExpansion( nextSVGgroupOfRowXandBelow );
currentSVGgroupOfRowXandBelow = nextSVGgroupOfRowXandBelow;
this.setupRootGroupForEachRow( currentSVGgroupOfRowXandBelow );
currentSVGgroupOfRowXandBelowProgramaticDataStorage = this.getProgramaticDataStorageFromSVG_js_Item( currentSVGgroupOfRowXandBelow );
currentSVGgroupOfRowXandBelowProgramaticDataStorage._type = "currentSVGgroupOfRowXandBelow";
currentSVGgroupOfRowXandBelowProgramaticDataStorage._attachedTo = currentSVGgroupOfRowXandBelow;
rowOffsetMainArea = 1;
}
this.precomputeValuesOnCreateForMainRows( outputRows ); // ONLY for main totals blocks on the right
var rowCount = 0;
if ( this.configDisplayOptions.createCombinedLineOnly !== true ) {
rowCount = outputRows.length;
for ( var rowIdx = 0; rowIdx < outputRows.length; rowIdx++ ) {
var rowOffset = rowIdx + rowOffsetMainArea;
var outputRow = outputRows[ rowIdx ];
currentSVGgroupOfRowXandBelow.data( "row-rowIdx", rowIdx );
var currentSVGgroupOfRowXandBelowProgramaticDataStorage = this.getProgramaticDataStorageFromSVG_js_Item( currentSVGgroupOfRowXandBelow );
currentSVGgroupOfRowXandBelowProgramaticDataStorage._type = "currentSVGgroupOfRowXandBelow";
currentSVGgroupOfRowXandBelowProgramaticDataStorage._attachedTo = currentSVGgroupOfRowXandBelow;
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setOutputRow( outputRow );
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setRowIdx( rowIdx );
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setRowOffset( rowOffset );
var SVGRowXmainBlocksGROUP = this.GLOBALS.masonViewerSVG.group();
currentSVGgroupOfRowXandBelow.add( SVGRowXmainBlocksGROUP );
SVGRowXmainBlocksGROUP.attr("label", "SVGRowXmainBlocksGROUP");
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setSVGRowXmainBlocksGROUP( SVGRowXmainBlocksGROUP );
this.addBoxUnderEachRowForMouseOver( SVGRowXmainBlocksGROUP, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowOffset );
// var labelTextSVG =
// Still call this.processLabelForRow, just not save the returned value
this.processLabelForRow( outputRow, currentSVGgroupOfRowXandBelow, rowOffset );
var splitAnyEntries = outputRow.splitAnyEntries;
if ( splitAnyEntries ) {
// commented out since moved to called by createMainLineHiddenBlocksIfNotCreatedCallbackCreator(...)
// processHiddenBlocksForRow( outputRow, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowOffset );
this.createMainLineHiddenBlocksIfNotCreatedCallbackCreator( outputRow, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowOffset );
this.createHiddenBlocksExpansionIcon( this.configDisplayOptions.CLICK_TO_EXPAND_TO_SHOW_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT, SVGRowXmainBlocksGROUP, rowOffset, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
}
this.processMainLineBlocksForRow( outputRow, currentSVGgroupOfRowXandBelow, SVGRowXmainBlocksGROUP, rowOffset );
this.processRowTotalBlockForRow( outputRow, currentSVGgroupOfRowXandBelow, rowOffset );
var nextSVGgroupOfRowXandBelow = this.GLOBALS.masonViewerSVG.group(); // Create a group for the next row and all rows below it will be enclosed in it
nextSVGgroupOfRowXandBelow.attr("label", "nextSVGgroupOfRowXandBelow");
this.setupRootGroupForEachRow( nextSVGgroupOfRowXandBelow );
// Only put so many nested groups under this "group of rows"
// so if that is exceeded, create a new "group of rows" and start putting the row groups under that
if ( rowIdx > 0 &&
( rowIdx % this.GLOBALS.rowsPerGroup
=== 0 )
)
{
var nextGroupOfRowsSVGgroup = this.GLOBALS.masonViewerSVG.group();
this.setupGroupOfRows( nextGroupOfRowsSVGgroup );
var nextGroupOfRowsSVGgroupProgramaticStorage = this.getProgramaticDataStorageFromSVG_js_Item( nextGroupOfRowsSVGgroup );
currentGroupOfRowsSVGgroup.add( nextGroupOfRowsSVGgroup );
currentGroupOfRowsSVGgroupProgramaticStorage.setNextProgramaticDataStorageGroupOfRows( nextGroupOfRowsSVGgroupProgramaticStorage );
currentGroupOfRowsSVGgroup = nextGroupOfRowsSVGgroup;
currentGroupOfRowsSVGgroupProgramaticStorage = nextGroupOfRowsSVGgroupProgramaticStorage;
currentGroupOfRowsSVGgroup.add( nextSVGgroupOfRowXandBelow );
currentGroupOfRowsSVGgroupProgramaticStorage.setFirstOutputRowSVGGroup( nextSVGgroupOfRowXandBelow );
} else {
currentSVGgroupOfRowXandBelow.add( nextSVGgroupOfRowXandBelow );
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setGroupToMoveForExpansion( nextSVGgroupOfRowXandBelow );
}
currentSVGgroupOfRowXandBelow = nextSVGgroupOfRowXandBelow;
}
}
// Done processing the rows, add everything else
// Add the vertical lines on a per viewer basis
this.addFullHeightLines();
// currentSVGgroupOfRowXandBelowProgramaticDataStorage = this.getProgramaticDataStorageFromSVG_js_Item( currentSVGgroupOfRowXandBelow );
//
// currentSVGgroupOfRowXandBelowProgramaticDataStorage._type = "currentSVGgroupOfRowXandBelow";
//
// currentSVGgroupOfRowXandBelowProgramaticDataStorage._attachedTo = currentSVGgroupOfRowXandBelow;
// // create totals row at bottom area
//
// if ( outputRows.length > 1 || this.configDisplayOptions.createCombinedLineOnly ) {
//
// processCombinedRow( outputRows, rowCount, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
// }
//
// // Create group for bottom line and scale
//
// nextSVGgroupOfRowXandBelow = this.GLOBALS.masonViewerSVG.group(); // Create a group for the row and all rows below it will be enclosed in it
//
//
// currentSVGgroupOfRowXandBelow.add( nextSVGgroupOfRowXandBelow );
//
// currentSVGgroupOfRowXandBelowProgramaticDataStorage.setGroupToMoveForExpansion( nextSVGgroupOfRowXandBelow );
//
//
// currentSVGgroupOfRowXandBelow = nextSVGgroupOfRowXandBelow;
//
// this.setupRootGroupForEachRow( currentSVGgroupOfRowXandBelow );
//
// currentSVGgroupOfRowXandBelowProgramaticDataStorage = this.getProgramaticDataStorageFromSVG_js_Item( currentSVGgroupOfRowXandBelow );
//
// currentSVGgroupOfRowXandBelowProgramaticDataStorage._type = "currentSVGgroupOfRowXandBelow";
//
// currentSVGgroupOfRowXandBelowProgramaticDataStorage._attachedTo = currentSVGgroupOfRowXandBelow;
// output bottom line and scale
this.addBottomLineAndBottomScale( currentSVGgroupOfRowXandBelow, rowCount );
// add top line
this.addTopLine( SVGrootGroupInsideBoundingBox );
};
////////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. addTopLine = function( currentSVGgroupOfRowXandBelow ) {
// var objectThis = this;
// .attr( "vector-effect", "non-scaling-stroke" )
var topLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.leftLineX - 0.5 ,
this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.rightLineX + 0.5,
this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
currentSVGgroupOfRowXandBelow.add( topLine );
};
////////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. addBottomLineAndBottomScale = function( currentSVGgroupOfRowXandBelow, rowCount ) {
// var objectThis = this;
var bottomOfGrid = ( rowCount + 1 ) * this.configDisplayOptions.ROW_HEIGHT;
if ( rowCount <= 1 || this.configDisplayOptions.skipCreateCombinedLine ) {
bottomOfGrid = ( rowCount ) * this.configDisplayOptions.ROW_HEIGHT;
}
if ( this.configDisplayOptions.createCombinedLineOnly ) {
bottomOfGrid = ( rowCount + 1 ) * this.configDisplayOptions.ROW_HEIGHT;
}
var leftScaleTextSVG = this.GLOBALS.masonViewerSVG.text( "1" );
var textY = ( bottomOfGrid ) + ( this.configDisplayOptions.ROW_HEIGHT / 2 );
textY = textY + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
this.setSVGTextPosition( { textSVG: leftScaleTextSVG, x: this.GLOBALS.leftLineX, y: textY } );
var rightScaleValue = this.constructorParams.requestParams.inputData.maxSequenceLength + "";
var rightScaleTextSVG = this.GLOBALS.masonViewerSVG.text( rightScaleValue );
// A hack to clear the broken font-size. Clear dy that was set to compensate
this.clearStyleAnd_dy_OnSVGtextItem( rightScaleTextSVG );
var textY = ( bottomOfGrid ) + ( this.configDisplayOptions.ROW_HEIGHT / 2 );
textY = textY + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
this.setSVGTextPosition( { textSVG: rightScaleTextSVG, x: this.GLOBALS.rightLineX, y: textY, otherAttrsToSet: [ { attrName: "text-anchor", attrValue: "end" } ] } );
// .attr( "vector-effect", "non-scaling-stroke" )
var bottomLine = this.GLOBALS.masonViewerSVG.line(
this.GLOBALS.leftLineX - 0.5,
( bottomOfGrid ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.rightLineX + 0.5,
( bottomOfGrid ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
currentSVGgroupOfRowXandBelow.add( leftScaleTextSVG );
currentSVGgroupOfRowXandBelow.add( rightScaleTextSVG );
currentSVGgroupOfRowXandBelow.add( bottomLine );
};
////////////////////////////////////////
// Resize overall image length initially or after any event that lengthens or shortens the image
MasonViewerPerInstanceRenderOnPage.prototype. resizeOverallImageLength = function( ) {
// var objectThis = this;
var visibleBlocksRowCount = this.constructorParams.data.outputRows.length;
if ( visibleBlocksRowCount > 1 && ( ! this.configDisplayOptions.skipCreateCombinedLine ) ) {
visibleBlocksRowCount += 1; // Add 1 for combined row if there is more than one row
}
if ( this.configDisplayOptions.createCombinedLineOnly ) {
visibleBlocksRowCount = 1; // Set to 1 since only displaying the "combined" line
}
var visibleRowsHeight = this.configDisplayOptions.ROW_HEIGHT * visibleBlocksRowCount; // this.GLOBALS.arrayOfcurrentSVGgroupOfRowXandBelow.length ;
var hiddenBlocksThatAreVisibleHeight = 0;
for ( var index = 0; index < this.GLOBALS.arrayOfcurrentSVGgroupOfRowXandBelow.length; index++ ) {
var SVGgroup = this.GLOBALS.arrayOfcurrentSVGgroupOfRowXandBelow[ index ];
var SVGgroupProgramaticDataStorage = this.getProgramaticDataStorageFromSVG_js_Item( SVGgroup );
if ( SVGgroupProgramaticDataStorage.getHiddenBlocksVisible() ) {
hiddenBlocksThatAreVisibleHeight += SVGgroupProgramaticDataStorage.getHiddenBlocksHeight();
}
// var z = 0;
}
var viewerHeightInsideTheBox = visibleRowsHeight + hiddenBlocksThatAreVisibleHeight;
this.GLOBALS.viewerHeightInsideTheBox = viewerHeightInsideTheBox;
var overallImageHeight =
this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE +
viewerHeightInsideTheBox +
this.configDisplayOptions.ROW_HEIGHT + // Add for sequence length text below the chart
this.configDisplayOptions.FOOTER_HEIGHT;
this.GLOBALS.masonViewerSVG.size( this.GLOBALS.overallWidth, overallImageHeight );
this.updateFullHeightLines();
};
////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. showHideAllVerticalDataLinesPer_GLOBALS_showVerticalDataLines = function( ) {
// var objectThis = this;
if ( this.GLOBALS.showVerticalDataLines ) {
this.constructorParams.objectThisMasonViewerPerInstance.showVerticalDataLines();
} else {
this.constructorParams.objectThisMasonViewerPerInstance.hideVerticalDataLines();
}
};
// mason_viewer_55_configDisplayOptionDefaults.js
// Mason Viewer
// defaults for Display options used in rendering the viewer on the page.
// These values are merged using $.extend with the values passed in to the function call
// MasonViewer.createMasonViewer( ... ) in the parameter 'configParams' which is the 3rd parameter.
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
/////////////////////////////////////////////////
/// Configuration Defaults
MasonViewerPerInstanceRenderOnPage.prototype.configDisplayOptionDefaults = {
TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE : 2,
LABEL_FONT_SIZE : 12,
ROW_HEIGHT : 15, // Adjust the ROW_HEIGHT to accommodate the height of the label
BLOCK_HEIGHT : 14, // Adjust the BLOCK_HEIGHT to accommodate the height of the label
LABEL_WIDTH : 100, // Adjust the LABEL_WIDTH to accommodate the width of the longest label
ICON_EXPAND_ROW_STARTING_POSITION : 1,
ICON_EXPAND_ROW_WIDTH : 15,
ICON_EXPAND_ROW_SPACE_AFTER : 2,
ROW_TOTALS_BAR_RIGHT_MAX_WIDTH : 30,
ROW_TOTAL_BLOCK_MINIMUM_SIZE : 1,
ROW_TOTALS_BAR_RIGHT_SPACE_FROM_MAIN_GRID : 10,
ROW_TOTALS_BAR_RIGHT_SPACE_FROM_RIGHT_EDGE : 4,
BORDER_COLOR : "black",
BORDER_WIDTH : 1,
FOOTER_HEIGHT : 2,
// Tool tip text
CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT_PREFIX : "Click to hide individual ",
CLICK_TO_EXPAND_TO_SHOW_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT_PREFIX : "Click to show individual ",
blockTypeLabelPlural : "blocks",
BLOCK_HIGHLIGHT_BORDER_COLOR : "pink",
BLOCK_HIGHLIGHT_BORDER_WIDTH : 2,
createCombinedLineOnly : undefined, // set to true to only create combined line
skipCreateCombinedLine : undefined, // set to true to skip create combined line
combinedLineLabel : "Combined", // label on left for combined line
combinedLineTooltipHTML : undefined, // tool tip for label on left for combined line
ALIGNMENT_LINE_COLOR : "black",
ALIGNMENT_LINE_WIDTH : 2
};
// mason_viewer_render_on_page_addnl_methods.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
MasonViewerPerInstanceRenderOnPage.prototype.deleteViewer = function( ) {
// this.constructorParams = {
// $rootDiv: $rootDiv,
// data: data,
// requestParams: requestParams,
// configParams: configParams,
// callbackFunctionsObj: callbackFunctionsObj,
// internalParams: internalParams,
// objectThisMasonViewerPerInstance: objectThisMasonViewerPerInstance
// var $rootDivChildren = this.constructorParams.$rootDiv.children();
// var $svgRoot = this.constructorParams.$rootDiv.children("svg");
// var $allSVGElements = $svgRoot.find("*");
// Javascript Stack Overflow Error on really large viewers so commented out
// var $allSVGElements = this.constructorParams.$rootDiv.find("*");
//
// $allSVGElements.off();
// $allSVGElements.data( null );
var $SVGroot = this.constructorParams.$rootDiv.find("svg");
$SVGroot.remove();
// this.constructorParams.$rootDiv.empty();
};
MasonViewerPerInstanceRenderOnPage.prototype.hideVerticalDataLines = function( ) {
this.GLOBALS.setSVGVerticalDataLines.hide();
this.GLOBALS.showVerticalDataLines = false;
// this.processVerticalDataLines();
};
MasonViewerPerInstanceRenderOnPage.prototype.showVerticalDataLines = function( ) {
this.GLOBALS.setSVGVerticalDataLines.show();
this.GLOBALS.showVerticalDataLines = true;
// this.processVerticalDataLines();
};
//MasonViewerPerInstanceRenderOnPage.prototype.processVerticalDataLines = function( ) {
//
// A mechanism to loop through the elements of a SVGJS set
//
// this.GLOBALS.setSVGVerticalDataLines.each( function( index ) {
//
// var SVGJSObjectInSet = this;
//
//// this.attr('id', 'shiny_new_id_' + i)
//
// })
//};
MasonViewerPerInstanceRenderOnPage.prototype.MESSAGE_TYPE_REMOVE_ALIGNMENTS = "REMOVE_ALIGNMENTS";
MasonViewerPerInstanceRenderOnPage.prototype.MESSAGE_TYPE_ADD_ALIGNMENTS = "ADD_ALIGNMENTS";
// Accept a message from MasonViewerPerInstance
MasonViewerPerInstanceRenderOnPage.prototype.acceptMessage = function( message ) {
if ( message.type === MasonViewerPerInstanceRenderOnPage.prototype.MESSAGE_TYPE_REMOVE_ALIGNMENTS ) {
this.removeAlignmentLines( message.data );
} else if ( message.type === MasonViewerPerInstanceRenderOnPage.prototype.MESSAGE_TYPE_ADD_ALIGNMENTS ) {
this.addAlignmentLines( message.data );
} else {
throw "unknown type in message at 'MasonViewerPerInstanceRenderOnPage.prototype.acceptMessage'. type: " + message.type;
}
};
MasonViewerPerInstanceRenderOnPage.prototype.removeAlignmentLines = function( params ) {
if ( this.GLOBALS.setSVGAlignmentLines ) {
this.GLOBALS.setSVGAlignmentLines.each(function(i) {
this.remove();
});
this.GLOBALS.setSVGAlignmentLines.clear();
}
};
////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype.addAlignmentLines = function( params ) {
// var extraLineHeight = this.configDisplayOptions.ROW_HEIGHT / 2;
var viewerHeightInsideTheBox = this.GLOBALS.viewerHeightInsideTheBox;
this.GLOBALS.setSVGAlignmentLines = this.GLOBALS.masonViewerSVG.set();
var linePosArray = params.linePosArray;
for ( var linePosArrayIndex = 0; linePosArrayIndex < linePosArray.length; linePosArrayIndex++ ) {
var linePos = linePosArray[ linePosArrayIndex ];
var linePixel = this.positionCharPositionToPixel( linePos );
var centerOfAlignmentLine = linePixel + this.GLOBALS.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
var halfOfAlignmentLineWidth = this.configDisplayOptions.ALIGNMENT_LINE_WIDTH / 2;
var x = centerOfAlignmentLine - halfOfAlignmentLineWidth; // center the alignment line
var y1 = this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var y2 =
this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE +
viewerHeightInsideTheBox;
// +
// extraLineHeight; // Add so it extends down into the sequence length text below the chart;
var verticalLineSVG =
this.GLOBALS.masonViewerSVG.line( x, y1, x, y2 )
.stroke( { color: this.configDisplayOptions.ALIGNMENT_LINE_COLOR, width: this.configDisplayOptions.ALIGNMENT_LINE_WIDTH } );
this.GLOBALS.setSVGAlignmentLines.add( verticalLineSVG );
}
};
MasonViewerPerInstanceRenderOnPage.prototype.registerBlockHoverListener = function( params ) {
var hoverListener = params.hoverListener;
if ( ! this.blockHoverCallList ) {
this.blockHoverCallList = [];
}
this.blockHoverCallList.push( hoverListener );
};
// TODO maybe rename this method
MasonViewerPerInstanceRenderOnPage.prototype.callListenersForBlockMouseEnter = function( params ) {
if ( this.blockHoverCallList ) {
var blockInfo = params.blockInfo;
var startPos = blockInfo.startPos;
var endPos = blockInfo.endPos;
var line1 = this.limitCharPositionMaxSeqLength( startPos - 0.5 );
// if ( line1 < 1 ) {
// line1 = 1;
// }
// var line2 = endPos + 0.5;
// if ( line2 > this.constructorParams.requestParams.inputData.maxSequenceLength ) {
// line2 = this.constructorParams.requestParams.inputData.maxSequenceLength;
// }
var line2 = this.limitCharPositionMaxSeqLength( endPos + 0.5 );
var callParams = { linePosArray: [ line1, line2 ] };
var message = this.createAddAlignmentsMessage( callParams );
for ( var blockHoverCallListIndex = 0; blockHoverCallListIndex < this.blockHoverCallList.length; blockHoverCallListIndex++ ) {
var blockHoverCallListItem = this.blockHoverCallList[ blockHoverCallListIndex ];
blockHoverCallListItem.passMessage( message );
}
}
};
MasonViewerPerInstanceRenderOnPage.prototype.callListenersForBlockMouseLeave = function( params ) {
if ( this.blockHoverCallList ) {
var message = this.createRemoveAlignmentsMessage( {} );
for ( var blockHoverCallListIndex = 0; blockHoverCallListIndex < this.blockHoverCallList.length; blockHoverCallListIndex++ ) {
var blockHoverCallListItem = this.blockHoverCallList[ blockHoverCallListIndex ];
blockHoverCallListItem.passMessage( message );
}
}
};
MasonViewerPerInstanceRenderOnPage.prototype.createAddAlignmentsMessage = function( data ) {
var localMessage = {
type: MasonViewerPerInstanceRenderOnPage.prototype.MESSAGE_TYPE_ADD_ALIGNMENTS,
data: data
};
var topLevelMessage = this.createMessage( localMessage );
return topLevelMessage;
};
MasonViewerPerInstanceRenderOnPage.prototype.createRemoveAlignmentsMessage = function( data ) {
var localMessage = {
type: MasonViewerPerInstanceRenderOnPage.prototype.MESSAGE_TYPE_REMOVE_ALIGNMENTS,
data: data
};
var topLevelMessage = this.createMessage( localMessage );
return topLevelMessage;
};
MasonViewerPerInstanceRenderOnPage.prototype.createMessage = function( data ) {
var message = {
type: MasonViewerPerInstance.prototype.MESSAGE_TYPE_RENDER_ON_PAGE,
data: data
};
return message;
};
// mason_viewer_render_on_page_animate.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
MasonViewerPerInstanceRenderOnPage.prototype.animateTransformY = function( params ) {
// var objectThis_MasonViewerPerInstanceRenderOnPage = this;
var SVGoGroupToMove = params.SVGoGroupToMove;
var yToTransformTo = params.yToTransformTo;
var functionToRunAfterAnimate = params.functionToRunAfterAnimate;
SVGoGroupToMove.animate({ duration: 150, ease: '-', delay: 0 }).transform( { y: yToTransformTo } ).after( functionToRunAfterAnimate );
// var SVGoGroupToMoveNativeSVGelement = SVGoGroupToMove.node;
//
// var $SVGoGroupToMoveNativeSVGelement = $( SVGoGroupToMoveNativeSVGelement );
//
// var SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject = $SVGoGroupToMoveNativeSVGelement.data( "SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject" );
//
// if ( SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject === undefined || SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject === null ) {
//
// SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject = SVGwrapNativeSVG_group_InSVGJSGroupObject( SVGoGroupToMoveNativeSVGelement );
//
// $SVGoGroupToMoveNativeSVGelement.data( "SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject", SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject );
// }
//
// SVGoGroupToMove_nativeSVGelement_wrappedInSVGJSGroupObject.animate({ duration: 150, ease: '-', delay: 0 }).transform( { y: yToTransformTo } ).after( functionToRunAfterAnimate );
// if ( yToTransformTo !== 0 ) {
// SVGoGroupToMove.animate({ duration: 150, ease: '-', delay: 0 }).transform( { y: yToTransformTo } ).after( functionToRunAfterAnimate );
// }
//
// var SVGoGroupToMoveNativeSVGelement = SVGoGroupToMove.node;
//
// var $SVGoGroupToMoveNativeSVGelement = $( SVGoGroupToMoveNativeSVGelement );
//
// var currentTransform = $SVGoGroupToMoveNativeSVGelement.attr("transform");
//
// // example: translate(0,90)
//
// var regexPattern = /translate(.)"/; // new RegExp (pattern,modifiers);
//
// var currentTranslate = regexPattern.exec( currentTransform );
//
// var z = 0;
// /* delay animation */
// this.animateTransformY_Timeout = setTimeout(function() {
// var interval = 1000 / 60
// , start = new Date().getTime()
// , finish = start + d
//
// /* start animation */
// fx.interval = setInterval(function(){
// // This code was borrowed from the emile.js micro framework by Thomas Fuchs, aka MadRobby.
// var time = new Date().getTime()
// , pos = time > finish ? 1 : (time - start) / d
//
// /* process values */
// fx.to(pos)
//
// /* finish off animation */
// if (time > finish) {
// clearInterval(fx.interval)
// fx._after ? fx._after.apply(element, [fx]) : fx.stop()
// }
//
// }, d > interval ? interval : d)
//
// }, delay || 0)
};
// mason_viewer_render_on_page_constants.js
// This is a part of MasonViewer
////////////// !!!!!!!!!!!!! Order of calling "precompute" call backs.
/////// For the Main blocks and the Hidden blocks, the precompute is called for each block right before the call to get the color
/////// For the Totals Per Row blocks on the right, the precompute is called for all the rows before the get color and size is called for each block
////// For the Totals Row, the precompute is called for all the rows before the get color is called for each block
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// A set of constants
MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS = {
MIN_MAX_VALUES: {
MINIMUM_ROWS_PER_GROUP: 20 // 100, // Min number of rows per "Group of rows
// TODO For testing
// MINIMUM_ROWS_PER_GROUP: 2, // Min number of rows per "Group of rows
// MAXIMUM_ROWS_PER_GROUP: 2 // Max number of rows per "Group of rows
},
CLASSES: {
PROT_COV_VIEWER_GROUP_OR_ROWS: "prot_cov_viewer_group_of_rows",
PROT_COV_VIEWER_GROUP_ROW_MAIN: "prot_cov_viewer_group_row_main",
PROT_COV_VIEWER_GROUP_ROW_VISIBLE: "prot_cov_viewer_group_row_visible"
},
JQUERY_DATA_LABELS: {
// Stored by jQuery code data()
JQUERY_DATA_LABEL_PROGRAMATIC : "programatic" // Data needed for the program to run
}
};
// mason_viewer_render_on_page_full_height_lines.js
// This is a part of MasonViewer
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
//////////////////////////////////
// This method adds vertical lines the full height of the viewer
//
// based on the contents of requestParams.inputData.vertLinesAllRowsItems
MasonViewerPerInstanceRenderOnPage.prototype.addFullHeightLines = function( ) {
var objectThis = this;
var rowIdx = 0;
var vertLinesAllRowsItems = this.constructorParams.requestParams.inputData.vertLinesAllRowsItems;
if ( vertLinesAllRowsItems && vertLinesAllRowsItems.length > 0 &&
objectThis.constructorParams.callbackFunctionsObj.allRowsVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.allRowsVerticalLines_callbackFunctions.getColorForLine ) {
this.GLOBALS.setSVGVerticalDataFullHeightLines = this.GLOBALS.masonViewerSVG.set();
for ( var vertLinesAllRowsItemsIdx = 0; vertLinesAllRowsItemsIdx < vertLinesAllRowsItems.length; vertLinesAllRowsItemsIdx++ ) {
var lineData = vertLinesAllRowsItems[ vertLinesAllRowsItemsIdx ];
var linePos = lineData.linePos;
var vertLineData = lineData.vertLineData;
if ( vertLineData === undefined || vertLineData === null ) {
throw " inputData.vertLinesAllRowsItems[ vertLinesAllRowsItemsIdx ].vertLineData is empty or null for vertLinesAllRowsItemsIdx = " + vertLinesAllRowsItemsIdx;
}
if ( linePos === undefined || linePos === null ) {
throw " inputData.vertLinesAllRowsItems[ vertLinesAllRowsItemsIdx ].linePos is empty or null for vertLinesAllRowsItemsIdx = " + vertLinesAllRowsItemsIdx;
}
// Add callbackDataStorage to lineData
lineData.callbackDataStorage = {};
if ( objectThis.constructorParams.callbackFunctionsObj.allRowsVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.allRowsVerticalLines_callbackFunctions.precomputeValuesOnCreate )
{
var precomputeValuesOnCreateParams =
{
vertLineData: vertLineData,
linePos: linePos,
callbackDataStorage: lineData.callbackDataStorage
};
objectThis.constructorParams.callbackFunctionsObj.allRowsVerticalLines_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
var linePixel = this.positionCharPositionToPixel( linePos );
var x = linePixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
var y1 = this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
// var y2 =
// this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE +
// this.GLOBALS.viewerHeightInsideTheBox; // Cannot use since not set yet
// y2 is a temporary value for now until update in callback below
var y2 =
this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE +
this.configDisplayOptions.ROW_HEIGHT;
var getColorForLineParams = { vertLineData: vertLineData, callbackDataStorage: lineData.callbackDataStorage, forHiddenLines: false };
var colorForLine = objectThis.constructorParams.callbackFunctionsObj.allRowsVerticalLines_callbackFunctions.getColorForLine( getColorForLineParams );
// returns colorForLine = "#112233"
// throws exception if not valid
this.isValidColor( colorForLine );
var verticalLineSVG = this.GLOBALS.masonViewerSVG.line( x, y1, x, y2 ).stroke( { color: colorForLine, width: this.configDisplayOptions.BORDER_WIDTH } );
this.GLOBALS.setSVGVerticalDataLines.add( verticalLineSVG );
this.GLOBALS.setSVGVerticalDataFullHeightLines.add( verticalLineSVG );
// Comment out since these lines are not part of a row
// this.addMouseOverToLinesInsideMainBox( verticalLineSVG );
this.addProgramaticDataStorageToSVG_js_Item( verticalLineSVG );
verticalLineSVG.data( "row-rowIdx", rowIdx );
verticalLineSVG.data( "placement", "primary row lines" );
verticalLineSVG.data( "block-id", lineData.id );
var attachMouseOverVerticalLineParams = {
verticalLineSVG: verticalLineSVG,
lineData: lineData,
callbackFunctions: objectThis.constructorParams.callbackFunctionsObj.allRowsVerticalLines_callbackFunctions
};
this.attachMouseOverVerticalLine( attachMouseOverVerticalLineParams );
// currentSVGgroupOfRowXandBelow.add( verticalLineSVG );
// SVGRowXmainLinesSET.add( verticalLineSVG );
// TODO Adding to this Set is probably incorrect
// SVGRowXmainBlocksGROUP.add( verticalLineSVG );
}
}
};
MasonViewerPerInstanceRenderOnPage.prototype.updateFullHeightLines = function( params ) {
if ( this.GLOBALS.setSVGVerticalDataFullHeightLines ) {
var y2 =
this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE +
this.GLOBALS.viewerHeightInsideTheBox;
this.GLOBALS.setSVGVerticalDataFullHeightLines.each( function(index) {
this.attr("y2", y2);
});
}
};
// mason_viewer_render_on_page_general_utils.js
// This is a part of MasonViewer
// General Utilities
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// Visible as attributes in the DOM
// blockBlockSVG.data( "label", { d1: 12, d4: "wwww"} );
// NOT Visible as attributes in the DOM
// blockBlockSVG.remember('oldBBox', { d1: 12, d4: "wwww"} );
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
//////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. convertBlockColorTo_SVGJS_FillColor = function( colorForBlock ) {
// SVGjs requires the fill color object to be { r: , g: , b: } or to be a string as listed above.
// The block callbacks are returning either a hex string six based (e.g. #ff0066)
// or an object with { red: , green: , blue: }
// If a string is passed in, it will be validated and returned
// If anything else is passed in, it will be assumed to be the object
// and will be validated and rounded and converted to { r: , g: , b: }
if ( colorForBlock === undefined || colorForBlock === null ) {
throw "ERROR: colorForBlock === undefined || colorForBlock === null";
}
if (typeof colorForBlock == 'string' || colorForBlock instanceof String) {
// Throws Exception if error
this.isValidColor( colorForBlock );
return colorForBlock;
} else {
var colorForBlockRoundedAndValidated = this.roundAndValidateColor( colorForBlock );
var fillColor = { r: colorForBlockRoundedAndValidated.red, g: colorForBlockRoundedAndValidated.green, b: colorForBlockRoundedAndValidated.blue };
return fillColor;
}
throw "Code error in 'convertBlockColorTo_SVGJS_FillColor', should have returned by this point: value passed is: " + colorForBlock;
};
//////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. isValidColor = function( colorParam ) {
if (typeof colorParam == 'string' || colorParam instanceof String) {
} else {
throw "'isValidColor' only valid for string input. colorParam: " + colorParam;
}
// if ( colorParam.match(/^#[a-f0-9]{6}$/i) !== null ) {
if ( /^#[a-f0-9]{6}$/i.test( colorParam ) ) {
// The pattern is in the string.
// Since the pattern covers from the start to the end of the string, the whole string is checked.
return;
}
throw "color is a string but is not a valid hex color with 6 positions (e.g. #ff0066): value passed is: " + colorParam;
};
// ^ match beginning
// # a hash
// [a-f0-9] any letter from a-f and 0-9
// {6} the previous group appears exactly 6 times
// $ match end
// i ignore case
//////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. roundAndValidateColor = function( colorForBlock ) {
// var objectThis = this;
if ( colorForBlock === undefined || colorForBlock === null ) {
throw "ERROR: colorForBlock === undefined || colorForBlock === null";
}
if ( colorForBlock.red === undefined || colorForBlock.red === null ) {
throw "ERROR: colorForBlock.red === undefined || colorForBlock.red === null";
}
if ( colorForBlock.green === undefined || colorForBlock.green === null ) {
throw "ERROR: colorForBlock.green === undefined || colorForBlock.green === null";
}
if ( colorForBlock.blue === undefined || colorForBlock.blue === null ) {
throw "ERROR: colorForBlock.blue === undefined || colorForBlock.blue === null";
}
var colorForBlockOut = { red: Math.round( colorForBlock.red ), green: Math.round( colorForBlock.green ), blue: Math.round( colorForBlock.blue ) };
if ( colorForBlockOut.red < 0 || colorForBlockOut.red > 255 ) {
throw "colorForBlock.red calculated < 0 or > 255, is = " + colorForBlockOut.red ;
}
if ( colorForBlockOut.green < 0 || colorForBlockOut.green > 255 ) {
throw "colorForBlock.green calculated < 0 or > 255, is = " + colorForBlockOut.green ;
}
if ( colorForBlockOut.blue < 0 || colorForBlockOut.blue > 255 ) {
throw "colorForBlock.blue calculated < 0 or > 255, is = " + colorForBlockOut.blue ;
}
return colorForBlockOut;
};
//////////////////////////////////////
// Get raw SVG element Id for SVG.js item
MasonViewerPerInstanceRenderOnPage.prototype. getIdForSVG_js_item = function( SVG_js_item ) {
var id = SVG_js_item.attr('id');
return id;
};
//////////////////////////////////////
// Get jQuery Object for SVG.js item
MasonViewerPerInstanceRenderOnPage.prototype. getJQueryObjForRawSVGFromSVG_js_item = function( SVG_js_item ) {
if ( SVG_js_item === undefined || SVG_js_item === null ) {
throw "ERROR: SVG_js_item === undefined || SVG_js_item === null";
}
var $jQueryObj = $( SVG_js_item.node );
// var id = getIdForSVG_js_item( SVG_js_item );
//
// var $jQueryObj = $( "#" + id );
return $jQueryObj;
};
//////////////////////////////////////
// Get SVG.js object for jQuery Object
MasonViewerPerInstanceRenderOnPage.prototype. getSVG_js_itemForJQueryObj = function( $jQueryObj ) {
if ( $jQueryObj === undefined || $jQueryObj === null ) {
throw "ERROR: $jQueryObj === undefined || $jQueryObj === null";
}
if ( $jQueryObj.length === 0 ) {
throw "ERROR: $jQueryObj.length === 0";
}
var SVG_js_item = $jQueryObj[0].instance;
return SVG_js_item;
};
//////////////////////////////////////////////////////////////
////// ProgramaticDataStorageGroupOfRows
//////////////////////////////////////
// Add ProgramaticDataStorageGroupOfRows to an jQuery item
MasonViewerPerInstanceRenderOnPage.prototype. addProgramaticDataStorageGroupOfRowsToJQueryItem = function( $item ) {
var programaticDataStorageGroupOfRows = new ProgramaticDataStorageGroupOfRows();
$item.data( MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.JQUERY_DATA_LABELS.JQUERY_DATA_LABEL_PROGRAMATIC, programaticDataStorageGroupOfRows );
programaticDataStorageGroupOfRows.$item = $item; // For debugging
return programaticDataStorageGroupOfRows;
};
//////////////////////////////////////
// Get ProgramaticDataStorageGroupOfRows in an jQuery item
MasonViewerPerInstanceRenderOnPage.prototype. getProgramaticDataStorageGroupOfRowsFromJQueryItem = function( $item ) {
var programaticDataStorageGroupOfRows = $item.data( MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.JQUERY_DATA_LABELS.JQUERY_DATA_LABEL_PROGRAMATIC );
if ( programaticDataStorageGroupOfRows === undefined ) {
// var z = 0;
}
return programaticDataStorageGroupOfRows;
};
//////////////////////////////////////
// Add ProgramaticDataStorageGroupOfRows to an SVG.js item, added to underlying SVG element via jQuery
MasonViewerPerInstanceRenderOnPage.prototype. addProgramaticDataStorageGroupOfRowsToSVG_js_Item = function( SVGitem ) {
var $jQueryItem = this.getJQueryObjForRawSVGFromSVG_js_item( SVGitem );
return this.addProgramaticDataStorageGroupOfRowsToJQueryItem( $jQueryItem );
};
//////////////////////////////////////
// Get ProgramaticDataStorageGroupOfRows in an SVG.js item, retreived from underlying SVG element via jQuery
MasonViewerPerInstanceRenderOnPage.prototype. getProgramaticDataStorageGroupOfRowsFromSVG_js_Item = function( SVGitem ) {
var $jQueryItem = this.getJQueryObjForRawSVGFromSVG_js_item( SVGitem );
var programaticDataStorageGroupOfRows = this.getProgramaticDataStorageGroupOfRowsFromJQueryItem( $jQueryItem );
return programaticDataStorageGroupOfRows;
};
/////////////////////////////////////////////////////////////
////////// ProgramaticDataStorage
//////////////////////////////////////
// Add ProgramaticDataStorage to an jQuery item
MasonViewerPerInstanceRenderOnPage.prototype. addProgramaticDataStorageToJQueryItem = function( $item ) {
var programaticDataStorage = new ProgramaticDataStorage();
$item.data( MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.JQUERY_DATA_LABELS.JQUERY_DATA_LABEL_PROGRAMATIC, programaticDataStorage );
programaticDataStorage.$item = $item; // For debugging
return programaticDataStorage;
};
//////////////////////////////////////
// Get ProgramaticDataStorage in an jQuery item
MasonViewerPerInstanceRenderOnPage.prototype. getProgramaticDataStorageFromJQueryItem = function( $item ) {
var programaticDataStorage = $item.data( MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.JQUERY_DATA_LABELS.JQUERY_DATA_LABEL_PROGRAMATIC );
if ( programaticDataStorage === undefined ) {
// var z = 0;
}
// if ( programaticDataStorage !== undefined ) {
//
// programaticDataStorage.$item = $item; // For debugging
// }
return programaticDataStorage;
};
//////////////////////////////////////
// Add ProgramaticDataStorage to an SVG.js item, added to underlying SVG element via jQuery
MasonViewerPerInstanceRenderOnPage.prototype. addProgramaticDataStorageToSVG_js_Item = function( SVGitem ) {
var $jQueryItem = this.getJQueryObjForRawSVGFromSVG_js_item( SVGitem );
return this.addProgramaticDataStorageToJQueryItem( $jQueryItem );
};
//////////////////////////////////////
// Get ProgramaticDataStorage in an SVG.js item, retreived from underlying SVG element via jQuery
MasonViewerPerInstanceRenderOnPage.prototype. getProgramaticDataStorageFromSVG_js_Item = function( SVGitem ) {
var $jQueryItem = this.getJQueryObjForRawSVGFromSVG_js_item( SVGitem );
var programaticDataStorage = this.getProgramaticDataStorageFromJQueryItem( $jQueryItem );
return programaticDataStorage;
};
//////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. set_class_directly_OnSVGItem_using_jQuery = function( SVGItem, classValue ) {
var $SVGItem = this.getJQueryObjForRawSVGFromSVG_js_item( SVGItem );
$SVGItem.attr( "class", classValue );
};
//////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. set_attr_directly_OnSVGtextItem_using_jQuery = function( SVGtextItem, attrName, attrValue ) {
var $SVGtextItem = this.getJQueryObjForRawSVGFromSVG_js_item( SVGtextItem );
$SVGtextItem.attr( attrName, attrValue );
var $tspanChild = $SVGtextItem.children( "tspan" );
$tspanChild.attr( attrName, attrValue );
};
//////////////////////////////////
// Clear the "style" attr on an SVG text item
// This hack is being used to clear out the invalid font-size entry
MasonViewerPerInstanceRenderOnPage.prototype. clearStyleAnd_dy_OnSVGtextItem = function( SVGtextItem ) {
// Does not work
// SVGitem.attr( "style", "" );
// Does work
var $SVGtextItem = this.getJQueryObjForRawSVGFromSVG_js_item( SVGtextItem );
$SVGtextItem.attr( "style", "" );
$SVGtextItem.attr( "dy", "" );
var $tspanChild = $SVGtextItem.children( "tspan" );
$tspanChild.attr( "style", "" );
$tspanChild.attr( "dy", "" );
// var z = 0;
};
////////////////////////////////////////////////////////
// attach Tool Tip to the provided jquery object using the provided function to get the tool tip text
MasonViewerPerInstanceRenderOnPage.prototype. attachToolTipToJqueryHtmlNode = function( $htmlNode, getTooltipTextFcn, callbackFunctions ) {
// var objectThis = this;
$htmlNode.mouseenter( function(eventObject) {
var text = getTooltipTextFcn();
Tip( text, DELAY, 0 );
if ( callbackFunctions && callbackFunctions.mouseenter ) {
callbackFunctions.mouseenter( this );
}
} );
$htmlNode.mouseleave( function(eventObject) {
UnTip();
if ( callbackFunctions && callbackFunctions.mouseleave ) {
callbackFunctions.mouseleave( this );
}
} );
};
// Not used since switched tool tip library
// $htmlNode.wTooltip({
// content: true,
// offsetY: 18,
// offsetX: 15,
// callBefore: getTooltipTextFcn,
//
// clickAction: function(tooltip, node){
// $(tooltip).hide();
// },
// style: {
// border: "1px solid black",
// background: "#E8EAFF",
// fontSize: "8pt",
// color: "black"
// }
// });
////////////////////////////////////////
////// Vertical Lines Representing provided data processing
///////////////
// Create Tool Tip for Vertical Lines Representing provided data processing
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverVerticalLine = function( params ) {
// var objectThis = this;
var verticalLineSVG = params.verticalLineSVG;
var lineData = params.lineData;
var callbackFunctions = params.callbackFunctions;
var $verticalLineSVG = this.getJQueryObjForRawSVGFromSVG_js_item( verticalLineSVG );
var getToolTextParams = {
vertLineData: lineData.vertLineData,
linePos: lineData.linePos,
callbackDataStorage: lineData.callbackDataStorage
};
this.attachToolTipToJqueryHtmlNode( $verticalLineSVG, function( tooltip, node ) {
var tooltipHTML = callbackFunctions.getLinesToolTipText( getToolTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
} );
};
////////////////////////
/////////////////////////////////
// Given a jQuery element in a SVG, return it's closest Group of Rows Group
MasonViewerPerInstanceRenderOnPage.prototype. get$groupOfRowsFor$currentElement = function( $currentElement ) {
// var objectThis = this;
var groupOfRowsSelector = "g." + MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.CLASSES.PROT_COV_VIEWER_GROUP_OR_ROWS;
// Get group of rows
var $groupOfRows = $currentElement.parent().closest( groupOfRowsSelector );
if ( $groupOfRows.length === 0 ) {
throw "Unable to find group of rows element using selector '" + groupOfRowsSelector + "'.";
}
return $groupOfRows;
};
/////////////////////////////////
// Given a jQuery element in a SVG, return it's closest parent group, closest Row Root group
MasonViewerPerInstanceRenderOnPage.prototype. get$rowMainGroupFor$currentElement = function( $currentElement ) {
// var objectThis = this;
var rowMainGroupSelector = "g." + MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.CLASSES.PROT_COV_VIEWER_GROUP_ROW_MAIN;
// Get Row Main Group since that is where the SVG.js set of elements to make visible is attached
var $rowMainGroup = $currentElement.parent().closest( rowMainGroupSelector );
if ( $rowMainGroup.length === 0 ) {
throw "Unable to find main group element using selector '" + rowMainGroupSelector + "'.";
}
return $rowMainGroup;
};
/////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. attachClickShowHideToggleHiddenBlocksRow = function( SVGObject ) {
var objectThis = this;
var $SVGObject = this.getJQueryObjForRawSVGFromSVG_js_item( SVGObject );
$SVGObject.click( function( event, ui ) {
objectThis.clickShowHideToggleHiddenBlocksRow( event, ui, this /* "this" for the clicked on element */ );
} );
};
/////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. setSVGTextPosition = function( setSVGTextPositionParams ) {
// var objectThis = this;
var textSVG = setSVGTextPositionParams.textSVG;
var x = setSVGTextPositionParams.x;
var y = setSVGTextPositionParams.y;
var otherAttrsToSet = setSVGTextPositionParams.otherAttrsToSet;
var additionalStyle = setSVGTextPositionParams.additionalStyle;
if ( additionalStyle === undefined || additionalStyle === null ) {
additionalStyle = "";
}
textSVG.move( x, y );
// Do not use since results in a call to textSVG.rebuild() which resets the "dy"
// textSVG.size( this.configDisplayOptions.LABEL_FONT_SIZE ); // TODO hard coded size
// textSVG.attr("dy", height);
this.set_attr_directly_OnSVGtextItem_using_jQuery( textSVG, "dy", ".35em" ); // Must be after setting the size
// TODO hard coded font size
this.set_attr_directly_OnSVGtextItem_using_jQuery( textSVG, "style", "font-size:" + this.configDisplayOptions.LABEL_FONT_SIZE + "px;font-family:Helvetica, Arial, sans-serif" + additionalStyle );
if ( otherAttrsToSet !== undefined && otherAttrsToSet !== null && otherAttrsToSet instanceof Array && otherAttrsToSet.length > 0 ) {
for ( var otherAttrsIdx = 0; otherAttrsIdx < otherAttrsToSet.length; otherAttrsIdx++ ) {
var otherAttr = otherAttrsToSet[ otherAttrsIdx ];
this.set_attr_directly_OnSVGtextItem_using_jQuery( textSVG, otherAttr.attrName, otherAttr.attrValue ); // Must be after setting the size
}
}
// var labelTextSVG_BBox = textSVG.bbox(); // The bbox() values are zero if the graph is hidden with the div having display: none;
//
// var height = labelTextSVG_BBox.height;
// var width = labelTextSVG_BBox.width;
// var z = 0;
};
/////////////////////////////
/// create "callbackDataStorage" on outputRow and on mainBlock
MasonViewerPerInstanceRenderOnPage.prototype. add_callbackDataStorage_ToElementsIn_outputRows = function( outputRows ) {
// var objectThis = this;
// First create "callbackDataStorage" on outputRow and on mainBlock
for ( var addDataStgRowIdx = 0; addDataStgRowIdx < outputRows.length; addDataStgRowIdx++ ) {
var addDataStgRow = outputRows[ addDataStgRowIdx ];
addDataStgRow.callbackDataStorage = {};
}
};
/////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. setupGroupOfRows = function( currentGroupOfRowsSVGgroup ) {
// var objectThis = this;
this.set_class_directly_OnSVGItem_using_jQuery( currentGroupOfRowsSVGgroup, MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.CLASSES.PROT_COV_VIEWER_GROUP_OR_ROWS );
var programaticDataStorageGroupOfRows = this.addProgramaticDataStorageGroupOfRowsToSVG_js_Item( currentGroupOfRowsSVGgroup );
programaticDataStorageGroupOfRows.setSVGGroup( currentGroupOfRowsSVGgroup );
return programaticDataStorageGroupOfRows;
};
/////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. setupRootGroupForEachRow = function( currentSVGgroupOfRowXandBelow ) {
// var objectThis = this;
this.GLOBALS.arrayOfcurrentSVGgroupOfRowXandBelow.push( currentSVGgroupOfRowXandBelow );
this.set_class_directly_OnSVGItem_using_jQuery( currentSVGgroupOfRowXandBelow, MasonViewerPerInstanceRenderOnPage.prototype. CONSTANTS.CLASSES.PROT_COV_VIEWER_GROUP_ROW_MAIN );
return this.addProgramaticDataStorageToSVG_js_Item( currentSVGgroupOfRowXandBelow );
};
//////////////////////////////////////////////
// Highlight box under each main row
MasonViewerPerInstanceRenderOnPage.prototype. highlightBoxUnderEachRow = function( SVGItem ) {
var objectThis = this;
var $SVGItem = $( SVGItem.node );
var $rowMainGroup = this.get$rowMainGroupFor$currentElement( $SVGItem );
var SVGrowMainGroupProgramaticDataStorage = objectThis.getProgramaticDataStorageFromJQueryItem( $rowMainGroup );
var boxUnderEachRow = SVGrowMainGroupProgramaticDataStorage.getMainBlocksBoxUnderEachRow();
if ( SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksVisible() ) {
boxUnderEachRow = SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksBoxUnderEachRow();
}
if ( boxUnderEachRow === undefined ) {
return;
}
var $boxUnderEachRow = $( boxUnderEachRow.node );
$boxUnderEachRow.css( { stroke: "lightgreen", "stroke-width": 5 } );
};
// stroke:pink;stroke-width:5
//////////////////////////////////////////////
// UN Highlight box under each main row
MasonViewerPerInstanceRenderOnPage.prototype. unhighlightBoxUnderEachRow = function( SVGItem ) {
// var objectThis = this;
if ( SVGItem === undefined ) {
return;
}
var $SVGItem = $( SVGItem.node );
var $rowMainGroup = this.get$rowMainGroupFor$currentElement( $SVGItem );
var SVGrowMainGroupProgramaticDataStorage = this.getProgramaticDataStorageFromJQueryItem( $rowMainGroup );
if ( SVGrowMainGroupProgramaticDataStorage === undefined ) {
return;
}
var boxUnderEachRow = SVGrowMainGroupProgramaticDataStorage.getMainBlocksBoxUnderEachRow();
if ( SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksVisible() ) {
boxUnderEachRow = SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksBoxUnderEachRow();
}
if ( boxUnderEachRow === undefined ) {
return;
}
var $boxUnderEachRow = $( boxUnderEachRow.node );
$boxUnderEachRow.css( { stroke: "black", "stroke-width": 0 } );
};
//////////////////////////////////////////////
// Add a box under each main row
MasonViewerPerInstanceRenderOnPage.prototype. addBoxUnderEachRowForMouseOver = function( currentSVGgroupOfRowXandBelow, SVGrowMainGroupProgramaticDataStorage, rowIdx ) {
var objectThis = this;
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var blockSVG = this.GLOBALS.masonViewerSVG.rect( this.GLOBALS.sequenceWidth, this.configDisplayOptions.BLOCK_HEIGHT );
currentSVGgroupOfRowXandBelow.add( blockSVG );
SVGrowMainGroupProgramaticDataStorage.setMainBlocksBoxUnderEachRow( blockSVG );
blockSVG.attr( { fill: { r: 255, g: 255, b: 255 },
stroke: { r: 0, g: 0, b: 0 },
"stroke-width": 0,
"fill-opacity": 0 } );
blockSVG.attr( "data-placement", "mainBlocksBoxUnderEachMainRow" );
blockSVG.attr( "rowIdx", rowIdx );
blockSVG.move( this.configDisplayOptions.MAIN_BOX_STARTING_POSITION, y );
this.addProgramaticDataStorageToSVG_js_Item( blockSVG );
var $blockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockSVG );
$blockSVG.hover( /* handlerIn */ function(eventObject) {
// var $this = $(this);
objectThis.highlightBoxUnderEachRow( this.instance );
}, /* handlerOut */ function(eventObject) {
// var $this = $(this);
objectThis.unhighlightBoxUnderEachRow( this.instance );
} );
};
///////////////////////////////////
// Add a box under each row hidden blocks
MasonViewerPerInstanceRenderOnPage.prototype. addHiddenOrTotalsBlocksBoxUnderEachRowForMouseOver = function( placementLabel, hiddenBlocksRowsHeight, currentSVGgroupOfRowXandBelow, SVGrowMainGroupProgramaticDataStorage, rowIdx ) {
var objectThis = this;
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var blockSVG = this.GLOBALS.masonViewerSVG.rect( this.GLOBALS.sequenceWidth, hiddenBlocksRowsHeight );
currentSVGgroupOfRowXandBelow.add( blockSVG );
SVGrowMainGroupProgramaticDataStorage.setHiddenBlocksBoxUnderEachRow( blockSVG );
blockSVG.attr( { fill: { r: 255, g: 255, b: 255 },
stroke: { r: 0, g: 0, b: 0 },
"stroke-width": 0,
"fill-opacity": 0 } );
blockSVG.attr( "data-placement", placementLabel );
blockSVG.attr( "rowIdx", rowIdx );
blockSVG.move( this.configDisplayOptions.MAIN_BOX_STARTING_POSITION, y );
this.addProgramaticDataStorageToSVG_js_Item( blockSVG );
var $blockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockSVG );
$blockSVG.hover( /* handlerIn */ function(eventObject) {
// var $this = $(this);
objectThis.highlightBoxUnderEachRow( this.instance );
}, /* handlerOut */ function(eventObject) {
// var $this = $(this);
objectThis.unhighlightBoxUnderEachRow( this.instance );
} );
blockSVG.hide();
};
///////////////////////////////////
// Add a box under each row hidden blocks
MasonViewerPerInstanceRenderOnPage.prototype. addHiddenBlocksBoxUnderEachRowForMouseOver = function( hiddenBlocksRowsHeight, currentSVGgroupOfRowXandBelow, SVGrowMainGroupProgramaticDataStorage, rowIdx ) {
// var objectThis = this;
this.addHiddenOrTotalsBlocksBoxUnderEachRowForMouseOver( "hiddenBlocksBoxUnderEachMainRow", hiddenBlocksRowsHeight, currentSVGgroupOfRowXandBelow, SVGrowMainGroupProgramaticDataStorage, rowIdx );
};
///////////////////////////////////
// Add a box under each row totals blocks
MasonViewerPerInstanceRenderOnPage.prototype. addTotalsBlocksBoxUnderEachRowForMouseOver = function( hiddenBlocksRowsHeight, currentSVGgroupOfRowXandBelow, SVGrowMainGroupProgramaticDataStorage, rowIdx ) {
// var objectThis = this;
this.addHiddenOrTotalsBlocksBoxUnderEachRowForMouseOver( "TotalsBlocksBoxUnderCombinedRow", hiddenBlocksRowsHeight, currentSVGgroupOfRowXandBelow, SVGrowMainGroupProgramaticDataStorage, rowIdx );
};
////////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. createHiddenBlocksContractionIcon = function( tooltipText, currentSVGgroupOfRowXandBelow, rowIdx, currentSVGgroupOfRowXandBelowProgramaticDataStorage ) {
// var objectThis = this;
var SVGGroupContractionIcon = this.GLOBALS.masonViewerSVG.group();
currentSVGgroupOfRowXandBelow.add( SVGGroupContractionIcon );
SVGGroupContractionIcon.attr("label", "SVGGroupContractionIcon");
this.attachClickShowHideToggleHiddenBlocksRow( SVGGroupContractionIcon );
SVGGroupContractionIcon.attr("CreatedBy", "createHiddenBlocksContractionIcon");
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + ( this.configDisplayOptions.ROW_HEIGHT / 4 ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var rectSVG = this.GLOBALS.masonViewerSVG.rect( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 2, this.configDisplayOptions.ROW_HEIGHT / 2 );
rectSVG.attr( { fill: { r: 255, g: 255, b: 255 },
stroke: { r: 255, g: 0, b: 0 },
"fill-opacity": 0 } );
rectSVG.move( this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 4, y );
this.attachToolTipToJqueryHtmlNode( $(rectSVG.node), function(tooltip, node) {
$(tooltip).html( tooltipText );
return tooltipText;
} );
var horizLineSVG = this.GLOBALS.masonViewerSVG.line( this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + ( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 4 ) + 2,
y + this.configDisplayOptions.ROW_HEIGHT / 4,
this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH - ( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 2 ) + ( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 4 ) - 2,
y + this.configDisplayOptions.ROW_HEIGHT / 4 )
.stroke({ color: '#f06', width: 1 });
this.attachToolTipToJqueryHtmlNode( $(horizLineSVG.node), function(tooltip, node) {
$(tooltip).html( tooltipText );
return tooltipText;
});
rectSVG.attr( "cursor", "pointer");
horizLineSVG.attr( "cursor", "pointer");
SVGGroupContractionIcon.add( rectSVG );
SVGGroupContractionIcon.add( horizLineSVG );
// var hiddenBlocksForRowSet = currentSVGgroupOfRowXandBelowProgramaticDataStorage.getHiddenBlocksForRowSet();
//
//
// hiddenBlocksForRowSet.add( rectSVG );
// hiddenBlocksForRowSet.add( horizLineSVG );
// rectSVG.hide();
// horizLineSVG.hide();
};
////////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. createHiddenBlocksExpansionIcon = function( tooltipText, currentSVGgroupOfRowXandBelow, rowIdx, currentSVGgroupOfRowXandBelowProgramaticDataStorage ) {
// var objectThis = this;
var SVGGroupExpansionIcon = this.GLOBALS.masonViewerSVG.group();
SVGGroupExpansionIcon.attr("label", "SVGGroupExpansionIcon");
var SVGSetExpansionIcon = this.GLOBALS.masonViewerSVG.set();
currentSVGgroupOfRowXandBelow.add( SVGGroupExpansionIcon );
this.attachClickShowHideToggleHiddenBlocksRow( SVGGroupExpansionIcon );
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setSVGGroupExpansionIcon( SVGSetExpansionIcon );
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + ( this.configDisplayOptions.ROW_HEIGHT / 4 ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var rectSVG = this.GLOBALS.masonViewerSVG.rect( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 2, this.configDisplayOptions.ROW_HEIGHT / 2 );
rectSVG.attr( { fill: { r: 255, g: 255, b: 255 },
stroke: { r: 255, g: 0, b: 0 },
"fill-opacity": 0 } );
rectSVG.move( this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 4, y );
var vertLineSVG = this.GLOBALS.masonViewerSVG.line( this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 2 ,
y + 2,
this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 2,
y + this.configDisplayOptions.ROW_HEIGHT / 2 - 2 )
.stroke({ color: '#f06', width: 1 });
var horizLineSVG = this.GLOBALS.masonViewerSVG.line( this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + ( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 4 ) + 2,
y + this.configDisplayOptions.ROW_HEIGHT / 4,
this.configDisplayOptions.ICON_EXPAND_ROW_STARTING_POSITION + this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH - ( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 2 ) + ( this.configDisplayOptions.ICON_EXPAND_ROW_WIDTH / 4 ) - 2,
y + this.configDisplayOptions.ROW_HEIGHT / 4 )
.stroke({ color: '#f06', width: 1 });
rectSVG.attr( "cursor", "pointer");
vertLineSVG.attr( "cursor", "pointer");
horizLineSVG.attr( "cursor", "pointer");
SVGGroupExpansionIcon.add( rectSVG );
SVGGroupExpansionIcon.add( vertLineSVG );
SVGGroupExpansionIcon.add( horizLineSVG );
SVGSetExpansionIcon.add( rectSVG );
SVGSetExpansionIcon.add( vertLineSVG );
SVGSetExpansionIcon.add( horizLineSVG );
this.attachToolTipToJqueryHtmlNode( $(rectSVG.node), function(tooltip, node) {
$(tooltip).html( tooltipText );
return tooltipText;
});
this.attachToolTipToJqueryHtmlNode( $(vertLineSVG.node), function(tooltip, node) {
$(tooltip).html( tooltipText );
return tooltipText;
});
this.attachToolTipToJqueryHtmlNode( $(horizLineSVG.node), function(tooltip, node) {
$(tooltip).html( tooltipText );
return tooltipText;
});
};
////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. addMouseOverToBlocks = function( blockSVG ) {
var objectThis = this;
var $blockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockSVG );
$blockSVG.hover( /* handlerIn */ function(eventObject) {
var $this = $(this);
$this.css(
{ stroke: objectThis.configDisplayOptions.BLOCK_HIGHLIGHT_BORDER_COLOR,
"stroke-width": objectThis.configDisplayOptions.BLOCK_HIGHLIGHT_BORDER_WIDTH } );
objectThis.highlightBoxUnderEachRow( this.instance );
}, /* handlerOut */ function(eventObject) {
var $this = $(this);
$this.css( { stroke: "black", "stroke-width": 0 } );
objectThis.unhighlightBoxUnderEachRow( this.instance );
} );
};
////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. addMouseOverToLinesInsideMainBox = function( lineSVG ) {
var objectThis = this;
var $lineSVG = this.getJQueryObjForRawSVGFromSVG_js_item( lineSVG );
$lineSVG.hover( /* handlerIn */ function(eventObject) {
// var $this = $(this);
// $this.css( { stroke: "pink", "stroke-width": 5 } );
objectThis.highlightBoxUnderEachRow( this.instance );
}, /* handlerOut */ function(eventObject) {
// var $this = $(this);
// $this.css( { stroke: "black", "stroke-width": 0 } );
objectThis.unhighlightBoxUnderEachRow( this.instance );
} );
};
// mason_viewer_render_on_page_hidden_row_show_hide.js
// This is a part of MasonViewer
////////////// !!!!!!!!!!!!! Order of calling "precompute" call backs.
/////// For the Main blocks and the Hidden blocks, the precompute is called for each block right before the call to get the color
/////// For the Totals Per Row blocks on the right, the precompute is called for all the rows before the get color and size is called for each block
////// For the Totals Row, the precompute is called for all the rows before the get color is called for each block
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// Visible as attributes in the DOM
// blockBlockSVG.data( "label", { d1: 12, d4: "wwww"} );
// NOT Visible as attributes in the DOM
// blockBlockSVG.remember('oldBBox', { d1: 12, d4: "wwww"} );
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
/////////////////////////////////
// Handling clicking to show or hide the hidden blocks for a row for a label.
// The click bubbles up to the group. Using jQuery since SVG.js click handling allowed the click to continue bubbling up
MasonViewerPerInstanceRenderOnPage.prototype. clickShowHideToggleHiddenBlocksRow = function( event, ui, clickThis /* "this" for the clicked on element */ ) {
var objectThis = this;
var $clickThis = $(clickThis);
var $rowMainGroup = this.get$rowMainGroupFor$currentElement( $clickThis );
var SVGrowMainGroupProgramaticDataStorage = this.getProgramaticDataStorageFromJQueryItem( $rowMainGroup );
// retrieve and run the callback that will create the hidden blocks if they are not already created
var createHiddenBlocksIfNotCreatedCallback = SVGrowMainGroupProgramaticDataStorage.getCreateHiddenBlocksIfNotCreatedCallback();
createHiddenBlocksIfNotCreatedCallback();
var hiddenBlocksForRowSet = SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksForRowSet( );
// Only perform this transform and show if there is a set of blocks to uncover and show
if ( hiddenBlocksForRowSet !== undefined && hiddenBlocksForRowSet !== null ) {
var SVGRowXmainBlocksGROUP = SVGrowMainGroupProgramaticDataStorage.getSVGRowXmainBlocksGROUP();
var hiddenBlocksHeight = SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksHeight();
var SVGGroupExpansionIcon = SVGrowMainGroupProgramaticDataStorage.getSVGGroupExpansionIcon();
var mainBlocksBoxUnderEachRow = SVGrowMainGroupProgramaticDataStorage.getMainBlocksBoxUnderEachRow();
var hiddenBlocksBoxUnderEachRow = SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksBoxUnderEachRow();
var SVGoGroupToMove = SVGrowMainGroupProgramaticDataStorage.getGroupToMoveForExpansion();
// var rowIdx = SVGofThis.data( "row-rowIdx" );
var animateAdjustChildGroupOfRowsVerticalOffset = true;
if ( SVGoGroupToMove ) {
animateAdjustChildGroupOfRowsVerticalOffset = false;
}
if ( SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksVisible() ) {
hiddenBlocksForRowSet.hide();
if ( hiddenBlocksBoxUnderEachRow !== undefined ) {
hiddenBlocksBoxUnderEachRow.hide();
}
if ( mainBlocksBoxUnderEachRow !== undefined ) {
mainBlocksBoxUnderEachRow.show();
}
if ( SVGRowXmainBlocksGROUP !== undefined ) {
SVGRowXmainBlocksGROUP.show();
}
SVGGroupExpansionIcon.show();
var yToTransformTo = 0;
var functionToRunAfterAnimate = function(){
SVGrowMainGroupProgramaticDataStorage.setHiddenBlocksVisible( false );
var adjustChildParams = {
animateAdjustChildGroupOfRowsVerticalOffset: animateAdjustChildGroupOfRowsVerticalOffset,
$rowMainGroup: $rowMainGroup
};
objectThis.adjustChildGroupOfRowsVerticalOffset( adjustChildParams );
objectThis.resizeOverallImageLength();
};
var animateTransformYParams = {
SVGoGroupToMove: SVGoGroupToMove,
yToTransformTo: yToTransformTo,
functionToRunAfterAnimate: functionToRunAfterAnimate
};
if ( SVGoGroupToMove ) {
this.animateTransformY( animateTransformYParams );
} else {
// no group to move so just run the next part
functionToRunAfterAnimate();
}
} else {
if ( SVGRowXmainBlocksGROUP !== undefined ) {
SVGRowXmainBlocksGROUP.hide();
}
if ( mainBlocksBoxUnderEachRow !== undefined ) {
mainBlocksBoxUnderEachRow.hide();
}
var yToTransformTo = hiddenBlocksHeight;
var functionToRunAfterAnimate = function(){
hiddenBlocksForRowSet.show();
if ( hiddenBlocksBoxUnderEachRow !== undefined ) {
hiddenBlocksBoxUnderEachRow.show();
}
SVGGroupExpansionIcon.hide();
SVGrowMainGroupProgramaticDataStorage.setHiddenBlocksVisible( true );
var adjustChildParams = {
animateAdjustChildGroupOfRowsVerticalOffset: animateAdjustChildGroupOfRowsVerticalOffset,
$rowMainGroup: $rowMainGroup
};
objectThis.adjustChildGroupOfRowsVerticalOffset( adjustChildParams );
objectThis.resizeOverallImageLength();
};
var animateTransformYParams = {
SVGoGroupToMove: SVGoGroupToMove,
yToTransformTo: yToTransformTo,
functionToRunAfterAnimate: functionToRunAfterAnimate
};
if ( SVGoGroupToMove ) {
this.animateTransformY( animateTransformYParams );
} else {
// no group to move so just run the next part
functionToRunAfterAnimate();
}
}
}
return false; // to stop bubbling up the click
};
/////////////////////////////
/////////////////////////////////
// Ajust the vertical offset of the Child group of rows to account for the new height in the current group of rows
MasonViewerPerInstanceRenderOnPage.prototype. adjustChildGroupOfRowsVerticalOffset = function( params ) {
// var objectThis = this;
var $rowMainGroup = params.$rowMainGroup;
var animateAdjustChildGroupOfRowsVerticalOffset = params.animateAdjustChildGroupOfRowsVerticalOffset;
var $groupOfRows = this.get$groupOfRowsFor$currentElement($rowMainGroup );
var SVGgroupOfRows = this.getSVG_js_itemForJQueryObj( $groupOfRows );
var groupOfRowsSVGgroupProgramaticStorage = this.getProgramaticDataStorageFromSVG_js_Item( SVGgroupOfRows );
var childGroupOfRowsProgramaticDataStorageGroupOfRows = groupOfRowsSVGgroupProgramaticStorage.getNextProgramaticDataStorageGroupOfRows();
if ( childGroupOfRowsProgramaticDataStorageGroupOfRows ) {
var SVGgroupOfRowXandBelow = groupOfRowsSVGgroupProgramaticStorage.getFirstOutputRowSVGGroup();
var totalHiddenRowsVerticalOffset = 0;
while ( SVGgroupOfRowXandBelow ) {
var rowProgramaticStorage = this.getProgramaticDataStorageFromSVG_js_Item( SVGgroupOfRowXandBelow );
if ( rowProgramaticStorage.getHiddenBlocksVisible() ) {
totalHiddenRowsVerticalOffset += rowProgramaticStorage.getHiddenBlocksHeight();
}
SVGgroupOfRowXandBelow = rowProgramaticStorage.getGroupToMoveForExpansion();
}
var childGroupOfRows = childGroupOfRowsProgramaticDataStorageGroupOfRows.getSVGGroup();
if ( animateAdjustChildGroupOfRowsVerticalOffset ) {
var animateTransformYParams = {
SVGoGroupToMove: childGroupOfRows,
yToTransformTo: totalHiddenRowsVerticalOffset,
functionToRunAfterAnimate: function(){}
};
this.animateTransformY( animateTransformYParams );
} else {
childGroupOfRows.transform( { y: totalHiddenRowsVerticalOffset } );
}
}
};
// mason_viewer_55_render_on_page_main_row.js
// This is a part of MasonViewer
////////////// !!!!!!!!!!!!! Order of calling "precompute" call backs.
/////// For the Main blocks and the Hidden blocks, the precompute is called for each block right before the call to get the color
/////// For the Totals Per Row blocks on the right, the precompute is called for all the rows before the get color and size is called for each block
////// For the Totals Row, the precompute is called for all the rows before the get color is called for each block
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// Visible as attributes in the DOM
// blockBlockSVG.data( "label", { d1: 12, d4: "wwww"} );
// NOT Visible as attributes in the DOM
// blockBlockSVG.remember('oldBBox', { d1: 12, d4: "wwww"} );
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
//////////////////////////////////
// Create a callback to create the hidden blocks if not created
MasonViewerPerInstanceRenderOnPage.prototype. createMainLineHiddenBlocksIfNotCreatedCallbackCreator = function ( outputRow, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowOffset ) {
var objectThis = this;
// create callback function
var createHiddenBlocksIfNotCreatedCallback = function() {
var hiddenBlocksForRowSet = currentSVGgroupOfRowXandBelowProgramaticDataStorage.getHiddenBlocksForRowSet( );
var outputRow = currentSVGgroupOfRowXandBelowProgramaticDataStorage.getOutputRow();
if ( outputRow !== undefined && outputRow !== null ) {
var splitAnyEntries = outputRow.splitAnyEntries;
if ( splitAnyEntries && ( hiddenBlocksForRowSet === undefined || hiddenBlocksForRowSet === null ) ) {
objectThis.processHiddenBlocksForRow( outputRow, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowOffset );
}
}
};
// assign callback function to storage
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setCreateHiddenBlocksIfNotCreatedCallback( createHiddenBlocksIfNotCreatedCallback );
};
//////////////////////////////////
// call the precompute call backs for the main rows.
// ONLY for main totals blocks on the right
MasonViewerPerInstanceRenderOnPage.prototype. precomputeValuesOnCreateForMainRows = function ( outputRows ) {
var objectThis = this;
for ( var rowIdx = 0; rowIdx < outputRows.length; rowIdx++ ) {
var outputRow = outputRows[ rowIdx ];
if ( outputRow.callbackDataStorage === undefined ) {
outputRow.callbackDataStorage = {};
}
// precomputeValuesOnCreate for Row Totals Bar on Right
if ( objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions.precomputeValuesOnCreate ) {
// Only Call if it exists
var precomputeValuesOnCreateParams = { rowItem: outputRow.inputRowItem, callbackDataStorage: outputRow.callbackDataStorage };
objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
}
};
//////////////////////////////////////////////
// Process the row total block, currently added to the right of the main grid
MasonViewerPerInstanceRenderOnPage.prototype. processRowTotalBlockForRow = function( outputRow, currentSVGgroupOfRowXandBelow, rowIdx ) {
var objectThis = this;
if ( ( ! objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions ) ||
( ! objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions.getColorAndSize ) ) {
return; // Exit if the call back functions do not exist
}
var getColorAndSizeParams = { rowItem: outputRow.inputRowItem, callbackDataStorage: outputRow.callbackDataStorage };
var colorAndSize = objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions.getColorAndSize( getColorAndSizeParams );
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var sizeZeroToOne = colorAndSize.blockSize;
if ( sizeZeroToOne > 0 ) {
var colorForBlock = colorAndSize.colorForBlock;
// returns colorForBlock = { red: 10, green: 255, blue: 1 }
// or colorForBlock = "#RRGGBB" (6 positions hex color)
var fillColor = this.convertBlockColorTo_SVGJS_FillColor( colorForBlock );
var rectWidth = sizeZeroToOne * this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_MAX_WIDTH;;
if ( rectWidth < this.configDisplayOptions.ROW_TOTAL_BLOCK_MINIMUM_SIZE ) {
rectWidth = this.configDisplayOptions.ROW_TOTAL_BLOCK_MINIMUM_SIZE;
}
var rowTotalBlockSVG = this.GLOBALS.masonViewerSVG.rect( rectWidth, this.configDisplayOptions.BLOCK_HEIGHT ).attr( { fill: fillColor } );
rowTotalBlockSVG.move( this.GLOBALS.rowTotalsBarRightStartingPoint, y );
this.addProgramaticDataStorageToSVG_js_Item( rowTotalBlockSVG );
rowTotalBlockSVG.data( "row-rowIdx", rowIdx );
rowTotalBlockSVG.data( "placement", "row total blocks" );
currentSVGgroupOfRowXandBelow.add( rowTotalBlockSVG );
}
// add a cover block of the full width
var rowTotalBlockCoverBlockFullWidthSVG =
this.GLOBALS.masonViewerSVG.rect( this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_MAX_WIDTH, this.configDisplayOptions.BLOCK_HEIGHT )
.attr( { fill: { r: 255, g: 255, b: 255 },
stroke: { r: 0, g: 0, b: 0 },
"stroke-width": 0.3,
"fill-opacity": 0 } );
rowTotalBlockCoverBlockFullWidthSVG.move( this.GLOBALS.rowTotalsBarRightStartingPoint, y );
this.addProgramaticDataStorageToSVG_js_Item( rowTotalBlockCoverBlockFullWidthSVG );
this.attachMouseOverRowTotalBlock( rowTotalBlockCoverBlockFullWidthSVG, outputRow );
this.attachClickHandlerRowTotalBlock( rowTotalBlockCoverBlockFullWidthSVG, outputRow );
rowTotalBlockCoverBlockFullWidthSVG.data( "row-rowIdx", rowIdx );
rowTotalBlockCoverBlockFullWidthSVG.data( "placement", "row total blocks" );
currentSVGgroupOfRowXandBelow.add( rowTotalBlockCoverBlockFullWidthSVG );
};
////////////////////////////////////////////////////////
///// Main Label
// Create Tool Tip for label, retrieves HTML from callback, called by wTooltip plugin
///////////////
// Create Tool Tip for the label at the start of the row
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverMainRowLabel = function( labelSVG, outputRow ) {
var objectThis = this;
if ( ( ! objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions ) ||
( ! objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.getToolTipText ) ) {
return; // Exit if the call back functions do not exist
}
var $labelSVG = this.getJQueryObjForRawSVGFromSVG_js_item( labelSVG );
var getToolTipTextParams = {
rowItem: outputRow.inputRowItem,
callbackDataStorage: outputRow.callbackDataStorage
};
this.attachToolTipToJqueryHtmlNode( $labelSVG, function( tooltip, node ) {
var tooltipHTML = objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.getToolTipText( getToolTipTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
} );
};
///////////////
// Handle Click for the label at the start of the row
MasonViewerPerInstanceRenderOnPage.prototype. attachClickHandlerMainRowLabel = function( labelSVG, outputRow ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.processClick === undefined
) {
return; // No click handler so exit early
}
var $labelSVG = this.getJQueryObjForRawSVGFromSVG_js_item( labelSVG );
var processClickParams = {
rowItem: outputRow.inputRowItem,
callbackDataStorage: outputRow.callbackDataStorage
};
$labelSVG.click( function( eventObject ) {
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.processClick( processClickParams );
});
};
////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. processLabelForRow = function( outputRow, currentSVGgroupOfRowXandBelow, rowIdx ) {
var objectThis = this;
var labelText = outputRow.label;
// var splitAnyEntries = outputRow.splitAnyEntries;
var labelTextSVG = this.GLOBALS.masonViewerSVG.text( labelText );
// var labelTextSVGContent = labelTextSVG.content;
this.addProgramaticDataStorageToSVG_js_Item( labelTextSVG );
labelTextSVG.data( "row-rowIdx", rowIdx );
currentSVGgroupOfRowXandBelow.add( labelTextSVG );
// A hack to clear the broken font-size. Clear dy that was set to compensate
this.clearStyleAnd_dy_OnSVGtextItem( labelTextSVG );
// The "y" for a text item is the "baseline" of the font, the bottom of characters without decenders
// SVG.js would have attempted to compensate this to allow the "y" to be at the top of the letters but
// the method of specifying the font size was difficult to use and somewhat broken
var textY = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + ( this.configDisplayOptions.ROW_HEIGHT / 2 );
textY = textY + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var labelAdditionalStyle = "";
if ( objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.processClick ) {
labelAdditionalStyle = "; cursor: pointer;";
}
this.setSVGTextPosition( { textSVG: labelTextSVG, x: this.configDisplayOptions.LABEL_STARTING_POSITION, y: textY, otherAttrsToSet: undefined, additionalStyle: labelAdditionalStyle } );
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
// var labelTextSVG_BBox = labelTextSVG.bbox(); // The bbox() values are zero if the graph is hidden with the div having display: none;
if ( objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.precomputeValuesOnCreate ) {
var precomputeValuesOnCreateParams = { callbackDataStorage: outputRow.callbackDataStorage, rowItem: outputRow.inputRowItem };
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
if ( objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.getToolTipText ) {
this.attachMouseOverMainRowLabel( labelTextSVG, outputRow );
}
if ( objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsLabel_callbackFunctions.processClick ) {
this.attachClickHandlerMainRowLabel( labelTextSVG, outputRow );
}
// attachClickShowHideToggleHiddenBlocksRow( labelTextSVG );
//
// this.attachToolTipToJqueryHtmlNode( $(labelTextSVG.node), function(tooltip, node) {
//
// var $rowMainGroup = this.get$rowMainGroupFor$currentElement( $(node) );
//
// var SVGrowMainGroupProgramaticDataStorage = this.getProgramaticDataStorageFromJQueryItem( $rowMainGroup );
//
// var tooltipText = "";
//
// if ( SVGrowMainGroupProgramaticDataStorage.getHiddenBlocksVisible() ) {
//
// tooltipText = this.configDisplayOptions.CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT;
//
// } else {
//
// tooltipText = this.configDisplayOptions.CLICK_TO_EXPAND_TO_SHOW_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT;
// }
//
// $(tooltip).html( tooltipText );
//
// return tooltipText;
// });
// }
return labelTextSVG;
};
////////////////////////////////////////////////////////
///// Main blocks
// Create Tool Tip for blocks, retrieves HTML from callback, called by a tooltip
///////////////
// Create Tool Tip for a block in a row where the blocks do not overlap
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverBlockNonOverlappingBlocksRow = function( blockBlockSVG, blockData, outputRow ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.getNonOverlappingBlocksToolTipText === undefined
) {
return; // EXIT early since no call back function to call
}
var $blockBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockBlockSVG );
var getSingleBlockToolTipTextParams = {
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
blockDataItems: blockData.blockDataItems,
rowItem: outputRow.inputRowItem,
callbackDataStorage: blockData.callbackDataStorage
};
var getTooltipTextFcn = function( tooltip, node ) {
var tooltipHTML = objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.getNonOverlappingBlocksToolTipText( getSingleBlockToolTipTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
};
var callbackFunctions = {
mouseenter: function( node ) {
objectThis.callListenersForBlockMouseEnter( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
},
mouseleave: function( node ) {
objectThis.callListenersForBlockMouseLeave( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
}
};
this.attachToolTipToJqueryHtmlNode( $blockBlockSVG, getTooltipTextFcn, callbackFunctions );
};
///////////////
// Create Tool Tip for blocks for a block in a row row where the blocks do overlap
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverBlockOverlappingBlocksRow = function( blockBlockSVG, blockData, outputRow ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.getOverlappingBlocksToolTipText === undefined
) {
return; // EXIT early since no call back function to call
}
var $blockBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockBlockSVG );
var getSingleBlockToolTipTextParams = {
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
blockDataItems: blockData.blockDataItems,
rowItem: outputRow.inputRowItem,
callbackDataStorage: blockData.callbackDataStorage
};
var getTooltipTextFcn = function( tooltip, node ) {
var tooltipHTML = objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.getOverlappingBlocksToolTipText( getSingleBlockToolTipTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
};
var callbackFunctions = {
mouseenter: function( node ) {
objectThis.callListenersForBlockMouseEnter( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
},
mouseleave: function( node ) {
objectThis.callListenersForBlockMouseLeave( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
}
};
this.attachToolTipToJqueryHtmlNode( $blockBlockSVG, getTooltipTextFcn, callbackFunctions );
};
///////////////
// Handle Click for block in the row where the blocks do not overlap
MasonViewerPerInstanceRenderOnPage.prototype. attachClickHandlerBlockNonOverlappingBlocks = function( blockBlockSVG, blockData, outputRow ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.processClick === undefined
) {
return; // No click handler so exit early
}
var $blockBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockBlockSVG );
var processClickParams = {
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
blockDataItems: blockData.blockDataItems,
rowItem: outputRow.inputRowItem,
callbackDataStorage: blockData.callbackDataStorage
};
$blockBlockSVG.click( function( eventObject ) {
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.processClick( processClickParams );
});
};
////////////////////////////////////
//////// Totals block in the row
///////////////
// Create Tool Tip for Totals block in the row
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverRowTotalBlock = function( rowTotalBlockSVG, outputRow ) {
var objectThis = this;
if ( ( ! objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions ) ||
( ! objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions.getTotalBarToolTipText ) ) {
return; // Exit if the call back functions do not exist
}
var $rowTotalBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( rowTotalBlockSVG );
var getTotalBarToolTipTextParams = {
rowItem: outputRow.inputRowItem,
callbackDataStorage: outputRow.callbackDataStorage
};
this.attachToolTipToJqueryHtmlNode( $rowTotalBlockSVG, function( tooltip, node ) {
// var $blockBlockSVG = $(node);
var tooltipHTML =
objectThis.
constructorParams.
callbackFunctionsObj.
rowTotalBar_callbackFunctions.
getTotalBarToolTipText( getTotalBarToolTipTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
} );
};
///////////////
// Handle Click for Totals block in the row
MasonViewerPerInstanceRenderOnPage.prototype. attachClickHandlerRowTotalBlock = function( rowTotalBlockSVG, outputRow ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions.processClick === undefined
) {
return; // No click handler so exit early
}
var $rowTotalBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( rowTotalBlockSVG );
var processClickParams = {
rowItem: outputRow.inputRowItem,
callbackDataStorage: outputRow.callbackDataStorage
};
$rowTotalBlockSVG.click( function( eventObject ) {
objectThis.constructorParams.callbackFunctionsObj.rowTotalBar_callbackFunctions.processClick( processClickParams );
});
};
////////////////////////////////////////
// Get the internal memory representation of the hidden blocks in arrays of arrays where blockStartPosPixel and blockEndPosPixel are set
MasonViewerPerInstanceRenderOnPage.prototype. getHiddenBlocksForRow = function( outputRow ) {
// var objectThis = this;
// var maxSequenceLength = this.constructorParams.requestParams.inputData.maxSequenceLength;
var hiddenBlockRows = [];
var prevEnds = [];
var prevEndsScaled = [];
var prevEndsLastEntry = -1;
var blockItems = outputRow.blockItems;
for ( var blockItemIdx = 0; blockItemIdx < blockItems.length; blockItemIdx++ ) {
var blockItem = blockItems[ blockItemIdx ];
var blockData = blockItem;
var blockStartPos = blockData.blockStartPos;
var blockEndPos = blockData.blockEndPos;
var startPixel = this.positionLeftEdgeToPixel( blockStartPos );
var endPixel = this.positionRightEdgeToPixel( blockEndPos );
for ( var index = 0; index <= prevEndsLastEntry; index++ ) {
if ( blockItem.blockStartPos === ( prevEnds[ index ] + 1 ) ) {
startPixel = prevEndsScaled[ index ] + 0.01;
}
}
blockItem.blockStartPositionPixel = startPixel;
blockItem.blockEndPositionPixel = endPixel;
// find where to put this entry
var addedToList = false;
for ( var hiddenBlockRowsIdx = 0; hiddenBlockRowsIdx < hiddenBlockRows.length; hiddenBlockRowsIdx++ ) {
var hiddenBlockRow = hiddenBlockRows[ hiddenBlockRowsIdx ];
var blockItemInList = hiddenBlockRow[ hiddenBlockRow.length - 1 ];
if ( startPixel > ( blockItemInList.blockEndPositionPixel /* add 1 to not allow them to butt together + 1 */ ) ) {
addedToList = true;
hiddenBlockRow.push( blockItem );
break;
}
}
if ( ! addedToList ) {
var hiddenBlockRow_NewRow = [];
hiddenBlockRow_NewRow.push( blockItem );
hiddenBlockRows.push( hiddenBlockRow_NewRow );
}
prevEndsLastEntry++;
prevEnds[ prevEndsLastEntry ] = blockItem.blockEndPos;
prevEndsScaled[ prevEndsLastEntry ] = endPixel;
}
return hiddenBlockRows;
};
////////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. processHiddenBlocksForRow = function( outputRow, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowOffset ) {
var objectThis = this;
if ( ! objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions ||
! objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.precomputeValuesOnCreate ) {
throw "callback function mainRowsBlocks_callbackFunctions.precomputeValuesOnCreate is missing";
}
var groupOfHiddenBlocksForRow = this.GLOBALS.masonViewerSVG.group();
groupOfHiddenBlocksForRow.attr("label", "groupOfHiddenBlocksForRow");
currentSVGgroupOfRowXandBelow.add( groupOfHiddenBlocksForRow );
// Only set setHiddenBlocksForRowSet( ) when the set actually has contents. It is tested for undefined to mean empty
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setHiddenBlocksForRowSet( groupOfHiddenBlocksForRow );
// looping through the blockItems placing them into rows
var hiddenBlockRows = this.getHiddenBlocksForRow( outputRow );
var hiddenBlocksRowsHeight = ( hiddenBlockRows.length - 1 ) * this.configDisplayOptions.ROW_HEIGHT;
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setHiddenBlocksHeight( hiddenBlocksRowsHeight );
var boxUnderHeight = hiddenBlocksRowsHeight + this.configDisplayOptions.ROW_HEIGHT; // add for row being replaced since this is the true height
this.addHiddenBlocksBoxUnderEachRowForMouseOver( boxUnderHeight, groupOfHiddenBlocksForRow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowOffset );
// .attr( "vector-effect", "non-scaling-stroke" )
for ( var hiddenBlockRowIdx = 0; hiddenBlockRowIdx < hiddenBlockRows.length; hiddenBlockRowIdx++ ) {
var hiddenBlockRow = hiddenBlockRows[ hiddenBlockRowIdx ];
var hiddenBlocksRowItems = hiddenBlockRow;
// Looping through the hidden blocks for a given row
for ( var hiddenBlockIdx = 0; hiddenBlockIdx < hiddenBlocksRowItems.length; hiddenBlockIdx++ ) {
var blockData = hiddenBlocksRowItems[ hiddenBlockIdx ];
// Add callbackDataStorage to blockData
blockData.callbackDataStorage = {};
var precomputeValuesOnCreateParams =
{ rowItem: outputRow.inputRowItem,
blockDataItems: blockData.blockDataItems,
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
callbackDataStorage: blockData.callbackDataStorage,
splitAnyEntriesForRow: false, // always false for hidden blocks
forHiddenBlocks: true };
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
var x = blockData.blockStartPositionPixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION; // ADD OFFSET to allow for label on left
if ( x < this.configDisplayOptions.MAIN_BOX_STARTING_POSITION ) {
x = this.configDisplayOptions.MAIN_BOX_STARTING_POSITION ;
}
var y = ( ( hiddenBlockRowIdx ) * this.configDisplayOptions.ROW_HEIGHT ) + ( rowOffset * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var rectWidth = blockData.blockEndPositionPixel - blockData.blockStartPositionPixel ;
var getColorForBlockParams = { rowItem: outputRow.inputRowItem, blockDataItems: blockData.blockDataItems, callbackDataStorage: blockData.callbackDataStorage, forHiddenBlocks: true };
var colorForBlock = objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.getColorForBlock( getColorForBlockParams );
// returns colorForBlock = { red: 10, green: 255, blue: 1 }
// or colorForBlock = "#RRGGBB" (6 positions hex color)
var fillColor = this.convertBlockColorTo_SVGJS_FillColor( colorForBlock );
var blockBlockSVG = this.GLOBALS.masonViewerSVG.rect( rectWidth, this.configDisplayOptions.BLOCK_HEIGHT ).attr( { fill: fillColor } );
blockBlockSVG.move( x, y );
this.addMouseOverToBlocks( blockBlockSVG );
this.addProgramaticDataStorageToSVG_js_Item( blockBlockSVG );
blockBlockSVG.data( "row-rowIdx", rowOffset );
blockBlockSVG.data( "placement", "initially hidden row blocks" );
blockBlockSVG.data( "block-id", blockData.id );
// var programaticData = { };
this.attachMouseOverBlockNonOverlappingBlocksRow( blockBlockSVG, blockData, outputRow );
this.attachClickHandlerBlockNonOverlappingBlocks( blockBlockSVG, blockData, outputRow );
groupOfHiddenBlocksForRow.add( blockBlockSVG );
}
}
// Start processing Vertical Lines for this line
// Output the lines for the row
var mainLineLines = outputRow.vertLinesItems;
this.processHiddenLinesForRowVerticalLines( mainLineLines, hiddenBlockRows, groupOfHiddenBlocksForRow, rowOffset );
this.showHideAllVerticalDataLinesPer_GLOBALS_showVerticalDataLines( );
// End processing Vertical Lines for this line
var leftLine = this.GLOBALS.masonViewerSVG.line(
this.GLOBALS.leftLineX ,
( ( rowOffset ) * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.leftLineX ,
( ( ( rowOffset + 1 ) * this.configDisplayOptions.ROW_HEIGHT ) + hiddenBlocksRowsHeight ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
var rightLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.rightLineX,
( ( rowOffset ) * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.rightLineX,
( ( ( rowOffset + 1 ) * this.configDisplayOptions.ROW_HEIGHT ) + hiddenBlocksRowsHeight ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
leftLine.data("placement", "lines with initially hidden row blocks");
rightLine.data("placement", "lines with initially hidden row blocks");
groupOfHiddenBlocksForRow.add( leftLine );
groupOfHiddenBlocksForRow.add( rightLine );
this.createHiddenBlocksContractionIcon( this.configDisplayOptions.CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT, groupOfHiddenBlocksForRow, rowOffset, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
};
///////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. processHiddenLinesForRowVerticalLines = function( mainLineLines, hiddenBlockRows, groupOfHiddenBlocksForRow, rowOffset ) {
var objectThis = this;
// Start processing Vertical Lines for this line
// Output the lines for the row
if ( mainLineLines && mainLineLines.length > 0 &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.getColorForLine ) {
for ( var hiddenBlockRowIdx = 0; hiddenBlockRowIdx < hiddenBlockRows.length; hiddenBlockRowIdx++ ) {
// var hiddenBlockRow = hiddenBlockRows[ hiddenBlockRowIdx ];
// var hiddenBlocksRowItems = hiddenBlockRow;
for ( var mainLineLinesIdx = 0; mainLineLinesIdx < mainLineLines.length; mainLineLinesIdx++ ) {
var lineData = mainLineLines[ mainLineLinesIdx ];
// Add callbackDataStorage to lineData
lineData.callbackDataStorage = {};
if ( objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.precomputeValuesOnCreate )
{
var precomputeValuesOnCreateParams =
{ vertLineData: lineData.vertLineData,
linePos: lineData.linePos,
forHiddenLines: true,
callbackDataStorage: lineData.callbackDataStorage
};
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
var linePos = lineData.linePos;
var linePixel = this.positionCharPositionToPixel( linePos );
var x = linePixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
// var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var y = ( ( hiddenBlockRowIdx ) * this.configDisplayOptions.ROW_HEIGHT ) + ( rowOffset * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var getColorForLineParams = { vertLineData: lineData.vertLineData, callbackDataStorage: lineData.callbackDataStorage, forHiddenLines: true };
var colorForLine = objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.getColorForLine( getColorForLineParams );
// returns colorForLine = "#112233"
// throws exception if not valid
this.isValidColor( colorForLine );
var verticalLineSVG = this.GLOBALS.masonViewerSVG.line( x, y, x, y + this.configDisplayOptions.BLOCK_HEIGHT ).stroke( { color: colorForLine, width: this.configDisplayOptions.BORDER_WIDTH } );
this.GLOBALS.setSVGVerticalDataLines.add( verticalLineSVG );
this.addMouseOverToLinesInsideMainBox( verticalLineSVG );
this.addProgramaticDataStorageToSVG_js_Item( verticalLineSVG );
verticalLineSVG.data( "rowOffset_hiddenBlockRowIdx", rowOffset + "_" + hiddenBlockRowIdx );
verticalLineSVG.data( "placement", "primary row lines" );
verticalLineSVG.data( "block-id", lineData.id );
var attachMouseOverVerticalLineParams = {
verticalLineSVG: verticalLineSVG,
lineData: lineData,
callbackFunctions: objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions
};
this.attachMouseOverVerticalLine( attachMouseOverVerticalLineParams );
// currentSVGgroupOfRowXandBelow.add( verticalLineSVG );
// SVGRowXmainLinesSET.add( verticalLineSVG );
// TODO Adding to this Set is probably incorrect
groupOfHiddenBlocksForRow.add( verticalLineSVG );
}
}
}
};
////////////////////////////////////////
// mainLineBlocks:
// [
// {
// blockStartPos: 10,
// blockEndPos: 15,
// blockData: [ {"id":85,"otherData":"TheOtherData"} ] // This property is only pass through to the call back
//
// }
MasonViewerPerInstanceRenderOnPage.prototype. processMainLineBlocksForRow = function( outputRow, currentSVGgroupOfRowXandBelow, SVGRowXmainBlocksGROUP, rowIdx ) {
var objectThis = this;
if ( ! objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions ||
! objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.precomputeValuesOnCreate ) {
throw "callback function mainRowsBlocks_callbackFunctions.precomputeValuesOnCreate is missing";
}
if ( ! objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions ||
! objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.getColorForBlock ) {
throw "callback function mainRowsBlocks_callbackFunctions.getColorForBlock is missing";
}
var mainLineBlocks = outputRow.mainLineBlocks;
if ( mainLineBlocks.length > 0 ) {
var splitAnyEntriesForRow = outputRow.splitAnyEntries;
for ( var mainLineBlocksIdx = 0; mainLineBlocksIdx < mainLineBlocks.length; mainLineBlocksIdx++ ) {
var blockData = mainLineBlocks[ mainLineBlocksIdx ];
// Add callbackDataStorage to blockData
blockData.callbackDataStorage = {};
var precomputeValuesOnCreateParams =
{ rowItem: outputRow.inputRowItem,
blockDataItems: blockData.blockDataItems,
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
callbackDataStorage: blockData.callbackDataStorage,
splitAnyEntriesForRow: splitAnyEntriesForRow,
forHiddenBlocks: false };
objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
var blockStartPos = blockData.blockStartPos;
var blockEndPos = blockData.blockEndPos;
var startPixel = this.positionLeftEdgeToPixel( blockStartPos );
var endPixel = this.positionRightEdgeToPixel( blockEndPos );
var rectWidth = endPixel - startPixel;
var x = startPixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var getColorForBlockParams = { rowItem: outputRow.inputRowItem, blockDataItems: blockData.blockDataItems, callbackDataStorage: blockData.callbackDataStorage, forHiddenBlocks: false };
var colorForBlock = objectThis.constructorParams.callbackFunctionsObj.mainRowsBlocks_callbackFunctions.getColorForBlock( getColorForBlockParams );
// returns colorForBlock = { red: 10, green: 255, blue: 1 }
// or colorForBlock = "#RRGGBB" (6 positions hex color)
var fillColor = this.convertBlockColorTo_SVGJS_FillColor( colorForBlock );
var blockBlockSVG = this.GLOBALS.masonViewerSVG.rect( rectWidth, this.configDisplayOptions.BLOCK_HEIGHT ).attr( { fill: fillColor } );
blockBlockSVG.move( x, y );
this.addMouseOverToBlocks( blockBlockSVG );
this.addProgramaticDataStorageToSVG_js_Item( blockBlockSVG );
blockBlockSVG.data( "row-rowIdx", rowIdx );
blockBlockSVG.data( "placement", "primary row blocks" );
blockBlockSVG.data( "block-id", blockData.id );
if ( splitAnyEntriesForRow ) {
this.attachMouseOverBlockOverlappingBlocksRow( blockBlockSVG, blockData, outputRow );
} else {
this.attachMouseOverBlockNonOverlappingBlocksRow( blockBlockSVG, blockData, outputRow );
this.attachClickHandlerBlockNonOverlappingBlocks( blockBlockSVG, blockData, outputRow );
}
// currentSVGgroupOfRowXandBelow.add( blockBlockSVG );
SVGRowXmainBlocksGROUP.add( blockBlockSVG );
}
}
// Start processing Vertical Lines for this line
// Commented out to compare the speed.
// Would need to move this code elsewhere if still wanted,
// or have code that just draws single lines the height of the viewer like
// the way the alignment lines are drawn
// Output the lines for the row
var mainLineLines = outputRow.vertLinesItems;
this.processMainLineVerticalLines( mainLineLines, SVGRowXmainBlocksGROUP, rowIdx );
// End processing Vertical Lines for this row
// .attr( "vector-effect", "non-scaling-stroke" )
var leftLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.leftLineX , ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE, this.GLOBALS.leftLineX ,
( ( rowIdx + 1 ) * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
var rightLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.rightLineX,
( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.rightLineX,
( ( rowIdx + 1 ) * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
leftLine.data("placement", "lines with primary row blocks");
rightLine.data("placement", "lines with primary row blocks");
currentSVGgroupOfRowXandBelow.add( leftLine );
currentSVGgroupOfRowXandBelow.add( rightLine );
};
///////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. processMainLineVerticalLines = function( mainLineLines, SVGRowXmainBlocksGROUP, rowIdx ) {
var objectThis = this;
if ( mainLineLines && mainLineLines.length > 0 &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.getColorForLine ) {
for ( var mainLineLinesIdx = 0; mainLineLinesIdx < mainLineLines.length; mainLineLinesIdx++ ) {
var lineData = mainLineLines[ mainLineLinesIdx ];
// Add callbackDataStorage to lineData
lineData.callbackDataStorage = {};
if ( objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.precomputeValuesOnCreate )
{
var precomputeValuesOnCreateParams =
{
vertLineData: lineData.vertLineData,
linePos: lineData.linePos,
forHiddenLines: false,
callbackDataStorage: lineData.callbackDataStorage
};
objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
var linePos = lineData.linePos;
var linePixel = this.positionCharPositionToPixel( linePos );
var x = linePixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var getColorForLineParams = { vertLineData: lineData.vertLineData, callbackDataStorage: lineData.callbackDataStorage, forHiddenLines: false };
var colorForLine = objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions.getColorForLine( getColorForLineParams );
// returns colorForLine = "#112233"
// throws exception if not valid
this.isValidColor( colorForLine );
var verticalLineSVG = this.GLOBALS.masonViewerSVG.line( x, y, x, y + this.configDisplayOptions.BLOCK_HEIGHT ).stroke( { color: colorForLine, width: this.configDisplayOptions.BORDER_WIDTH } );
this.GLOBALS.setSVGVerticalDataLines.add( verticalLineSVG );
this.addMouseOverToLinesInsideMainBox( verticalLineSVG );
this.addProgramaticDataStorageToSVG_js_Item( verticalLineSVG );
verticalLineSVG.data( "row-rowIdx", rowIdx );
verticalLineSVG.data( "placement", "primary row lines" );
verticalLineSVG.data( "block-id", lineData.id );
var attachMouseOverVerticalLineParams = {
verticalLineSVG: verticalLineSVG,
lineData: lineData,
callbackFunctions: objectThis.constructorParams.callbackFunctionsObj.mainRowsVerticalLines_callbackFunctions
};
this.attachMouseOverVerticalLine( attachMouseOverVerticalLineParams );
// currentSVGgroupOfRowXandBelow.add( verticalLineSVG );
// SVGRowXmainLinesSET.add( verticalLineSVG );
// TODO Adding to this Set is probably incorrect
SVGRowXmainBlocksGROUP.add( verticalLineSVG );
}
}
};
// mason_viewer_render_on_page_pixel_positioning.js
// This is a part of MasonViewer
// Pixel positioning code
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// Visible as attributes in the DOM
// blockBlockSVG.data( "label", { d1: 12, d4: "wwww"} );
// NOT Visible as attributes in the DOM
// blockBlockSVG.remember('oldBBox', { d1: 12, d4: "wwww"} );
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
///////// All of these function expect "1" based positions
//////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. positionLeftEdgeToPixel = function( leftEdgeCharPosition ) {
leftEdgeCharPosition -= 0.5; // subract 0.5 to extend towards previous block
var positionPixel = this.positionPrivateCharPosToPixel( leftEdgeCharPosition );
return positionPixel;
};
//////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. positionRightEdgeToPixel = function( rightEdgeCharPosition ) {
rightEdgeCharPosition += 0.5; // add 0.5 to extend towards next block
var positionPixel = this.positionPrivateCharPosToPixel( rightEdgeCharPosition );
return positionPixel;
};
//////////////////////////////////////
// This is designed for lines
MasonViewerPerInstanceRenderOnPage.prototype. positionCharPositionToPixel = function( positionCharPosition ) {
var positionPixel = this.positionPrivateCharPosToPixel( positionCharPosition );
return positionPixel;
};
//////////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. positionPrivateCharPosToPixel = function( positionCharPosition ) {
positionCharPosition = this.limitCharPositionMaxSeqLength( positionCharPosition );
positionCharPosition -= 0.5; // subtract to be zero based
var positionPixel = ( positionCharPosition * this.GLOBALS.sequenceMultiplier );
return positionPixel;
};
//////////////////////////////////////
// restrict charPosition to the limits of the viewer
MasonViewerPerInstanceRenderOnPage.prototype. limitCharPositionMaxSeqLength = function( positionCharPosition ) {
var minPosition = 0.5;
var maxPosition = this.constructorParams.requestParams.inputData.maxSequenceLength + 0.5;
if ( positionCharPosition maxPosition ) {
positionCharPosition = maxPosition;
}
return positionCharPosition;
};
// mason_viewer_55_render_on_page_totals_row.js
// This is a part of MasonViewer
////////////// !!!!!!!!!!!!! Order of calling "precompute" call backs.
/////// For the Main blocks and the Hidden blocks, the precompute is called for each block right before the call to get the color
/////// For the Totals Per Row blocks on the right, the precompute is called for all the rows before the get color and size is called for each block
////// For the Totals Row, the precompute is called for all the rows before the get color is called for each block
//////////////////////////////////
// JavaScript directive: all variables have to be declared with "var", maybe other things
"use strict";
// https://github.com/wout/svg.js#animating-elements
// Svg.js has a dedicated color module handling different types of colors. Accepted values are:
// hex string; three based (e.g. #f06) or six based (e.g. #ff0066)
// rgb string; e.g. rgb(255, 0, 102)
// rgb object; e.g. { r: 255, g: 0, b: 102 }
// Visible as attributes in the DOM
// blockBlockSVG.data( "label", { d1: 12, d4: "wwww"} );
// NOT Visible as attributes in the DOM
// blockBlockSVG.remember('oldBBox', { d1: 12, d4: "wwww"} );
// SVG.js remember method doesn't just save a reference to an object so not using it
// !!!!!!!!!!! All variables that have SVG in them but not "$" are some instance of a type from the svg.js library !!!!!!!!
//////////////////////////////////////////////
//////// Blocks in the Totals Row
///////////////
// Create Tool Tip for blocks for a block in the Totals row
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverBlockTotalsOverlappingBlocksRow = function( blockBlockSVG, blockData ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getBlocksToolTipText === undefined
) {
return; // EXIT early since no call back function to call
}
var $blockBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockBlockSVG );
var getSingleBlockToolTipTextParams = {
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
blockDataItems: blockData.blockDataItems,
callbackDataStorage: blockData.callbackDataStorage
};
var getTooltipTextFcn = function( tooltip, node ) {
var tooltipHTML = objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getBlocksToolTipText( getSingleBlockToolTipTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
};
var callbackFunctions = {
mouseenter: function( node ) {
objectThis.callListenersForBlockMouseEnter( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
},
mouseleave: function( node ) {
objectThis.callListenersForBlockMouseLeave( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
}
};
this.attachToolTipToJqueryHtmlNode( $blockBlockSVG, getTooltipTextFcn, callbackFunctions );
};
///////////////
// Create Tool Tip for blocks for a block in the Totals row
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverBlockTotalsNonOverlappingBlocksRow = function( blockBlockSVG, blockData ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getBlocksToolTipText === undefined
) {
return; // EXIT early since no call back function to call
}
var $blockBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockBlockSVG );
var getSingleBlockToolTipTextParams = {
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
blockDataItems: blockData.blockDataItems,
callbackDataStorage: blockData.callbackDataStorage
};
var getTooltipTextFcn = function( tooltip, node ) {
var tooltipHTML = objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getBlocksToolTipText( getSingleBlockToolTipTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
};
var callbackFunctions = {
mouseenter: function( node ) {
objectThis.callListenersForBlockMouseEnter( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
},
mouseleave: function( node ) {
objectThis.callListenersForBlockMouseLeave( { node: node, blockInfo: getSingleBlockToolTipTextParams } );
}
};
this.attachToolTipToJqueryHtmlNode( $blockBlockSVG, getTooltipTextFcn, callbackFunctions );
};
///////////////
// Handle Click for blocks for a block in the Totals row
MasonViewerPerInstanceRenderOnPage.prototype. attachClickHandlerBlockCombinedRow = function( blockBlockSVG, blockData ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.processClick === undefined
) {
return; // No click handler so exit early
}
var $blockBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( blockBlockSVG );
var processClickParams = {
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
blockDataItems: blockData.blockDataItems,
callbackDataStorage: blockData.callbackDataStorage
};
$blockBlockSVG.click( function( eventObject ) {
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.processClick( processClickParams );
});
};
////////////////////////////////////
//////// Totals block in the Totals row
///////////////
// Create Tool Tip for Totals block in the Totals row
MasonViewerPerInstanceRenderOnPage.prototype. attachMouseOverCombinedRowTotalBlock = function( rowTotalBlockSVG, callbackDataStorage ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.getTotalBarToolTipText === undefined
) {
return; // No mouse over handler so exit early
}
var $rowTotalBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( rowTotalBlockSVG );
var getCombinedRowBlockToolTipTextParams = {
callbackDataStorage: callbackDataStorage
};
this.attachToolTipToJqueryHtmlNode( $rowTotalBlockSVG, function( tooltip, node ) {
// var $blockBlockSVG = $(node);
var tooltipHTML = objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.getTotalBarToolTipText( getCombinedRowBlockToolTipTextParams );
$(tooltip).html( tooltipHTML );
return tooltipHTML;
} );
};
///////////////
// Handle Click for Totals block in the Totals row
MasonViewerPerInstanceRenderOnPage.prototype. attachClickHandlerCombinedRowTotalBlock = function( rowTotalBlockSVG, callbackDataStorage ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.processClick === undefined
) {
return; // No click handler so exit early
}
var $rowTotalBlockSVG = this.getJQueryObjForRawSVGFromSVG_js_item( rowTotalBlockSVG );
var processClickParams = {
callbackDataStorage: callbackDataStorage
};
$rowTotalBlockSVG.click( function( eventObject ) {
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.processClick( processClickParams );
});
};
////////////////////////////////////////
////// Processing Totals Row at bottom
MasonViewerPerInstanceRenderOnPage.prototype. processCombinedRow = function( outputRows, rowIdx, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage ) {
// var objectThis = this;
currentSVGgroupOfRowXandBelow.attr("class", "prot_cov_viewer_group_row_main" );
currentSVGgroupOfRowXandBelow.attr("label", "Totals Row Group" );
// var rowIdx = outputRows.length;
var combinedBlockItems = this.combineTotalsBlocksWhereStartEndMatch( outputRows );
var splitOutput = this.constructorParams.objectThisMasonViewerPerInstance.combineOverlapsProteinPositionBased( combinedBlockItems );
var splitAnyEntries = splitOutput.splitAnyEntries;
var mainLineTotalBlocks = splitOutput.outputList;
this.processTotalsLabel( rowIdx, splitAnyEntries, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
this.addBoxUnderEachRowForMouseOver( currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowIdx );
var outputTotalRow = { mainLineTotalBlocks: mainLineTotalBlocks, combinedBlockItems: combinedBlockItems,
splitAnyEntries: splitAnyEntries };
var SVGRowXmainBlocksGROUP = this.GLOBALS.masonViewerSVG.group();
currentSVGgroupOfRowXandBelow.add( SVGRowXmainBlocksGROUP );
SVGRowXmainBlocksGROUP.attr("label", "SVGRowXmainBlocksGROUP_processCombinedRow");
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setSVGRowXmainBlocksGROUP( SVGRowXmainBlocksGROUP );
this.processCombinedRowMainLineBlocks( outputTotalRow, currentSVGgroupOfRowXandBelow, SVGRowXmainBlocksGROUP, rowIdx );
if ( splitAnyEntries ) {
this.createTotalsLineHiddenBlocksIfNotCreatedCallbackCreator( rowIdx, combinedBlockItems, splitOutput.splitAnyEntries,
currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage
// ,
// setOfTotalsHiddenBlocksForRow
);
// processCombinedRowHiddenBlocks( rowIdx, combinedBlockItems, splitOutput.splitAnyEntries,
// currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage,
// setOfTotalsHiddenBlocksForRow );
}
this.processRowTotalBlockForCombinedRow( rowIdx, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
};
//////////////////////////////////
// Create a callback to create the hidden blocks if not created
MasonViewerPerInstanceRenderOnPage.prototype. createTotalsLineHiddenBlocksIfNotCreatedCallbackCreator = function ( rowIdx, combinedBlockItems, splitAnyEntries,
currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage
// ,
// setOfTotalsHiddenBlocksForRow
) {
var objectThis = this;
// create callback function
var createHiddenBlocksIfNotCreatedCallback = function() {
var hiddenBlocksForRowSet = currentSVGgroupOfRowXandBelowProgramaticDataStorage.getHiddenBlocksForRowSet( );
if ( splitAnyEntries && ( hiddenBlocksForRowSet === undefined || hiddenBlocksForRowSet === null ) ) {
objectThis.processCombinedRowHiddenBlocks( rowIdx, combinedBlockItems, splitAnyEntries,
currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage
// ,
// setOfTotalsHiddenBlocksForRow
);
}
};
// assign callback function to storage
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setCreateHiddenBlocksIfNotCreatedCallback( createHiddenBlocksIfNotCreatedCallback );
};
//////////////////////
// Label for totals Row
MasonViewerPerInstanceRenderOnPage.prototype. processTotalsLabel = function( rowIdx, splitAnyEntries, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage ) {
var objectThis = this;
var labelText = this.configDisplayOptions.combinedLineLabel;
var labelTextSVG = this.GLOBALS.masonViewerSVG.text( labelText );
// var labelTextSVGContent = labelTextSVG.content;
this.addProgramaticDataStorageToSVG_js_Item( labelTextSVG );
labelTextSVG.data( "Totals-Label", "" );
currentSVGgroupOfRowXandBelow.add( labelTextSVG );
// A hack to clear the broken font-size. Clear dy that was set to compensate
objectThis.clearStyleAnd_dy_OnSVGtextItem( labelTextSVG );
// The "y" for a text item is the "baseline" of the font, the bottom of characters without decenders
// SVG.js would have attempted to compensate this to allow the "y" to be at the top of the letters but
// the method of specifying the font size was difficult to use and somewhat broken
var textY = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + ( this.configDisplayOptions.ROW_HEIGHT / 2 );
textY = textY + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var labelAdditionalStyle = "";
// if ( splitAnyEntries ) {
//
// labelAdditionalStyle = "; cursor: pointer;"
// }
this.setSVGTextPosition( { textSVG: labelTextSVG, x: this.configDisplayOptions.LABEL_STARTING_POSITION, y: textY, otherAttrsToSet: undefined, additionalStyle: labelAdditionalStyle } );
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
// var labelTextSVG_BBox = labelTextSVG.bbox(); // The bbox() values are zero if the graph is hidden with the div having display: none;
if ( this.configDisplayOptions.combinedLineTooltipHTML ) {
var labelTooltipHTML = this.configDisplayOptions.combinedLineTooltipHTML;
var $labelTextSVG = this.getJQueryObjForRawSVGFromSVG_js_item( labelTextSVG );
this.attachToolTipToJqueryHtmlNode( $labelTextSVG, function( tooltip, node ) {
var tooltipHTML = labelTooltipHTML;
$(tooltip).html( tooltipHTML );
return tooltipHTML;
} );
}
if ( splitAnyEntries ) {
this.createHiddenBlocksExpansionIcon( this.configDisplayOptions.CLICK_TO_EXPAND_TO_SHOW_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT, currentSVGgroupOfRowXandBelow, rowIdx, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
}
// return labelTextSVG; Not used so not returned
};
////////////////////////////////////////
// Get the internal memory representation of the totals blocks in arrays of arrays where blockStartPosPixel and blockEndPosPixel are set
MasonViewerPerInstanceRenderOnPage.prototype. combineTotalsBlocksWhereStartEndMatch = function( outputRows ) {
// var objectThis = this;
var combinedBlockItems = [];
// First roll all the blockItems into one array
var allBlockItems = [];
for ( var outputRowsIdx = 0; outputRowsIdx < outputRows.length; outputRowsIdx++ ) {
var outputRow = outputRows[ outputRowsIdx ];
var blockItems = outputRow.blockItems;
for ( var blockItemIdx = 0; blockItemIdx < blockItems.length; blockItemIdx++ ) {
var blockItem = blockItems[ blockItemIdx ];
allBlockItems.push( blockItem );
}
}
// Now combine them
for ( var blockItemIdx = 0; blockItemIdx < allBlockItems.length; blockItemIdx++ ) {
var blockItem = allBlockItems[ blockItemIdx ];
if ( blockItem !== null ) {
for ( var blockItemOtherIdx = blockItemIdx + 1; blockItemOtherIdx < allBlockItems.length; blockItemOtherIdx++ ) {
var blockItemOther = allBlockItems[ blockItemOtherIdx ];
if ( blockItemOther !== null ) {
if ( blockItem.blockStartPos === blockItemOther.blockStartPos && blockItem.blockEndPos === blockItemOther.blockEndPos ) {
blockItem.blockDataItems = blockItem.blockDataItems.concat( blockItemOther.blockDataItems );
allBlockItems[ blockItemOtherIdx ] = null;
}
}
}
combinedBlockItems.push( blockItem );
}
}
combinedBlockItems.sort( this.constructorParams.objectThisMasonViewerPerInstance.combineOverlaps_Z_compareForSortBlocks );
return combinedBlockItems;
};
////////////////////////////////////////
// Get the internal memory representation of the totals blocks in arrays of arrays where blockStartPosPixel and blockEndPosPixel are set
MasonViewerPerInstanceRenderOnPage.prototype. placeTotalsBlocksIntoRows = function( blockItems ) {
// var objectThis = this;
var totalBlockRows = [];
var prevEnds = [];
var prevEndsScaled = [];
var prevEndsLastEntry = -1;
for ( var blockItemIdx = 0; blockItemIdx < blockItems.length; blockItemIdx++ ) {
var blockItem = blockItems[ blockItemIdx ];
var blockData = blockItem;
var blockStartPos = blockData.blockStartPos;
var blockEndPos = blockData.blockEndPos;
var startPixel = this.positionLeftEdgeToPixel( blockStartPos );
var endPixel = this.positionRightEdgeToPixel( blockEndPos );
for ( var index = 0; index <= prevEndsLastEntry; index++ ) {
if ( blockItem.blockStartPos === ( prevEnds[ index ] + 1 ) ) {
startPixel = prevEndsScaled[ index ] + .01;
}
}
blockItem.totalBlockStartPositionPixel = startPixel;
blockItem.totalBlockEndPositionPixel = endPixel;
// find where to put this entry
var addedToList = false;
for ( var totalBlockRowsIdx = 0; totalBlockRowsIdx < totalBlockRows.length; totalBlockRowsIdx++ ) {
var totalBlockRow = totalBlockRows[ totalBlockRowsIdx ];
var blockItemInList = totalBlockRow[ totalBlockRow.length - 1 ];
if ( startPixel > ( blockItemInList.totalBlockEndPositionPixel /* add 1 to not allow them to butt together + 1 */ ) ) {
addedToList = true;
totalBlockRow.push( blockItem );
break;
}
}
if ( ! addedToList ) {
var totalBlockRow_NewRow = [];
totalBlockRow_NewRow.push( blockItem );
totalBlockRows.push( totalBlockRow_NewRow );
}
prevEndsLastEntry++;
prevEnds[ prevEndsLastEntry ] = blockItem.blockEndPos;
prevEndsScaled[ prevEndsLastEntry ] = endPixel;
}
return totalBlockRows;
};
////////////////////////////////////////
// mainLineBlocks:
// [
// {
// blockStartPos: 10,
// blockEndPos: 15,
// blockData: [ {"id":85,"otherData":"TheOtherData"} ] // This property is only pass through to the call back
//
// }
MasonViewerPerInstanceRenderOnPage.prototype. processCombinedRowMainLineBlocks = function( outputRow, currentSVGgroupOfRowXandBelow, SVGRowXmainBlocksGROUP, rowIdx ) {
var objectThis = this;
if ( ! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions ||
! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.precomputeValuesOnCreate ) {
throw "callback function combinedRow_callbackFunctions.precomputeValuesOnCreate is missing";
}
if ( ! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions ||
! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getColorForBlock ) {
throw "callback function combinedRow_callbackFunctions.getColorForBlock is missing";
}
var mainLineBlocks = outputRow.mainLineTotalBlocks;
if ( mainLineBlocks.length > 0 ) {
var splitAnyEntriesForRow = outputRow.splitAnyEntries;
for ( var mainLineBlocksIdx = 0; mainLineBlocksIdx < mainLineBlocks.length; mainLineBlocksIdx++ ) {
var blockData = mainLineBlocks[ mainLineBlocksIdx ];
// Add callbackDataStorage to blockData
blockData.callbackDataStorage = {};
var precomputeValuesOnCreateParams =
{
blockDataItems: blockData.blockDataItems,
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
splitAnyEntriesForRow: splitAnyEntriesForRow,
callbackDataStorage: blockData.callbackDataStorage
};
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
var blockStartPos = blockData.blockStartPos;
var blockEndPos = blockData.blockEndPos;
var startPixel = this.positionLeftEdgeToPixel( blockStartPos );
var endPixel = this.positionRightEdgeToPixel( blockEndPos );
var rectWidth = endPixel - startPixel;
var x = startPixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var getColorForBlockParams = { blockDataItems: blockData.blockDataItems, callbackDataStorage: blockData.callbackDataStorage };
var colorForBlock = objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getColorForBlock( getColorForBlockParams );
// returns colorForBlock = { red: 10, green: 255, blue: 1 }
// or colorForBlock = "#RRGGBB" (6 positions hex color)
var fillColor = this.convertBlockColorTo_SVGJS_FillColor( colorForBlock );
var blockBlockSVG = this.GLOBALS.masonViewerSVG.rect( rectWidth, this.configDisplayOptions.BLOCK_HEIGHT ).attr( { fill: fillColor } );
blockBlockSVG.move( x, y );
this.addMouseOverToBlocks( blockBlockSVG );
this.addProgramaticDataStorageToSVG_js_Item( blockBlockSVG );
blockBlockSVG.data( "row-rowIdx", rowIdx );
blockBlockSVG.data( "placement", "primary row blocks" );
blockBlockSVG.data( "block-id", blockData.id );
if ( splitAnyEntriesForRow ) {
this.attachMouseOverBlockTotalsOverlappingBlocksRow( blockBlockSVG, blockData, outputRow );
} else {
this.attachMouseOverBlockTotalsNonOverlappingBlocksRow( blockBlockSVG, blockData, outputRow );
this.attachClickHandlerBlockCombinedRow( blockBlockSVG, blockData, outputRow );
}
// currentSVGgroupOfRowXandBelow.add( blockBlockSVG );
SVGRowXmainBlocksGROUP.add( blockBlockSVG );
}
}
// Start processing Vertical Lines for this line
// Output the lines for the row
var combinedRowLines = this.constructorParams.requestParams.inputData.vertLinesCombinedRow;
this.processCombinedRowMainLineVerticalLines( combinedRowLines, SVGRowXmainBlocksGROUP, rowIdx );
// End processing Vertical Lines for this line
// .attr( "vector-effect", "non-scaling-stroke" )
var leftLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.leftLineX , ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE, this.GLOBALS.leftLineX ,
( ( rowIdx + 1 ) * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
var rightLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.rightLineX,
( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.rightLineX,
( ( rowIdx + 1 ) * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
leftLine.data("placement", "left edge line for primary totals row blocks");
rightLine.data("placement", "right edge line for primary totals row blocks");
currentSVGgroupOfRowXandBelow.add( leftLine );
currentSVGgroupOfRowXandBelow.add( rightLine );
};
///////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. processCombinedRowMainLineVerticalLines = function( combinedRowLines, SVGRowXmainBlocksGROUP, rowIdx ) {
var objectThis = this;
if ( combinedRowLines && combinedRowLines.length > 0 &&
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.getColorForLine ) {
for ( var combinedRowLinesIdx = 0; combinedRowLinesIdx < combinedRowLines.length; combinedRowLinesIdx++ ) {
var lineData = combinedRowLines[ combinedRowLinesIdx ];
// Add callbackDataStorage to lineData
lineData.callbackDataStorage = {};
if ( objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.precomputeValuesOnCreate )
{
var precomputeValuesOnCreateParams =
{ vertLineData: lineData.vertLineData,
linePos: lineData.linePos,
forHiddenLines: false,
callbackDataStorage: lineData.callbackDataStorage
};
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
var linePos = lineData.linePos;
var linePixel = this.positionCharPositionToPixel( linePos );
var x = linePixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var getColorForLineParams = { vertLineData: lineData.vertLineData, callbackDataStorage: lineData.callbackDataStorage, forHiddenLines: false };
var colorForLine = objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.getColorForLine( getColorForLineParams );
// returns colorForLine = "#112233"
// throws exception if not valid
this.isValidColor( colorForLine );
var verticalLineSVG = this.GLOBALS.masonViewerSVG.line( x, y, x, y + this.configDisplayOptions.BLOCK_HEIGHT ).stroke( { color: colorForLine, width: this.configDisplayOptions.BORDER_WIDTH } );
this.GLOBALS.setSVGVerticalDataLines.add( verticalLineSVG );
this.addProgramaticDataStorageToSVG_js_Item( verticalLineSVG );
verticalLineSVG.data( "row-rowIdx", rowIdx );
verticalLineSVG.data( "placement", "primary totals row lines" );
verticalLineSVG.data( "block-id", lineData.id );
var attachMouseOverVerticalLineParams = {
verticalLineSVG: verticalLineSVG,
lineData: lineData,
callbackFunctions: objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions
};
this.attachMouseOverVerticalLine( attachMouseOverVerticalLineParams );
// currentSVGgroupOfRowXandBelow.add( verticalLineSVG );
// SVGRowXmainLinesSET.add( verticalLineSVG );
// TODO Adding to this Set is probably incorrect
SVGRowXmainBlocksGROUP.add( verticalLineSVG );
}
}
// End processing Vertical Lines for this line
};
////////////////////////////////////////
// Output hidden blocks for totals row
MasonViewerPerInstanceRenderOnPage.prototype. processCombinedRowHiddenBlocks
= function( rowIdx, combinedBlockItems, splitAnyEntriesForRow,
currentSVGgroupOfRowXandBelow,
currentSVGgroupOfRowXandBelowProgramaticDataStorage
// ,
// setOfTotalBlocksForRow
) {
var objectThis = this;
if ( ! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions ||
! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.precomputeValuesOnCreate ) {
throw "callback function combinedRow_callbackFunctions.precomputeValuesOnCreate is missing";
}
if ( ! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions ||
! objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getColorForBlock ) {
throw "callback function combinedRow_callbackFunctions.getColorForBlock is missing";
}
// var setOfTotalsHiddenBlocksForRow = this.GLOBALS.masonViewerSVG.set(); // set of all the hidden blocks in this row
var groupOfTotalsHiddenBlocksForRow = this.GLOBALS.masonViewerSVG.group(); // set of all the hidden blocks in this row
currentSVGgroupOfRowXandBelow.add( groupOfTotalsHiddenBlocksForRow );
groupOfTotalsHiddenBlocksForRow.attr("label", "groupOfTotalsHiddenBlocksForRow_processCombinedRow");
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setHiddenBlocksForRowSet( groupOfTotalsHiddenBlocksForRow );
var firstRowY = rowIdx * this.configDisplayOptions.ROW_HEIGHT;
var totalBlockRows = this.placeTotalsBlocksIntoRows( combinedBlockItems );
var totalBlocksRowsHeight = totalBlockRows.length * this.configDisplayOptions.ROW_HEIGHT;
var totalBlocksRowsHeightForHiddenBlockHeight = ( totalBlockRows.length - 1 ) * this.configDisplayOptions.ROW_HEIGHT;
currentSVGgroupOfRowXandBelowProgramaticDataStorage.setHiddenBlocksHeight( totalBlocksRowsHeightForHiddenBlockHeight );
this.addTotalsBlocksBoxUnderEachRowForMouseOver( totalBlocksRowsHeight, groupOfTotalsHiddenBlocksForRow, currentSVGgroupOfRowXandBelowProgramaticDataStorage, rowIdx );
// First loop through calling the "precompute"
for ( var totalBlockRowIdx = 0; totalBlockRowIdx < totalBlockRows.length; totalBlockRowIdx++ ) {
var totalBlockRow = totalBlockRows[ totalBlockRowIdx ];
var totalBlocksRowItems = totalBlockRow;
// Looping through the total blocks for a given row
for ( var totalBlockIdx = 0; totalBlockIdx < totalBlocksRowItems.length; totalBlockIdx++ ) {
var blockData = totalBlocksRowItems[ totalBlockIdx ];
blockData.callbackDataStorage = {};
var precomputeValuesOnCreateParams =
{
blockDataItems: blockData.blockDataItems,
startPos: blockData.blockStartPos,
endPos: blockData.blockEndPos,
splitAnyEntriesForRow: false, // always false for hidden blocks
forHiddenBlocks: true,
callbackDataStorage: blockData.callbackDataStorage
};
objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
}
for ( var totalBlockRowIdx = 0; totalBlockRowIdx < totalBlockRows.length; totalBlockRowIdx++ ) {
var totalBlockRow = totalBlockRows[ totalBlockRowIdx ];
var totalBlocksRowItems = totalBlockRow;
// Looping through the total blocks for a given row
for ( var totalBlockIdx = 0; totalBlockIdx < totalBlocksRowItems.length; totalBlockIdx++ ) {
var blockData = totalBlocksRowItems[ totalBlockIdx ];
var x = blockData.totalBlockStartPositionPixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION; // ADD OFFSET to allow for label on left
if ( x < this.configDisplayOptions.MAIN_BOX_STARTING_POSITION ) {
x = this.configDisplayOptions.MAIN_BOX_STARTING_POSITION ;
}
var y = ( ( totalBlockRowIdx ) * this.configDisplayOptions.ROW_HEIGHT ) + ( firstRowY );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var rectWidth = blockData.totalBlockEndPositionPixel - blockData.totalBlockStartPositionPixel;
var getColorForBlockParams = { blockDataItems: blockData.blockDataItems, callbackDataStorage: blockData.callbackDataStorage };
var colorForBlock = objectThis.constructorParams.callbackFunctionsObj.combinedRow_callbackFunctions.getColorForBlock( getColorForBlockParams );
// returns colorForBlock = { red: 10, green: 255, blue: 1 }
// or colorForBlock = "#RRGGBB" (6 positions hex color)
var fillColor = this.convertBlockColorTo_SVGJS_FillColor( colorForBlock );
var blockBlockSVG = this.GLOBALS.masonViewerSVG.rect( rectWidth, this.configDisplayOptions.BLOCK_HEIGHT ).attr( { fill: fillColor } );
blockBlockSVG.move( x, y );
this.addMouseOverToBlocks( blockBlockSVG );
this.addProgramaticDataStorageToSVG_js_Item( blockBlockSVG );
blockBlockSVG.data( "row-rowIdx", rowIdx );
blockBlockSVG.data( "placement", "initially hidden total row blocks" );
blockBlockSVG.data( "block-id", blockData.id );
this.attachMouseOverBlockTotalsNonOverlappingBlocksRow( blockBlockSVG, blockData );
this.attachClickHandlerBlockCombinedRow( blockBlockSVG, blockData );
currentSVGgroupOfRowXandBelow.add( blockBlockSVG );
groupOfTotalsHiddenBlocksForRow.add( blockBlockSVG );
// blockBlockSVG.hide();
}
}
// Start processing Vertical Lines for this line
// Output the lines for the row
var combinedRowLines = this.constructorParams.requestParams.inputData.vertLinesCombinedRow;
this.processCombinedRowHiddenLinesVerticalLines( combinedRowLines, totalBlockRows, groupOfTotalsHiddenBlocksForRow, rowIdx );
this.showHideAllVerticalDataLinesPer_GLOBALS_showVerticalDataLines( );
// .attr( "vector-effect", "non-scaling-stroke" )
var leftLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.leftLineX , ( firstRowY ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.leftLineX ,
( ( firstRowY ) + totalBlocksRowsHeight ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
var rightLine = this.GLOBALS.masonViewerSVG.line( this.GLOBALS.rightLineX,
( firstRowY ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE,
this.GLOBALS.rightLineX,
( ( firstRowY ) + totalBlocksRowsHeight ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE ).stroke( { color: this.configDisplayOptions.BORDER_COLOR, width: this.configDisplayOptions.BORDER_WIDTH } );
// currentSVGgroupOfRowXandBelow.add( leftLine );
// currentSVGgroupOfRowXandBelow.add( rightLine );
groupOfTotalsHiddenBlocksForRow.add( leftLine );
groupOfTotalsHiddenBlocksForRow.add( rightLine );
// leftLine.hide();
// rightLine.hide();
// createHiddenBlocksContractionIcon( this.configDisplayOptions.CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT, currentSVGgroupOfRowXandBelow, rowIdx, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
this.createHiddenBlocksContractionIcon( this.configDisplayOptions.CLICK_TO_CONTRACT_TO_HIDE_INDIVIDUAL_BLOCKS_TOOLTIP_TEXT, groupOfTotalsHiddenBlocksForRow, rowIdx, currentSVGgroupOfRowXandBelowProgramaticDataStorage );
groupOfTotalsHiddenBlocksForRow.hide();
};
///////////////////////////////////
MasonViewerPerInstanceRenderOnPage.prototype. processCombinedRowHiddenLinesVerticalLines = function( combinedRowLines, totalBlockRows, groupOfTotalsHiddenBlocksForRow, rowIdx ) {
var objectThis = this;
// Start processing Vertical Lines for this line
// Output the lines for the row
if ( combinedRowLines && combinedRowLines.length > 0 &&
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.getColorForLine ) {
for ( var totalBlockRowIdx = 0; totalBlockRowIdx < totalBlockRows.length; totalBlockRowIdx++ ) {
// var totalBlockRow = totalBlockRows[ totalBlockRowIdx ];
// var totalBlocksRowItems = totalBlockRow;
for ( var combinedRowLinesIdx = 0; combinedRowLinesIdx < combinedRowLines.length; combinedRowLinesIdx++ ) {
var lineData = combinedRowLines[ combinedRowLinesIdx ];
// Add callbackDataStorage to lineData
lineData.callbackDataStorage = {};
if ( objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions &&
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.precomputeValuesOnCreate )
{
var precomputeValuesOnCreateParams =
{
vertLineData: lineData.vertLineData,
linePos: lineData.linePos,
forHiddenLines: true,
callbackDataStorage: lineData.callbackDataStorage
};
objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
}
var linePos = lineData.linePos;
var linePixel = this.positionCharPositionToPixel( linePos );
var x = linePixel + this.configDisplayOptions.MAIN_BOX_STARTING_POSITION;// ADD OFFSET to allow for label on left
// var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT ) + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var y = ( ( totalBlockRowIdx ) * this.configDisplayOptions.ROW_HEIGHT ) + ( rowIdx * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var getColorForLineParams = {
vertLineData: lineData.vertLineData,
callbackDataStorage: lineData.callbackDataStorage, forHiddenLines: false };
var colorForLine = objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions.getColorForLine( getColorForLineParams );
// returns colorForLine = "#112233"
// throws exception if not valid
this.isValidColor( colorForLine );
var verticalLineSVG = this.GLOBALS.masonViewerSVG.line( x, y, x, y + this.configDisplayOptions.BLOCK_HEIGHT ).stroke( { color: colorForLine, width: this.configDisplayOptions.BORDER_WIDTH } );
this.GLOBALS.setSVGVerticalDataLines.add( verticalLineSVG );
this.addMouseOverToLinesInsideMainBox( verticalLineSVG );
this.addProgramaticDataStorageToSVG_js_Item( verticalLineSVG );
verticalLineSVG.data( "rowIdx_combinedRowLinesIdx", rowIdx + "_" + combinedRowLinesIdx );
verticalLineSVG.data( "placement", "initally hidden totals row lines" );
verticalLineSVG.data( "block-id", lineData.id );
var attachMouseOverVerticalLineParams = {
verticalLineSVG: verticalLineSVG,
lineData: lineData,
callbackFunctions: objectThis.constructorParams.callbackFunctionsObj.combinedRowVerticalLines_callbackFunctions
};
this.attachMouseOverVerticalLine( attachMouseOverVerticalLineParams );
// currentSVGgroupOfRowXandBelow.add( verticalLineSVG );
// SVGRowXmainLinesSET.add( verticalLineSVG );
// TODO Adding to this Set is probably incorrect
groupOfTotalsHiddenBlocksForRow.add( verticalLineSVG );
}
}
}
};
//////////////////////////////////////////////
// Process the Totals Row Total Block, currently added to the right of the main grid
MasonViewerPerInstanceRenderOnPage.prototype. processRowTotalBlockForCombinedRow = function( rowIdx, currentSVGgroupOfRowXandBelow, currentSVGgroupOfRowXandBelowProgramaticDataStorage ) {
var objectThis = this;
if ( objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions === null ) {
return; // Exit if call back functions not defined
}
if ( objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.precomputeValuesOnCreate === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.precomputeValuesOnCreate === null ) {
return; // Exit if call back functions not defined
}
if ( objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.getColorAndSize === undefined ||
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.getColorAndSize === null ) {
return; // Exit if call back functions not defined
}
var callbackDataStorage = {};
// precomputeValuesOnCreate for Row Totals Bar on Right
var precomputeValuesOnCreateParams = { callbackDataStorage: callbackDataStorage };
objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.precomputeValuesOnCreate( precomputeValuesOnCreateParams );
var getColorAndSizeParams = { callbackDataStorage: callbackDataStorage };
var colorAndSize = objectThis.constructorParams.callbackFunctionsObj.combinedRowTotalBar_callbackFunctions.getColorAndSize( getColorAndSizeParams );
var y = ( rowIdx * this.configDisplayOptions.ROW_HEIGHT );
y = y + this.configDisplayOptions.TOP_ROW_OFFSET_FROM_TOP_OF_IMAGE;
var sizeZeroToOne = colorAndSize.blockSize;
if ( sizeZeroToOne > 0 ) {
var colorForBlock = colorAndSize.colorForBlock;
// returns colorForBlock = { red: 10, green: 255, blue: 1 }
// or colorForBlock = "#RRGGBB" (6 positions hex color)
var fillColor = this.convertBlockColorTo_SVGJS_FillColor( colorForBlock );
var rectWidth = sizeZeroToOne * this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_MAX_WIDTH;;
if ( rectWidth < this.configDisplayOptions.ROW_TOTAL_BLOCK_MINIMUM_SIZE ) {
rectWidth = this.configDisplayOptions.ROW_TOTAL_BLOCK_MINIMUM_SIZE;
}
var rowTotalBlockSVG = this.GLOBALS.masonViewerSVG.rect( rectWidth, this.configDisplayOptions.BLOCK_HEIGHT ).attr( { fill: fillColor } );
rowTotalBlockSVG.move( this.GLOBALS.rowTotalsBarRightStartingPoint, y );
this.addProgramaticDataStorageToSVG_js_Item( rowTotalBlockSVG );
rowTotalBlockSVG.data( "row-rowIdx", rowIdx );
rowTotalBlockSVG.data( "placement", "totals row: row total blocks" );
currentSVGgroupOfRowXandBelow.add( rowTotalBlockSVG );
}
// add a cover block of the full width
var rowTotalBlockCoverBlockFullWidthSVG =
this.GLOBALS.masonViewerSVG.rect( this.configDisplayOptions.ROW_TOTALS_BAR_RIGHT_MAX_WIDTH, this.configDisplayOptions.BLOCK_HEIGHT )
.attr( { fill: { r: 255, g: 255, b: 255 },
stroke: { r: 0, g: 0, b: 0 },
"stroke-width": 0.3,
"fill-opacity": 0 } );
rowTotalBlockCoverBlockFullWidthSVG.move( this.GLOBALS.rowTotalsBarRightStartingPoint, y );
this.addProgramaticDataStorageToSVG_js_Item( rowTotalBlockCoverBlockFullWidthSVG );
this.attachMouseOverCombinedRowTotalBlock( rowTotalBlockCoverBlockFullWidthSVG, callbackDataStorage );
this.attachClickHandlerCombinedRowTotalBlock( rowTotalBlockCoverBlockFullWidthSVG, callbackDataStorage );
rowTotalBlockCoverBlockFullWidthSVG.data( "row-rowIdx", rowIdx );
rowTotalBlockCoverBlockFullWidthSVG.data( "placement", "totals row: row total blocks clear overlay" );
currentSVGgroupOfRowXandBelow.add( rowTotalBlockCoverBlockFullWidthSVG );
};
// mason_viewer_95_end_outer_enclosing_function.js
// !!!!!!!! IMPORTANT, only include this file when building the combined file !!!!!!!!!!!!!!!!!!!!!!!!!
// This file is expected to get a compile error.
// The matching closing "{" is in the file mason_viewer_05_start_outer_enclosing_function.js
// All the files: mason_viewer_01 thru mason_viewer_95 are to be included in the order they are numbered
// If including directly into the page for testing, skip mason_viewer_01 and mason_viewer_95
})( window );