clustergrammer
Version:
This is a clustergram implemented in D3.js. I started from the example http://bost.ocks.org/mike/miserables/ and added the following features
1,803 lines (1,345 loc) • 439 kB
JavaScript
module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var make_config = __webpack_require__(1);
var make_params = __webpack_require__(9);
var make_viz = __webpack_require__(37);
var resize_viz = __webpack_require__(80);
var play_demo = __webpack_require__(124);
var ini_demo = __webpack_require__(163);
var filter_viz_using_nodes = __webpack_require__(166);
var filter_viz_using_names = __webpack_require__(167);
var update_cats = __webpack_require__(168);
var reset_cats = __webpack_require__(169);
var two_translate_zoom = __webpack_require__(92);
var external_update_view = __webpack_require__(171);
var export_matrix = __webpack_require__(174);
var crop_matrix = __webpack_require__(176);
var run_zoom = __webpack_require__(81);
var d3_tip_custom = __webpack_require__(49);
// moved d3.slider to src
d3.slider = __webpack_require__(178);
/* eslint-disable */
var awesomplete = __webpack_require__(180);
// getting css from src
__webpack_require__(182);
__webpack_require__(186);
/* clustergrammer v1.11.6
* Nick Fernandez, Ma'ayan Lab, Icahn School of Medicine at Mount Sinai
* (c) 2017
*/
function Clustergrammer(args) {
/* Main program
* ----------------------------------------------------------------------- */
// consume and validate user input
// build giant config object
// visualize based on config object
// handle user events
// consume and validate user arguments, produce configuration object
var config = make_config(args);
var cgm = {};
// make visualization parameters using configuration object
cgm.params = make_params(config);
cgm.config = config;
// set up zoom
cgm.params.zoom_behavior = d3.behavior.zoom().scaleExtent([1, cgm.params.viz.real_zoom * cgm.params.viz.zoom_switch]).on('zoom', function () {
run_zoom(cgm);
});
cgm.params.zoom_behavior.translate([cgm.params.viz.clust.margin.left, cgm.params.viz.clust.margin.top]);
if (cgm.params.use_sidebar) {
var make_sidebar = __webpack_require__(188);
make_sidebar(cgm);
}
// make visualization using parameters
make_viz(cgm);
function external_resize() {
d3.select(cgm.params.viz.viz_svg).style('opacity', 0.5);
var wait_time = 500;
if (this.params.viz.run_trans === true) {
wait_time = 2500;
}
setTimeout(resize_fun, wait_time, this);
}
function resize_fun(cgm) {
resize_viz(cgm);
}
function run_update_cats(cat_data) {
update_cats(this, cat_data);
}
function zoom_api(pan_dx, pan_dy, fin_zoom) {
two_translate_zoom(this.params, pan_dx, pan_dy, fin_zoom);
}
function expose_d3_tip_custom() {
// this allows external modules to have access to d3_tip
return d3_tip_custom;
}
// add more API endpoints
cgm.update_view = external_update_view;
cgm.resize_viz = external_resize;
cgm.play_demo = play_demo;
cgm.ini_demo = ini_demo;
cgm.filter_viz_using_nodes = filter_viz_using_nodes;
cgm.filter_viz_using_names = filter_viz_using_names;
cgm.update_cats = run_update_cats;
cgm.reset_cats = reset_cats;
cgm.zoom = zoom_api;
cgm.export_matrix = export_matrix;
cgm.crop_matrix = crop_matrix;
cgm.d3_tip_custom = expose_d3_tip_custom;
return cgm;
}
module.exports = Clustergrammer;
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var utils = __webpack_require__(2);
var transpose_network = __webpack_require__(3);
var get_available_filters = __webpack_require__(4);
var get_filter_default_state = __webpack_require__(5);
var set_defaults = __webpack_require__(6);
var check_sim_mat = __webpack_require__(7);
var check_nodes_for_categories = __webpack_require__(8);
module.exports = function make_config(args) {
var defaults = set_defaults();
// Mixin defaults with user-defined arguments.
var config = utils.extend(defaults, args);
config.network_data = args.network_data;
var super_string = ': ';
// replace undersores with space in row/col names
_.each(['row', 'col'], function (inst_rc) {
var inst_nodes = config.network_data[inst_rc + '_nodes'];
var has_cats = check_nodes_for_categories(inst_nodes);
inst_nodes.forEach(function (d) {
if (has_cats) {
config.super_labels = true;
config.super[inst_rc] = d.name.split(super_string)[0];
d.name = d.name.split(super_string)[1];
}
d.name = d.name.replace(/_/g, ' ');
});
});
config.network_data.row_nodes_names = utils.pluck(config.network_data.row_nodes, 'name');
config.network_data.col_nodes_names = utils.pluck(config.network_data.col_nodes, 'name');
config.sim_mat = check_sim_mat(config);
var filters = get_available_filters(config.network_data.views);
var default_states = {};
_.each(_.keys(filters.possible_filters), function (inst_filter) {
var tmp_state = get_filter_default_state(filters.filter_data, inst_filter);
default_states[inst_filter] = tmp_state;
});
// process view
if (_.has(config.network_data, 'views')) {
config.network_data.views.forEach(function (inst_view) {
_.each(_.keys(filters.possible_filters), function (inst_filter) {
if (!_.has(inst_view, inst_filter)) {
inst_view[inst_filter] = default_states[inst_filter];
}
});
var inst_nodes = inst_view.nodes;
// proc row/col nodes names in views
_.each(['row', 'col'], function (inst_rc) {
var has_cats = check_nodes_for_categories(inst_nodes[inst_rc + '_nodes']);
inst_nodes[inst_rc + '_nodes'].forEach(function (d) {
if (has_cats) {
d.name = d.name.split(super_string)[1];
}
d.name = d.name.replace(/_/g, ' ');
});
});
});
}
var col_nodes = config.network_data.col_nodes;
var row_nodes = config.network_data.row_nodes;
// add names and instantaneous positions to links
config.network_data.links.forEach(function (d) {
d.name = row_nodes[d.source].name + '_' + col_nodes[d.target].name;
d.row_name = row_nodes[d.source].name;
d.col_name = col_nodes[d.target].name;
});
// transpose network if necessary
if (config.transpose) {
config.network_data = transpose_network(config.network_data);
var tmp_col_label = args.col_label;
var tmp_row_label = args.row_label;
args.row_label = tmp_col_label;
args.col_label = tmp_row_label;
}
// super-row/col labels
if (!utils.is_undefined(args.row_label) && !utils.is_undefined(args.col_label)) {
config.super_labels = true;
config.super = {};
config.super.row = args.row_label;
config.super.col = args.col_label;
}
// initialize cluster ordering - both rows and columns
config.inst_order = {};
if (!utils.is_undefined(args.order) && utils.is_supported_order(args.order)) {
config.inst_order.row = args.order;
config.inst_order.col = args.order;
} else {
config.inst_order.row = 'clust';
config.inst_order.col = 'clust';
}
// set row or column order directly -- note that row/col are swapped
// !! need to swap row/col orderings
if (!utils.is_undefined(args.row_order) && utils.is_supported_order(args.row_order)) {
// !! row and col orderings are swapped, need to fix
config.inst_order.col = args.row_order;
}
if (!utils.is_undefined(args.col_order) && utils.is_supported_order(args.col_order)) {
// !! row and col orderings are swapped, need to fix
config.inst_order.row = args.col_order;
}
var row_has_group = utils.has(config.network_data.row_nodes[0], 'group');
var col_has_group = utils.has(config.network_data.col_nodes[0], 'group');
config.show_dendrogram = row_has_group || col_has_group;
if (utils.has(config.network_data.links[0], 'value_orig')) {
config.keep_orig = true;
} else {
config.keep_orig = false;
}
return config;
};
/***/ },
/* 2 */
/***/ function(module, exports) {
'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
/* Utility functions
* ----------------------------------------------------------------------- */
module.exports = {
normal_name: function normal_name(d) {
var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
return inst_name;
},
is_supported_order: function is_supported_order(order) {
return order === 'ini' || order === 'clust' || order === 'rank_var' || order === 'rank' || order === 'class' || order == 'alpha';
},
/* Returns whether or not an object has a certain property.
*/
has: function has(obj, key) {
return obj != null && hasOwnProperty.call(obj, key);
},
property: function property(key) {
return function (obj) {
return obj == null ? void 0 : obj[key];
};
},
// Convenience version of a common use case of `map`: fetching a property.
pluck: function pluck(arr, key) {
var self = this;
// Double check that we have lodash or underscore available
if (window._) {
// Underscore provides a _.pluck function. Use that.
if (typeof _.pluck === 'function') {
return _.pluck(arr, key);
} else if (typeof _.map === 'function') {
// Lodash does not have a pluck function.
// Use _.map with the property function defined above.
return _.map(arr, self.property(key));
}
} else if (arr.map && typeof arr.map === 'function') {
// If lodash or underscore not available, check to see if the native arr.map is available.
// If so, use it with the property function defined above.
return arr.map(self.property(key));
}
},
/* Returns true if the object is undefined.
*/
is_undefined: function is_undefined(obj) {
return obj === void 0;
},
/* Mixes two objects in together, overwriting a target with a source.
*/
extend: function extend(target, source) {
target = target || {};
for (var prop in source) {
if (_typeof(source[prop]) === 'object') {
target[prop] = this.extend(target[prop], source[prop]);
} else {
target[prop] = source[prop];
}
}
return target;
}
};
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var utils = __webpack_require__(2);
/* Transpose network.
*/
module.exports = function (net) {
var tnet = {},
inst_link,
i;
tnet.row_nodes = net.col_nodes;
tnet.col_nodes = net.row_nodes;
tnet.links = [];
for (i = 0; i < net.links.length; i++) {
inst_link = {};
inst_link.source = net.links[i].target;
inst_link.target = net.links[i].source;
inst_link.value = net.links[i].value;
// Optional highlight.
if (utils.has(net.links[i], 'highlight')) {
inst_link.highlight = net.links[i].highlight;
}
if (utils.has(net.links[i], 'value_up')) {
inst_link.value_up = net.links[i].value_up;
}
if (utils.has(net.links[i], 'value_dn')) {
inst_link.value_dn = net.links[i].value_dn;
}
if (utils.has(net.links[i], 'info')) {
inst_link.info = net.links[i].info;
}
tnet.links.push(inst_link);
}
return tnet;
};
/***/ },
/* 4 */
/***/ function(module, exports) {
'use strict';
module.exports = function get_available_filters(views) {
var possible_filters = {};
var filter_data = {};
_.each(views, function (inst_view) {
var inst_keys = _.keys(inst_view);
_.each(inst_keys, function (inst_key) {
if (inst_key != 'nodes') {
if (!_.has(filter_data, inst_key)) {
filter_data[inst_key] = [];
}
filter_data[inst_key].push(inst_view[inst_key]);
filter_data[inst_key] = _.uniq(filter_data[inst_key]);
}
});
});
var tmp_filters = _.keys(filter_data);
_.each(tmp_filters, function (inst_filter) {
var options = filter_data[inst_filter];
var num_options = options.length;
var filter_type = 'categorical';
_.each(options, function (inst_option) {
if (typeof inst_option === 'number') {
filter_type = 'numerical';
}
});
if (num_options > 1) {
possible_filters[inst_filter] = filter_type;
}
});
var filters = {};
filters.possible_filters = possible_filters;
filters.filter_data = filter_data;
return filters;
};
/***/ },
/* 5 */
/***/ function(module, exports) {
"use strict";
module.exports = function get_filter_default_state(filter_data, filter_type) {
var default_state = filter_data[filter_type].sort(function (a, b) {
return b - a;
})[0];
default_state = String(default_state);
return default_state;
};
/***/ },
/* 6 */
/***/ function(module, exports) {
'use strict';
module.exports = function set_defaults() {
var defaults = {
// Label options
row_label_scale: 1,
col_label_scale: 1,
super_labels: false,
super: {},
show_label_tooltips: true,
show_tile_tooltips: true,
// matrix options
transpose: false,
tile_colors: ['#FF0000', '#1C86EE'],
bar_colors: ['#FF0000', '#1C86EE'],
// value-cat colors
// cat_value_colors: ['#2F4F4F', '#8A2BE2'],
cat_value_colors: ['#2F4F4F', '#9370DB'],
outline_colors: ['orange', 'black'],
highlight_color: '#FFFF00',
tile_title: false,
// Default domain is set to 0: the domain will be set automatically
input_domain: 0,
opacity_scale: 'linear',
do_zoom: true,
is_zoom: 0,
is_slider_drag: false,
is_cropping: false,
background_color: '#FFFFFF',
super_border_color: '#F5F5F5',
outer_margins: {
top: 0,
bottom: 0,
left: 0,
right: 0
},
ini_expand: false,
grey_border_width: 2,
tile_click_hlight: false,
super_label_scale: 1,
make_tile_tooltip: function make_tile_tooltip(d) {
return d.info;
},
// initialize view, e.g. initialize with row filtering
ini_view: null,
// record of requested views
requested_view: null,
use_sidebar: true,
title: null,
about: null,
sidebar_width: 160,
sidebar_icons: true,
row_search_placeholder: 'Row',
buffer_width: 10,
show_sim_mat: false,
cat_colors: null,
resize: true,
clamp_opacity: 0.85,
expand_button: true,
max_allow_fs: 20,
dendro_filter: { 'row': false, 'col': false },
cat_filter: { 'row': false, 'col': false },
crop_filter_nodes: { 'row': false, 'col': false },
row_tip_callback: null,
col_tip_callback: null,
tile_tip_callback: null,
matrix_update_callback: null,
dendro_callback: null,
new_cat_data: null
};
return defaults;
};
/***/ },
/* 7 */
/***/ function(module, exports) {
"use strict";
module.exports = function check_sim_mat(config) {
var sim_mat = false;
var num_rows = config.network_data.row_nodes_names.length;
var num_cols = config.network_data.col_nodes_names.length;
if (num_rows == num_cols) {
// the sort here was causing errors
var rows = config.network_data.row_nodes_names;
var cols = config.network_data.col_nodes_names;
sim_mat = true;
_.each(rows, function (inst_row) {
var inst_index = rows.indexOf(inst_row);
if (inst_row !== cols[inst_index]) {
sim_mat = false;
}
});
}
if (sim_mat) {
config.expand_button = false;
}
return sim_mat;
};
/***/ },
/* 8 */
/***/ function(module, exports) {
'use strict';
module.exports = function check_nodes_for_categories(nodes) {
var super_string = ': ';
var has_cat = true;
_.each(nodes, function (inst_node) {
if (inst_node.name.indexOf(super_string) < 0) {
has_cat = false;
}
});
return has_cat;
};
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var make_network_using_view = __webpack_require__(10);
var ini_sidebar_params = __webpack_require__(13);
var make_requested_view = __webpack_require__(14);
var get_available_filters = __webpack_require__(4);
var calc_viz_params = __webpack_require__(15);
var ini_zoom_info = __webpack_require__(36);
/*
Params: calculates the size of all the visualization elements in the
clustergram.
*/
module.exports = function make_params(input_config) {
var config = $.extend(true, {}, input_config);
var params = config;
// keep a copy of inst_view
params.inst_nodes = {};
params.inst_nodes.row_nodes = params.network_data.row_nodes;
params.inst_nodes.col_nodes = params.network_data.col_nodes;
// when pre-loading the visualization using a view
if (params.ini_view !== null) {
var requested_view = params.ini_view;
var filters = get_available_filters(params.network_data.views);
params.viz = {};
params.viz.possible_filters = filters.possible_filters;
params.viz.filter_data = filters.filter_data;
requested_view = make_requested_view(params, requested_view);
params.network_data = make_network_using_view(config, params, requested_view);
// save ini_view as requested_view
params.requested_view = requested_view;
}
params = calc_viz_params(params);
if (params.use_sidebar) {
params.sidebar = ini_sidebar_params(params);
}
params.zoom_info = ini_zoom_info();
return params;
};
/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var filter_network_using_new_nodes = __webpack_require__(11);
var get_subset_views = __webpack_require__(12);
module.exports = function make_network_using_view(config, params, requested_view) {
var orig_views = config.network_data.views;
var is_enr = false;
if (_.has(orig_views[0], 'enr_score_type')) {
is_enr = true;
}
var sub_views = get_subset_views(params, orig_views, requested_view);
//////////////////////////////
// Enrichr specific rules
//////////////////////////////
if (is_enr && sub_views.length == 0) {
requested_view = { 'N_row_sum': 'all', 'N_col_sum': '10' };
sub_views = get_subset_views(params, orig_views, requested_view);
}
var inst_view = sub_views[0];
var new_network_data;
// get new_network_data or default back to old_network_data
if (typeof inst_view !== 'undefined') {
var new_nodes = inst_view.nodes;
new_network_data = filter_network_using_new_nodes(config, new_nodes);
} else {
new_network_data = config.network_data;
}
return new_network_data;
};
/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var utils = __webpack_require__(2);
module.exports = function filter_network_using_new_nodes(config, new_nodes) {
var links = config.network_data.links;
// get new names of rows and cols
var row_names = utils.pluck(new_nodes.row_nodes, 'name');
var col_names = utils.pluck(new_nodes.col_nodes, 'name');
var new_links = _.filter(links, function (d) {
var inst_row = d.name.split('_')[0];
var inst_col = d.name.split('_')[1];
var row_index = _.indexOf(row_names, inst_row);
var col_index = _.indexOf(col_names, inst_col);
if (row_index > -1 & col_index > -1) {
// redefine source and target
d.source = row_index;
d.target = col_index;
return d;
}
});
// set up new_network_data
var new_network_data = {};
// rows
new_network_data.row_nodes = new_nodes.row_nodes;
new_network_data.row_nodes_names = row_names;
// cols
new_network_data.col_nodes = new_nodes.col_nodes;
new_network_data.col_nodes_names = col_names;
// links
new_network_data.links = new_links;
// save all links
new_network_data.all_links = links;
// add back all views
new_network_data.views = config.network_data.views;
return new_network_data;
};
/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var utils = __webpack_require__(2);
var get_filter_default_state = __webpack_require__(5);
module.exports = function get_subset_views(params, views, requested_view) {
var inst_value;
var found_filter;
var request_filters = _.keys(requested_view);
// find a view that matches all of the requested view/filter-attributes
_.each(request_filters, function (inst_filter) {
inst_value = requested_view[inst_filter];
// if the value is a number, then convert it to an integer
if (/[^a-z_]/i.test(inst_value)) {
inst_value = parseInt(inst_value, 10);
}
// only run filtering if any of the views has the filter
found_filter = false;
_.each(views, function (tmp_view) {
if (utils.has(tmp_view, inst_filter)) {
found_filter = true;
}
});
if (found_filter) {
views = _.filter(views, function (d) {
return d[inst_filter] == inst_value;
});
}
});
// remove duplicate complete default states
var export_views = [];
var found_default = false;
var check_default;
var inst_default_state;
// check if each view is a default state: all filters are at default
// there can only be one of these
_.each(views, function (inst_view) {
check_default = true;
// check each filter in a view to see if it is in the default state
_.each(_.keys(params.viz.possible_filters), function (inst_filter) {
inst_default_state = get_filter_default_state(params.viz.filter_data, inst_filter);
if (inst_view[inst_filter] != inst_default_state) {
check_default = false;
}
});
// found defaule view, only append if you have not already found a default
if (check_default) {
if (found_default === false) {
found_default = true;
export_views.push(inst_view);
}
} else {
export_views.push(inst_view);
}
});
// if (export_views.length > 1){
// console.log('found more than one view in get_subset_views')
// console.log(requested_view)
// console.log(export_views)
// } else {
// console.log('found single view in get_subset_views')
// console.log(requested_view)
// console.log(export_views[0])
// console.log('\n')
// }
return export_views;
};
/***/ },
/* 13 */
/***/ function(module, exports) {
"use strict";
module.exports = function ini_sidebar_params(params) {
var sidebar = {};
sidebar.wrapper = {};
// sidebar.wrapper.width = 170;
sidebar.row_search = {};
sidebar.row_search.box = {};
sidebar.row_search.box.height = 34;
sidebar.row_search.box.width = 95;
sidebar.row_search.placeholder = params.row_search_placeholder;
sidebar.row_search.margin_left = 7;
sidebar.slider = {};
sidebar.slider.width = params.sidebar_width - 30;
sidebar.slider.margin_left = 15;
sidebar.key_cat = {};
sidebar.key_cat.width = params.sidebar_width - 15;
sidebar.key_cat.margin_left = 5;
sidebar.key_cat.max_height = 100;
sidebar.title = params.title;
sidebar.title_margin_left = 7;
sidebar.about = params.about;
sidebar.width = params.sidebar_width;
sidebar.buttons = {};
sidebar.buttons.width = params.sidebar_width - 15;
sidebar.text = {};
sidebar.icons = params.sidebar_icons;
sidebar.icon_margin_left = -5;
return sidebar;
};
/***/ },
/* 14 */
/***/ function(module, exports) {
'use strict';
module.exports = function make_view_request(params, requested_view) {
// this will add all necessary information to a view request
// it will grab necessary view information from the sliders
// only one component will be changed at a time
var changed_component = _.keys(requested_view)[0];
// add additional filter information from othe possible filters
_.each(_.keys(params.viz.possible_filters), function (inst_filter) {
if (inst_filter != changed_component) {
if (!d3.select(params.root + ' .slider_' + inst_filter).empty()) {
var inst_state = d3.select(params.root + ' .slider_' + inst_filter).attr('current_state');
requested_view[inst_filter] = inst_state;
}
}
});
return requested_view;
};
/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ini_label_params = __webpack_require__(16);
var ini_viz_params = __webpack_require__(17);
var set_viz_wrapper_size = __webpack_require__(23);
var get_svg_dim = __webpack_require__(25);
var calc_label_params = __webpack_require__(26);
var calc_clust_width = __webpack_require__(27);
var calc_clust_height = __webpack_require__(28);
var calc_val_max = __webpack_require__(29);
var calc_matrix_params = __webpack_require__(30);
var set_zoom_params = __webpack_require__(33);
var calc_default_fs = __webpack_require__(35);
module.exports = function calc_viz_params(params) {
var preserve_cats = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
params.labels = ini_label_params(params);
params.viz = ini_viz_params(params, preserve_cats);
set_viz_wrapper_size(params);
params = get_svg_dim(params);
params.viz = calc_label_params(params.viz);
params.viz = calc_clust_width(params.viz);
params.viz = calc_clust_height(params.viz);
if (params.sim_mat) {
if (params.viz.clust.dim.width <= params.viz.clust.dim.height) {
params.viz.clust.dim.height = params.viz.clust.dim.width;
} else {
params.viz.clust.dim.width = params.viz.clust.dim.height;
}
}
params = calc_val_max(params);
params = calc_matrix_params(params);
params = set_zoom_params(params);
params = calc_default_fs(params);
return params;
};
/***/ },
/* 16 */
/***/ function(module, exports) {
"use strict";
module.exports = function ini_label_params(params) {
var labels = {};
labels.super_label_scale = params.super_label_scale;
labels.super_labels = params.super_labels;
labels.super_label_fs = 13.8;
if (labels.super_labels) {
labels.super = {};
labels.super.row = params.super.row;
labels.super.col = params.super.col;
}
labels.show_label_tooltips = params.show_label_tooltips;
labels.row_max_char = _.max(params.network_data.row_nodes, function (inst) {
return inst.name.length;
}).name.length;
labels.col_max_char = _.max(params.network_data.col_nodes, function (inst) {
return inst.name.length;
}).name.length;
labels.max_allow_fs = params.max_allow_fs;
return labels;
};
/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var utils = __webpack_require__(2);
var get_available_filters = __webpack_require__(4);
var make_cat_params = __webpack_require__(18);
module.exports = function ini_viz_params(params) {
var preserve_cats = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
var viz = {};
viz.root = params.root;
viz.root_tips = params.root.replace('#', '.') + '_' + 'd3-tip';
viz.viz_wrapper = params.root + ' .viz_wrapper';
viz.do_zoom = params.do_zoom;
viz.background_color = params.background_color;
viz.super_border_color = params.super_border_color;
viz.outer_margins = params.outer_margins;
viz.is_expand = params.ini_expand;
viz.grey_border_width = params.grey_border_width;
viz.show_dendrogram = params.show_dendrogram;
viz.tile_click_hlight = params.tile_click_hlight;
viz.inst_order = params.inst_order;
viz.expand_button = params.expand_button;
viz.sim_mat = params.sim_mat;
viz.dendro_filter = params.dendro_filter;
viz.cat_filter = params.cat_filter;
viz.cat_value_colors = params.cat_value_colors;
viz.viz_svg = viz.viz_wrapper + ' .viz_svg';
viz.zoom_element = viz.viz_wrapper + ' .viz_svg';
viz.uni_duration = 1000;
// extra space below the clustergram (was 5)
// will increase this to accomidate dendro slider
viz.bottom_space = 10;
viz.run_trans = false;
viz.duration = 1000;
viz.resize = params.resize;
if (utils.has(params, 'size')) {
viz.fixed_size = params.size;
} else {
viz.fixed_size = false;
}
// width is 1 over this value
viz.border_fraction = 65;
viz.uni_margin = 5;
viz.super_labels = {};
viz.super_labels.margin = {};
viz.super_labels.dim = {};
viz.super_labels.margin.left = viz.grey_border_width;
viz.super_labels.margin.top = viz.grey_border_width;
viz.super_labels.dim.width = 0;
if (params.labels.super_labels) {
viz.super_labels.dim.width = 15 * params.labels.super_label_scale;
}
viz.triangle_opacity = 0.6;
viz.norm_labels = {};
viz.norm_labels.width = {};
viz.dendro_room = {};
if (viz.show_dendrogram) {
viz.dendro_room.symbol_width = 10;
} else {
viz.dendro_room.symbol_width = 0;
}
viz.cat_colors = params.cat_colors;
viz = make_cat_params(params, viz, preserve_cats);
if (_.has(params, 'group_level') == false) {
if (viz.show_dendrogram) {
params.group_level = {};
}
params.group_level.row = 5;
params.group_level.col = 5;
}
viz.dendro_opacity = 0.35;
viz.spillover_col_slant = viz.norm_labels.width.col;
var filters = get_available_filters(params.network_data.views);
viz.possible_filters = filters.possible_filters;
viz.filter_data = filters.filter_data;
return viz;
};
/***/ },
/* 18 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var process_category_info = __webpack_require__(19);
var calc_cat_params = __webpack_require__(22);
module.exports = function make_cat_params(params, viz) {
var preserve_cats = arguments.length <= 2 || arguments[2] === undefined ? true : arguments[2];
viz = process_category_info(params, viz, preserve_cats);
viz = calc_cat_params(params, viz);
return viz;
};
/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var utils = __webpack_require__(2);
var colors = __webpack_require__(20);
var check_if_value_cats = __webpack_require__(21);
module.exports = function process_category_info(params, viz) {
var preserve_cats = arguments.length <= 2 || arguments[2] === undefined ? true : arguments[2];
var super_string = ': ';
var tmp_super;
var inst_info;
var inst_color;
viz.show_categories = {};
viz.all_cats = {};
viz.cat_names = {};
viz.cat_info = {};
// this will hold the information for calculating the opacity of the value
// function
var ini_val_opacity = {};
ini_val_opacity.row = null;
ini_val_opacity.col = null;
var predefine_colors = false;
if (viz.cat_colors === null) {
viz.cat_colors = {};
viz.cat_colors.value_opacity = ini_val_opacity;
predefine_colors = false;
} else {
predefine_colors = true;
}
if (preserve_cats === false) {
predefine_colors = false;
}
var num_colors = 0;
_.each(['row', 'col'], function (inst_rc) {
viz.show_categories[inst_rc] = false;
viz.all_cats[inst_rc] = [];
var tmp_keys = _.keys(params.network_data[inst_rc + '_nodes'][0]);
_.each(tmp_keys, function (d) {
if (d.indexOf('cat-') >= 0) {
viz.show_categories[inst_rc] = true;
viz.all_cats[inst_rc].push(d);
}
});
viz.cat_info[inst_rc] = null;
if (viz.show_categories[inst_rc]) {
if (predefine_colors === false) {
viz.cat_colors[inst_rc] = {};
}
viz.cat_info[inst_rc] = {};
viz.cat_names[inst_rc] = {};
_.each(viz.all_cats[inst_rc], function (cat_title) {
_.each(params.network_data[inst_rc + '_nodes'], function (inst_node) {
// look for title of category in category name
if (typeof inst_node[cat_title] === 'string') {
if (inst_node[cat_title].indexOf(super_string) > 0) {
tmp_super = inst_node[cat_title].split(super_string)[0];
viz.cat_names[inst_rc][cat_title] = tmp_super;
} else {
viz.cat_names[inst_rc][cat_title] = cat_title;
}
} else {
viz.cat_names[inst_rc][cat_title] = cat_title;
}
});
var cat_instances = utils.pluck(params.network_data[inst_rc + '_nodes'], cat_title);
var cat_states = _.uniq(cat_instances).sort();
// check whether all the categories are of value type
inst_info = check_if_value_cats(cat_states);
// add histogram to inst_info
if (inst_info.type === 'cat_strings') {
var cat_hist = _.countBy(cat_instances);
inst_info.cat_hist = cat_hist;
} else {
inst_info.cat_hist = null;
}
// pass info_info object
viz.cat_info[inst_rc][cat_title] = inst_info;
if (predefine_colors === false) {
viz.cat_colors[inst_rc][cat_title] = {};
_.each(cat_states, function (cat_tmp, i) {
inst_color = colors.get_random_color(i + num_colors);
viz.cat_colors[inst_rc][cat_title][cat_tmp] = inst_color;
// hack to get 'Not' categories to not be dark colored
// also doing this for false
if (typeof cat_tmp === 'string') {
if (cat_tmp.indexOf('Not ') >= 0 || cat_tmp.indexOf(': false') > 0) {
viz.cat_colors[inst_rc][cat_title][cat_tmp] = '#eee';
}
}
num_colors = num_colors + 1;
});
}
});
}
if (params.sim_mat) {
// sending row color info to columns since row color info can be updated
// using the update_cats endpoint
viz.cat_colors.col = viz.cat_colors.row;
}
});
viz.cat_colors = viz.cat_colors;
viz.cat_colors.opacity = 0.6;
viz.cat_colors.active_opacity = 0.9;
return viz;
};
/***/ },
/* 20 */
/***/ function(module, exports) {
"use strict";
// colors from http://graphicdesign.stackexchange.com/revisions/3815/8
var all_colors;
all_colors = ["#393b79", "#aec7e8", "#ff7f0e", "#ffbb78", "#98df8a", "#bcbd22", "#404040", "#ff9896", "#c5b0d5", "#8c564b", "#1f77b4", "#5254a3", "#FFDB58", "#c49c94", "#e377c2", "#7f7f7f", "#2ca02c", "#9467bd", "#dbdb8d", "#17becf", "#637939", "#6b6ecf", "#9c9ede", "#d62728", "#8ca252", "#8c6d31", "#bd9e39", "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"];
// too light colors
// "#e7969c",
// "#c7c7c7",
// "#f7b6d2",
// "#cedb9c",
// "#9edae5",
function get_default_color() {
return '#EEE';
}
function get_random_color(i) {
return all_colors[i % get_num_colors()];
}
function get_num_colors() {
return all_colors.length;
}
module.exports = {
get_default_color: get_default_color,
get_random_color: get_random_color,
get_num_colors: get_num_colors
};
/***/ },
/* 21 */
/***/ function(module, exports) {
'use strict';
module.exports = function check_if_value_cats(cat_states) {
var tmp_cat = cat_states[0];
var has_title = false;
var might_have_values = false;
var cat_types = 'cat_strings';
var max_abs_val = NaN;
var all_values = [];
var cat_scale = null;
var super_string = ': ';
if (typeof tmp_cat === 'string') {
if (tmp_cat.indexOf(super_string) > -1) {
has_title = true;
tmp_cat = tmp_cat.split(super_string)[1];
}
}
if (isNaN(tmp_cat) == false) {
might_have_values = true;
}
// check each value for number
if (might_have_values) {
// the default state is that all are now values, check each one
cat_types = 'cat_values';
_.each(cat_states, function (inst_cat) {
if (has_title) {
inst_cat = inst_cat.split(super_string)[1];
}
// checking whether inst_cat is 'not a number'
if (isNaN(inst_cat) == true) {
cat_types = 'cat_strings';
} else {
inst_cat = parseFloat(inst_cat);
all_values.push(inst_cat);
}
});
}
if (cat_types === 'cat_values') {
// get absolute value
var max_value = _.max(all_values, function (d) {
return Math.abs(d);
});
max_abs_val = Math.abs(max_value);
cat_scale = d3.scale.linear().domain([0, max_abs_val]).range([0, 1]);
}
var inst_info = {};
inst_info.type = cat_types;
inst_info.max_abs_val = max_abs_val;
inst_info.cat_scale = cat_scale;
return inst_info;
};
/***/ },
/* 22 */
/***/ function(module, exports) {
'use strict';
module.exports = function calc_cat_params(params, viz) {
var separtion_room;
// increase the width of the label container based on the label length
var label_scale = d3.scale.linear().domain([5, 15]).range([85, 120]).clamp('true');
viz.cat_room = {};
viz.cat_room.symbol_width = 12;
viz.cat_room.separation = 3;
_.each(['row', 'col'], function (inst_rc) {
viz.norm_labels.width[inst_rc] = label_scale(params.labels[inst_rc + '_max_char']) * params[inst_rc + '_label_scale'];
viz['num_' + inst_rc + '_nodes'] = params.network_data[inst_rc + '_nodes'].length;
// if (_.has(config, 'group_level')){
// config.group_level[inst_rc] = 5;
// }
if (inst_rc === 'row') {
viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width;
} else {
viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width + 3 * viz.uni_margin;
}
var num_cats = viz.all_cats[inst_rc].length;
if (viz.show_categories[inst_rc]) {
separtion_room = (num_cats - 1) * viz.cat_room.separation;
var adjusted_cats;
if (inst_rc === 'row') {
adjusted_cats = num_cats + 1;
} else {
adjusted_cats = num_cats;
}
viz.cat_room[inst_rc] = adjusted_cats * viz.cat_room.symbol_width + separtion_room;
} else {
// no categories
if (inst_rc == 'row') {
viz.cat_room[inst_rc] = viz.cat_room.symbol_width;
} else {
viz.cat_room[inst_rc] = 0;
}
}
});
return viz;
};
/***/ },
/* 23 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var calc_viz_dimensions = __webpack_require__(24);
module.exports = function set_viz_wrapper_size(params) {
// Create wrapper around SVG visualization
if (d3.select(params.root + ' .viz_wrapper').empty()) {
d3.select(params.root).append('div').classed('sidebar_wrapper', true);
d3.select(params.root).append('div').classed('viz_wrapper', true);
}
var cont_dim = calc_viz_dimensions(params);
d3.select(params.root + ' .sidebar_wrapper').style('float', 'left').style('width', params.sidebar_width + 'px').style('height', cont_dim.height + 'px').style('overflow', 'hidden');
d3.select(params.viz.viz_wrapper).style('float', 'left').style('width', cont_dim.width + 'px').style('height', cont_dim.height + 'px');
};
/***/ },
/* 24 */
/***/ function(module, exports) {
'use strict';
module.exports = function calc_viz_dimensions(params) {
var cont_dim = {};
var extra_space = params.buffer_width;
// var screen_width = window.innerWidth;
// var screen_height = window.innerHeight;
// // resize container, then resize visualization within container
// d3.select(params.root)
// .style('width', screen_width+'px')
// .style('height', screen_height+'px');
var container_width = d3.select(params.root).style('width').replace('px', '');
var container_height = d3.select(params.root).style('height').replace('px', '');
// get outer_margins
var outer_margins;
if (params.viz.is_expand === false) {
outer_margins = params.viz.outer_margins;
cont_dim.width = container_width - params.sidebar_width - extra_space;
} else {
outer_margins = params.viz.outer_margins;
cont_dim.width = container_width - extra_space;
}
cont_dim.top = outer_margins.top;
cont_dim.left = outer_margins.left;
if (params.viz.resize) {
cont_dim.height = container_height;
} else {
if (params.viz.is_expand) {
cont_dim.width = params.viz.fixed_size.width;
} else {
cont_dim.width = params.viz.fixed_size.width - params.sidebar_width;
}
cont_dim.height = params.viz.fixed_size.height;
}
return cont_dim;
};
/***/ },
/* 25 */
/***/ function(module, exports) {
'use strict';
module.exports = function get_svg_dim(params) {
params.viz.svg_dim = {};
params.viz.svg_dim.width = Number(d3.select(params.viz.viz_wrapper).style('width').replace('px', ''));
params.viz.svg_dim.height = Number(d3.select(params.viz.viz_wrapper).style('height').replace('px', ''));
return params;
};
/***/ },
/* 26 */
/***/ function(module, exports) {
"use strict";
module.exports = function calc_label_params(viz) {
viz.norm_labels.margin = {};
viz.norm_labels.margin.left = viz.super_labels.margin.left + viz.super_labels.dim.width;
viz.norm_labels.margin.top = viz.super_labels.margin.top + viz.super_labels.dim.width;
viz.label_background = {};
viz.label_background.row = viz.norm_labels.width.row + viz.cat_room.row + viz.uni_margin;
viz.label_background.col = viz.norm_labels.width.col + viz.cat_room.col + viz.uni_margin;
return viz;
};
/***/ },
/* 27 */
/***/ function(module, exports) {
"use strict";
module.exports = function calc_clust_width(viz) {
viz.clust = {};
viz.clust.margin = {};
// margin on left/top of the clustergram/matrix
// 1) norm_label margin and width
// 2) cat_room and uni_margin
viz.clust.margin.left = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.row + viz.uni_margin;
viz.clust.margin.top = viz.norm_labels.margin.top + viz.norm_labels.width.col + viz.cat_room.col + viz.uni_margin;
// the clustergram/matrix width is the svg width minus:
// the margin of the clustergram on the left
// the room for the spillover on the right
// ** the dendro will fit in the spillover room on the right
var ini_clust_width = viz.svg_dim.width - viz.clust.margin.left - viz.spillover_col_slant;
// make tmp scale to calc height of triangle col labels
var tmp_x_scale = d3.scale.ordinal().rangeBands([0, ini_clust_width]).domain(_.range(viz.num_col_nodes));
var triangle_height = tmp_x_scale.rangeBand() / 2;
// prevent the visualization from being unnecessarily wide
if (triangle_height > viz.norm_labels.width.col) {
var reduce_width = viz.norm_labels.width.col / triangle_height;
ini_clust_width = ini_clust_width * reduce_width;
}
viz.clust.dim = {};
viz.clust.dim.width = ini_clust_width;
return viz;
};
/***/ },
/* 28 */
/***/ function(module, exports) {
"use strict";
module.exports = function calc_clust_height(viz) {
// the clustergram/matrix height is the svg width minus:
// the margin of the clustergram on the top
// the dendrogram
// the bottom_space
var ini_clust_height = viz.svg_dim.height - viz.clust.margin.top - viz.dendro_room.col - viz.bottom_space;
viz.clust.dim.height = ini_clust_height;
return viz;
};
/***/ },
/* 29 */
/***/ function(module, exports) {
"use strict";
module.exports = function calc_val_max(params) {
var val_max = Math.abs(_.max(params.network_data.col_nodes, function (d) {
return Math.abs(d.value);
}).value);
params.labels.bar_scale_col = d3.scale.linear().domain([0, val_max]).range([0, 0.75 * params.viz.norm_labels.width.col]);
val_max = Math.abs(_.max(params.network_data.row_nodes, function (d) {
return Math.abs(d.value);
}).value);
params.labels.bar_scale_row = d3.scale.linear().domain([0, val_max]).range([0, params.viz.norm_labels.width.row]);
return params;
};
/***/ },
/* 30 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var ini_matrix_params = __webpack_require__(31);
module.exports = function calc_matrix_params(params) {
params.matrix = ini_matrix_params(params);
params.viz.x_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.width]);
params.viz.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]);
_.each(['row', 'col'], function (inst_rc) {
var inst_order = params.viz.inst_order[inst_rc];
if (inst_order === 'custom') {
inst_order = 'clust';
}
if (inst_rc === 'row') {
params.viz.x_scale.domain(params.matrix.orders[inst_order + '_' + inst_rc]);
} else {
params.viz.y_scale.domain(params.matrix.orders[inst_order + '_' + inst_rc]);
}
});
params.viz.border_width = {};
params.viz.border_width.x = params.viz.x_scale.rangeBand() / params.viz.border_fraction;
params.viz.border_width.y = params.viz.y_scale.rangeBand() / params.viz.border_fraction;
return params;
};
/***/ },
/* 31 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var utils = __webpack_require__(2);
var initialize_matrix = __webpack_require__(32);
module.exports = function ini_matrix_params(params) {
var matrix = {};
var network_data = params.network_data;
matrix.tile_colors = params.tile_colors;
matrix.bar_colors = params.bar_colors;
matrix.outline_colors = params.outline_colors;
matrix.hlight_color = params.highlight_color;
matrix.tile_title = params.tile_title;
matrix.show_tile_tooltips = params.show_tile_tooltips;
matrix.make_tile_tooltip = params.make_tile_tooltip;
// initialized clicked tile and rows
matrix.click_hlight_x = -666;
matrix.click_hlight_y = -666;
matrix.click_hlight_row = -666;
matrix.click_hlight_col = -666;
// definition of a large matrix (num links) determines if transition is run
matrix.def_large_matrix = 10000;
matrix.opacity_function = params.opacity_scale;
matrix.orders = {};
_.each(['row', 'col'], function (inst_rc) {
// row ordering is based on col info and vice versa
var other_rc;
if (inst_rc === 'row') {
other_rc = 'col';
} else {
other_rc = 'row';
}
// the nodes are defined using other_rc
var inst_nodes = network_data[other_rc + '_nodes'];
var num_nodes = inst_nodes.length;
var nodes_names = utils.pluck(inst_nodes, 'name');
var tmp = nodes_names.sort();
var alpha_index = _.map(tmp, function (d) {
return network_data[other_rc + '_nodes_names'].indexOf(d);
});
matrix.orders['alpha_' + inst_rc] = alpha_index;
var possible_orders = ['clust', 'rank'];
if (_.has(inst_nodes[0], 'rankvar')) {
possible_orders.push('rankvar');
}
if (params.viz.all_cats[other_rc].length > 0) {
_.each(params.viz.all_cats[other_rc], function (inst_cat) {
// the index of the category has replaced - with _
inst_cat = inst_cat.replace('-', '_');
possible_orders.push(inst_cat + '_index');
});
}
_.each(possible_orders, function (inst_order) {
var tmp_order_index = d3.range(num_nodes).sort(function (a, b) {
return inst_nodes[b][inst_order] - inst_nodes[a][inst_order];
});
matrix.orders[inst_order + '_' + inst_rc] = tmp_order_index;
});
});
if (utils.has(network_data, 'all_links')) {
matrix.max_link = _.max(network_data.all_links, function (d) {
return Math.abs(d.value);
}).value;
} else {
matrix.max_link = _.max(network_data.links, function (d) {
return Math.abs(d.value);
}).value;
}
matrix.abs_max_val = Math.abs(matrix.max_link) * params.clamp_opacity;
if (params.input_domain === 0) {
if (matrix.opacity_function === 'linear') {
matrix.opacity_scale = d3.scale.linear().domain([0, matrix.abs_max_val]).clamp(true).range([0.0, 1.0]);
} else if (matrix.opacity_function === 'log') {
matrix.opacity_scale = d3.scale.log().domain([0.001, matrix.abs_max_val]).clamp(true).range([0.0, 1.0]);
}
} else {
if (matrix.opacity_function === 'linear') {
matrix.opacity_scale = d3.scale.linear().domain([0, params.input_domain]).clamp(true).range([0.0, 1.0]);
} else if (matrix.opacity_function === 'log') {
matrix.opacity_scale = d3.scale.log().domain([0.001, params.input_domain]).clamp(true).range([0.0, 1.0]);