Commit d75438e8 authored by Joshua Gould's avatar Joshua Gould

scroll lens updates

parent db2d4b78
...@@ -2316,9 +2316,10 @@ morpheus.HeatMap.prototype = { ...@@ -2316,9 +2316,10 @@ morpheus.HeatMap.prototype = {
} else if (this.tooltipMode === 1) { } else if (this.tooltipMode === 1) {
this.$tipInfoWindow.html(tipText); this.$tipInfoWindow.html(tipText);
} }
if (tipFollowText !== '') { if (tipFollowText !== '') {
this.tipFollowHidden = false; this.tipFollowHidden = false;
this.$tipFollow.css('class', 'morpheus-tip-inline morpheus-padding-ver').html('<span style="max-width:400px;">' + tipFollowText + '</span>'); this.$tipFollow.html('<span style="max-width:400px;">' + tipFollowText + '</span>');
this._updateTipFollowPosition(options); this._updateTipFollowPosition(options);
} else { } else {
this.tipFollowHidden = true; this.tipFollowHidden = true;
......
morpheus.HeatMapToolBar = function(controller) { morpheus.HeatMapToolBar = function (controller) {
this.controller = controller; this.controller = controller;
this.rowSearchResultModelIndices = []; this.rowSearchResultModelIndices = [];
this.columnSearchResultModelIndices = []; this.columnSearchResultModelIndices = [];
var _this = this; var _this = this;
var $el = $('<div name="toolbar" class=" hidden-print container-fluid">' var $el = $('<div name="toolbar" class=" hidden-print container-fluid">'
+ '<div class="row"><div name="toolbarSearch" class="col-xs-12"></div></div>' + '<div class="row"><div name="lineOneColumn" class="col-xs-12"></div></div>'
+ '<div class="row"><div name="toolbarButtons" class="col-xs-12" style="border-bottom: 1px solid #e7e7e7;padding-bottom:4px; margin-bottom:14px;"></div></div>' + '<div class="row"><div name="lineTwoColumn" class="col-xs-12" style="border-bottom: 1px solid #e7e7e7;padding-bottom:4px; margin-bottom:14px;"></div></div>'
+ '</div>'); + '</div>');
var searchHtml = []; var searchHtml = [];
var $search = $('<form name="searchForm" class="form form-inline" role="search"></form>'); var $search = $('<form name="searchForm" class="form form-inline" role="search"></form>');
$search.on('submit', function(e) { $search.on('submit', function (e) {
e.preventDefault(); e.preventDefault();
}); });
// search rows // search rows
if (controller.options.toolbar.searchRows) { if (controller.options.toolbar.searchRows) {
searchHtml.push('<div class="form-group">'); searchHtml.push('<div class="form-group">');
searchHtml.push('<div class="input-group input-group-sm">'); // group searchHtml.push('<div class="input-group input-group-sm">');
searchHtml.push('<div class="input-group-btn">'); searchHtml.push('<div class="input-group-btn">');
searchHtml searchHtml
.push('<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span data-toggle="tooltip" title="Search rows. Quote search term for exact match. Narrow search with field: modifier. Exclude matches using - modifier. Use min..max to perform a range search.">Rows</span> <span class="caret"></span></button>'); .push('<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span data-toggle="tooltip" title="Search rows. Quote search term for exact match. Narrow search with field: modifier. Exclude matches using - modifier. Use min..max to perform a range search.">Rows</span> <span class="caret"></span></button>');
searchHtml.push('<ul name="rowSearchOptions" class="dropdown-menu">'); searchHtml.push('<ul name="rowSearchOptions" class="dropdown-menu">');
searchHtml.push('<li><a name="exact" href="#">Exact Match</a></li>'); searchHtml.push('<li><a name="exact" href="#">Exact Match</a></li>');
searchHtml searchHtml
.push('<li class="active"><a name="contains" href="#">Contains</a></li>'); .push('<li class="active"><a name="contains" href="#">Contains</a></li>');
searchHtml.push('</ul>'); searchHtml.push('</ul>');
searchHtml.push('</div>'); // input-group-btn searchHtml.push('</div>'); // input-group-btn
searchHtml searchHtml
.push('<input type="text" style="width:240px;padding-right:25px;" class="form-control input-sm" autocomplete="off" name="searchRows">'); .push('<input type="text" style="border-top:3px solid rgb(127,127,127);width:240px;padding-buttons:25px;" class="form-control input-sm" autocomplete="off" name="searchRows">');
searchHtml.push('</div>');
searchHtml.push('</div>'); searchHtml.push('</div>');
searchHtml.push('<div class="form-group">'); searchHtml.push('<div class="form-group">');
searchHtml.push('<span name="rowSearchDiv" style="display:none;">'); searchHtml.push('<span name="rowSearchDiv" style="display:none;">');
searchHtml searchHtml
.push('<h6 name="searchResultsRows" style="display: inline;"></h6>'); .push('<h6 name="searchResultsRows" style="display: inline;"></h6>');
searchHtml searchHtml
.push('<button name="previousRowMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Previous"><i class="fa fa-chevron-up"></i></button>'); .push('<button name="previousRowMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Previous"><i class="fa fa-chevron-up"></i></button>');
searchHtml searchHtml
.push('<button name="nextRowMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Next"><i class="fa fa-chevron-down"></i></button>'); .push('<button name="nextRowMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Next"><i class="fa fa-chevron-down"></i></button>');
searchHtml searchHtml
.push('<button name="rowMatchesToTop" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Matches To Top"><i class="fa fa-level-up"></i></button>'); .push('<button name="rowMatchesToTop" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Matches To Top"><i class="fa fa-level-up"></i></button>');
searchHtml.push('</span>'); searchHtml.push('</span>');
searchHtml.push('</div>'); searchHtml.push('</div>');
} }
if (controller.options.toolbar.searchColumns) { if (controller.options.toolbar.searchColumns) {
searchHtml searchHtml
.push('<div class="form-group" style="margin-right:18px;"></div>'); // spacer .push('<div class="form-group" style="margin-buttons:18px;"></div>'); // spacer
// search columns // search columns
searchHtml.push('<div class="form-group">'); searchHtml.push('<div class="form-group">');
searchHtml.push('<div class="input-group input-group-sm">'); // group searchHtml.push('<div class="input-group input-group-sm">'); // group
searchHtml.push('<div class="input-group-btn">'); searchHtml.push('<div class="input-group-btn">');
searchHtml searchHtml
.push('<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span data-toggle="tooltip" title="Search columns. Quote search term for exact match. Narrow search with field: modifier. Exclude matches using - modifier. Use min..max to perform a range search.">Columns</span> <span class="caret"></span></button>'); .push('<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span data-toggle="tooltip" title="Search columns. Quote search term for exact match. Narrow search with field: modifier. Exclude matches using - modifier. Use min..max to perform a range search.">Columns</span> <span class="caret"></span></button>');
searchHtml searchHtml
.push('<ul name="columnSearchOptions" class="dropdown-menu">'); .push('<ul name="columnSearchOptions" class="dropdown-menu">');
searchHtml.push('<li><a name="exact" href="#">Exact Match</a></li>'); searchHtml.push('<li><a name="exact" href="#">Exact Match</a></li>');
searchHtml searchHtml
.push('<li class="active"><a name="contains" href="#">Contains</a></li>'); .push('<li class="active"><a name="contains" href="#">Contains</a></li>');
searchHtml.push('</ul>'); searchHtml.push('</ul>');
searchHtml.push('</div>'); // input-group-btn searchHtml.push('</div>'); // input-group-btn
searchHtml searchHtml
.push('<input type="text" style="width:240px;padding-right:25px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchColumns"></div>'); .push('<input type="text" style="border-buttons:4px solid rgb(127,127,127);width:240px;padding-buttons:25px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchColumns"></div>');
searchHtml.push('</div>');
searchHtml.push('</div>'); searchHtml.push('</div>');
searchHtml.push('<div class="form-group" style="margin-left:4px;">'); searchHtml.push('<div class="form-group" style="margin-left:4px;">');
searchHtml searchHtml
.push('<h6 name="searchResultsColumns" style="display: inline;"></h6>'); .push('<h6 name="searchResultsColumns" style="display: inline;"></h6>');
searchHtml.push('<span name="columnSearchDiv" style="display:none;">'); searchHtml.push('<span name="columnSearchDiv" style="display:none;">');
searchHtml searchHtml
.push('<button name="previousColumnMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Previous"><i class="fa fa-chevron-up"></i></button>'); .push('<button name="previousColumnMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Previous"><i class="fa fa-chevron-up"></i></button>');
searchHtml searchHtml
.push('<button name="nextColumnMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Next"><i class="fa fa-chevron-down"></i></button>'); .push('<button name="nextColumnMatch" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Next"><i class="fa fa-chevron-down"></i></button>');
searchHtml searchHtml
.push('<button name="columnMatchesToTop" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Matches To Top"><i class="fa fa-level-up"></i></button>'); .push('<button name="columnMatchesToTop" type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Matches To Top"><i class="fa fa-level-up"></i></button>');
searchHtml.push('</span>'); searchHtml.push('</span>');
searchHtml.push('</div>'); searchHtml.push('</div>');
} }
// search values // search values
searchHtml searchHtml
.push('<div name="searchValuesDiv" class="form-group" style="margin-left:18px;">'); .push('<div name="searchValuesDiv" class="form-group" style="margin-left:18px;">');
searchHtml searchHtml
.push('<div class="input-group input-group-sm"><span class="input-group-addon">Values</span><input type="text" style="width:240px;padding-right:25px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchValues"></div>'); .push('<div class="input-group input-group-sm"><span class="input-group-addon">Values</span><input type="text" style="width:240px;padding-buttons:25px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchValues"></div>');
searchHtml.push('</div>'); searchHtml.push('</div>');
searchHtml.push('<div class="form-group" style="margin-left:4px;">'); searchHtml.push('<div class="form-group" style="margin-left:4px;">');
searchHtml searchHtml
.push('<h6 name="searchResultsValues" style="display: inline;"></h6>'); .push('<h6 name="searchResultsValues" style="display: inline;"></h6>');
searchHtml.push('</div>'); searchHtml.push('</div>');
// row dendrogram // row dendrogram
searchHtml searchHtml
.push('<div style="display: none; margin-left:18px;" name="searchRowDendrogramWrapper" class="form-group">'); .push('<div style="display: none; margin-left:18px;" name="searchRowDendrogramWrapper" class="form-group">');
searchHtml searchHtml
.push('<div class="input-group input-group-sm"><span class="input-group-addon">Row Dendrogram</span><input type="text" style="width:240px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchRowDendrogram"></div>'); .push('<div class="input-group input-group-sm"><span class="input-group-addon">Row Dendrogram</span><input type="text" style="width:240px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchRowDendrogram"></div>');
searchHtml searchHtml
.push('<h6 name="searchResultsRowDendrogram" style="display: inline;"></h6>'); .push('<h6 name="searchResultsRowDendrogram" style="display: inline;"></h6>');
searchHtml.push('</div>'); searchHtml.push('</div>');
// column dendrogram // column dendrogram
searchHtml searchHtml
.push('<div style="display: none; margin-left:18px;" name="searchColumnDendrogramWrapper" class="form-group">'); .push('<div style="display: none; margin-left:18px;" name="searchColumnDendrogramWrapper" class="form-group">');
searchHtml searchHtml
.push('<div class="input-group input-group-sm"><span class="input-group-addon">Column Dendrogram</span><input type="text" style="width:240px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchColumnDendrogram"></div>'); .push('<div class="input-group input-group-sm"><span class="input-group-addon">Column Dendrogram</span><input type="text" style="width:240px;" class="form-control input-sm" autocapitalize="off" autocomplete="off" name="searchColumnDendrogram"></div>');
searchHtml searchHtml
.push('<h6 name="searchResultsColumnDendrogram" style="display: inline;"></h6>'); .push('<h6 name="searchResultsColumnDendrogram" style="display: inline;"></h6>');
searchHtml.push('</div>'); searchHtml.push('</div>');
// dimensions // dimensions
searchHtml.push('<div class="form-group" name="datasetInfoGroup">'); searchHtml.push('<div class="form-group" name="datasetInfoGroup">');
searchHtml searchHtml
.push('<h6 style="display: inline; margin-left:30px;" name="dim"></h6>'); .push('<h6 style="display: inline; margin-left:30px;" name="dim"></h6>');
searchHtml searchHtml
.push('<h6 style="display: inline; margin-left:30px;" name="selection"></h6>'); .push('<h6 style="display: inline; margin-left:30px;" name="selection"></h6>');
searchHtml.push('</div>'); searchHtml.push('</div>');
searchHtml.push('<div name="right" class="form-group pull-right">'); searchHtml.push('<div name="buttons" style="margin-left:18px;" class="form-group"></div>');
// searchHtml
// .push('<div id="hangout-div"></div>');
// searchHtml
// .push('<button onclick="TogetherJS(this); return false;" type="button"
// class="btn btn-default btn-xs" title="Collaboration"><i class="fa
// fa-users"></button></i>');
// searchHtml.push('<span style="margin-left:6px;"></span>');
// searchHtml
// .push('<button name="tutorial" type="button" class="btn btn-default
// btn-xs" title="Tutorial"><i class="fa
// fa-question-circle"></button></i>');
searchHtml.push('</div>');
$(searchHtml.join('')).appendTo($search); $(searchHtml.join('')).appendTo($search);
if (!controller.options.toolbar.searchValues) { if (!controller.options.toolbar.searchValues) {
$search.find('[name=searchValuesDiv]').css('display', 'none'); $search.find('[name=searchValuesDiv]').css('display', 'none');
} }
if (controller.options.tour) { var $buttons = $search.find('[name=buttons]');
var $tour = $('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Take a tour"><i class="fa fa-plane"></i></button>');
$tour.prependTo($search.find('[name=right]'));
$tour.on('click', function(e) {
e.preventDefault();
controller.options.tour(controller);
});
}
if (controller.options.$help) {
controller.options.$help.appendTo($search.find('[name=right]'));
}
var $tools = $('<form name="tools" class="form-inline" role="form"></form>'); var $tools = $('<form name="tools" class="form-inline" role="form"></form>');
$tools.on('submit', function(e) { $tools.on('submit', function (e) {
e.preventDefault(); e.preventDefault();
}); });
var $toolbarForm = $('<form name="view" class="form-inline" role="form"></form>');
$toolbarForm.on('submit', function(e) {
e.preventDefault();
});
var toolbarHtml = []; var toolbarHtml = [];
// zoom // zoom
if (controller.options.toolbar.zoom) { if (controller.options.toolbar.zoom) {
toolbarHtml.push('<div class="form-group">');
toolbarHtml toolbarHtml
.push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Zoom Out (-)" name="out"><span class="fa fa-minus"></span></button>'); .push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Zoom Out (-)" name="out"><span class="fa fa-minus"></span></button>');
toolbarHtml toolbarHtml
.push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Zoom In (+)" name="in"><span class="fa fa-plus"></span></button>'); .push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Zoom In (+)" name="in"><span class="fa fa-plus"></span></button>');
toolbarHtml toolbarHtml
.push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Fit To Window" name="fit"><span class="fa fa-compress"></span></button>'); .push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Fit To Window" name="fit"><span class="fa fa-compress"></span></button>');
toolbarHtml toolbarHtml
.push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Reset Zoom" name="resetZoom">100%</button>'); .push('<button type="button" class="btn btn-default btn-xs" data-toggle="tooltip" title="Reset Zoom" name="resetZoom">100%</button>');
} }
toolbarHtml.push('<div class="morpheus-button-divider"></div>'); toolbarHtml.push('<div class="morpheus-button-divider"></div>');
if (controller.options.toolbar.sort) { if (controller.options.toolbar.sort) {
toolbarHtml toolbarHtml
.push('<button data-toggle="tooltip" title="Sort" name="sort" type="button" class="btn btn-default btn-xs"><span class="fa fa-sort-alpha-asc"></span></button>'); .push('<button data-toggle="tooltip" title="Sort" name="sort" type="button" class="btn btn-default btn-xs"><span class="fa fa-sort-alpha-asc"></span></button>');
} }
if (controller.options.toolbar.options) { if (controller.options.toolbar.options) {
toolbarHtml toolbarHtml
.push('<button name="options" data-toggle="tooltip" title="Options" type="button" class="btn btn-default btn-xs"><span class="fa fa-cog"></span></button>'); .push('<button name="options" data-toggle="tooltip" title="Options" type="button" class="btn btn-default btn-xs"><span class="fa fa-cog"></span></button>');
} }
toolbarHtml.push('<div class="morpheus-button-divider"></div>'); toolbarHtml.push('<div class="morpheus-button-divider"></div>');
if (controller.options.toolbar.saveImage) { if (controller.options.toolbar.saveImage) {
toolbarHtml toolbarHtml
.push('<button name="saveImage" data-toggle="tooltip" title="Save Image (' .push('<button name="saveImage" data-toggle="tooltip" title="Save Image ('
+ morpheus.Util.COMMAND_KEY + morpheus.Util.COMMAND_KEY
+ 'S)" type="button" class="btn btn-default btn-xs"><span class="fa fa-file-image-o"></span></button>'); + 'S)" type="button" class="btn btn-default btn-xs"><span class="fa fa-file-image-o"></span></button>');
} }
if (controller.options.toolbar.saveDataset) { if (controller.options.toolbar.saveDataset) {
toolbarHtml toolbarHtml
.push('<button name="saveDataset" data-toggle="tooltip" title="Save Dataset (' .push('<button name="saveDataset" data-toggle="tooltip" title="Save Dataset ('
+ morpheus.Util.COMMAND_KEY + morpheus.Util.COMMAND_KEY
+ 'Shift+S)" type="button" class="btn btn-default btn-xs"><span class="fa fa-floppy-o"></span></button>'); + 'Shift+S)" type="button" class="btn btn-default btn-xs"><span class="fa fa-floppy-o"></span></button>');
} }
if (controller.options.toolbar.openFile) { if (controller.options.toolbar.openFile) {
toolbarHtml toolbarHtml
.push('<button name="openFile" data-toggle="tooltip" title="Open File (' .push('<button name="openFile" data-toggle="tooltip" title="Open File ('
+ morpheus.Util.COMMAND_KEY + morpheus.Util.COMMAND_KEY
+ 'O)" type="button" class="btn btn-default btn-xs"><span class="fa fa-folder-open-o"></span></button>'); + 'O)" type="button" class="btn btn-default btn-xs"><span class="fa fa-folder-open-o"></span></button>');
} }
toolbarHtml.push('<div class="morpheus-button-divider"></div>'); toolbarHtml.push('<div class="morpheus-button-divider"></div>');
if (controller.options.toolbar.filter) { if (controller.options.toolbar.filter) {
toolbarHtml toolbarHtml
.push('<button name="filterButton" data-toggle="tooltip" title="Filter" type="button" class="btn btn-default btn-xs"><span class="fa fa-filter"></span></button>'); .push('<button name="filterButton" data-toggle="tooltip" title="Filter" type="button" class="btn btn-default btn-xs"><span class="fa fa-filter"></span></button>');
} }
if (typeof Plotly !== 'undefined') { if (typeof Plotly !== 'undefined') {
toolbarHtml toolbarHtml
.push('<button name="chart" data-toggle="tooltip" title="Chart" type="button" class="btn btn-default btn-xs"><span class="fa fa-line-chart"></span></button>'); .push('<button name="chart" data-toggle="tooltip" title="Chart" type="button" class="btn btn-default btn-xs"><span class="fa fa-line-chart"></span></button>');
} }
var tools = [ { var tools = [{
tool : new morpheus.HClusterTool() tool: new morpheus.HClusterTool()
}, { }, {
tool : new morpheus.MarkerSelection() tool: new morpheus.MarkerSelection()
}, { }, {
tool : new morpheus.NearestNeighbors() tool: new morpheus.NearestNeighbors()
}, { }, {
tool : new morpheus.NewHeatMapTool(), tool: new morpheus.NewHeatMapTool(),
}, null, { }, null, {
tool : new morpheus.AdjustDataTool() tool: new morpheus.AdjustDataTool()
}, { }, {
tool : new morpheus.CollapseDatasetTool() tool: new morpheus.CollapseDatasetTool()
}, { }, {
tool : new morpheus.CreateAnnotation() tool: new morpheus.CreateAnnotation()
}, { }, {
tool : new morpheus.SimilarityMatrixTool() tool: new morpheus.SimilarityMatrixTool()
}, { }, {
tool : new morpheus.TransposeTool() tool: new morpheus.TransposeTool()
}, { }, {
tool : new morpheus.WordCloudTool() tool: new morpheus.WordCloudTool()
} ]; // DevAPI, { }]; // DevAPI, {
this.getToolByName = function(name) { this.getToolByName = function (name) {
for (var i = 0; i < tools.length; i++) { for (var i = 0; i < tools.length; i++) {
if (tools[i] && tools[i].tool.toString if (tools[i] && tools[i].tool.toString
&& tools[i].tool.toString() === name) { && tools[i].tool.toString() === name) {
return tools[i].tool; return tools[i].tool;
} }
} }
...@@ -234,19 +210,19 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -234,19 +210,19 @@ morpheus.HeatMapToolBar = function(controller) {
if (controller.options.toolbar.tools) { if (controller.options.toolbar.tools) {
toolbarHtml.push('<div class="btn-group">'); toolbarHtml.push('<div class="btn-group">');
toolbarHtml toolbarHtml
.push('<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span title="Tools" data-toggle="tooltip" class="fa fa-wrench"></span> <span class="fa fa-caret-down"></span></button>'); .push('<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span title="Tools" data-toggle="tooltip" class="fa fa-wrench"></span> <span class="fa fa-caret-down"></span></button>');
toolbarHtml.push('<ul name="tools" class="dropdown-menu" role="menu">'); toolbarHtml.push('<ul name="tools" class="dropdown-menu" role="menu">');
for (var i = 0; i < tools.length; i++) { for (var i = 0; i < tools.length; i++) {
if (tools[i] == null) { if (tools[i] == null) {
toolbarHtml toolbarHtml
.push('<li role="presentation" class="divider"></li>'); .push('<li role="presentation" class="divider"></li>');
} else if (tools[i].action) { } else if (tools[i].action) {
toolbarHtml.push('<li><a name="' + i + '" href="#">' toolbarHtml.push('<li><a name="' + i + '" href="#">'
+ tools[i].name + '</a></li>'); + tools[i].name + '</a></li>');
} else { } else {
toolbarHtml.push('<li><a name="' + i + '" href="#">' toolbarHtml.push('<li><a name="' + i + '" href="#">'
+ tools[i].tool.toString() + '</a></li>'); + tools[i].tool.toString() + '</a></li>');
} }
} }
toolbarHtml.push('</ul></div>'); toolbarHtml.push('</ul></div>');
...@@ -258,27 +234,25 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -258,27 +234,25 @@ morpheus.HeatMapToolBar = function(controller) {
toolbarHtml.push('<div class="btn-group">'); toolbarHtml.push('<div class="btn-group">');
toolbarHtml toolbarHtml
.push('<button type="button" class="btn btn-default btn-xs" data-toggle="dropdown"><span title="Color Key" data-toggle="tooltip" class="fa fa-key"></span></button>'); .push('<button type="button" class="btn btn-default btn-xs" data-toggle="dropdown"><span title="Color Key" data-toggle="tooltip" class="fa fa-key"></span></button>');
toolbarHtml.push('<ul name="key" class="dropdown-menu" role="menu">'); toolbarHtml.push('<ul name="key" class="dropdown-menu" role="menu">');
toolbarHtml.push('<li name="keyContent"></li>'); toolbarHtml.push('<li name="keyContent"></li>');
toolbarHtml.push('</ul>'); toolbarHtml.push('</ul>');
toolbarHtml.push('</div>'); toolbarHtml.push('</div>');
} }
toolbarHtml $search.appendTo($el.find('[name=lineOneColumn]'));
.push('<div style="position:relative;display:inline;margin-left:12px;"><div name="tip" class="morpheus-tip" style="overflow:hidden;"></div></div>'); var $toolbarForm = $(toolbarHtml.join(''));
toolbarHtml.push('</div>'); $toolbarForm.appendTo($buttons);
$search.appendTo($el.find('[name=toolbarSearch]')); if (controller.options.$help) {
$(toolbarHtml.join('')).appendTo($toolbarForm); controller.options.$help.appendTo($buttons);
$toolbarForm.appendTo($el.find('[name=toolbarButtons]')); }
$('<div name="tip" style="height: 14px; font-size: 12px;overflow:hidden;"></div>').appendTo($el.find('[name=lineTwoColumn]'));
$el.prependTo(controller.$content); $el.prependTo(controller.$content);
// gapi.hangout.render('hangout-div', {
// 'widget_size' : '72',
// 'render' : 'createhangout'
// });
var $tools = $el.find('[name=tools]'); var $tools = $el.find('[name=tools]');
this.$tip = $el.find('[name=tip]'); this.$tip = $el.find('[name=tip]');
$tools.on('click', 'li > a', function(e) { $tools.on('click', 'li > a', function (e) {
e.preventDefault(); e.preventDefault();
var index = parseInt($(this).attr('name')); var index = parseInt($(this).attr('name'));
if (tools[index].tool) { if (tools[index].tool) {
...@@ -290,42 +264,42 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -290,42 +264,42 @@ morpheus.HeatMapToolBar = function(controller) {
this.defaultRowMatchMode = 'contains'; this.defaultRowMatchMode = 'contains';
this.defaultColumnMatchMode = 'contains'; this.defaultColumnMatchMode = 'contains';
var $rowSearchOptions = $el.find('[name=rowSearchOptions]'); var $rowSearchOptions = $el.find('[name=rowSearchOptions]');
$rowSearchOptions.on('click', 'li > a', function(e) { $rowSearchOptions.on('click', 'li > a', function (e) {
e.preventDefault(); e.preventDefault();
_this.defaultRowMatchMode = $(this).attr('name'); _this.defaultRowMatchMode = $(this).attr('name');
$rowSearchOptions.find('li').removeClass('active'); $rowSearchOptions.find('li').removeClass('active');
$(this).parent('li').addClass('active'); $(this).parent('li').addClass('active');
_this.search(true); _this.search(true);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'rowSearchMatchMode' eventAction: 'rowSearchMatchMode'
}); });
}); });
var $columnSearchOptions = $el.find('[name=columnSearchOptions]'); var $columnSearchOptions = $el.find('[name=columnSearchOptions]');
$columnSearchOptions.on('click', 'li > a', function(e) { $columnSearchOptions.on('click', 'li > a', function (e) {
e.preventDefault(); e.preventDefault();
_this.defaultColumnMatchMode = $(this).attr('name'); _this.defaultColumnMatchMode = $(this).attr('name');
$columnSearchOptions.find('li').removeClass('active'); $columnSearchOptions.find('li').removeClass('active');
$(this).parent('li').addClass('active'); $(this).parent('li').addClass('active');
_this.search(false); _this.search(false);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'columnSearchMatchMode' eventAction: 'columnSearchMatchMode'
}); });
}); });
var filterModal = []; var filterModal = [];
var filterLabelId = _.uniqueId('morpheus'); var filterLabelId = _.uniqueId('morpheus');
filterModal filterModal
.push('<div class="modal fade" tabindex="1" role="dialog" aria-labelledby="' .push('<div class="modal fade" tabindex="1" role="dialog" aria-labelledby="'
+ filterLabelId + '">'); + filterLabelId + '">');
filterModal.push('<div class="modal-dialog" role="document">'); filterModal.push('<div class="modal-dialog" role="document">');
filterModal.push('<div class="modal-content">'); filterModal.push('<div class="modal-content">');
filterModal.push('<div class="modal-header">'); filterModal.push('<div class="modal-header">');
filterModal filterModal
.push('<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>'); .push('<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>');
filterModal.push('<h4 class="modal-title" id="' + filterLabelId filterModal.push('<h4 class="modal-title" id="' + filterLabelId
+ '">Filter</h4>'); + '">Filter</h4>');
filterModal.push('</div>'); filterModal.push('</div>');
filterModal.push('<div class="modal-body">'); filterModal.push('<div class="modal-body">');
filterModal.push(''); filterModal.push('');
...@@ -334,7 +308,7 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -334,7 +308,7 @@ morpheus.HeatMapToolBar = function(controller) {
filterModal.push('</div>'); filterModal.push('</div>');
filterModal.push('</div>'); filterModal.push('</div>');
var $filterModal = $(filterModal.join('')); var $filterModal = $(filterModal.join(''));
$filterModal.on('mousewheel', function(e) { $filterModal.on('mousewheel', function (e) {
e.stopPropagation(); e.stopPropagation();
}); });
var $filter = $('<div></div>'); var $filter = $('<div></div>');
...@@ -342,40 +316,40 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -342,40 +316,40 @@ morpheus.HeatMapToolBar = function(controller) {
$filterModal.appendTo($el); $filterModal.appendTo($el);
var filterHtml = []; var filterHtml = [];
filterHtml filterHtml
.push('<div class="radio"><label><input type="radio" name="rowsOrColumns" value="rows" checked>Rows</label></div> '); .push('<div class="radio"><label><input type="radio" name="rowsOrColumns" value="rows" checked>Rows</label></div> ');
filterHtml filterHtml
.push('<div class="radio"><label><input type="radio" name="rowsOrColumns" value="columns">Columns</label></div>'); .push('<div class="radio"><label><input type="radio" name="rowsOrColumns" value="columns">Columns</label></div>');
var $filterChooser = $(filterHtml.join('')); var $filterChooser = $(filterHtml.join(''));
$filterChooser.appendTo($filter); $filterChooser.appendTo($filter);
var columnFilterUI = new morpheus.FilterUI(controller.getProject(), true); var columnFilterUI = new morpheus.FilterUI(controller.getProject(), true);
var rowFilterUI = new morpheus.FilterUI(controller.getProject(), false); var rowFilterUI = new morpheus.FilterUI(controller.getProject(), false);
controller.getProject().getRowFilter().on('focus', function(e) { controller.getProject().getRowFilter().on('focus', function (e) {
$filterChooser.find('[value=rows]').prop('checked', true); $filterChooser.find('[value=rows]').prop('checked', true);
columnFilterUI.$div.hide(); columnFilterUI.$div.hide();
rowFilterUI.$div.show(); rowFilterUI.$div.show();
$filterModal.modal('show'); $filterModal.modal('show');
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'rowFilter' eventAction: 'rowFilter'
}); });
}); });
controller.getProject().getColumnFilter().on('focus', function(e) { controller.getProject().getColumnFilter().on('focus', function (e) {
$filterChooser.find('[value=columns]').prop('checked', true); $filterChooser.find('[value=columns]').prop('checked', true);
columnFilterUI.$div.show(); columnFilterUI.$div.show();
rowFilterUI.$div.hide(); rowFilterUI.$div.hide();
$filterModal.modal('show'); $filterModal.modal('show');
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'columnFilter' eventAction: 'columnFilter'
}); });
}); });
rowFilterUI.$div.appendTo($filter); rowFilterUI.$div.appendTo($filter);
columnFilterUI.$div.appendTo($filter); columnFilterUI.$div.appendTo($filter);
columnFilterUI.$div.css('display', 'none'); columnFilterUI.$div.css('display', 'none');
var $filterRadio = $filterChooser.find('[name=rowsOrColumns]'); var $filterRadio = $filterChooser.find('[name=rowsOrColumns]');
$filterRadio.on('change', function(e) { $filterRadio.on('change', function (e) {
var val = $filterRadio.filter(':checked').val(); var val = $filterRadio.filter(':checked').val();
if (val === 'columns') { if (val === 'columns') {
columnFilterUI.$div.show(); columnFilterUI.$div.show();
...@@ -386,67 +360,67 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -386,67 +360,67 @@ morpheus.HeatMapToolBar = function(controller) {
} }
e.preventDefault(); e.preventDefault();
}); });
$el.find('[name=filterButton]').on('click', function() { $el.find('[name=filterButton]').on('click', function () {
$filterModal.modal('show'); $filterModal.modal('show');
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'filter' eventAction: 'filter'
}); });
}); });
$el.find('[data-toggle="tooltip"]').tooltip({ $el.find('[data-toggle="tooltip"]').tooltip({
placement : 'bottom', placement: 'bottom',
container : 'body', container: 'body',
trigger : 'hover' trigger: 'hover'
}).on('click', function() { }).on('click', function () {
$(this).tooltip('hide'); $(this).tooltip('hide');
}); });
var $key = $el.find('[name=key]'); var $key = $el.find('[name=key]');
var $keyContent = $el.find('[name=keyContent]'); var $keyContent = $el.find('[name=keyContent]');
$key.dropdown().parent().on('show.bs.dropdown', function() { $key.dropdown().parent().on('show.bs.dropdown', function () {
new morpheus.HeatMapColorSchemeLegend(controller, $keyContent); new morpheus.HeatMapColorSchemeLegend(controller, $keyContent);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'colorKey' eventAction: 'colorKey'
}); });
}); });
$el.find('[name=openFile]').on('click', function() { $el.find('[name=openFile]').on('click', function () {
morpheus.HeatMap.showTool(new morpheus.OpenFileTool({ morpheus.HeatMap.showTool(new morpheus.OpenFileTool({
customUrls : controller._customUrls customUrls: controller._customUrls
}), controller); }), controller);
}); });
$el.find('[name=saveImage]').on('click', function() { $el.find('[name=saveImage]').on('click', function () {
morpheus.HeatMap.showTool(new morpheus.SaveImageTool(), controller); morpheus.HeatMap.showTool(new morpheus.SaveImageTool(), controller);
}); });
$el.find('[name=saveDataset]').on('click', function() { $el.find('[name=saveDataset]').on('click', function () {
morpheus.HeatMap.showTool(new morpheus.SaveDatasetTool(), controller); morpheus.HeatMap.showTool(new morpheus.SaveDatasetTool(), controller);
}); });
$el.find('[name=chart]').on( $el.find('[name=chart]').on(
'click', 'click',
function() { function () {
new morpheus.ChartTool2({ new morpheus.ChartTool2({
project : controller.getProject(), project: controller.getProject(),
getVisibleTrackNames : _.bind( getVisibleTrackNames: _.bind(
controller.getVisibleTrackNames, controller) controller.getVisibleTrackNames, controller)
});
morpheus.Util.trackEvent({
eventCategory : 'ToolBar',
eventAction : 'chart'
});
}); });
morpheus.Util.trackEvent({
eventCategory: 'ToolBar',
eventAction: 'chart'
});
});
var _this = this; var _this = this;
$el $el
.find('[name=tutorial]') .find('[name=tutorial]')
.on( .on(
'click', 'click',
function() { function () {
window window
.open('http://www.broadinstitute.org/cancer/software/morpheus/tutorial.html'); .open('http://www.broadinstitute.org/cancer/software/morpheus/tutorial.html');
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'tutorial' eventAction: 'tutorial'
}); });
}); });
this.$previousColumnMatch = $el.find('[name=previousColumnMatch]'); this.$previousColumnMatch = $el.find('[name=previousColumnMatch]');
this.$nextColumnMatch = $el.find('[name=nextColumnMatch]'); this.$nextColumnMatch = $el.find('[name=nextColumnMatch]');
...@@ -462,98 +436,98 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -462,98 +436,98 @@ morpheus.HeatMapToolBar = function(controller) {
this.$rowSearchDiv = $el.find('[name=rowSearchDiv]'); this.$rowSearchDiv = $el.find('[name=rowSearchDiv]');
this.$columnSearchDiv = $el.find('[name=columnSearchDiv]'); this.$columnSearchDiv = $el.find('[name=columnSearchDiv]');
this.$searchRowDendrogramWrapper = $el this.$searchRowDendrogramWrapper = $el
.find('[name=searchRowDendrogramWrapper]'); .find('[name=searchRowDendrogramWrapper]');
this.$searchRowDendrogram = $el.find('[name=searchRowDendrogram]'); this.$searchRowDendrogram = $el.find('[name=searchRowDendrogram]');
this.$searchResultsRowDendrogram = $el this.$searchResultsRowDendrogram = $el
.find('[name=searchResultsRowDendrogram]'); .find('[name=searchResultsRowDendrogram]');
this.$searchColumnDendrogramWrapper = $el this.$searchColumnDendrogramWrapper = $el
.find('[name=searchColumnDendrogramWrapper]'); .find('[name=searchColumnDendrogramWrapper]');
this.$searchColumnDendrogram = $el.find('[name=searchColumnDendrogram]'); this.$searchColumnDendrogram = $el.find('[name=searchColumnDendrogram]');
this.$searchResultsColumnDendrogram = $el this.$searchResultsColumnDendrogram = $el
.find('[name=searchResultsColumnDendrogram]'); .find('[name=searchResultsColumnDendrogram]');
controller.on('dendrogramAnnotated', function(e) { controller.on('dendrogramAnnotated', function (e) {
(e.isColumns ? _this.$searchColumnDendrogramWrapper (e.isColumns ? _this.$searchColumnDendrogramWrapper
: _this.$searchRowDendrogramWrapper).show(); : _this.$searchRowDendrogramWrapper).show();
}); });
controller.on('dendrogramChanged', function(e) { controller.on('dendrogramChanged', function (e) {
(e.isColumns ? _this.$searchColumnDendrogramWrapper (e.isColumns ? _this.$searchColumnDendrogramWrapper
: _this.$searchRowDendrogramWrapper).hide(); : _this.$searchRowDendrogramWrapper).hide();
}); });
var project = controller.getProject(); var project = controller.getProject();
morpheus.Util.autosuggest({ morpheus.Util.autosuggest({
$el : this.$rowTextField, $el: this.$rowTextField,
filter : function(terms, cb) { filter: function (terms, cb) {
var indices = []; var indices = [];
var meta = project.getSortedFilteredDataset().getRowMetadata(); var meta = project.getSortedFilteredDataset().getRowMetadata();
controller.getVisibleTrackNames(false).forEach(function(name) { controller.getVisibleTrackNames(false).forEach(function (name) {
indices.push(morpheus.MetadataUtil.indexOf(meta, name)); indices.push(morpheus.MetadataUtil.indexOf(meta, name));
}); });
meta = new morpheus.MetadataModelColumnView(meta, indices); meta = new morpheus.MetadataModelColumnView(meta, indices);
morpheus.MetadataUtil.autocomplete(meta)(terms, cb); morpheus.MetadataUtil.autocomplete(meta)(terms, cb);
}, },
select : function() { select: function () {
_this.search(true); _this.search(true);
} }
}); });
this.$rowTextField.on('keyup', _.debounce(function(e) { this.$rowTextField.on('keyup', _.debounce(function (e) {
if (e.which === 13) { if (e.which === 13) {
e.preventDefault(); e.preventDefault();
} }
_this.search(true); _this.search(true);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'searchRows' eventAction: 'searchRows'
}); });
}, 500)); }, 500));
morpheus.Util.autosuggest({ morpheus.Util.autosuggest({
$el : this.$columnTextField, $el: this.$columnTextField,
filter : function(terms, cb) { filter: function (terms, cb) {
var indices = []; var indices = [];
var meta = project.getSortedFilteredDataset().getColumnMetadata(); var meta = project.getSortedFilteredDataset().getColumnMetadata();
controller.getVisibleTrackNames(true).forEach(function(name) { controller.getVisibleTrackNames(true).forEach(function (name) {
indices.push(morpheus.MetadataUtil.indexOf(meta, name)); indices.push(morpheus.MetadataUtil.indexOf(meta, name));
}); });
meta = new morpheus.MetadataModelColumnView(meta, indices); meta = new morpheus.MetadataModelColumnView(meta, indices);
morpheus.MetadataUtil.autocomplete(meta)(terms, cb); morpheus.MetadataUtil.autocomplete(meta)(terms, cb);
}, },
select : function() { select: function () {
_this.search(false); _this.search(false);
} }
}); });
this.$columnTextField.on('keyup', _.debounce(function(e) { this.$columnTextField.on('keyup', _.debounce(function (e) {
if (e.which === 13) { if (e.which === 13) {
e.preventDefault(); e.preventDefault();
} }
_this.search(false); _this.search(false);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'searchColumns' eventAction: 'searchColumns'
}); });
}, 500)); }, 500));
// TODO combine search with autocomplete // TODO combine search with autocomplete
this.$searchRowDendrogram.on('keyup', _.debounce(function(e) { this.$searchRowDendrogram.on('keyup', _.debounce(function (e) {
if (e.which === 13) { if (e.which === 13) {
// _this.$searchRowDendrogram.autocomplete('close'); // _this.$searchRowDendrogram.autocomplete('close');
e.preventDefault(); e.preventDefault();
} }
_this.searchDendrogram(false); _this.searchDendrogram(false);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'searchRowDendrogram' eventAction: 'searchRowDendrogram'
}); });
}, 500)); }, 500));
this.$searchColumnDendrogram.on('keyup', _.debounce(function(e) { this.$searchColumnDendrogram.on('keyup', _.debounce(function (e) {
if (e.which === 13) { if (e.which === 13) {
// _this.$searchColumnDendrogram.autocomplete('close'); // _this.$searchColumnDendrogram.autocomplete('close');
e.preventDefault(); e.preventDefault();
} }
_this.searchDendrogram(true); _this.searchDendrogram(true);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'searchColumnDendrogram' eventAction: 'searchColumnDendrogram'
}); });
}, 500)); }, 500));
...@@ -566,26 +540,27 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -566,26 +540,27 @@ morpheus.HeatMapToolBar = function(controller) {
} else { } else {
var viewIndices = new morpheus.Set(); var viewIndices = new morpheus.Set();
morpheus.DatasetUtil.searchValues(project morpheus.DatasetUtil.searchValues(project
.getSortedFilteredDataset(), text, function(value, i, j) { .getSortedFilteredDataset(), text, function (value, i, j) {
viewIndices.add(new morpheus.Identifier([ i, j ])); viewIndices.add(new morpheus.Identifier([i, j]));
}); });
project.getElementSelectionModel().setViewIndices(viewIndices); project.getElementSelectionModel().setViewIndices(viewIndices);
$searchResultsLabel.html(viewIndices.size() + ' match' $searchResultsLabel.html(viewIndices.size() + ' match'
+ (viewIndices.size() === 1 ? '' : 'es')); + (viewIndices.size() === 1 ? '' : 'es'));
} }
} }
morpheus.Util.autosuggest({ morpheus.Util.autosuggest({
$el : this.$valueTextField, $el: this.$valueTextField,
filter : function(terms, cb) { filter: function (terms, cb) {
morpheus.DatasetUtil.autocompleteValues( morpheus.DatasetUtil.autocompleteValues(
project.getSortedFilteredDataset())(terms, cb); project.getSortedFilteredDataset())(terms, cb);
}, },
select : function() { select: function () {
searchValues(); searchValues();
} }
}); });
this.$valueTextField.on('keyup', _.debounce(function(e) { this.$valueTextField.on('keyup', _.debounce(function (e) {
if (e.which === 13) { if (e.which === 13) {
_this.$valueTextField.autocomplete('close'); _this.$valueTextField.autocomplete('close');
e.preventDefault(); e.preventDefault();
...@@ -593,61 +568,61 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -593,61 +568,61 @@ morpheus.HeatMapToolBar = function(controller) {
searchValues(); searchValues();
}, 500)); }, 500));
$toolbarForm.on('submit', function(e) { $toolbarForm.on('submit', function (e) {
e.preventDefault(); e.preventDefault();
}); });
$toolbarForm.on('click', '[name=in]', function(e) { $toolbarForm.on('click', '[name=in]', function (e) {
e.preventDefault(); e.preventDefault();
controller.zoom(true); controller.zoom(true);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'zoomIn' eventAction: 'zoomIn'
}); });
}); });
$toolbarForm.on('click', '[name=out]', function(e) { $toolbarForm.on('click', '[name=out]', function (e) {
e.preventDefault(); e.preventDefault();
controller.zoom(false); controller.zoom(false);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'zoomOut' eventAction: 'zoomOut'
}); });
}); });
$toolbarForm.on('click', '[name=options]', function(e) { $toolbarForm.on('click', '[name=options]', function (e) {
e.preventDefault(); e.preventDefault();
controller.showOptions(); controller.showOptions();
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'options' eventAction: 'options'
}); });
}); });
$toolbarForm.on('click', '[name=sort]', function(e) { $toolbarForm.on('click', '[name=sort]', function (e) {
e.preventDefault(); e.preventDefault();
new morpheus.SortDialog(project); new morpheus.SortDialog(project);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'sort' eventAction: 'sort'
}); });
}); });
$toolbarForm.on('click', '[name=fit]', function(e) { $toolbarForm.on('click', '[name=fit]', function (e) {
e.preventDefault(); e.preventDefault();
controller.fitToWindow(true); controller.fitToWindow(true);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'fit' eventAction: 'fit'
}); });
}); });
$toolbarForm.on('click', '[name=resetZoom]', function(e) { $toolbarForm.on('click', '[name=resetZoom]', function (e) {
e.preventDefault(); e.preventDefault();
controller.resetZoom(); controller.resetZoom();
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'resetZoom' eventAction: 'resetZoom'
}); });
}); });
this.$el = $el; this.$el = $el;
var updateFilterStatus = function() { var updateFilterStatus = function () {
if (controller.getProject().getRowFilter().isEnabled() if (controller.getProject().getRowFilter().isEnabled()
|| controller.getProject().getColumnFilter().isEnabled()) { || controller.getProject().getColumnFilter().isEnabled()) {
_this.$el.find('[name=filterButton]').addClass('btn-primary'); _this.$el.find('[name=filterButton]').addClass('btn-primary');
} else { } else {
_this.$el.find('[name=filterButton]').removeClass('btn-primary'); _this.$el.find('[name=filterButton]').removeClass('btn-primary');
...@@ -657,65 +632,65 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -657,65 +632,65 @@ morpheus.HeatMapToolBar = function(controller) {
updateFilterStatus(); updateFilterStatus();
this.$columnMatchesToTop this.$columnMatchesToTop
.on( .on(
'click', 'click',
function(e) { function (e) {
e.preventDefault(); e.preventDefault();
var $this = $(this); var $this = $(this);
$this.toggleClass('btn-primary'); $this.toggleClass('btn-primary');
var sortKeys = project.getColumnSortKeys(); var sortKeys = project.getColumnSortKeys();
// clear existing sort keys except dendrogram // clear existing sort keys except dendrogram
sortKeys = sortKeys sortKeys = sortKeys
.filter(function(key) { .filter(function (key) {
return (key instanceof morpheus.SpecifiedModelSortOrder && key.name === 'dendrogram'); return (key instanceof morpheus.SpecifiedModelSortOrder && key.name === 'dendrogram');
}); });
if ($this.hasClass('btn-primary')) { if ($this.hasClass('btn-primary')) {
var key = new morpheus.MatchesOnTopSortKey(project, var key = new morpheus.MatchesOnTopSortKey(project,
_this.columnSearchResultModelIndices, _this.columnSearchResultModelIndices,
'matches on top'); 'matches on top');
sortKeys.splice(0, 0, key); sortKeys.splice(0, 0, key);
controller.scrollLeft(0); controller.scrollLeft(0);
} }
_this.searching = true; _this.searching = true;
project.setColumnSortKeys(sortKeys, true); project.setColumnSortKeys(sortKeys, true);
_this._updateSearchIndices(true); _this._updateSearchIndices(true);
_this.searching = false; _this.searching = false;
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'columnMatchesToTop' eventAction: 'columnMatchesToTop'
}); });
}); });
this.$rowMatchesToTop this.$rowMatchesToTop
.on( .on(
'click', 'click',
function(e) { function (e) {
e.preventDefault(); e.preventDefault();
var $this = $(this); var $this = $(this);
$this.toggleClass('btn-primary'); $this.toggleClass('btn-primary');
var sortKeys = project.getRowSortKeys(); var sortKeys = project.getRowSortKeys();
// clear existing sort keys except // clear existing sort keys except
// dendrogram // dendrogram
sortKeys = sortKeys sortKeys = sortKeys
.filter(function(key) { .filter(function (key) {
return (key instanceof morpheus.SpecifiedModelSortOrder && key.name === 'dendrogram'); return (key instanceof morpheus.SpecifiedModelSortOrder && key.name === 'dendrogram');
}); });
if ($this.hasClass('btn-primary')) { if ($this.hasClass('btn-primary')) {
var key = new morpheus.MatchesOnTopSortKey(project, var key = new morpheus.MatchesOnTopSortKey(project,
_this.rowSearchResultModelIndices, _this.rowSearchResultModelIndices,
'matches on top'); 'matches on top');
sortKeys.splice(0, 0, key); sortKeys.splice(0, 0, key);
controller.scrollTop(0); controller.scrollTop(0);
} }
_this.searching = true; _this.searching = true;
project.setRowSortKeys(sortKeys, true); project.setRowSortKeys(sortKeys, true);
_this._updateSearchIndices(false); _this._updateSearchIndices(false);
_this.searching = false; _this.searching = false;
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'rowMatchesToTop' eventAction: 'rowMatchesToTop'
}); });
}); });
project.on('rowSortOrderChanged.morpheus', function(e) { project.on('rowSortOrderChanged.morpheus', function (e) {
if (_this.searching) { if (_this.searching) {
return; return;
} }
...@@ -723,7 +698,7 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -723,7 +698,7 @@ morpheus.HeatMapToolBar = function(controller) {
_this.$rowMatchesToTop.removeClass('btn-primary'); _this.$rowMatchesToTop.removeClass('btn-primary');
}); });
project.on('columnSortOrderChanged.morpheus', function(e) { project.on('columnSortOrderChanged.morpheus', function (e) {
if (_this.searching) { if (_this.searching) {
return; return;
} }
...@@ -731,82 +706,82 @@ morpheus.HeatMapToolBar = function(controller) { ...@@ -731,82 +706,82 @@ morpheus.HeatMapToolBar = function(controller) {
_this.$columnMatchesToTop.removeClass('btn-primary'); _this.$columnMatchesToTop.removeClass('btn-primary');
}); });
controller.getProject().on('rowFilterChanged.morpheus', function(e) { controller.getProject().on('rowFilterChanged.morpheus', function (e) {
_this.search(true); _this.search(true);
updateFilterStatus(); updateFilterStatus();
}); });
controller.getProject().on('columnFilterChanged.morpheus', function(e) { controller.getProject().on('columnFilterChanged.morpheus', function (e) {
_this.search(false); _this.search(false);
updateFilterStatus(); updateFilterStatus();
}); });
controller.getProject().on('datasetChanged.morpheus', function() { controller.getProject().on('datasetChanged.morpheus', function () {
_this.search(true); _this.search(true);
_this.search(false); _this.search(false);
updateFilterStatus(); updateFilterStatus();
}); });
controller.getProject().getRowSelectionModel().on( controller.getProject().getRowSelectionModel().on(
'selectionChanged.morpheus', function() { 'selectionChanged.morpheus', function () {
_this.updateSelectionLabel(); _this.updateSelectionLabel();
}); });
controller.getProject().getColumnSelectionModel().on( controller.getProject().getColumnSelectionModel().on(
'selectionChanged.morpheus', function() { 'selectionChanged.morpheus', function () {
_this.updateSelectionLabel(); _this.updateSelectionLabel();
}); });
this.rowSearchResultViewIndicesSorted = null; this.rowSearchResultViewIndicesSorted = null;
this.currentRowSearchIndex = 0; this.currentRowSearchIndex = 0;
this.columnSearchResultViewIndicesSorted = null; this.columnSearchResultViewIndicesSorted = null;
this.currentColumnSearchIndex = -1; this.currentColumnSearchIndex = -1;
this.$previousColumnMatch this.$previousColumnMatch
.on( .on(
'click', 'click',
function() { function () {
_this.currentColumnSearchIndex--; _this.currentColumnSearchIndex--;
if (_this.currentColumnSearchIndex < 0) { if (_this.currentColumnSearchIndex < 0) {
_this.currentColumnSearchIndex = _this.columnSearchResultViewIndicesSorted.length - 1; _this.currentColumnSearchIndex = _this.columnSearchResultViewIndicesSorted.length - 1;
} }
controller controller
.scrollLeft(controller .scrollLeft(controller
.getHeatMapElementComponent() .getHeatMapElementComponent()
.getColumnPositions() .getColumnPositions()
.getPosition( .getPosition(
_this.columnSearchResultViewIndicesSorted[_this.currentColumnSearchIndex])); _this.columnSearchResultViewIndicesSorted[_this.currentColumnSearchIndex]));
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'previousColumnMatch' eventAction: 'previousColumnMatch'
}); });
}); });
this.$previousRowMatch this.$previousRowMatch
.on( .on(
'click', 'click',
function() { function () {
_this.currentRowSearchIndex--; _this.currentRowSearchIndex--;
if (_this.currentRowSearchIndex < 0) { if (_this.currentRowSearchIndex < 0) {
_this.currentRowSearchIndex = _this.rowSearchResultViewIndicesSorted.length - 1; _this.currentRowSearchIndex = _this.rowSearchResultViewIndicesSorted.length - 1;
} }
controller controller
.scrollTop(controller .scrollTop(controller
.getHeatMapElementComponent() .getHeatMapElementComponent()
.getRowPositions() .getRowPositions()
.getPosition( .getPosition(
_this.rowSearchResultViewIndicesSorted[_this.currentRowSearchIndex])); _this.rowSearchResultViewIndicesSorted[_this.currentRowSearchIndex]));
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'previousRowMatch' eventAction: 'previousRowMatch'
}); });
}); });
this.$nextColumnMatch.on('click', function() { this.$nextColumnMatch.on('click', function () {
_this.next(true); _this.next(true);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'nextColumnMatch' eventAction: 'nextColumnMatch'
}); });
}); });
this.$nextRowMatch.on('click', function() { this.$nextRowMatch.on('click', function () {
_this.next(false); _this.next(false);
morpheus.Util.trackEvent({ morpheus.Util.trackEvent({
eventCategory : 'ToolBar', eventCategory: 'ToolBar',
eventAction : 'nextRowMatch' eventAction: 'nextRowMatch'
}); });
}); });
this.updateDimensionsLabel(); this.updateDimensionsLabel();
...@@ -817,23 +792,23 @@ morpheus.HeatMapToolBar.FILTER_SEARCH_MODE = 1; ...@@ -817,23 +792,23 @@ morpheus.HeatMapToolBar.FILTER_SEARCH_MODE = 1;
morpheus.HeatMapToolBar.MATCHES_TO_TOP_SEARCH_MODE = 2; morpheus.HeatMapToolBar.MATCHES_TO_TOP_SEARCH_MODE = 2;
morpheus.HeatMapToolBar.SELECT_MATCHES_SEARCH_MODE = 3; morpheus.HeatMapToolBar.SELECT_MATCHES_SEARCH_MODE = 3;
morpheus.HeatMapToolBar.prototype = { morpheus.HeatMapToolBar.prototype = {
quickColumnFilter : false, quickColumnFilter: false,
searching : false, searching: false,
rowSearchMode : morpheus.HeatMapToolBar.SELECT_MATCHES_SEARCH_MODE, rowSearchMode: morpheus.HeatMapToolBar.SELECT_MATCHES_SEARCH_MODE,
columnSearchMode : morpheus.HeatMapToolBar.SELECT_MATCHES_SEARCH_MODE, columnSearchMode: morpheus.HeatMapToolBar.SELECT_MATCHES_SEARCH_MODE,
_updateSearchIndices : function(isColumns) { _updateSearchIndices: function (isColumns) {
var project = this.controller.getProject(); var project = this.controller.getProject();
if (isColumns) { if (isColumns) {
var viewIndices = []; var viewIndices = [];
var modelIndices = this.columnSearchResultModelIndices; var modelIndices = this.columnSearchResultModelIndices;
for (var i = 0, length = modelIndices.length; i < length; i++) { for (var i = 0, length = modelIndices.length; i < length; i++) {
var index = project var index = project
.convertModelColumnIndexToView(modelIndices[i]); .convertModelColumnIndexToView(modelIndices[i]);
if (index !== -1) { if (index !== -1) {
viewIndices.push(index); viewIndices.push(index);
} }
} }
viewIndices.sort(function(a, b) { viewIndices.sort(function (a, b) {
return a < b ? -1 : 1; return a < b ? -1 : 1;
}); });
this.columnSearchResultViewIndicesSorted = viewIndices; this.columnSearchResultViewIndicesSorted = viewIndices;
...@@ -847,14 +822,14 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -847,14 +822,14 @@ morpheus.HeatMapToolBar.prototype = {
viewIndices.push(index); viewIndices.push(index);
} }
} }
viewIndices.sort(function(a, b) { viewIndices.sort(function (a, b) {
return a < b ? -1 : 1; return a < b ? -1 : 1;
}); });
this.rowSearchResultViewIndicesSorted = viewIndices; this.rowSearchResultViewIndicesSorted = viewIndices;
this.currentRowSearchIndex = -1; this.currentRowSearchIndex = -1;
} }
}, },
next : function(isColumns) { next: function (isColumns) {
var controller = this.controller; var controller = this.controller;
if (isColumns) { if (isColumns) {
this.currentColumnSearchIndex++; this.currentColumnSearchIndex++;
...@@ -862,35 +837,35 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -862,35 +837,35 @@ morpheus.HeatMapToolBar.prototype = {
this.currentColumnSearchIndex = 0; this.currentColumnSearchIndex = 0;
} }
controller controller
.scrollLeft(controller .scrollLeft(controller
.getHeatMapElementComponent() .getHeatMapElementComponent()
.getColumnPositions() .getColumnPositions()
.getPosition( .getPosition(
this.columnSearchResultViewIndicesSorted[this.currentColumnSearchIndex])); this.columnSearchResultViewIndicesSorted[this.currentColumnSearchIndex]));
} else { } else {
this.currentRowSearchIndex++; this.currentRowSearchIndex++;
if (this.currentRowSearchIndex >= this.rowSearchResultViewIndicesSorted.length) { if (this.currentRowSearchIndex >= this.rowSearchResultViewIndicesSorted.length) {
this.currentRowSearchIndex = 0; this.currentRowSearchIndex = 0;
} }
controller controller
.scrollTop(controller .scrollTop(controller
.getHeatMapElementComponent() .getHeatMapElementComponent()
.getRowPositions() .getRowPositions()
.getPosition( .getPosition(
this.rowSearchResultViewIndicesSorted[this.currentRowSearchIndex])); this.rowSearchResultViewIndicesSorted[this.currentRowSearchIndex]));
} }
}, },
setSearchText : function(options) { setSearchText: function (options) {
var $tf = options.isColumns ? this.$columnTextField var $tf = options.isColumns ? this.$columnTextField
: this.$rowTextField; : this.$rowTextField;
var existing = options.append ? $.trim($tf.val()) : ''; var existing = options.append ? $.trim($tf.val()) : '';
if (existing !== '') { if (existing !== '') {
existing += ' '; existing += ' ';
} }
if (options.onTop) { if (options.onTop) {
options.isColumns ? this.$columnMatchesToTop options.isColumns ? this.$columnMatchesToTop
.addClass('btn-primary') : this.$rowMatchesToTop .addClass('btn-primary') : this.$rowMatchesToTop
.addClass('btn-primary'); .addClass('btn-primary');
} }
$tf.val(existing + options.text); $tf.val(existing + options.text);
...@@ -900,17 +875,17 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -900,17 +875,17 @@ morpheus.HeatMapToolBar.prototype = {
// click next // click next
} }
}, },
updateDimensionsLabel : function() { updateDimensionsLabel: function () {
var p = this.controller.getProject(); var p = this.controller.getProject();
var d = p.getFullDataset(); var d = p.getFullDataset();
var f = p.getSortedFilteredDataset(); var f = p.getSortedFilteredDataset();
var text = 'showing ' + morpheus.Util.intFormat(f.getRowCount()) var text = 'showing ' + morpheus.Util.intFormat(f.getRowCount())
+ ' of ' + morpheus.Util.intFormat(d.getRowCount()) + ' rows, ' + ' of ' + morpheus.Util.intFormat(d.getRowCount()) + ' rows, '
+ morpheus.Util.intFormat(f.getColumnCount()) + ' of ' + morpheus.Util.intFormat(f.getColumnCount()) + ' of '
+ morpheus.Util.intFormat(d.getColumnCount()) + ' columns'; + morpheus.Util.intFormat(d.getColumnCount()) + ' columns';
this.$dimensionsLabel.html(text); this.$dimensionsLabel.html(text);
}, },
updateSelectionLabel : function() { updateSelectionLabel: function () {
var nc = this.controller.getProject().getColumnSelectionModel().count(); var nc = this.controller.getProject().getColumnSelectionModel().count();
var nr = this.controller.getProject().getRowSelectionModel().count(); var nr = this.controller.getProject().getRowSelectionModel().count();
var text = []; var text = [];
...@@ -926,26 +901,26 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -926,26 +901,26 @@ morpheus.HeatMapToolBar.prototype = {
text.push(' selected'); text.push(' selected');
this.$selectionLabel.html(text.join('')); this.$selectionLabel.html(text.join(''));
}, },
searchDendrogram : function(isColumns) { searchDendrogram: function (isColumns) {
var text = $.trim(isColumns ? this.$searchColumnDendrogram.val() var text = $.trim(isColumns ? this.$searchColumnDendrogram.val()
: this.$searchRowDendrogram.val()); : this.$searchRowDendrogram.val());
var dendrogram = isColumns ? this.controller.columnDendrogram var dendrogram = isColumns ? this.controller.columnDendrogram
: this.controller.rowDendrogram; : this.controller.rowDendrogram;
var $searchResults = isColumns ? this.$searchResultsColumnDendrogram var $searchResults = isColumns ? this.$searchResultsColumnDendrogram
: this.$searchResultsRowDendrogram; : this.$searchResultsRowDendrogram;
var matches = morpheus.AbstractDendrogram.search( var matches = morpheus.AbstractDendrogram.search(
dendrogram.tree.rootNode, text); dendrogram.tree.rootNode, text);
if (matches === -1) { if (matches === -1) {
$searchResults.html(''); $searchResults.html('');
} else { } else {
$searchResults.html(matches + ' match' $searchResults.html(matches + ' match'
+ (matches === 1 ? '' : 'es')); + (matches === 1 ? '' : 'es'));
} }
if (matches <= 0) { if (matches <= 0) {
var positions = isColumns ? this.controller var positions = isColumns ? this.controller
.getHeatMapElementComponent().getColumnPositions() .getHeatMapElementComponent().getColumnPositions()
: this.controller.getHeatMapElementComponent() : this.controller.getHeatMapElementComponent()
.getRowPositions(); .getRowPositions();
positions.setSquishedIndices(null); positions.setSquishedIndices(null);
if (isColumns) { if (isColumns) {
this.controller.getProject().setGroupColumns([], true); this.controller.getProject().setGroupColumns([], true);
...@@ -953,25 +928,25 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -953,25 +928,25 @@ morpheus.HeatMapToolBar.prototype = {
this.controller.getProject().setGroupRows([], true); this.controller.getProject().setGroupRows([], true);
} }
positions.setSize(isColumns ? this.controller.getFitColumnSize() positions.setSize(isColumns ? this.controller.getFitColumnSize()
: this.controller.getFitRowSize()); : this.controller.getFitRowSize());
} else { } else {
morpheus.AbstractDendrogram.squishNonSearchedNodes(this.controller, morpheus.AbstractDendrogram.squishNonSearchedNodes(this.controller,
isColumns); isColumns);
} }
this.controller.updateDataset(); // need to update spaces for group this.controller.updateDataset(); // need to update spaces for group
// by // by
this.controller.revalidate(); this.controller.revalidate();
}, },
search : function(isRows) { search: function (isRows) {
this.searching = true; this.searching = true;
var isMatchesOnTop = isRows ? this.$rowMatchesToTop var isMatchesOnTop = isRows ? this.$rowMatchesToTop
.hasClass('btn-primary') : this.$columnMatchesToTop .hasClass('btn-primary') : this.$columnMatchesToTop
.hasClass('btn-primary'); .hasClass('btn-primary');
var controller = this.controller; var controller = this.controller;
var project = controller.getProject(); var project = controller.getProject();
var sortKeys = isRows ? project.getRowSortKeys() : project var sortKeys = isRows ? project.getRowSortKeys() : project
.getColumnSortKeys(); .getColumnSortKeys();
var keyIndex = -1; var keyIndex = -1;
for (var i = 0; i < sortKeys.length; i++) { for (var i = 0; i < sortKeys.length; i++) {
if (sortKeys[i].toString() === 'matches on top') { if (sortKeys[i].toString() === 'matches on top') {
...@@ -985,25 +960,25 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -985,25 +960,25 @@ morpheus.HeatMapToolBar.prototype = {
var dataset = project.getSortedFilteredDataset(); var dataset = project.getSortedFilteredDataset();
var $searchResultsLabel = this.$el.find('[name=searchResults' var $searchResultsLabel = this.$el.find('[name=searchResults'
+ (isRows ? 'Rows' : 'Columns') + ']'); + (isRows ? 'Rows' : 'Columns') + ']');
var searchText = !isRows ? $.trim(this.$columnTextField.val()) : $ var searchText = !isRows ? $.trim(this.$columnTextField.val()) : $
.trim(this.$rowTextField.val()); .trim(this.$rowTextField.val());
var metadata = isRows ? dataset.getRowMetadata() : dataset var metadata = isRows ? dataset.getRowMetadata() : dataset
.getColumnMetadata(); .getColumnMetadata();
var visibleIndices = []; var visibleIndices = [];
controller.getVisibleTrackNames(!isRows).forEach(function(name) { controller.getVisibleTrackNames(!isRows).forEach(function (name) {
visibleIndices.push(morpheus.MetadataUtil.indexOf(metadata, name)); visibleIndices.push(morpheus.MetadataUtil.indexOf(metadata, name));
}); });
metadata = new morpheus.MetadataModelColumnView(metadata, metadata = new morpheus.MetadataModelColumnView(metadata,
visibleIndices); visibleIndices);
var searchResultViewIndices = morpheus.MetadataUtil.search({ var searchResultViewIndices = morpheus.MetadataUtil.search({
model : metadata, model: metadata,
text : searchText, text: searchText,
isColumns : !isRows, isColumns: !isRows,
defaultMatchMode : isRows ? this.defaultRowMatchMode defaultMatchMode: isRows ? this.defaultRowMatchMode
: this.defaultColumnMatchMode : this.defaultColumnMatchMode
}); });
if (searchText === '') { if (searchText === '') {
$searchResultsLabel.html(''); $searchResultsLabel.html('');
...@@ -1015,7 +990,7 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -1015,7 +990,7 @@ morpheus.HeatMapToolBar.prototype = {
} else { } else {
$searchResultsLabel.html(searchResultViewIndices.length + ' match' $searchResultsLabel.html(searchResultViewIndices.length + ' match'
+ (searchResultViewIndices.length === 1 ? '' : 'es')); + (searchResultViewIndices.length === 1 ? '' : 'es'));
if (isRows) { if (isRows) {
this.$rowSearchDiv.show(); this.$rowSearchDiv.show();
} else { } else {
...@@ -1029,15 +1004,15 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -1029,15 +1004,15 @@ morpheus.HeatMapToolBar.prototype = {
for (var i = 0, length = searchResultViewIndices.length; i < length; i++) { for (var i = 0, length = searchResultViewIndices.length; i < length; i++) {
var viewIndex = searchResultViewIndices[i]; var viewIndex = searchResultViewIndices[i];
searchResultsModelIndices.push(isRows ? project searchResultsModelIndices.push(isRows ? project
.convertViewRowIndexToModel(viewIndex) : project .convertViewRowIndexToModel(viewIndex) : project
.convertViewColumnIndexToModel(viewIndex)); .convertViewColumnIndexToModel(viewIndex));
} }
} }
if (searchResultViewIndices !== null && isMatchesOnTop) { if (searchResultViewIndices !== null && isMatchesOnTop) {
var key = new morpheus.MatchesOnTopSortKey(project, var key = new morpheus.MatchesOnTopSortKey(project,
searchResultsModelIndices, 'matches on top'); searchResultsModelIndices, 'matches on top');
sortKeys = sortKeys.filter(function(key) { sortKeys = sortKeys.filter(function (key) {
return !(key instanceof morpheus.MatchesOnTopSortKey); return !(key instanceof morpheus.MatchesOnTopSortKey);
}); });
searchResultViewIndices = key.indices; // matching indices searchResultViewIndices = key.indices; // matching indices
...@@ -1064,33 +1039,33 @@ morpheus.HeatMapToolBar.prototype = { ...@@ -1064,33 +1039,33 @@ morpheus.HeatMapToolBar.prototype = {
if (isRows) { if (isRows) {
this.rowSearchResultModelIndices = searchResultsModelIndices; this.rowSearchResultModelIndices = searchResultsModelIndices;
this.rowSearchResultViewIndicesSorted = searchResultViewIndices this.rowSearchResultViewIndicesSorted = searchResultViewIndices
.sort(function(a, b) { .sort(function (a, b) {
return a < b ? -1 : 1; return a < b ? -1 : 1;
}); });
this.currentRowSearchIndex = -1; this.currentRowSearchIndex = -1;
} else { } else {
this.columnSearchResultModelIndices = searchResultsModelIndices; this.columnSearchResultModelIndices = searchResultsModelIndices;
this.columnSearchResultViewIndicesSorted = searchResultViewIndices this.columnSearchResultViewIndicesSorted = searchResultViewIndices
.sort(function(a, b) { .sort(function (a, b) {
return a < b ? -1 : 1; return a < b ? -1 : 1;
}); });
this.currentColumnSearchIndex = -1; this.currentColumnSearchIndex = -1;
} }
// update selection // update selection
(!isRows ? project.getColumnSelectionModel() : project (!isRows ? project.getColumnSelectionModel() : project
.getRowSelectionModel()).setViewIndices( .getRowSelectionModel()).setViewIndices(
searchResultsViewIndicesSet, true); searchResultsViewIndicesSet, true);
if (isMatchesOnTop) { // resort if (isMatchesOnTop) { // resort
if (isRows) { if (isRows) {
project.setRowSortKeys(morpheus.SortKey.keepExistingSortKeys( project.setRowSortKeys(morpheus.SortKey.keepExistingSortKeys(
sortKeys, project.getRowSortKeys()), true); sortKeys, project.getRowSortKeys()), true);
} else { } else {
project.setColumnSortKeys(morpheus.SortKey project.setColumnSortKeys(morpheus.SortKey
.keepExistingSortKeys(sortKeys, project .keepExistingSortKeys(sortKeys, project
.getColumnSortKeys()), true); .getColumnSortKeys()), true);
} }
} }
this.updateDimensionsLabel(); this.updateDimensionsLabel();
......
morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex, morpheus.HeatMapTooltipProvider = function (heatMap, rowIndex, columnIndex,
options, separator, quick) { options, separator, quick) {
var dataset = heatMap.project.getSortedFilteredDataset(); var dataset = heatMap.project.getSortedFilteredDataset();
var tipText = []; var tipText = [];
if (!quick) { if (!quick) {
if (options.value) { // key value pairs for custom tooltip if (options.value) { // key value pairs for custom tooltip
_.each(options.value, function(pair) { _.each(options.value, function (pair) {
if (tipText.length > 0) { if (tipText.length > 0) {
tipText.push(separator); tipText.push(separator);
} }
...@@ -27,16 +27,16 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex, ...@@ -27,16 +27,16 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex,
if (rowIndex !== -1 && columnIndex !== -1) { if (rowIndex !== -1 && columnIndex !== -1) {
for (var i = 0, nseries = dataset.getSeriesCount(); i < nseries; i++) { for (var i = 0, nseries = dataset.getSeriesCount(); i < nseries; i++) {
morpheus.HeatMapTooltipProvider._matrixValueToString(dataset, morpheus.HeatMapTooltipProvider._matrixValueToString(dataset,
rowIndex, columnIndex, i, tipText, separator, rowIndex, columnIndex, i, tipText, separator,
options.showSeriesNameInTooltip || i > 0); options.showSeriesNameInTooltip || i > 0);
} }
if (quick) { if (quick) {
var quickRowTracks = heatMap.rowTracks.filter(function(t) { var quickRowTracks = heatMap.rowTracks.filter(function (t) {
return t.settings.inlineTooltip; return t.settings.inlineTooltip;
}); });
morpheus.HeatMapTooltipProvider._tracksToString(options, morpheus.HeatMapTooltipProvider._tracksToString(options,
quickRowTracks, dataset.getRowMetadata(), rowIndex, quickRowTracks, dataset.getRowMetadata(), rowIndex,
tipText, separator); tipText, separator);
// if (quickRowTracks.length > 0) { // if (quickRowTracks.length > 0) {
// tipText // tipText
...@@ -44,10 +44,10 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex, ...@@ -44,10 +44,10 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex,
// style="height:1px;background-color:LightGrey;"></div>'); // style="height:1px;background-color:LightGrey;"></div>');
// } // }
morpheus.HeatMapTooltipProvider._tracksToString(options, morpheus.HeatMapTooltipProvider._tracksToString(options,
heatMap.columnTracks.filter(function(t) { heatMap.columnTracks.filter(function (t) {
return t.settings.inlineTooltip; return t.settings.inlineTooltip;
}), dataset.getColumnMetadata(), columnIndex, tipText, }), dataset.getColumnMetadata(), columnIndex, tipText,
separator); separator);
} }
} }
...@@ -55,25 +55,25 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex, ...@@ -55,25 +55,25 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex,
if (!quick) { if (!quick) {
if (rowIndex !== -1) { if (rowIndex !== -1) {
morpheus.HeatMapTooltipProvider._metadataToString(options, morpheus.HeatMapTooltipProvider._metadataToString(options,
heatMap.rowTracks, dataset.getRowMetadata(), rowIndex, heatMap.rowTracks, dataset.getRowMetadata(), rowIndex,
tipText, separator); tipText, separator);
} }
if (columnIndex !== -1) { if (columnIndex !== -1) {
morpheus.HeatMapTooltipProvider._metadataToString(options, morpheus.HeatMapTooltipProvider._metadataToString(options,
heatMap.columnTracks, dataset.getColumnMetadata(), heatMap.columnTracks, dataset.getColumnMetadata(),
columnIndex, tipText, separator); columnIndex, tipText, separator);
} }
} else if (options.name != null) { } else if (options.name != null) {
var metadata = (rowIndex !== -1 ? dataset.getRowMetadata() : dataset var metadata = (rowIndex !== -1 ? dataset.getRowMetadata() : dataset
.getColumnMetadata()); .getColumnMetadata());
var vector = metadata.getByName(options.name); var vector = metadata.getByName(options.name);
var track = heatMap.getTrack(options.name, columnIndex !== -1); var track = heatMap.getTrack(options.name, columnIndex !== -1);
var colorByName = track != null ? track.settings.colorByField : null; var colorByName = track != null ? track.settings.colorByField : null;
var additionalVector = colorByName != null ? metadata var additionalVector = colorByName != null ? metadata
.getByName(colorByName) : null; .getByName(colorByName) : null;
morpheus.HeatMapTooltipProvider.vectorToString(vector, morpheus.HeatMapTooltipProvider.vectorToString(vector,
rowIndex !== -1 ? rowIndex : columnIndex, tipText, separator, rowIndex !== -1 ? rowIndex : columnIndex, tipText, separator,
additionalVector); additionalVector);
} }
var rowNodes = []; var rowNodes = [];
...@@ -90,70 +90,86 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex, ...@@ -90,70 +90,86 @@ morpheus.HeatMapTooltipProvider = function(heatMap, rowIndex, columnIndex,
if (!quick) { if (!quick) {
if (heatMap.rowDendrogram) { if (heatMap.rowDendrogram) {
selectedRowNodes = _ selectedRowNodes = _
.values(heatMap.rowDendrogram.selectedRootNodeIdToNode); .values(heatMap.rowDendrogram.selectedRootNodeIdToNode);
} }
if (heatMap.columnDendrogram) { if (heatMap.columnDendrogram) {
selectedColumnNodes = _ selectedColumnNodes = _
.values(heatMap.columnDendrogram.selectedRootNodeIdToNode); .values(heatMap.columnDendrogram.selectedRootNodeIdToNode);
} }
if (selectedRowNodes.length > 0 && rowNodes.length > 0) { if (selectedRowNodes.length > 0 && rowNodes.length > 0) {
var nodeIds = {}; var nodeIds = {};
_.each(selectedRowNodes, function(n) { _.each(selectedRowNodes, function (n) {
nodeIds[n.id] = true; nodeIds[n.id] = true;
}); });
rowNodes = _.filter(rowNodes, function(n) { rowNodes = _.filter(rowNodes, function (n) {
return nodeIds[n.id] === undefined; return nodeIds[n.id] === undefined;
}); });
} }
if (selectedColumnNodes.length > 0 && columnNodes.length > 0) { if (selectedColumnNodes.length > 0 && columnNodes.length > 0) {
var nodeIds = {}; var nodeIds = {};
_.each(selectedColumnNodes, function(n) { _.each(selectedColumnNodes, function (n) {
nodeIds[n.id] = true; nodeIds[n.id] = true;
}); });
columnNodes = _.filter(columnNodes, function(n) { columnNodes = _.filter(columnNodes, function (n) {
return nodeIds[n.id] === undefined; return nodeIds[n.id] === undefined;
}); });
} }
} }
morpheus.HeatMapTooltipProvider._nodesToString(tipText, rowNodes, null, morpheus.HeatMapTooltipProvider._nodesToString(tipText, rowNodes, null,
separator); separator);
morpheus.HeatMapTooltipProvider._nodesToString(tipText, columnNodes, null, morpheus.HeatMapTooltipProvider._nodesToString(tipText, columnNodes, null,
separator); separator);
if (!quick) { if (!quick) {
if (selectedRowNodes.length > 0) { if (selectedRowNodes.length > 0) {
morpheus.HeatMapTooltipProvider._nodesToString(tipText, morpheus.HeatMapTooltipProvider._nodesToString(tipText,
selectedRowNodes, heatMap.rowDendrogram._selectedNodeColor, selectedRowNodes, heatMap.rowDendrogram._selectedNodeColor,
separator); separator);
} }
if (selectedColumnNodes.length > 0) { if (selectedColumnNodes.length > 0) {
morpheus.HeatMapTooltipProvider._nodesToString(tipText, morpheus.HeatMapTooltipProvider._nodesToString(tipText,
selectedColumnNodes, selectedColumnNodes,
heatMap.columnDendrogram._selectedNodeColor, separator); heatMap.columnDendrogram._selectedNodeColor, separator);
} }
} }
return tipText.join(''); return tipText.join('');
}; };
morpheus.HeatMapTooltipProvider._matrixValueToString = function(dataset, morpheus.HeatMapTooltipProvider._matrixValueToString = function (dataset,
rowIndex, columnIndex, seriesIndex, tipText, separator, rowIndex, columnIndex, seriesIndex, tipText, separator,
showSeriesNameInTooltip) { showSeriesNameInTooltip) {
var val = dataset.getValue(rowIndex, columnIndex, seriesIndex); var val = dataset.getValue(rowIndex, columnIndex, seriesIndex);
if (val != null) { if (val != null) {
if (val.toObject || !_.isNumber(val)) { if (val.toObject || !_.isNumber(val)) {
var obj = val.toObject ? val.toObject() : val; var obj = val.toObject ? val.toObject() : val;
var keys = _.keys(obj); var keys = _.keys(obj);
_.each(keys, function(key) { if (keys.length === 0) {
if (key !== '__v') { // special value key var v = morpheus.Util.formatObject(obj);
var v = morpheus.Util.formatObject(obj[key]); if (tipText.length > 0) {
if (tipText.length > 0) { tipText.push(separator);
tipText.push(separator); }
if (showSeriesNameInTooltip) {
tipText.push(dataset.getName(seriesIndex));
tipText.push(': ');
}
tipText.push('<b>');
tipText.push(v);
tipText.push('</b>');
} else {
for (var i = 0, nkeys = keys.length; i < nkeys; i++) {
var key = keys[i];
if (key !== '__v') { // special value key
var v = morpheus.Util.formatObject(obj[key]);
if (tipText.length > 0) {
tipText.push(separator);
}
tipText.push(key);
tipText.push(': <b>');
tipText.push(v);
tipText.push('</b>');
} }
tipText.push(key);
tipText.push(': <b>');
tipText.push(v);
tipText.push('</b>');
} }
}); }
} else { } else {
if (tipText.length > 0) { if (tipText.length > 0) {
tipText.push(separator); tipText.push(separator);
...@@ -170,9 +186,9 @@ morpheus.HeatMapTooltipProvider._matrixValueToString = function(dataset, ...@@ -170,9 +186,9 @@ morpheus.HeatMapTooltipProvider._matrixValueToString = function(dataset,
} }
}; };
morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index, morpheus.HeatMapTooltipProvider.vectorToString = function (vector, index,
tipText, separator, additionalVector) { tipText, separator, additionalVector) {
var arrayValueToString = function(arrayFieldName, arrayVal) { var arrayValueToString = function (arrayFieldName, arrayVal) {
if (arrayVal != null) { if (arrayVal != null) {
if (arrayFieldName != null) { if (arrayFieldName != null) {
if (tipText.length > 0) { if (tipText.length > 0) {
...@@ -184,7 +200,7 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index, ...@@ -184,7 +200,7 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index,
tipText.push(' '); tipText.push(' ');
var obj = arrayVal.toObject(); var obj = arrayVal.toObject();
var keys = _.keys(obj); var keys = _.keys(obj);
_.each(keys, function(key) { _.each(keys, function (key) {
var subVal = obj[key]; var subVal = obj[key];
if (subVal != null && subVal != '') { if (subVal != null && subVal != '') {
if (tipText.length > 0) { if (tipText.length > 0) {
...@@ -208,27 +224,27 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index, ...@@ -208,27 +224,27 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index,
var primaryVal = vector.getValue(index); var primaryVal = vector.getValue(index);
if (primaryVal != null && primaryVal != '') { if (primaryVal != null && primaryVal != '') {
var primaryFields = vector.getProperties().get( var primaryFields = vector.getProperties().get(
morpheus.VectorKeys.FIELDS); morpheus.VectorKeys.FIELDS);
if (primaryFields != null) { if (primaryFields != null) {
var visibleFieldIndices = vector.getProperties().get( var visibleFieldIndices = vector.getProperties().get(
morpheus.VectorKeys.VISIBLE_FIELDS); morpheus.VectorKeys.VISIBLE_FIELDS);
if (visibleFieldIndices === undefined) { if (visibleFieldIndices === undefined) {
visibleFieldIndices = morpheus.Util visibleFieldIndices = morpheus.Util
.seq(primaryFields.length); .seq(primaryFields.length);
} }
var additionalFieldNames = additionalVector != null ? additionalVector var additionalFieldNames = additionalVector != null ? additionalVector
.getProperties().get(morpheus.VectorKeys.FIELDS) .getProperties().get(morpheus.VectorKeys.FIELDS)
: null; : null;
var additionalVal = additionalFieldNames != null ? additionalVector var additionalVal = additionalFieldNames != null ? additionalVector
.getValue(index) .getValue(index)
: null; : null;
if (tipText.length > 0) { if (tipText.length > 0) {
tipText.push(separator); tipText.push(separator);
} }
tipText.push(vector.getName()); tipText.push(vector.getName());
for (var j = 0; j < visibleFieldIndices.length; j++) { for (var j = 0; j < visibleFieldIndices.length; j++) {
arrayValueToString(primaryFields[visibleFieldIndices[j]], arrayValueToString(primaryFields[visibleFieldIndices[j]],
primaryVal[visibleFieldIndices[j]]); primaryVal[visibleFieldIndices[j]]);
} }
if (additionalVal != null) { if (additionalVal != null) {
...@@ -238,8 +254,8 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index, ...@@ -238,8 +254,8 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index,
tipText.push(additionalVector.getName()); tipText.push(additionalVector.getName());
for (var j = 0; j < visibleFieldIndices.length; j++) { for (var j = 0; j < visibleFieldIndices.length; j++) {
arrayValueToString( arrayValueToString(
additionalFieldNames[visibleFieldIndices[j]], additionalFieldNames[visibleFieldIndices[j]],
additionalVal[visibleFieldIndices[j]]); additionalVal[visibleFieldIndices[j]]);
} }
} }
...@@ -256,17 +272,15 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index, ...@@ -256,17 +272,15 @@ morpheus.HeatMapTooltipProvider.vectorToString = function(vector, index,
} }
} }
}; };
morpheus.HeatMapTooltipProvider._tracksToString = function(options, tracks, morpheus.HeatMapTooltipProvider._tracksToString = function (options, tracks, metadata, index, tipText, separator) {
metadata, index, tipText, separator) {
for (var i = 0; i < tracks.length; i++) { for (var i = 0; i < tracks.length; i++) {
var vector = metadata.getByName(tracks[i].name); morpheus.HeatMapTooltipProvider.vectorToString(metadata.getByName(tracks[i].name), index, tipText,
morpheus.HeatMapTooltipProvider.vectorToString(vector, index, tipText, separator);
separator);
} }
}; };
morpheus.HeatMapTooltipProvider._metadataToString = function(options, tracks, morpheus.HeatMapTooltipProvider._metadataToString = function (options, tracks,
metadata, index, tipText, separator) { metadata, index, tipText, separator) {
var filtered = []; var filtered = [];
for (var i = 0, ntracks = tracks.length; i < ntracks; i++) { for (var i = 0, ntracks = tracks.length; i < ntracks; i++) {
var track = tracks[i]; var track = tracks[i];
...@@ -276,19 +290,17 @@ morpheus.HeatMapTooltipProvider._metadataToString = function(options, tracks, ...@@ -276,19 +290,17 @@ morpheus.HeatMapTooltipProvider._metadataToString = function(options, tracks,
} else { } else {
filtered.push(track); filtered.push(track);
} }
} }
} }
// show the vector that we're mousing over 1st // show the vector that we're mousing over 1st
morpheus.HeatMapTooltipProvider._tracksToString(options, filtered, morpheus.HeatMapTooltipProvider._tracksToString(options, filtered,
metadata, index, tipText, separator); metadata, index, tipText, separator);
}; };
morpheus.HeatMapTooltipProvider._nodesToString = function(tipText, nodes, morpheus.HeatMapTooltipProvider._nodesToString = function (tipText, nodes,
color, separator) { color, separator) {
var renderField = function(name, value) { var renderField = function (name, value) {
if (value != null) { if (value != null) {
if (tipText.length > 0) { if (tipText.length > 0) {
tipText.push(separator); tipText.push(separator);
...@@ -314,9 +326,9 @@ morpheus.HeatMapTooltipProvider._nodesToString = function(tipText, nodes, ...@@ -314,9 +326,9 @@ morpheus.HeatMapTooltipProvider._nodesToString = function(tipText, nodes,
} }
} }
}; };
_.each(nodes, function(node) { _.each(nodes, function (node) {
if (node.info) { if (node.info) {
for ( var name in node.info) { for (var name in node.info) {
var value = node.info[name]; var value = node.info[name];
renderField(name, value); renderField(name, value);
} }
...@@ -328,4 +340,4 @@ morpheus.HeatMapTooltipProvider._nodesToString = function(tipText, nodes, ...@@ -328,4 +340,4 @@ morpheus.HeatMapTooltipProvider._nodesToString = function(tipText, nodes,
// renderField('height', node.height); // renderField('height', node.height);
} }
}); });
}; };
\ No newline at end of file
...@@ -19,7 +19,7 @@ morpheus.ScentedSearch = function (model, positions, isVertical, scrollbar, ...@@ -19,7 +19,7 @@ morpheus.ScentedSearch = function (model, positions, isVertical, scrollbar,
scrollbar.canvas.style.cursor = index < 0 ? 'default' : 'pointer'; scrollbar.canvas.style.cursor = index < 0 ? 'default' : 'pointer';
var tipOptions = { var tipOptions = {
event: e, event: e,
heatMapLens: true heatMapLens: index >= 0
}; };
if (isVertical) { if (isVertical) {
controller.setToolTip(index >= 0 ? _this.searchIndices[index] : -1, controller.setToolTip(index >= 0 ? _this.searchIndices[index] : -1,
...@@ -35,6 +35,7 @@ morpheus.ScentedSearch = function (model, positions, isVertical, scrollbar, ...@@ -35,6 +35,7 @@ morpheus.ScentedSearch = function (model, positions, isVertical, scrollbar,
// but the canvas cursor has no effect // but the canvas cursor has no effect
document.body.style.cursor = 'default'; document.body.style.cursor = 'default';
scrollbar.canvas.style.cursor = 'default'; scrollbar.canvas.style.cursor = 'default';
controller.setToolTip(-1, -1, {event: e});
}; };
$(scrollbar.canvas).on('mousemove', mouseMove).on('mouseout', mouseExit); $(scrollbar.canvas).on('mousemove', mouseMove).on('mouseout', mouseExit);
}; };
...@@ -215,4 +216,4 @@ morpheus.ScentedSearch.prototype = { ...@@ -215,4 +216,4 @@ morpheus.ScentedSearch.prototype = {
} }
}; };
morpheus.Util.extend(morpheus.ScentedSearch, morpheus.AbstractCanvas); morpheus.Util.extend(morpheus.ScentedSearch, morpheus.AbstractCanvas);
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment