Mercurial > repos > azomics > clustergrammer_flow
view js/clustergrammerIPG.js @ 0:fee56ee2f7ac draft
"planemo upload for repository https://github.com/ImmPortDB/immport-galaxy-tools/tree/master/flowtools/clustergrammer_flow commit b11dfcf10d287c1da91ffb1d5d0148c7f8f61356"
author | azomics |
---|---|
date | Fri, 31 Jul 2020 19:06:45 -0400 |
parents | |
children |
line wrap: on
line source
var Clustergrammer = /******/ (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__) { var make_config = __webpack_require__(1); var make_params = __webpack_require__(9); var make_viz = __webpack_require__(37); var resize_viz = __webpack_require__(124); var play_demo = __webpack_require__(165); var ini_demo = __webpack_require__(205); var filter_viz_using_nodes = __webpack_require__(208); var filter_viz_using_names = __webpack_require__(209); var update_cats = __webpack_require__(210); var reset_cats = __webpack_require__(211); var two_translate_zoom = __webpack_require__(116); var external_update_view = __webpack_require__(213); var save_matrix = __webpack_require__(216); var brush_crop_matrix = __webpack_require__(220); var run_zoom = __webpack_require__(125); var d3_tip_custom = __webpack_require__(48); var all_reorder = __webpack_require__(115); var make_matrix_string = __webpack_require__(218); // moved d3.slider to src d3.slider = __webpack_require__(222); /* eslint-disable */ var awesomplete = __webpack_require__(224); // getting css from src __webpack_require__(225); __webpack_require__(229); /* clustergrammer v1.19.2 * Nicolas 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.square_zoom * cgm.params.viz.zoom_ratio.x]).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__(231); 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, 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; } function api_reorder(inst_rc, inst_order) { if (inst_order === 'sum') { inst_order = 'rank'; } if (inst_order === 'var') { inst_order = 'rankvar'; } all_reorder(this, inst_order, inst_rc); } function export_matrix_string() { return make_matrix_string(this.params); } // 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.save_matrix = save_matrix; cgm.brush_crop_matrix = brush_crop_matrix; cgm.d3_tip_custom = expose_d3_tip_custom; cgm.reorder = api_reorder; cgm.export_matrix_string = export_matrix_string; return cgm; } module.exports = Clustergrammer; /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { 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, i) { // add index to row_nodes and col_nodes d[inst_rc + '_index'] = i; 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 = String(d.name); 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, i) { // add index to row_nodes and col_nodes d[inst_rc + '_index'] = i; if (has_cats) { d.name = d.name.split(super_string)[1]; } d.name = String(d.name); d.name = d.name.replace(/_/g, ' '); }); }); }); } var col_nodes = config.network_data.col_nodes; var row_nodes = config.network_data.row_nodes; // console.log( config.network_data.links[0] ) // console.log( config.network_data.links[1] ) // console.log( config.network_data.links[2] ) // console.log(_.has(config.network_data,'mat')); /////////////////////////// // convert 'mat' to links /////////////////////////// if (_.has(config.network_data, 'mat')) { var links = []; var mat = config.network_data.mat; var inst_link = {}; // console.log('found mat') for (var i = 0; i < mat.length; i++) { for (var j = 0; j < mat[0].length; j++) { // console.log(mat[i][j]) inst_link = {}; inst_link.source = i; inst_link.target = j; inst_link.value = mat[i][j]; links.push(inst_link); } } // save to network_data config.network_data.links = links; } // 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) { /* Utility functions * ----------------------------------------------------------------------- */ module.exports = { normal_name: function (d) { var inst_name = d.name.replace(/_/g, ' ').split('#')[0]; return inst_name; }, is_supported_order: function (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 (obj, key) { return obj != null && hasOwnProperty.call(obj, key); }, property: function (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 (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 (obj) { return obj === void 0; }, /* Mixes two objects in together, overwriting a target with a source. */ extend: function (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__) { 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) { 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) { 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) { 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 (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, cat_update_callback: null, dendro_callback: null, dendro_click_callback: null, new_row_cats: null, make_modals: true, show_viz_border: false }; return defaults; }; /***/ }, /* 7 */ /***/ function(module, exports) { 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) { module.exports = function check_nodes_for_categories(nodes) { var super_string = ': '; var has_cat = true; _.each(nodes, function (inst_node) { var inst_name = String(inst_node.name); if (inst_name.indexOf(super_string) < 0) { has_cat = false; } }); return has_cat; }; /***/ }, /* 9 */ /***/ function(module, exports, __webpack_require__) { 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__) { 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__) { 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; // add cat_colors if necessary if (_.has(config.network_data, 'cat_colors')) { new_network_data.cat_colors = config.network_data.cat_colors; } return new_network_data; }; /***/ }, /* 12 */ /***/ function(module, exports, __webpack_require__) { 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) { 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) { 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__) { var ini_label_params = __webpack_require__(16); var set_viz_wrapper_size = __webpack_require__(17); var get_svg_dim = __webpack_require__(19); var calc_label_params = __webpack_require__(20); var calc_clust_width = __webpack_require__(21); var calc_clust_height = __webpack_require__(22); var calc_val_max = __webpack_require__(23); var calc_matrix_params = __webpack_require__(24); var set_zoom_params = __webpack_require__(29); var calc_default_fs = __webpack_require__(31); var utils = __webpack_require__(2); var get_available_filters = __webpack_require__(4); var make_cat_params = __webpack_require__(32); module.exports = function calc_viz_params(params, predefined_cat_colors = true) { params.labels = ini_label_params(params); params.viz = ini_viz_params(params, predefined_cat_colors); 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); function ini_viz_params(params, predefined_cat_colors = true) { 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; // console.log('ini_viz_params -> make_cat_params') // console.log('predefined_cat_colors outside function ' + String(predefined_cat_colors)) viz = make_cat_params(params, viz, predefined_cat_colors); 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; viz.viz_nodes = {}; // nodes that should be visible based on visible area viz.viz_nodes.row = params.network_data.row_nodes_names; viz.viz_nodes.col = params.network_data.col_nodes_names; // nodes that are currently visible viz.viz_nodes.curr_row = params.network_data.row_nodes_names; viz.viz_nodes.curr_col = params.network_data.col_nodes_names; // correct panning in x direction viz.x_offset = 0; return viz; } return params; }; /***/ }, /* 16 */ /***/ function(module, exports) { 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 = 20; 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__) { var calc_viz_dimensions = __webpack_require__(18); 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'); }; /***/ }, /* 18 */ /***/ function(module, exports) { 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; }; /***/ }, /* 19 */ /***/ function(module, exports) { 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; }; /***/ }, /* 20 */ /***/ function(module, exports) { 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; }; /***/ }, /* 21 */ /***/ function(module, exports) { 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; }; /***/ }, /* 22 */ /***/ function(module, exports) { 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; }; /***/ }, /* 23 */ /***/ function(module, exports) { 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; }; /***/ }, /* 24 */ /***/ function(module, exports, __webpack_require__) { var ini_matrix_params = __webpack_require__(25); var calc_downsampled_levels = __webpack_require__(27); module.exports = function calc_matrix_params(params) { params.matrix = ini_matrix_params(params); // X and Y scales: set domains and ranges ////////////////////////////////////////////// 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]); var inst_order; _.each(['row', 'col'], function (inst_rc) { 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]); } }); // border width 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; // rect width needs matrix and zoom parameters params.viz.rect_width = params.viz.x_scale.rangeBand() - params.viz.border_width.x; // moved calculateion to calc_matrix_params params.viz.rect_height = params.viz.y_scale.rangeBand() - params.viz.border_width.y; calc_downsampled_levels(params); return params; }; /***/ }, /* 25 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var initialize_matrix = __webpack_require__(26); 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; matrix.true_max=_.max(network_data.all_links, function (d) { return d.value; }).value; matrix.true_min=_.min(network_data.all_links, function (d) { return d.value; }).value; } else { matrix.max_link = _.max(network_data.links, function (d) { return Math.abs(d.value); }).value; matrix.true_max=_.max(network_data.links, function (d) { return d.value; }).value; matrix.true_min=_.min(network_data.links, function (d) { return d.value; }).value; } matrix.mid_val = (matrix.true_max + matrix.true_min) / 2; 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([matrix.mid_val, matrix.true_max]).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]); } } var has_val_up = utils.has(network_data.links[0], 'value_up'); var has_val_dn = utils.has(network_data.links[0], 'value_dn'); if (has_val_up || has_val_dn) { matrix.tile_type = 'updn'; } else { matrix.tile_type = 'simple'; } if (utils.has(network_data.links[0], 'highlight')) { matrix.highlight = 1; } else { matrix.highlight = 0; } matrix.matrix = initialize_matrix(network_data); matrix.wait_tooltip = 0; return matrix; }; /***/ }, /* 26 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); module.exports = function (network_data) { var matrix = []; var ini_object; var keep_orig; if (utils.has(network_data.links[0], 'value_orig')) { keep_orig = true; } else { keep_orig = false; } network_data.row_nodes.forEach(function (tmp, row_index) { matrix[row_index] = {}; matrix[row_index].name = network_data.row_nodes[row_index].name; matrix[row_index].row_index = row_index; matrix[row_index].row_data = d3.range(network_data.col_nodes.length).map(function (col_index) { if (utils.has(network_data.links[0], 'value_up') || utils.has(network_data.links[0], 'value_dn')) { ini_object = { pos_x: col_index, pos_y: row_index, value: 0, value_up: 0, value_dn: 0, highlight: 0 }; } else { ini_object = { pos_x: col_index, pos_y: row_index, value: 0, highlight: 0 }; } if (keep_orig) { ini_object.value_orig = 0; } return ini_object; }); }); network_data.links.forEach(function (link) { // transfer additional link information is necessary matrix[link.source].row_data[link.target].value = link.value; matrix[link.source].row_data[link.target].row_name = link.row_name; matrix[link.source].row_data[link.target].col_name = link.col_name; if (utils.has(link, 'value_up') || utils.has(link, 'value_dn')) { matrix[link.source].row_data[link.target].value_up = link.value_up; matrix[link.source].row_data[link.target].value_dn = link.value_dn; } if (keep_orig) { matrix[link.source].row_data[link.target].value_orig = link.value_orig; } if (link.highlight) { matrix[link.source].row_data[link.target].highlight = link.highlight; } if (link.info) { matrix[link.source].row_data[link.target].info = link.info; } }); return matrix; }; /***/ }, /* 27 */ /***/ function(module, exports, __webpack_require__) { var calc_downsampled_matrix = __webpack_require__(28); module.exports = function calc_downsampled_levels(params) { // console.log('---- before ---------') // console.log(params.matrix.matrix[0].row_data[0].value) // height of downsampled rectangles var ds_height = 3; var min_rect_height = 2; var total_zoom = ds_height / params.viz.rect_height; // amount of zooming that is tolerated for the downsampled rows var inst_zt = 2; params.viz.ds_zt = inst_zt; var num_levels = Math.floor(Math.log(total_zoom) / Math.log(inst_zt)); if (params.viz.rect_height < min_rect_height && num_levels > 0) { // increase ds opacity, as more rows are compressed into a single downsampled // row, increase the opacity of the downsampled row. Max increase will be 2x // when 100 or more rows are compressed var max_opacity_scale = 2; params.viz.ds_opacity_scale = d3.scale.linear().domain([1, 100]).range([1, max_opacity_scale]).clamp(true); var ds; params.viz.ds_num_levels = num_levels; // array of downsampled parameters params.viz.ds = []; // array of downsampled matrices at varying levels params.matrix.ds_matrix = []; var inst_order = params.viz.inst_order.row; // cloning var mat = $.extend(true, {}, params.matrix.matrix); // calculate parameters for different levels for (var i = 0; i < num_levels; i++) { // instantaneous ds_level (-1 means no downsampling) params.viz.ds_level = 0; ds = {}; ds.height = ds_height; ds.num_levels = num_levels; var inst_zoom_tolerance = Math.pow(inst_zt, i); ds.zt = inst_zoom_tolerance; // the number of downsampled rows is given by the height of the clustergram // divided by the adjusted height of the downsampled rect. // the adjusted height is the height divided by the zooming tolerance of // the downsampled layer // number of downsampled rows ds.num_rows = Math.round(params.viz.clust.dim.height / (ds.height / inst_zoom_tolerance)); // x_scale ///////////////////////// ds.x_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.width]); ds.x_scale.domain(params.matrix.orders[inst_order + '_row']); // y_scale ///////////////////////// ds.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]); ds.y_scale.domain(d3.range(ds.num_rows + 1)); ds.rect_height = ds.y_scale.rangeBand() - params.viz.border_width.y; params.viz.ds.push(ds); var matrix = calc_downsampled_matrix(params, mat, i); params.matrix.ds_matrix.push(matrix); } // reset row viz_nodes since downsampling params.viz.viz_nodes.row = d3.range(params.matrix.ds_matrix[0].length).map(String); } else { // set ds to null if no downsampling is done params.viz.ds = null; // instantaneous ds_level (-1 means no downsampling) params.viz.ds_level = -1; params.viz.ds_num_levels = 0; } // console.log('---- after ---------') // console.log(params.matrix.matrix[0].row_data[0].value) }; /***/ }, /* 28 */ /***/ function(module, exports) { module.exports = function calc_downsampled_matrix(params, mat, ds_level) { var inst_num_rows = params.viz.ds[ds_level].num_rows; var num_compressed_rows = params.network_data.row_nodes.length / inst_num_rows; // increase ds opacity, as more rows are compressed into a single downsampled // row, increase the opacity of the downsampled row. var opacity_factor = params.viz.ds_opacity_scale(num_compressed_rows); var mod_val = params.viz.clust.dim.height / inst_num_rows; var ds_mat = []; var inst_obj; var len_ds_array = inst_num_rows + 1; var i; var x; // initialize array of objects for (i = 0; i < len_ds_array; i++) { inst_obj = {}; inst_obj.row_index = i; inst_obj.name = String(i); inst_obj.all_names = []; ds_mat.push(inst_obj); } _.each(mat, function (inst_row) { // row ordering information is contained in y_scale var inst_y = params.viz.y_scale(inst_row.row_index); var ds_index = Math.round(inst_y / mod_val); var inst_row_data = inst_row.row_data; // gather names ds_mat[ds_index].all_names.push(inst_row.name); // gather row_data if (_.has(ds_mat[ds_index], 'row_data')) { for (x = 0; x < inst_row_data.length; x++) { ds_mat[ds_index].row_data[x].value = ds_mat[ds_index].row_data[x].value + inst_row_data[x].value; } } else { var new_data = []; for (x = 0; x < inst_row_data.length; x++) { new_data[x] = inst_row_data[x]; } ds_mat[ds_index].row_data = new_data; } }); // average the values _.each(ds_mat, function (tmp_ds) { var tmp_row_data = tmp_ds.row_data; var num_names = tmp_ds.all_names.length; _.each(tmp_row_data, function (tmp_obj) { tmp_obj.value = tmp_obj.value / num_names * opacity_factor; }); }); // all names were found var all_names = []; _.each(ds_mat, function (inst_row) { all_names = all_names.concat(inst_row.all_names); }); return ds_mat; }; /***/ }, /* 29 */ /***/ function(module, exports, __webpack_require__) { var calc_zoom_switching = __webpack_require__(30); module.exports = function set_zoom_params(params) { params.viz.zoom_scale_font = {}; params.viz.zoom_scale_font.row = 1; params.viz.zoom_scale_font.col = 1; var max_zoom_limit = 0.75; var half_col_height = params.viz.x_scale.rangeBand() / 2; params.viz.square_zoom = params.viz.norm_labels.width.col / half_col_height * max_zoom_limit; params.viz = calc_zoom_switching(params.viz); return params; }; /***/ }, /* 30 */ /***/ function(module, exports) { module.exports = function calc_zoom_switching(viz) { var width_by_col = viz.clust.dim.width / viz.num_col_nodes; var height_by_row = viz.clust.dim.height / viz.num_row_nodes; viz.zoom_ratio = {}; viz.zoom_ratio.x = width_by_col / height_by_row; viz.zoom_ratio.y = 1; if (viz.zoom_ratio.x < 1) { viz.zoom_ratio.y = 1 / viz.zoom_ratio.x; viz.zoom_ratio.x = 1; } return viz; }; /***/ }, /* 31 */ /***/ function(module, exports) { module.exports = function calc_default_fs(params) { params.labels.default_fs_row = params.viz.y_scale.rangeBand() * 1.01; params.labels.default_fs_col = params.viz.x_scale.rangeBand() * 0.87; if (params.labels.default_fs_row > params.labels.max_allow_fs) { params.labels.default_fs_row = params.labels.max_allow_fs; } if (params.labels.default_fs_col > params.labels.max_allow_fs) { params.labels.default_fs_col = params.labels.max_allow_fs; } return params; }; /***/ }, /* 32 */ /***/ function(module, exports, __webpack_require__) { var calc_cat_params = __webpack_require__(33); var utils = __webpack_require__(2); var colors = __webpack_require__(34); var check_if_value_cats = __webpack_require__(35); module.exports = function make_cat_params(params, viz, predefined_cat_colors = true) { 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; viz.cat_colors = {}; viz.cat_colors.value_opacity = ini_val_opacity; 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]); tmp_keys = tmp_keys.sort(); _.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]) { viz.cat_colors[inst_rc] = {}; viz.cat_info[inst_rc] = {}; viz.cat_names[inst_rc] = {}; _.each(viz.all_cats[inst_rc], function (cat_title) { var inst_node = params.network_data[inst_rc + '_nodes'][0]; // 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_titles = utils.pluck(params.network_data[inst_rc + '_nodes'], cat_title); var cat_instances = []; _.each(cat_instances_titles, function (inst_cat) { var new_cat; if (inst_cat.indexOf(': ') > 0) { new_cat = inst_cat.split(': ')[1]; } else { new_cat = inst_cat; } cat_instances.push(new_cat); }); var cat_states = _.uniq(cat_instances_titles).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') { // remove titles from categories in hist 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; viz.cat_colors[inst_rc][cat_title] = {}; _.each(cat_states, function (cat_tmp, inst_index) { inst_color = colors.get_random_color(inst_index + 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 (_.has(params.network_data, 'cat_colors') && predefined_cat_colors === true) { viz.cat_colors[inst_rc] = params.network_data.cat_colors[inst_rc]; } if (params.sim_mat) { // sending row color info to columns since row color info can be updated 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; viz = calc_cat_params(params, viz); return viz; }; /***/ }, /* 33 */ /***/ function(module, exports) { 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; }; /***/ }, /* 34 */ /***/ function(module, exports) { // 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 }; /***/ }, /* 35 */ /***/ function(module, exports) { 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; }; /***/ }, /* 36 */ /***/ function(module, exports) { module.exports = function ini_zoom_info() { var zoom_info = {}; zoom_info.zoom_x = 1; zoom_info.zoom_y = 1; zoom_info.trans_x = 0; zoom_info.trans_y = 0; return zoom_info; }; /***/ }, /* 37 */ /***/ function(module, exports, __webpack_require__) { var generate_matrix = __webpack_require__(38); var make_row_label_container = __webpack_require__(49); var make_col_label_container = __webpack_require__(103); var generate_super_labels = __webpack_require__(111); var spillover = __webpack_require__(112); var initialize_resizing = __webpack_require__(123); var ini_doubleclick = __webpack_require__(133); var make_col_cat = __webpack_require__(152); var make_row_cat = __webpack_require__(158); var trim_text = __webpack_require__(118); var make_row_dendro = __webpack_require__(159); var make_col_dendro = __webpack_require__(160); var make_svg_dendro_sliders = __webpack_require__(161); var make_row_dendro_spillover = __webpack_require__(164); module.exports = function make_viz(cgm) { var params = cgm.params; d3.select(params.viz.viz_wrapper + ' svg').remove(); var svg_group = d3.select(params.viz.viz_wrapper).append('svg').attr('class', 'viz_svg').attr('id', 'svg_' + params.root.replace('#', '')).attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('is_zoom', 0).attr('stopped_zoom', 1); svg_group.append('rect').attr('class', 'super_background').style('width', params.viz.svg_dim.width).style('height', params.viz.svg_dim.height).style('fill', 'white'); generate_matrix(params, svg_group); make_row_label_container(cgm); if (params.viz.show_dendrogram) { make_row_dendro(cgm); make_col_dendro(cgm); } make_row_dendro_spillover(cgm); make_col_label_container(cgm); // initial trim text if (params.viz.ds_level === -1) { _.each(['row', 'col'], function (inst_rc) { var inst_fs = Number(d3.select('.' + inst_rc + '_label_group').select('text').style('font-size').replace('px', '')); var min_trim_fs = 8; if (inst_fs > min_trim_fs) { d3.selectAll(params.root + ' .' + inst_rc + '_label_group').each(function () { trim_text(params, this, inst_rc); }); } }); } // make category colorbars make_row_cat(cgm); if (params.viz.show_categories.col) { make_col_cat(cgm); } spillover(cgm); if (params.labels.super_labels) { generate_super_labels(params); } // sliders should go above super labels make_svg_dendro_sliders(cgm); function border_colors() { var inst_color = params.viz.super_border_color; if (params.viz.is_expand || params.show_viz_border == false) { inst_color = 'white'; } return inst_color; } // left border d3.select(params.viz.viz_svg).append('rect').classed('left_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,0)'); // right border d3.select(params.viz.viz_svg).append('rect').classed('right_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', function () { var inst_offset = params.viz.svg_dim.width - params.viz.grey_border_width; return 'translate(' + inst_offset + ',0)'; }); // top border d3.select(params.viz.viz_svg).append('rect').classed('top_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () { var inst_offset = 0; return 'translate(' + inst_offset + ',0)'; }); // bottom border d3.select(params.viz.viz_svg).append('rect').classed('bottom_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () { var inst_offset = params.viz.svg_dim.height - params.viz.grey_border_width; return 'translate(0,' + inst_offset + ')'; }); initialize_resizing(cgm); ini_doubleclick(cgm); if (params.viz.do_zoom) { d3.select(params.viz.zoom_element).call(params.zoom_behavior); } d3.select(params.viz.zoom_element).on('dblclick.zoom', null); }; /***/ }, /* 38 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var draw_gridlines = __webpack_require__(39); var add_click_hlight = __webpack_require__(40); var make_matrix_rows = __webpack_require__(41); module.exports = function (params, svg_elem) { var network_data = params.network_data; var matrix = []; var clust_group; // append a group that will hold clust_group and position it once clust_group = svg_elem.append('g').attr('class', 'clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')').append('g').attr('class', 'clust_group').classed('clust_group', true); // clustergram background rect clust_group.append('rect').classed('background', true).classed('grey_background', true).style('fill', '#eee').style('opacity', 0.25).attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height); // pass in params and the rows (row_nodes) that need to be made // in this case all row nodes // make_matrix_rows(params, params.matrix.matrix, params.network_data.row_nodes_names); // initialize at ds_level 0 if (params.viz.ds === null) { // do not use downsampled matrix make_matrix_rows(params, params.matrix.matrix, 'all', params.viz.ds_level); } else { // use downsampled matrix make_matrix_rows(params, params.matrix.ds_matrix[0], 'all', params.viz.ds_level); } // add callback function to tile group - if one is supplied by the user if (typeof params.click_tile === 'function') { d3.selectAll(params.root + ' .tile').on('click', function (d) { // export row/col name and value from tile var tile_info = {}; tile_info.row = params.network_data.row_nodes[d.pos_y].name; tile_info.col = params.network_data.col_nodes[d.pos_x].name; tile_info.value = d.value; if (utils.has(d, 'value_up')) { tile_info.value_up = d.value_up; } if (utils.has(d, 'value_dn')) { tile_info.value_dn = d.value_dn; } if (utils.has(d, 'info')) { tile_info.info = d.info; } // run the user supplied callback function params.click_tile(tile_info); add_click_hlight(params, this); }); } else { // highlight clicked tile if (params.tile_click_hlight) { d3.selectAll(params.root + ' .tile').on('click', function () { add_click_hlight(params, this); }); } } // draw grid lines after drawing tiles var delays = {}; var duration = 0; delays.enter = 0; draw_gridlines(params, delays, duration); // Matrix API return { get_clust_group: function () { return clust_group; }, get_matrix: function () { return matrix; }, get_nodes: function (type) { if (type === 'row') { return network_data.row_nodes; } return network_data.col_nodes; } }; }; /***/ }, /* 39 */ /***/ function(module, exports) { // var grid_lines_viz = require('./grid_lines_viz'); // var toggle_grid_lines = require('./toggle_grid_lines'); module.exports = function draw_gridlines(params, delays, duration) { // var row_nodes = params.network_data.row_nodes; // var col_nodes = params.network_data.col_nodes; // // Fade in new gridlines // /////////////////////////// // // append horizontal line groups // var horz_lines = d3.select(params.root+' .clust_group') // .selectAll('.horz_lines') // .data(row_nodes, function(d){return d.name;}) // .enter() // .append('g') // .attr('class','horz_lines'); // // append vertical line groups // var vert_lines = d3.select(params.root+' .clust_group') // .selectAll('.vert_lines') // .data(col_nodes) // .enter() // .append('g') // .attr('class', 'vert_lines'); // grid_lines_viz(params, duration); // horz_lines // .select('line') // .attr('opacity',0) // .attr('stroke','white') // .attr('opacity', 1); // vert_lines // .select('line') // .style('stroke', 'white') // .attr('opacity',0) // .transition().delay(delays.enter).duration(2*duration) // .attr('opacity', 1); // toggle_grid_lines(params); }; /***/ }, /* 40 */ /***/ function(module, exports) { module.exports = function (params, clicked_rect) { // get x position of rectangle d3.select(clicked_rect).each(function (d) { var pos_x = d.pos_x; var pos_y = d.pos_y; d3.selectAll(params.root + ' .click_hlight').remove(); if (pos_x != params.matrix.click_hlight_x || pos_y != params.matrix.click_hlight_y) { // save pos_x to params.viz.click_hlight_x params.matrix.click_hlight_x = pos_x; params.matrix.click_hlight_y = pos_y; // draw the highlighting rectangle as four rectangles // so that the width and height can be controlled // separately var rel_width_hlight = 6; var opacity_hlight = 0.85; var hlight_width = rel_width_hlight * params.viz.border_width.x; var hlight_height = rel_width_hlight * params.viz.border_width.y; // top highlight d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('top_hlight', true).attr('width', params.viz.x_scale.rangeBand()).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('transform', function () { return 'translate(' + params.viz.x_scale(pos_x) + ',0)'; }).attr('opacity', opacity_hlight); // left highlight d3.select(clicked_rect.parentNode) .append('rect') .classed('click_hlight', true) .classed('left_hlight', true) .attr('width', hlight_width) .attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99) .attr('fill', params.matrix.hlight_color).attr('transform', function () { return "translate(" + params.viz.x_scale(pos_x) + "," + hlight_height * 0.99 + ")"; }) .attr('opacity', opacity_hlight); // right highlight d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('right_hlight', true).attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).attr('fill', params.matrix.hlight_color).attr('transform', function () { var tmp_translate = params.viz.x_scale(pos_x) + params.viz.x_scale.rangeBand() - hlight_width; return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')'; }).attr('opacity', opacity_hlight); // bottom highlight d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('bottom_hlight', true).attr('width', function () { return params.viz.x_scale.rangeBand() - 1.98 * hlight_width; }).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('transform', function () { var tmp_translate_x = params.viz.x_scale(pos_x) + hlight_width * 0.99; var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height; return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')'; }).attr('opacity', opacity_hlight); } else { params.matrix.click_hlight_x = -666; params.matrix.click_hlight_y = -666; } }); }; /***/ }, /* 41 */ /***/ function(module, exports, __webpack_require__) { var make_simple_rows = __webpack_require__(42); var d3_tip_custom = __webpack_require__(48); // current matrix can change with downsampling module.exports = function make_matrix_rows(params, current_matrix, row_names = 'all', ds_level = -1) { // defaults var y_scale = params.viz.y_scale; var make_tip = true; var row_class = 'row'; if (ds_level >= 0) { y_scale = params.viz.ds[ds_level].y_scale; // do not show tip when rows are downsampled make_tip = false; row_class = 'ds' + String(ds_level) + '_row'; } if (make_tip) { // do not remove tile_tip here ///////////////////////////////// // make rows in the matrix - add key names to rows in matrix ///////////////////////////////////////////////////////////// // d3-tooltip - for tiles var tip = d3_tip_custom().attr('class', function () { var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_tile_tip'; return class_string; }).style('display', 'none').direction('nw').offset([0, 0]).html(function (d) { var inst_value = String(d.value.toFixed(3)); var tooltip_string; if (params.keep_orig) { var orig_value = String(d.value_orig.toFixed(3)); tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<p> normalized value: ' + inst_value + '</p>' + '<div> original value: ' + orig_value + '</div>'; } else { tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<div> value: ' + inst_value + '</div>'; } return tooltip_string; }); } else { tip = null; } // gather a subset of row data from the matrix or use all rows var matrix_subset = []; if (row_names === 'all') { matrix_subset = current_matrix; } else { _.each(current_matrix, function (inst_row) { if (_.contains(row_names, inst_row.name)) { matrix_subset.push(inst_row); } }); } d3.select(params.root + ' .clust_group').selectAll('.row').data(matrix_subset, function (d) { return d.name; }).enter().append('g').classed(row_class, true).attr('transform', function (d) { return 'translate(0,' + y_scale(d.row_index) + ')'; }).each(function (d) { make_simple_rows(params, d, tip, this, ds_level); }); if (params.viz.ds_level === -1 && tip != null) { d3.selectAll(params.root + ' .row').call(tip); } }; /***/ }, /* 42 */ /***/ function(module, exports, __webpack_require__) { /* eslint-disable */ var draw_up_tile = __webpack_require__(43); var draw_dn_tile = __webpack_require__(44); var mouseover_tile = __webpack_require__(45); var mouseout_tile = __webpack_require__(46); var fine_position_tile = __webpack_require__(47); module.exports = function make_simple_rows(params, inst_data, tip, row_selection, ds_level = -1) { var inp_row_data = inst_data.row_data; var make_tip = true; var rect_height = params.viz.rect_height; if (ds_level >= 0) { // make_tip = false; rect_height = params.viz.ds[ds_level].rect_height; } var keep_orig; if (_.has(params.network_data.links[0], 'value_orig')) { keep_orig = true; } else { keep_orig = false; } var row_values; if (keep_orig === false) { // value: remove zero values to make visualization faster row_values = _.filter(inp_row_data, function (num) { return num.value !== 0; }); } else { row_values = inp_row_data; } // generate tiles in the current row var tile = d3.select(row_selection).selectAll('rect').data(row_values, function (d) { return d.col_name; }).enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', rect_height).style('fill', function (d) { // switch the color based on up/dn value var inst_fill; if (d.value_orig === 'NaN') { inst_fill = '#000000'; } else { inst_fill = d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1]; } return inst_fill; }).style('fill-opacity', function (d) { // calculate output opacity using the opacity scale var inst_opacity; if (d.value_orig === 'NaN') { // console.log('found NaN while making tiles'); inst_opacity = 0.175; } else { var op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val); inst_opacity = params.matrix.opacity_scale(op_val); } return inst_opacity; }).attr('transform', function (d) { return fine_position_tile(params, d); }); if (make_tip) { tile.on('mouseover', function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } mouseover_tile(params, this, tip, args); }).on('mouseout', function () { mouseout_tile(params, this, tip); }); } // // tile circles // ///////////////////////////// // var tile = d3.select(row_selection) // .selectAll('circle') // .data(row_values, function(d){ return d.col_name; }) // .enter() // .append('circle') // .attr('cx', params.viz.rect_height/2) // .attr('cy', params.viz.rect_height/2) // .attr('r', params.viz.rect_height/3) // .attr('class', 'tile_circle') // // .attr('width', params.viz.rect_width/2) // // .attr('height', params.viz.rect_height/2) // // // switch the color based on up/dn value // // .style('fill', function(d) { // // // return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1]; // // return 'black'; // // }) // .on('mouseover', function(...args) { // mouseover_tile(params, this, tip, args); // }) // .on('mouseout', function() { // mouseout_tile(params, this, tip); // }) // .style('fill-opacity', function(d) { // // calculate output opacity using the opacity scale // var output_opacity = params.matrix.opacity_scale(Math.abs(d.value)); // if (output_opacity < 0.3){ // output_opacity = 0; // } else if (output_opacity < 0.6){ // output_opacity = 0.35; // } else { // output_opacity = 1; // } // return output_opacity; // // return 0.1; // }) // .attr('transform', function(d) { // return fine_position_tile(params, d); // }); if (params.matrix.tile_type == 'updn') { // value split var row_split_data = _.filter(inp_row_data, function (num) { return num.value_up != 0 || num.value_dn != 0; }); // tile_up d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) { return d.col_name; }).enter().append('path').attr('class', 'tile_up').attr('d', function () { return draw_up_tile(params); }).attr('transform', function (d) { fine_position_tile(params, d); }).style('fill', function () { return params.matrix.tile_colors[0]; }).style('fill-opacity', function (d) { var inst_opacity = 0; if (Math.abs(d.value_dn) > 0) { inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_up)); } return inst_opacity; }).on('mouseover', function (...args) { mouseover_tile(params, this, tip, args); }).on('mouseout', function () { mouseout_tile(params, this, tip); }); // tile_dn d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) { return d.col_name; }).enter().append('path').attr('class', 'tile_dn').attr('d', function () { return draw_dn_tile(params); }).attr('transform', function (d) { fine_position_tile(params, d); }).style('fill', function () { return params.matrix.tile_colors[1]; }).style('fill-opacity', function (d) { var inst_opacity = 0; if (Math.abs(d.value_up) > 0) { inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_dn)); } return inst_opacity; }).on('mouseover', function (...args) { mouseover_tile(params, this, tip, args); }).on('mouseout', function () { mouseout_tile(params, this, tip); }); // remove rect when tile is split tile.each(function (d) { if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) { d3.select(this).remove(); } }); } // append title to group if (params.matrix.tile_title) { tile.append('title').text(function (d) { var inst_string = 'value: ' + d.value; return inst_string; }); } }; /***/ }, /* 43 */ /***/ function(module, exports) { module.exports = function draw_up_tile(params) { var start_x = 0; var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x; var start_y = 0; var final_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y; var output_string = 'M' + start_x + ',' + start_y + ', L' + start_x + ', ' + final_y + ', L' + final_x + ',0 Z'; return output_string; }; /***/ }, /* 44 */ /***/ function(module, exports) { module.exports = function draw_dn_tile(params) { var start_x = 0; var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x; var start_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y; var final_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y; var output_string = 'M' + start_x + ', ' + start_y + ' , L' + final_x + ', ' + final_y + ', L' + final_x + ',0 Z'; return output_string; }; /***/ }, /* 45 */ /***/ function(module, exports) { module.exports = function mouseover_tile(params, inst_selection, tip, inst_arguments) { var inst_data = inst_arguments[0]; var args = [].slice.call(inst_arguments); var timeout; var delay = 1000; d3.select(inst_selection).classed('hovering', true); _.each(['row', 'col'], function (inst_rc) { d3.selectAll(params.root + ' .' + inst_rc + '_label_group text').style('font-weight', function (d) { var font_weight; var inst_found = inst_data[inst_rc + '_name'].replace(/_/g, ' ') === d.name; if (inst_found) { font_weight = 'bold'; } else { font_weight = 'normal'; } return font_weight; }); }); args.push(inst_selection); clearTimeout(timeout); timeout = setTimeout(check_if_hovering, delay, inst_selection); function check_if_hovering() { if (d3.select(inst_selection).classed('hovering')) { var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom')); if (inst_zoom === 0) { if (params.matrix.show_tile_tooltips && tip !== null) { d3.selectAll(params.viz.root_tips + '_tile_tip').style('display', 'block'); tip.show.apply(inst_selection, args); if (params.tile_tip_callback != null) { var tile_info = args[0]; params.tile_tip_callback(tile_info); } } } } } }; /***/ }, /* 46 */ /***/ function(module, exports) { module.exports = function mouseout_tile(params, inst_selection, tip) { d3.select(inst_selection).classed('hovering', false); d3.selectAll(params.viz.root_tips + '_tile_tip').style('display', 'none'); _.each(['row', 'col'], function (inst_rc) { d3.selectAll(params.root + ' .' + inst_rc + '_label_group text').style('font-weight', 'normal'); }); if (tip != null) { tip.hide(); } }; /***/ }, /* 47 */ /***/ function(module, exports) { module.exports = function fine_position_tile(params, d) { var offset_x; // prevent rows not in x_scale domain from causing errors if (d.pos_x in params.viz.x_scale.domain()) { offset_x = params.viz.x_scale(d.pos_x); } else { offset_x = 0; } var x_pos = offset_x + 0.5 * params.viz.border_width.x; var y_pos = 0.5 * params.viz.border_width.y; return 'translate(' + x_pos + ',' + y_pos + ')'; }; /***/ }, /* 48 */ /***/ function(module, exports) { module.exports = function d3_tip_custom() { /* eslint-disable */ // Copyright (c) 2013 Justin Palmer // // Tooltips for d3.js SVG visualizations // Public - contructs a new tooltip // // Returns a tip // ****************** // Nick Fernandez modified version 4-19-2016 // improved multiple svg, scrolling+zooming support // made syntax fixes ////////////////////////////////////////////// var direction = d3_tip_direction, offset = d3_tip_offset, html = d3_tip_html, node = initNode(), svg = null, point = null, target = null; function tip(vis) { svg = getSVGNode(vis); point = svg.createSVGPoint(); document.body.appendChild(node); } // Public - show the tooltip on the screen // // Returns a tip tip.show = function () { var args = Array.prototype.slice.call(arguments); if (args[args.length - 1] instanceof SVGElement) { target = args.pop(); } var content = html.apply(this, args); var poffset = offset.apply(this, args); var dir = direction.apply(this, args); var nodel = d3.select(node); var i = 0; var coords; // add z-index to make sure tooltips appear on top nodel.html(content).style({ opacity: 1, 'pointer-events': 'all' }).style('z-index', 99); while (i--) { nodel.classed(directions[i], false); } coords = direction_callbacks.get(dir).apply(this); nodel.classed(dir, true).style({ top: coords.top + poffset[0] + 'px', left: coords.left + poffset[1] + 'px' }); // quick fix for fading tile tooltips if (isFunction(this) === false) { var inst_class = d3.select(this).attr('class'); if (inst_class.indexOf('tile') >= 0) { setTimeout(fade_tips, 5000, this); } } return tip; }; // Public - hide the tooltip // // Returns a tip tip.hide = function () { // // hide all d3-tip tooltips // d3.selectAll('.d3-tip') // .style('display', 'none'); var nodel = d3.select(node); nodel.style({ opacity: 0, 'pointer-events': 'none' }); return tip; }; // Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value. // // n - name of the attribute // v - value of the attribute // // Returns tip or attribute value tip.attr = function (n) { if (arguments.length < 2 && typeof n === 'string') { return d3.select(node).attr(n); } else { var args = Array.prototype.slice.call(arguments); d3.selection.prototype.attr.apply(d3.select(node), args); } return tip; }; // Public: Proxy style calls to the d3 tip container. Sets or gets a style value. // // n - name of the property // v - value of the property // // Returns tip or style property value tip.style = function (n) { if (arguments.length < 2 && typeof n === 'string') { return d3.select(node).style(n); } else { var args = Array.prototype.slice.call(arguments); d3.selection.prototype.style.apply(d3.select(node), args); } return tip; }; // Public: Set or get the direction of the tooltip // // v - One of n(north), s(south), e(east), or w(west), nw(northwest), // sw(southwest), ne(northeast) or se(southeast) // // Returns tip or direction tip.direction = function (v) { if (!arguments.length) { return direction; } direction = v == null ? v : d3.functor(v); return tip; }; // Public: Sets or gets the offset of the tip // // v - Array of [x, y] offset // // Returns offset or tip.offset = function (v) { if (!arguments.length) { return offset; } offset = v == null ? v : d3.functor(v); return tip; }; // Public: sets or gets the html value of the tooltip // // v - String value of the tip // // Returns html value or tip tip.html = function (v) { if (!arguments.length) { return html; } html = v == null ? v : d3.functor(v); return tip; }; function d3_tip_direction() { return 'n'; } function d3_tip_offset() { return [0, 0]; } function d3_tip_html() { return ' '; } var direction_callbacks = d3.map({ n: direction_n, s: direction_s, e: direction_e, w: direction_w, nw: direction_nw, ne: direction_ne, sw: direction_sw, se: direction_se, south_custom: direction_south_custom }), directions = direction_callbacks.keys(); function direction_south_custom() { var bbox = getScreenBBox(); return { top: bbox.s.y, left: bbox.s.x }; } function direction_n() { var bbox = getScreenBBox(); return { top: bbox.n.y - node.offsetHeight, left: bbox.n.x - node.offsetWidth / 2 }; } function direction_s() { var bbox = getScreenBBox(); return { top: bbox.s.y, left: bbox.s.x - node.offsetWidth / 2 }; } function direction_e() { var bbox = getScreenBBox(); return { top: bbox.e.y - node.offsetHeight / 2, left: bbox.e.x }; } function direction_w() { var bbox = getScreenBBox(); return { top: bbox.w.y - node.offsetHeight / 2, left: bbox.w.x - node.offsetWidth }; } function direction_nw() { var bbox = getScreenBBox(); return { top: bbox.nw.y - node.offsetHeight, left: bbox.nw.x - node.offsetWidth }; } function direction_ne() { var bbox = getScreenBBox(); return { top: bbox.ne.y - node.offsetHeight, left: bbox.ne.x }; } function direction_sw() { var bbox = getScreenBBox(); return { top: bbox.sw.y, left: bbox.sw.x - node.offsetWidth }; } function direction_se() { var bbox = getScreenBBox(); return { top: bbox.se.y, left: bbox.e.x }; } function initNode() { var node = d3.select(document.createElement('div')); node.style({ position: 'absolute', opacity: 0, pointerEvents: 'none', boxSizing: 'border-box' }); return node.node(); } function getSVGNode(el) { el = el.node(); if (el.tagName.toLowerCase() == 'svg') { return el; } return el.ownerSVGElement; } // Private - gets the screen coordinates of a shape // // Given a shape on the screen, will return an SVGPoint for the directions // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest), // sw(southwest). // // +-+-+ // | | // + + // | | // +-+-+ // // Returns an Object {n, s, e, w, nw, sw, ne, se} function getScreenBBox() { var targetel = target || d3.event.target; var bbox = {}; var matrix = targetel.getScreenCTM(); var tbbox = targetel.getBBox(); var width = tbbox.width; var height = tbbox.height; var x = tbbox.x; var y = tbbox.y; var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; // Nick - prevents bugs with scrolling and zooming on the same object matrix.a = 1; matrix.d = 1; // changing order of adding scrolling, // original ordering was causing problems with pre-translated or rotated // elements. matrix.e = matrix.e + scrollLeft; matrix.f = matrix.f + scrollTop; point.x = x; //+ scrollLeft point.y = y; //+ scrollTop bbox.nw = point.matrixTransform(matrix); point.x = point.x + width; bbox.ne = point.matrixTransform(matrix); point.y = point.y + height; bbox.se = point.matrixTransform(matrix); point.x = point.x - width; bbox.sw = point.matrixTransform(matrix); point.y = point.y - height / 2; bbox.w = point.matrixTransform(matrix); point.x = point.x + width; bbox.e = point.matrixTransform(matrix); point.x = point.x - width / 2; point.y = point.y - height / 2; bbox.n = point.matrixTransform(matrix); point.y = point.y + height; bbox.s = point.matrixTransform(matrix); return bbox; } // only fade tips if you are still hovering on the current tip function fade_tips(inst_selection) { var is_hovering = d3.select(inst_selection).classed('hovering'); if (is_hovering) { d3.selectAll('.d3-tip').transition().duration(250).style('opacity', 0).style('display', 'none'); } } function isFunction(functionToCheck) { var getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; } return tip; }; /***/ }, /* 49 */ /***/ function(module, exports, __webpack_require__) { var make_row_labels = __webpack_require__(50); module.exports = function make_row_label_container(cgm, text_delay) { var params = cgm.params; var row_container; // row container holds all row text and row visualizations (triangles rects) //////////////////////////////////////////////////////////////////////////// if (d3.select(params.viz.viz_svg + ' .row_container').empty()) { row_container = d3.select(params.viz.viz_svg).append('g').classed('row_container', true).attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')'); } else { row_container = d3.select(params.viz.viz_svg).select('.row_container').attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')'); } if (d3.select(params.root + ' .row_white_background').empty()) { row_container.append('rect').classed('row_white_background', true).classed('white_bars', true).attr('fill', params.viz.background_color).attr('width', params.viz.label_background.row).attr('height', 30 * params.viz.clust.dim.height + 'px'); } // add container to hold text row labels if not already there if (d3.select(params.root + ' .row_label_container').empty()) { row_container.append('g').classed('row_label_container', true).attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').append('g').classed('row_label_zoom_container', true); } else { row_container.select(params.root + ' .row_label_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)'); } // make row labels in the container /////////////////////////////////////// if (params.viz.ds_level === -1) { make_row_labels(cgm, 'all', text_delay); } }; /***/ }, /* 50 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var add_row_click_hlight = __webpack_require__(51); var row_reorder = __webpack_require__(52); var make_row_tooltips = __webpack_require__(102); module.exports = function make_row_labels(cgm, row_names = 'all', text_delay = 0) { // console.log('make_row_labels') // console.log(row_names) var params = cgm.params; var row_nodes = []; if (row_names === 'all') { row_nodes = params.network_data.row_nodes; } else { _.each(params.network_data.row_nodes, function (inst_row) { if (_.contains(row_names, inst_row.name)) { row_nodes.push(inst_row); } }); } // make row labels in row_label_zoom_container, bind row_nodes data var row_labels = d3.select(params.root + ' .row_label_zoom_container').selectAll('g').data(row_nodes, function (d) { return d.name; }).enter().append('g').classed('row_label_group', true); var row_nodes_names = params.network_data.row_nodes_names; row_labels.attr('transform', function (d) { // var inst_index = d.row_index; var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }); row_labels.on('dblclick', function (d) { var data_attr = '__data__'; var row_name = this[data_attr].name; // if (params.sim_mat){ // row_reorder(cgm, this, row_name); // d3.selectAll(params.root+' .col_label_text') // .filter(function(d){ // return d.name == row_name;} // )[0][0]; // // this is causing buggyness may reenable // // col_reorder -> two_translate_zoom -> show_visible_area -> make_row_labels -> col_reorder // // col_reorder(cgm, col_selection, row_name); // } else { // row_reorder(cgm, this, row_name); // } row_reorder(cgm, this, row_name); if (params.tile_click_hlight) { add_row_click_hlight(this, d.ini); } }); make_row_tooltips(params); // append rectangle behind text row_labels.insert('rect').style('opacity', 0); // append row label text row_labels.append('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35).attr('text-anchor', 'end').style('font-size', params.labels.default_fs_row + 'px').text(function (d) { return utils.normal_name(d); }).attr('pointer-events', 'none').style('opacity', 0).style('cursor', 'default').transition().delay(text_delay).duration(text_delay).style('opacity', 1); // change the size of the highlighting rects row_labels.each(function () { var bbox = d3.select(this).select('text')[0][0].getBBox(); d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.y_scale.rangeBand()).style('fill', function () { var inst_hl = 'yellow'; return inst_hl; }).style('opacity', function (d) { var inst_opacity = 0; // highlight target genes if (d.target === 1) { inst_opacity = 1; } return inst_opacity; }); }); // almost-deprecated row value bars /////////////////////////////// if (utils.has(params.network_data.row_nodes[0], 'value')) { row_labels.append('rect').classed('row_bars', true).attr('width', function (d) { var inst_value = 0; inst_value = params.labels.bar_scale_row(Math.abs(d.value)); return inst_value; }).attr('x', function (d) { var inst_value = 0; inst_value = -params.labels.bar_scale_row(Math.abs(d.value)); return inst_value; }).attr('height', params.viz.y_scale.rangeBand()).attr('fill', function (d) { return d.value > 0 ? params.matrix.bar_colors[0] : params.matrix.bar_colors[1]; }).attr('opacity', 0.4); } }; /***/ }, /* 51 */ /***/ function(module, exports) { module.exports = function (params, clicked_row, id_clicked_row) { if (id_clicked_row != params.click_hlight_row) { var rel_width_hlight = 6; var opacity_hlight = 0.85; var hlight_height = rel_width_hlight * params.viz.border_width.x; d3.selectAll(params.root + ' .click_hlight').remove(); // // highlight selected row // d3.selectAll(params.root+' .row_label_group') // .select('rect') // d3.select(this) // .select('rect') // .style('opacity', 1); d3.select(clicked_row).append('rect').classed('click_hlight', true).classed('row_top_hlight', true).attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight); d3.select(clicked_row).append('rect').classed('click_hlight', true).classed('row_bottom_hlight', true).attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () { var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height; return 'translate(0,' + tmp_translate_y + ')'; }); } else { d3.selectAll(params.root + ' .click_hlight').remove(); params.click_hlight_row = -666; } }; /***/ }, /* 52 */ /***/ function(module, exports, __webpack_require__) { var reposition_tile_highlight = __webpack_require__(53); var toggle_dendro_view = __webpack_require__(54); var ini_zoom_info = __webpack_require__(36); var get_previous_zoom = __webpack_require__(101); var calc_downsampled_levels = __webpack_require__(27); module.exports = function row_reorder(cgm, row_selection, inst_row) { var params = cgm.params; var prev_zoom = get_previous_zoom(params); if (prev_zoom.zoom_y === 1 && prev_zoom.zoom_x === 1) { params.viz.inst_order.row = 'custom'; toggle_dendro_view(cgm, 'col'); d3.selectAll(params.root + ' .toggle_col_order .btn').classed('active', false); params.viz.run_trans = true; var mat = $.extend(true, {}, params.matrix.matrix); var row_nodes = params.network_data.row_nodes; var col_nodes = params.network_data.col_nodes; // find the index of the row var tmp_arr = []; row_nodes.forEach(function (node) { tmp_arr.push(node.name); }); // find index inst_row = _.indexOf(tmp_arr, inst_row); // gather the values of the input genes tmp_arr = []; col_nodes.forEach(function (node, index) { tmp_arr.push(mat[inst_row].row_data[index].value); }); // sort the rows var tmp_sort = d3.range(tmp_arr.length).sort(function (a, b) { return tmp_arr[b] - tmp_arr[a]; }); // resort cols (cols are reorderd by double clicking a row) params.viz.x_scale.domain(tmp_sort); // save to custom col order params.matrix.orders.custom_row = tmp_sort; // reorder matrix //////////////////// var t; if (params.network_data.links.length > params.matrix.def_large_matrix) { t = d3.select(params.root + ' .viz_svg'); } else { t = d3.select(params.root + ' .viz_svg').transition().duration(2500); } var col_nodes_names = params.network_data.col_nodes_names; // Move Col Labels t.select('.col_zoom_container').selectAll('.col_label_text').attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ')rotate(-90)'; }); // reorder col_class groups t.selectAll('.col_cat_group').attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ',0)'; }); // reorder tiles in matrix (do not change row order) if (params.viz.ds_level === -1) { t.selectAll('.tile').attr('transform', function (d) { return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)'; }); t.selectAll('.tile_up').attr('transform', function (d) { return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)'; }); t.selectAll('.tile_dn').attr('transform', function (d) { return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)'; }); } // highlight selected row /////////////////////////////// // unhilight and unbold all columns (already unbolded earlier) d3.selectAll(params.root + ' .row_label_group').select('rect').style('opacity', 0); // highlight column name d3.select(row_selection).select('rect').style('opacity', 1); reposition_tile_highlight(params); // redefine x and y positions params.network_data.links.forEach(function (d) { d.x = params.viz.x_scale(d.target); d.y = params.viz.y_scale(d.source); }); params.zoom_info = ini_zoom_info(); setTimeout(function () { params.viz.run_trans = false; }, 2500); // calculate downsmapling if necessary if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) { calc_downsampled_levels(params); // var zooming_stopped = true; // var zooming_out = true; // var make_all_rows = true; // // show_visible_area is also run with two_translate_zoom, but at that point // // the parameters were not updated and two_translate_zoom if only run // // if needed to reset zoom // show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows); } } }; /***/ }, /* 53 */ /***/ function(module, exports) { module.exports = function (params) { // resize click hlight var rel_width_hlight = 6; // var opacity_hlight = 0.85; var hlight_width = rel_width_hlight * params.viz.border_width.x; var hlight_height = rel_width_hlight * params.viz.border_width.y; // reposition tile highlight //////////////////////////////// // top highlight d3.select(params.root + ' .top_hlight').attr('width', params.viz.x_scale.rangeBand()).attr('height', hlight_height).transition().duration(2500).attr('transform', function () { return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',0)'; }); // left highlight d3.select(params.root + ' .left_hlight').attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).transition().duration(2500).attr('transform', function () { return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',' + hlight_height * 0.99 + ')'; }); // right highlight d3.select(params.root + ' .right_hlight').attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).transition().duration(2500).attr('transform', function () { var tmp_translate = params.viz.x_scale(params.matrix.click_hlight_x) + params.viz.x_scale.rangeBand() - hlight_width; return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')'; }); // bottom highlight d3.select(params.root + ' .bottom_hlight').attr('width', function () { return params.viz.x_scale.rangeBand() - 1.98 * hlight_width; }).attr('height', hlight_height).transition().duration(2500).attr('transform', function () { var tmp_translate_x = params.viz.x_scale(params.matrix.click_hlight_x) + hlight_width * 0.99; var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height; return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')'; }); }; /***/ }, /* 54 */ /***/ function(module, exports, __webpack_require__) { var make_dendro_triangles = __webpack_require__(55); module.exports = function toggle_dendro_view(cgm, inst_rc, wait_time = 1500) { var params = cgm.params; // row and col are reversed if (inst_rc === 'row') { if (params.viz.inst_order.col === 'clust') { // the last true tells the viz that I'm chaning group size and not to // delay the change in dendro setTimeout(make_dendro_triangles, wait_time, cgm, 'row', true); } } if (inst_rc === 'col') { if (params.viz.inst_order.row === 'clust') { setTimeout(make_dendro_triangles, wait_time, cgm, 'col', true); } } if (params.viz.inst_order.row != 'clust' && params.viz.dendro_filter.col === false) { d3.selectAll(params.root + ' .col_dendro_group').style('opacity', 0).on('mouseover', null).on('mouseout', null); d3.select(params.root + ' .col_slider_group').style('opacity', 0); // toggle crop buttons d3.selectAll(params.root + ' .col_dendro_crop_buttons').style('opacity', 0).on('mouseover', null).on('mouseout', null); } if (params.viz.inst_order.col != 'clust' && params.viz.dendro_filter.row === false) { d3.selectAll(params.root + ' .row_dendro_group').style('opacity', 0).on('mouseover', null).on('mouseout', null).on('click', null); d3.select(params.root + ' .row_slider_group').style('opacity', 0); // toggle crop buttons d3.selectAll(params.root + ' .row_dendro_crop_buttons').style('opacity', 0).on('mouseover', null).on('mouseout', null); } }; /***/ }, /* 55 */ /***/ function(module, exports, __webpack_require__) { var calc_row_dendro_triangles = __webpack_require__(56); var calc_col_dendro_triangles = __webpack_require__(57); var dendro_group_highlight = __webpack_require__(58); var d3_tip_custom = __webpack_require__(48); var make_dendro_crop_buttons = __webpack_require__(60); var make_cat_breakdown_graph = __webpack_require__(63); module.exports = function make_dendro_triangles(cgm, inst_rc, is_change_group = false) { var params = cgm.params; // in case sim_mat if (inst_rc === 'both') { inst_rc = 'row'; } var other_rc; if (inst_rc === 'row') { other_rc = 'col'; } else { other_rc = 'row'; } // orders are switched! if (params.viz.inst_order[other_rc] === 'clust') { d3.select(params.root + ' .' + inst_rc + '_slider_group').style('opacity', 1); } var dendro_info; if (inst_rc === 'row') { dendro_info = calc_row_dendro_triangles(params); } else { dendro_info = calc_col_dendro_triangles(params); } if (d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_crop_buttons').empty() === false) { make_dendro_crop_buttons(cgm, inst_rc); } // constant dendrogram opacity var inst_dendro_opacity = params.viz.dendro_opacity; function still_hovering(inst_selection, inst_data, i) { if (d3.select(inst_selection).classed('hovering')) { // define where graph should be built var inst_selector = params.viz.root_tips + '_' + inst_rc + '_dendro_tip'; // prevent mouseover from making multiple graphs if (d3.select(inst_selector + ' .cat_graph').empty()) { if (params.viz.cat_info[inst_rc] !== null) { make_cat_breakdown_graph(params, inst_rc, inst_data, dendro_info[i], inst_selector, true); } } d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('opacity', 1); } } var wait_before_tooltip = 500; // remove any old dendro tooltips from this visualization d3.selectAll(cgm.params.viz.root_tips + '_' + inst_rc + '_dendro_tip').remove(); // run transition rules var run_transition; if (d3.selectAll(params.root + ' .' + inst_rc + '_dendro_group').empty()) { run_transition = false; } else { run_transition = true; d3.selectAll(params.root + ' .' + inst_rc + '_dendro_group').remove(); // d3.selectAll(params.root+' .dendro_tip').remove(); } // d3-tooltip var tmp_y_offset = 0; var tmp_x_offset = -5; var dendro_tip = d3_tip_custom().attr('class', function () { // add root element to class var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_' + inst_rc + '_dendro_tip'; return class_string; }).direction('nw').offset([tmp_y_offset, tmp_x_offset]).style('display', 'none').style('opacity', 0); dendro_tip.html(function () { var full_string = '<div class="cluster_info_container"></div>Click for cluster information <br>' + 'and additional options.'; return full_string; }); if (is_change_group) { run_transition = false; } var dendro_traps = d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').data(dendro_info, function (d) { return d.name; }).enter().append('path').style('opacity', 0).attr('class', inst_rc + '_dendro_group').style('fill', 'black'); // draw triangles (shown as trapezoids) ////////////////////////////////////////// var start_x; var start_y; var mid_x; var mid_y; var final_x; var final_y; // row triangles dendro_traps.attr('d', function (d) { if (inst_rc === 'row') { // row triangles start_x = 0; start_y = d.pos_top; mid_x = 30; mid_y = d.pos_mid; final_x = 0; final_y = d.pos_bot; } else { // column triangles start_x = d.pos_top; start_y = 0; mid_x = d.pos_mid; mid_y = 30; final_x = d.pos_bot; final_y = 0; } var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z'; return output_string; }); dendro_traps.on('mouseover', function (d, i) { // if (params.sim_mat){ // inst_rc = 'both'; // } // run instantly on mouseover d3.select(this).classed('hovering', true); if (cgm.params.dendro_callback != null) { cgm.params.dendro_callback(this); } // display tip // this is needed for it to show in the right place and the opacity // will be toggled to delay the tooltip for the user d3.select(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('display', 'block'); dendro_group_highlight(params, this, d, inst_rc); // show the tip (make sure it is displaying before it is shown) dendro_tip.show(d); // set opacity to zero d3.select(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('opacity', 0); // check if still hovering setTimeout(still_hovering, wait_before_tooltip, this, d, i); }).on('mouseout', function () { if (params.viz.inst_order[other_rc] === 'clust') { d3.select(this).style('opacity', inst_dendro_opacity); } d3.selectAll(params.root + ' .dendro_shadow').remove(); d3.select(this).classed('hovering', false); dendro_tip.hide(this); }).on('click', function (d, i) { $(params.root + ' .dendro_info').modal('toggle'); var group_string = d.all_names.join(', '); d3.select(params.root + ' .dendro_info input').attr('value', group_string); var inst_selector = params.root + ' .dendro_info'; // remove old graphs (modals are not within params.root) d3.selectAll('.dendro_info .cluster_info_container .cat_graph').remove(); if (params.viz.cat_info[inst_rc] !== null) { make_cat_breakdown_graph(params, inst_rc, d, dendro_info[i], inst_selector); } if (cgm.params.dendro_click_callback != null) { cgm.params.dendro_click_callback(this); } }).call(dendro_tip); var triangle_opacity; if (params.viz.inst_order[other_rc] === 'clust') { triangle_opacity = inst_dendro_opacity; } else { triangle_opacity = 0; } if (run_transition) { d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').transition().delay(1000).duration(1000).style('opacity', triangle_opacity); } else { d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').style('opacity', triangle_opacity); } }; /***/ }, /* 56 */ /***/ function(module, exports) { module.exports = function calc_row_dendro_triangles(params) { var triangle_info = {}; var inst_level = params.group_level.row; var row_nodes = params.network_data.row_nodes; var row_nodes_names = params.network_data.row_nodes_names; _.each(row_nodes, function (d) { // console.log('row_node '+d.name) var tmp_group = d.group[inst_level]; var inst_index = _.indexOf(row_nodes_names, d.name); var inst_top = params.viz.y_scale(inst_index); var inst_bot = inst_top + params.viz.y_scale.rangeBand(); if (_.has(triangle_info, tmp_group) === false) { triangle_info[tmp_group] = {}; triangle_info[tmp_group].name_top = d.name; triangle_info[tmp_group].name_bot = d.name; triangle_info[tmp_group].pos_top = inst_top; triangle_info[tmp_group].pos_bot = inst_bot; triangle_info[tmp_group].pos_mid = (inst_top + inst_bot) / 2; triangle_info[tmp_group].name = tmp_group; triangle_info[tmp_group].all_names = []; triangle_info[tmp_group].inst_rc = 'row'; } triangle_info[tmp_group].all_names.push(d.name); if (inst_top < triangle_info[tmp_group].pos_top) { triangle_info[tmp_group].name_top = d.name; triangle_info[tmp_group].pos_top = inst_top; triangle_info[tmp_group].pos_mid = (inst_top + triangle_info[tmp_group].pos_bot) / 2; } if (inst_bot > triangle_info[tmp_group].pos_bot) { triangle_info[tmp_group].name_bot = d.name; triangle_info[tmp_group].pos_bot = inst_bot; triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot) / 2; } }); var group_info = []; _.each(triangle_info, function (d) { group_info.push(d); }); return group_info; }; /***/ }, /* 57 */ /***/ function(module, exports) { module.exports = function calc_col_dendro_triangles(params) { var triangle_info = {}; var inst_level = params.group_level.col; var col_nodes = params.network_data.col_nodes; var col_nodes_names = params.network_data.col_nodes_names; _.each(col_nodes, function (d) { var tmp_group = d.group[inst_level]; var inst_index = _.indexOf(col_nodes_names, d.name); var inst_top = params.viz.x_scale(inst_index); var inst_bot = inst_top + params.viz.x_scale.rangeBand(); if (_.has(triangle_info, tmp_group) === false) { triangle_info[tmp_group] = {}; triangle_info[tmp_group].name_top = d.name; triangle_info[tmp_group].name_bot = d.name; triangle_info[tmp_group].pos_top = inst_top; triangle_info[tmp_group].pos_bot = inst_bot; triangle_info[tmp_group].pos_mid = (inst_top + inst_bot) / 2; triangle_info[tmp_group].name = tmp_group; triangle_info[tmp_group].all_names = []; triangle_info[tmp_group].inst_rc = 'col'; } triangle_info[tmp_group].all_names.push(d.name); if (inst_top < triangle_info[tmp_group].pos_top) { triangle_info[tmp_group].name_top = d.name; triangle_info[tmp_group].pos_top = inst_top; triangle_info[tmp_group].pos_mid = (inst_top + triangle_info[tmp_group].pos_bot) / 2; } if (inst_bot > triangle_info[tmp_group].pos_bot) { triangle_info[tmp_group].name_bot = d.name; triangle_info[tmp_group].pos_bot = inst_bot; triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot) / 2; } }); var group_info = []; _.each(triangle_info, function (d) { group_info.push(d); }); return group_info; }; /***/ }, /* 58 */ /***/ function(module, exports, __webpack_require__) { var dendro_shade_bars = __webpack_require__(59); module.exports = function dendro_group_highlight(params, inst_selection, inst_data, inst_rc) { // only make shadows if there is more than one crop button if (d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons')[0].length > 1) { setTimeout(still_hovering, 500); } else { d3.selectAll(params.root + ' .dendro_shadow').remove(); } function still_hovering() { // check that user is still hovering over dendrogram group if (d3.select(inst_selection).classed('hovering')) { // check that user is not using dendrogram slider if (params.is_slider_drag === false) { d3.select(inst_selection).style('opacity', 0.7); if (d3.select(params.viz.viz_svg).classed('running_update') === false) { make_shadow_bars(); } } } } function make_shadow_bars() { if (inst_rc === 'row') { // row and col labling are reversed if (params.viz.inst_order.col === 'clust') { dendro_shade_bars(params, inst_selection, inst_rc, inst_data); } } else if (inst_rc === 'col') { // row and col labeling are reversed if (params.viz.inst_order.row === 'clust') { dendro_shade_bars(params, inst_selection, inst_rc, inst_data); } } else if (inst_rc === 'both') { if (params.viz.inst_order.col === 'clust') { dendro_shade_bars(params, inst_selection, 'row', inst_data); } if (params.viz.inst_order.row === 'clust') { dendro_shade_bars(params, inst_selection, 'col', inst_data); } } } }; /***/ }, /* 59 */ /***/ function(module, exports) { module.exports = function dendro_shade_bars(params, inst_selection, inst_rc, inst_data) { var inst_opacity = 0.2; var bot_height; d3.selectAll(params.root + ' .dendro_shadow').remove(); if (inst_rc == 'row') { // top shade d3.select(params.root + ' .clust_group').append('rect').attr('width', params.viz.clust.dim.width + 'px').attr('height', inst_data.pos_top + 'px').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity); bot_height = params.viz.clust.dim.height - inst_data.pos_bot; // bottom shade d3.select(params.root + ' .clust_group').append('rect').attr('width', params.viz.clust.dim.width + 'px').attr('height', bot_height + 'px').attr('transform', 'translate(0,' + inst_data.pos_bot + ')').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity); } else if (inst_rc === 'col') { // top shade d3.select(params.root + ' .clust_group').append('rect').attr('width', inst_data.pos_top + 'px').attr('height', params.viz.clust.dim.height + 'px').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity); // bottom shade bot_height = params.viz.clust.dim.width - inst_data.pos_bot; d3.select(params.root + ' .clust_group').append('rect').attr('width', bot_height + 'px').attr('height', params.viz.clust.dim.height + 'px').attr('transform', 'translate(' + inst_data.pos_bot + ',0)').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity); } }; /***/ }, /* 60 */ /***/ function(module, exports, __webpack_require__) { var calc_row_dendro_triangles = __webpack_require__(56); var calc_col_dendro_triangles = __webpack_require__(57); var d3_tip_custom = __webpack_require__(48); var dendro_group_highlight = __webpack_require__(58); var run_dendro_filter = __webpack_require__(61); var zoom_crop_triangles = __webpack_require__(62); module.exports = function make_dendro_crop_buttons(cgm, inst_rc) { var params = cgm.params; var button_opacity = params.viz.dendro_opacity * 0.60; // information needed to make dendro var dendro_info; var other_rc; if (inst_rc === 'row') { dendro_info = calc_row_dendro_triangles(params); other_rc = 'col'; } else { dendro_info = calc_col_dendro_triangles(params); other_rc = 'row'; } // d3-tooltip var tmp_y_offset = 5; var tmp_x_offset = -5; var dendro_crop_tip = d3_tip_custom().attr('class', function () { var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_' + inst_rc + '_dendro_crop_tip'; return class_string; }).direction('nw').style('display', 'none').offset([tmp_y_offset, tmp_x_offset]); var wait_before_tooltip = 500; d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').remove(); d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').remove(); var icons; // position triangles var start_x; var start_y; var mid_x; var mid_y; var final_x; var final_y; // need to improve to account for zooming var min_tri_height = 45; var scale_down_tri = 0.25; var tri_height; var tri_width; var tri_dim; // make crop buttons or undo buttons var button_class = inst_rc + '_dendro_crop_buttons'; if (d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').classed('ran_filter') === false) { // Crop Triangle ////////////////////////////// icons = d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').data(dendro_info, function (d) { return d.name; }).enter().append('path').classed(button_class, true).attr('d', function (d) { // redefine tri_height = 10; tri_width = 10; var tmp_height = d.pos_bot - d.pos_top; // Row Dendrogram Crop Triangle if (inst_rc === 'row') { if (tmp_height < min_tri_height) { tri_height = tmp_height * scale_down_tri; } // pointing left start_x = tri_width; start_y = -tri_height; mid_x = 0; mid_y = 0; final_x = tri_width; final_y = tri_height; tri_dim = tri_height; // Column Dendrogram Crop Triangle } else { if (tmp_height < min_tri_height) { tri_width = tmp_height * scale_down_tri; } // pointing upward start_x = -tri_width; start_y = tri_height; mid_x = 0; mid_y = 0; final_x = tri_width; final_y = tri_height; tri_dim = tri_width; } // save triangle height // d3.select(this)[0][0].__data__.tri_dim = tri_dim; var data_key = '__data__'; d3.select(this)[0][0][data_key].tri_dim = tri_dim; var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z'; return output_string; }); dendro_crop_tip.html(function () { var full_string = 'Click to crop cluster'; return full_string; }); } else { // Undo Triangle ////////////////////////////// icons = d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').data(dendro_info, function (d) { return d.name; }).enter().append('path').classed(button_class, true).attr('d', function (d) { // redefine tri_height = 10; tri_width = 12; var tmp_height = d.pos_bot - d.pos_top; if (inst_rc === 'row') { if (tmp_height < min_tri_height) { tri_height = tmp_height * scale_down_tri; } // pointing right start_x = 0; start_y = -tri_height; mid_x = tri_width; mid_y = 0; final_x = 0; final_y = tri_height; } else { if (tmp_height < min_tri_height) { tri_width = tmp_height * scale_down_tri; } // pointing downward start_x = -tri_width; start_y = 0; mid_x = 0; mid_y = tri_height; final_x = tri_width; final_y = 0; } // save triangle height var data_key = '__data__'; d3.select(this)[0][0][data_key].tri_dim = 10; var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z'; return output_string; }); dendro_crop_tip.html(function () { var full_string = 'Click to undo crop'; return full_string; }); } icons.style('cursor', 'pointer').style('opacity', function () { var inst_opacity; // if (d3.select(this).classed('hide_crop')){ // inst_opacity = 0; // } else { // inst_opacity = button_opacity; // } inst_opacity = button_opacity; return inst_opacity; }).attr('transform', function (d) { var inst_translate; var inst_x; var inst_y; if (inst_rc === 'row') { inst_x = params.viz.uni_margin; inst_y = d.pos_mid; } else { inst_x = d.pos_mid; inst_y = params.viz.uni_margin; } inst_translate = 'translate(' + inst_x + ',' + inst_y + ')'; return inst_translate; }).on('mouseover', function (d) { d3.select(this).classed('hovering', true); dendro_crop_tip.show(d); dendro_group_highlight(params, this, d, inst_rc); // display with zero opacity d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').style('opacity', 0).style('display', 'block'); // check if still hovering setTimeout(still_hovering, wait_before_tooltip, this); }).on('mouseout', function () { d3.select(this).classed('hovering', false); d3.selectAll(params.root + ' .dendro_shadow').remove(); d3.select(this).style('opacity', button_opacity); dendro_crop_tip.hide(this); }).on('click', function (d) { // give user visual cue d3.select(this).style('opacity', 0.9).transition().duration(1000).style('opacity', 0); // remove dendro shadows when clicked d3.selectAll(params.root + ' .dendro_shadow').remove(); /* filter using dendrogram */ if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter.row === false && cgm.params.cat_filter.col === false) { // Run Filtering /////////////////// // use class as 'global' variable d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)').classed('ran_filter', true); d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)'); // do not display dendrogram slider if filtering has been run d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('display', 'none'); // do not display other crop buttons since they are inactive d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_container').style('display', 'none'); // do not display brush-crop button if performing dendro crop d3.select(cgm.params.root + ' .crop_button').style('opacity', 0.2); } else { // Undo Filtering /////////////////// // use class as 'global' variable d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)').classed('ran_filter', false); d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)'); if (params.viz.inst_order[other_rc] === 'clust') { // display slider when cropping has not been done d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('display', 'block'); } // display other crop buttons when cropping has not been done d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_container').style('display', 'block'); // display brush-crop button if not performing dendro crop d3.select(cgm.params.root + ' .crop_button').style('opacity', 1); } run_dendro_filter(cgm, d, inst_rc); }).call(dendro_crop_tip); // ordering has been reversed if (params.viz.inst_order[other_rc] != 'clust') { // do not display if not in cluster order d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').style('display', 'none'); } function still_hovering(inst_selection) { if (d3.select(inst_selection).classed('hovering')) { // increase opacity d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').style('opacity', 1).style('display', 'block'); } } zoom_crop_triangles(params, params.zoom_info, inst_rc); }; /***/ }, /* 61 */ /***/ function(module, exports) { module.exports = function run_dendro_filter(cgm, d, inst_rc) { var names = {}; if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter.row === false && cgm.params.cat_filter.col === false) { d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('opacity', 0.35).style('pointer-events', 'none'); names[inst_rc] = d.all_names; var tmp_names = cgm.params.network_data[inst_rc + '_nodes_names']; // keep a backup of the inst_view var inst_row_nodes = cgm.params.network_data.row_nodes; var inst_col_nodes = cgm.params.network_data.col_nodes; cgm.filter_viz_using_names(names); // overwrite with backup of original nodes cgm.params.inst_nodes.row_nodes = inst_row_nodes; cgm.params.inst_nodes.col_nodes = inst_col_nodes; d3.selectAll(cgm.params.root + ' .dendro_shadow').transition().duration(1000).style('opacity', 0).remove(); // keep the names of all the nodes cgm.params.dendro_filter[inst_rc] = tmp_names; /* reset filter */ } else { names[inst_rc] = cgm.params.dendro_filter[inst_rc]; cgm.filter_viz_using_names(names); cgm.params.dendro_filter[inst_rc] = false; } }; /***/ }, /* 62 */ /***/ function(module, exports) { module.exports = function zoom_crop_triangles(params, zoom_info, inst_rc) { if (inst_rc === 'row') { // transform icons (undo zoom on triangles) d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) { var inst_x = params.viz.uni_margin; var inst_y = d.pos_mid; var curr_zoom = zoom_info.zoom_y; var tri_dim = d3.select(this).data()[0].tri_dim; var inst_zoom = constrain_zoom(curr_zoom, tri_dim); return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, ' + 1 / inst_zoom + ')'; }); } else { // transform icons (undo zoom on triangles) d3.select(params.root + ' .col_dendro_icons_group').selectAll('path').attr('transform', function (d) { var inst_x = d.pos_mid; var inst_y = params.viz.uni_margin; var curr_zoom = zoom_info.zoom_x; var tri_dim = d3.select(this).data()[0].tri_dim; var inst_zoom = constrain_zoom(curr_zoom, tri_dim); return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(' + 1 / inst_zoom + ', 1)'; }); } function constrain_zoom(curr_zoom, tri_height) { var inst_zoom; var default_tri_height = 10; if (tri_height * curr_zoom < default_tri_height) { inst_zoom = 1; } else { var max_zoom = default_tri_height / tri_height; inst_zoom = curr_zoom / max_zoom; } return inst_zoom; } }; /***/ }, /* 63 */ /***/ function(module, exports, __webpack_require__) { var calc_cat_cluster_breakdown = __webpack_require__(64); module.exports = function make_cat_breakdown_graph(params, inst_rc, inst_data, dendro_info, selector, tooltip = false) { /* This function is used to make the category breakdown graphs for tooltips on dendrogram mousover and on dendrogram click modal popup. */ // in case sim_mat if (inst_rc === 'both') { inst_rc = 'row'; } var cat_breakdown = calc_cat_cluster_breakdown(params, inst_data, inst_rc); if (cat_breakdown.length > 0) { // put cluster information in dendro_tip /////////////////////////////////////////// var cluster_info_container = d3.select(selector + ' .cluster_info_container'); // loop through cat_breakdown data var super_string = ': '; var paragraph_string = '<p>'; var width = 370; var bar_offset = 23; var bar_height = 20; var max_string_length = 25; var bar_width = 180; var title_height = 27; var shift_tooltip_left = 177; // these are the indexes where the number-of-nodes and the number of downsampled // nodes are stored var num_nodes_index = 4; var num_nodes_ds_index = 5; var offset_ds_count = 150; var binom_pval_index = 6; var is_downsampled = false; if (cat_breakdown[0].bar_data[0][num_nodes_ds_index] != null) { width = width + 100; shift_tooltip_left = shift_tooltip_left + offset_ds_count - 47; is_downsampled = true; } // the index that will be used to generate the bars (will be different if // downsampled) var cluster_total = dendro_info.all_names.length; var bars_index = num_nodes_index; if (is_downsampled) { bars_index = num_nodes_ds_index; // calculate the total number of nodes in downsampled case var inst_bar_data = cat_breakdown[0].bar_data; cluster_total = 0; _.each(inst_bar_data, function (tmp_data) { cluster_total = cluster_total + tmp_data[num_nodes_ds_index]; }); } // limit on the number of category types shown var max_cats = 3; // limit the number of bars shown var max_bars = 25; // calculate height needed for svg based on cat_breakdown data var svg_height = 20; _.each(cat_breakdown.slice(0, max_cats), function (tmp_break) { var num_bars = tmp_break.bar_data.length; if (num_bars > max_bars) { num_bars = max_bars; } svg_height = svg_height + title_height * (num_bars + 1); }); // Cluster Information Title (for tooltip only not modal) if (tooltip) { cluster_info_container.append('text').text('Cluster Information'); } var main_dendro_svg = cluster_info_container.append('div').style('margin-top', '5px').classed('cat_graph', true).append('svg').style('height', svg_height + 'px').style('width', width + 'px'); // make background main_dendro_svg.append('rect').classed('cat_background', true).attr('height', svg_height + 'px').attr('width', width + 'px').attr('fill', 'white').attr('opacity', 1); // the total amout to shift down the next category var shift_down = title_height; // limit the category-types cat_breakdown = cat_breakdown.slice(0, max_cats); _.each(cat_breakdown, function (cat_data) { var max_bar_value = cat_data.bar_data[0][bars_index]; // offset the count column based on how large the counts are var digit_offset_scale = d3.scale.linear().domain([0, 100000]).range([20, 30]); // only keep the top max_bars categories cat_data.bar_data = cat_data.bar_data.slice(0, max_bars); cluster_info_container.style('margin-bottom', '5px'); var cat_graph_group = main_dendro_svg.append('g').classed('cat_graph_group', true).attr('transform', 'translate(10, ' + shift_down + ')'); // shift down based on number of bars shift_down = shift_down + title_height * (cat_data.bar_data.length + 1); var inst_title = cat_data.type_name; // ensure that title is not too long if (inst_title.length >= max_string_length) { inst_title = inst_title.slice(0, max_string_length) + '..'; } // make title cat_graph_group.append('text').classed('cat_graph_title', true).text(inst_title).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 800); // shift the position of the numbers based on the size of the number var count_offset = digit_offset_scale(max_bar_value); // Count Title cat_graph_group.append('text').text('Count').attr('transform', function () { var inst_x = bar_width + count_offset; var inst_translate = 'translate(' + inst_x + ', 0)'; return inst_translate; }); // Percentage Title cat_graph_group.append('text').text('Pct').attr('transform', function () { var inst_x = bar_width + count_offset + 60; var inst_translate = 'translate(' + inst_x + ', 0)'; return inst_translate; }); // Percentage Title cat_graph_group.append('text').text('P-val').attr('transform', function () { var inst_x = bar_width + count_offset + 115; var inst_translate = 'translate(' + inst_x + ', 0)'; return inst_translate; }); // Count Downsampled Title if (is_downsampled) { cat_graph_group.append('text').text('Clusters').attr('transform', function () { var inst_x = bar_width + offset_ds_count; var inst_translate = 'translate(' + inst_x + ', 0)'; return inst_translate; }); } var line_y = 4; cat_graph_group.append('line').attr('x1', 0).attr('x2', bar_width).attr('y1', line_y).attr('y2', line_y).attr('stroke', 'blue').attr('stroke-width', 1).attr('opacity', 1.0); var cat_bar_container = cat_graph_group.append('g').classed('cat_bar_container', true).attr('transform', 'translate(0, 10)'); // make bar groups (hold bar and text) var cat_bar_groups = cat_bar_container.selectAll('g').data(cat_data.bar_data).enter().append('g').attr('transform', function (d, i) { var inst_y = i * bar_offset; return 'translate(0,' + inst_y + ')'; }); // bar length is max when all nodes in cluster are of // a single cat var bar_scale = d3.scale.linear().domain([0, max_bar_value]).range([0, bar_width]); // make bars cat_bar_groups.append('rect').attr('height', bar_height + 'px').attr('width', function (d) { var inst_width = bar_scale(d[bars_index]); return inst_width + 'px'; }).attr('fill', function (d) { // cat color is stored in the third element return d[3]; }).attr('opacity', params.viz.cat_colors.opacity).attr('stroke', 'grey').attr('stroke-width', '0.5px'); // make bar labels cat_bar_groups.append('text').classed('bar_labels', true).text(function (d) { var inst_text = d[1]; if (inst_text.indexOf(super_string) > 0) { inst_text = inst_text.split(super_string)[1]; } if (inst_text.indexOf(paragraph_string) > 0) { // required for Enrichr category names (needs improvements) inst_text = inst_text.split(paragraph_string)[0]; } // ensure that bar name is not too long if (inst_text.length >= max_string_length) { inst_text = inst_text.slice(0, max_string_length) + '..'; } return inst_text; }).attr('transform', function () { return 'translate(5, ' + 0.75 * bar_height + ')'; }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'right'); // Count/Pct Rows ///////////////////////////// var shift_count_num = 35; cat_bar_groups.append('text').classed('count_labels', true).text(function (d) { var inst_count = d[bars_index]; inst_count = inst_count.toLocaleString(); return String(inst_count); }).attr('transform', function () { var inst_x = bar_width + count_offset + shift_count_num; var inst_y = 0.75 * bar_height; return 'translate(' + inst_x + ', ' + inst_y + ')'; }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end'); cat_bar_groups.append('text').classed('count_labels', true).text(function (d) { // calculate the percentage relative to the current cluster var inst_count = d[bars_index] / cluster_total * 100; inst_count = Math.round(inst_count * 10) / 10; inst_count = inst_count.toLocaleString(); return String(inst_count); }).attr('transform', function () { var inst_x = bar_width + count_offset + shift_count_num + 47; var inst_y = 0.75 * bar_height; return 'translate(' + inst_x + ', ' + inst_y + ')'; }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end'); // Binomial Test Pvals cat_bar_groups.append('text').classed('count_labels', true).text(function (d) { // calculate the percentage relative to the current cluster var inst_count = d[binom_pval_index]; if (inst_count < 0.1) { inst_count = parseFloat(inst_count.toPrecision(3)); inst_count = inst_count.toExponential(); } else { inst_count = parseFloat(inst_count.toPrecision(2)); } // inst_count = inst_count.toLocaleString(); return inst_count; }).attr('transform', function () { var inst_x = bar_width + count_offset + shift_count_num + 112; var inst_y = 0.75 * bar_height; return 'translate(' + inst_x + ', ' + inst_y + ')'; }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end'); if (is_downsampled) { cat_bar_groups.append('text').classed('count_labels', true).text(function (d) { return String(d[num_nodes_index].toLocaleString()); }).attr('transform', function () { // downsampled cluster numbers are smaller and need less flexible offsetting var inst_x = bar_width + shift_count_num + offset_ds_count + 20; var inst_y = 0.75 * bar_height; return 'translate(' + inst_x + ', ' + inst_y + ')'; }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end'); } }); // reposition tooltip ///////////////////////////////////////////////// if (tooltip) { var dendro_tip = d3.select(selector); var old_top = dendro_tip.style('top').split('.px')[0]; var old_left = dendro_tip.style('left').split('.px')[0]; var shift_top = 0; var shift_left = 0; // shifting if (inst_rc === 'row') { // rows ////////////// shift_top = 0; shift_left = shift_tooltip_left; // // prevent graph from being too high // if (dendro_info.pos_top < svg_height){ // // do not shift position of category breakdown graph // // shift_top = -(svg_height + (dendro_info.pos_mid - dendro_info.pos_top)/2) ; // } } else { // columns ////////////// shift_top = svg_height + 32; shift_left = 30; } dendro_tip.style('top', function () { var new_top = String(parseInt(old_top, 10) - shift_top) + 'px'; return new_top; }).style('left', function () { var new_left = String(parseInt(old_left, 10) - shift_left) + 'px'; return new_left; }); } } }; /***/ }, /* 64 */ /***/ function(module, exports, __webpack_require__) { var binom_test = __webpack_require__(65); module.exports = function calc_cat_cluster_breakdown(params, inst_data, inst_rc) { // Category-breakdown of dendrogram-clusters ///////////////////////////////////////////// /* 1. get information for nodes in cluster 2. find category-types that are string-type 3. count instances of each category name for each category-type */ // in case sim_mat if (inst_rc === 'both') { inst_rc = 'row'; } // 1: get information for nodes in cluster /////////////////////////////////////////// // names of nodes in cluster var clust_names = inst_data.all_names; // array of nodes in the cluster var clust_nodes = []; var all_nodes = params.network_data[inst_rc + '_nodes']; var num_in_clust_index = null; var is_downsampled = false; var inst_name; _.each(all_nodes, function (inst_node) { inst_name = inst_node.name; if (clust_names.indexOf(inst_name) >= 0) { clust_nodes.push(inst_node); } }); // 2: find category-types that are string-type /////////////////////////////////////////////// var cat_breakdown = []; if (params.viz.cat_info[inst_rc] !== null) { var inst_cat_info = params.viz.cat_info[inst_rc]; // tmp list of all categories var tmp_types_index = _.keys(inst_cat_info); // this will hold the indexes of string-type categories var cat_types_index = []; // get category names (only include string-type categories) var cat_types_names = []; var type_name; var inst_index; var cat_index; for (var i = 0; i < tmp_types_index.length; i++) { cat_index = 'cat-' + String(i); if (params.viz.cat_info[inst_rc][cat_index].type === 'cat_strings') { type_name = params.viz.cat_names[inst_rc][cat_index]; cat_types_names.push(type_name); cat_types_index.push(cat_index); } else { // save number in clust category index if found if (params.viz.cat_names[inst_rc][cat_index] === 'number in clust') { num_in_clust_index = cat_index; is_downsampled = true; } } } var tmp_run_count = {}; var inst_breakdown = {}; var bar_data; var radix_param = 10; // sort by actual counts (rather than cluster counts) var sorting_index = 4; if (is_downsampled) { sorting_index = 5; } var no_title_given; if (type_name === cat_index) { no_title_given = true; } else { no_title_given = false; } if (cat_types_names.length > 0) { // 3: count instances of each category name for each category-type var cat_name; var num_in_clust = clust_names.length; // use the cat_hist to get the number of instances of this category in // all rows/cols // params _.each(cat_types_index, function (cat_index) { inst_index = cat_index.split('-')[1]; type_name = cat_types_names[inst_index]; if (no_title_given) { if (cat_index.indexOf('-') >= 0) { var tmp_num = parseInt(cat_index.split('-')[1], radix_param) + 1; type_name = 'Category ' + String(tmp_num); } else { // backup behavior type_name = 'Category'; } } tmp_run_count[type_name] = {}; // loop through the nodes and keep a running count of categories _.each(clust_nodes, function (tmp_node) { cat_name = tmp_node[cat_index]; if (cat_name.indexOf(': ') >= 0) { cat_name = cat_name.split(': ')[1]; } if (cat_name in tmp_run_count[type_name]) { tmp_run_count[type_name][cat_name].num_nodes = tmp_run_count[type_name][cat_name].num_nodes + 1; if (num_in_clust_index != null) { tmp_run_count[type_name][cat_name].num_nodes_ds = tmp_run_count[type_name][cat_name].num_nodes_ds + parseInt(tmp_node[num_in_clust_index].split(': ')[1], radix_param); } } else { tmp_run_count[type_name][cat_name] = {}; tmp_run_count[type_name][cat_name].num_nodes = 1; if (num_in_clust_index != null) { tmp_run_count[type_name][cat_name].num_nodes_ds = parseInt(tmp_node[num_in_clust_index].split(': ')[1], radix_param); } } }); inst_breakdown = {}; inst_breakdown.type_name = type_name; inst_breakdown.num_in_clust = num_in_clust; // sort cat info in cat_breakdown bar_data = []; var bar_color; var cat_title_and_name; var inst_run_count = tmp_run_count[type_name]; for (var inst_cat in inst_run_count) { var tot_num_cat = params.viz.cat_info[inst_rc][cat_index].cat_hist[inst_cat]; var total_nodes = params.network_data[inst_rc + '_nodes'].length; var expect_prob = tot_num_cat / total_nodes; // if no cat-title given if (no_title_given) { cat_title_and_name = inst_cat; } else { cat_title_and_name = type_name + ': ' + inst_cat; } // num_nodes: number of cat-nodes drawn in cluster var num_nodes = inst_run_count[inst_cat].num_nodes; var actual_k = num_nodes; var pval = binom_test(actual_k, num_in_clust, expect_prob); // working on tracking the 'real' number of nodes, which is only different // if downsampling has been done if (_.has(inst_run_count[inst_cat], 'num_nodes_ds')) { var num_nodes_ds = inst_run_count[inst_cat].num_nodes_ds; } else { num_nodes_ds = null; } bar_color = params.viz.cat_colors[inst_rc][cat_index][cat_title_and_name]; bar_data.push([cat_index, cat_title_and_name, inst_run_count[inst_cat], bar_color, num_nodes, num_nodes_ds, pval]); } bar_data.sort(function (a, b) { return b[sorting_index] - a[sorting_index]; }); inst_breakdown.bar_data = bar_data; cat_breakdown.push(inst_breakdown); }); } } return cat_breakdown; }; /***/ }, /* 65 */ /***/ function(module, exports, __webpack_require__) { // Load the math.js core // Create a new, empty math.js instance // It will only contain methods `import` and `config` // math.import(require('mathjs/lib/type/fraction')); var p_dict = __webpack_require__(66); var core = __webpack_require__(67); var math = core.create(); math.import(__webpack_require__(79)); module.exports = function binom_test(actual_k, n, p) { var fact = math.factorial; var pval; function binom_dist(k, n, p) { var bin_coeff = fact(n) / (fact(k) * fact(n - k)); p = bin_coeff * (Math.pow(p, k) * Math.pow(1 - p, n - k)); return p; } function my_binom_test_2(actual_k, n, p) { var cp = 0; var k; var dp; for (var inst_k = actual_k; inst_k < n + 1; inst_k++) { k = inst_k; dp = binom_dist(k, n, p); cp = cp + dp; } return cp; } // look up p-value from z-score using table function binom_prop_table(actual_k, n, p) { // expected average number of successes var mu = n * p; // standard deviation var sigma = Math.sqrt(n * p * (1 - p)); // how many standard deviations is the actual_k away // from the expected value var z = (actual_k - mu) / sigma; var z_vals = p_dict.z; var p_vals = p_dict.p; var found_index = -1; var found = false; for (var index = 0; index < z_vals.length; index++) { var inst_z = z_vals[index]; // increasing inst_z until z is less than inst_z if (z < inst_z && found === false) { found_index = index; found = true; } } // give it the smallest p-val if the z-score was larger than // any in the table if (found_index === -1) { found_index = z_vals.length - 1; } pval = p_vals[found_index]; return pval; } // calculate pval pval = my_binom_test_2(actual_k, n, p); if (isNaN(pval)) { pval = binom_prop_table(actual_k, n, p); } return pval; }; /***/ }, /* 66 */ /***/ function(module, exports) { module.exports = { "p": [0.5, 0.48006119416162751, 0.46017216272297101, 0.4403823076297575, 0.42074029056089696, 0.4012936743170763, 0.38208857781104733, 0.3631693488243809, 0.34457825838967582, 0.32635522028791997, 0.30853753872598688, 0.29115968678834636, 0.27425311775007355, 0.25784611080586473, 0.24196365222307303, 0.22662735237686821, 0.21185539858339669, 0.19766254312269238, 0.18406012534675947, 0.17105612630848183, 0.15865525393145707, 0.14685905637589591, 0.13566606094638267, 0.12507193563715024, 0.11506967022170828, 0.10564977366685535, 0.096800484585610358, 0.088507991437401956, 0.080756659233771066, 0.073529259609648304, 0.066807201268858071, 0.060570758002059008, 0.054799291699557974, 0.049471468033648075, 0.044565462758543006, 0.040059156863817086, 0.035930319112925789, 0.032156774795613713, 0.028716559816001783, 0.025588059521638611, 0.022750131948179195, 0.020182215405704383, 0.017864420562816542, 0.015777607391090499, 0.013903447513498595, 0.012224472655044696, 0.010724110021675795, 0.0093867055348385662, 0.0081975359245961138, 0.0071428107352714152, 0.0062096653257761323, 0.0053861459540666843, 0.0046611880237187467, 0.0040245885427583027, 0.0034669738030406647, 0.0029797632350545551, 0.002555130330427929, 0.0021859614549132405, 0.0018658133003840339, 0.0015888696473648667, 0.0013498980316300933, 0.0011442068310226977, 0.00096760321321835631, 0.00081635231282856037, 0.00068713793791584708, 0.00057702504239076592, 0.00048342414238377663, 0.0004040578018640207, 0.00033692926567687988, 0.00028029327681617744, 0.00023262907903552502, 0.00019261557563563279, 0.00015910859015753364, 0.00013112015442048433, 0.00010779973347738823, 8.8417285200803773e-05, 7.2348043925119787e-05, 5.9058912418922374e-05, 4.8096344017602614e-05, 3.9075596597787456e-05, 3.1671241833119863e-05, 2.5608816474041489e-05, 2.0657506912546683e-05, 1.6623763729652213e-05, 1.334574901590631e-05, 1.0688525774934402e-05, 8.5399054709917942e-06, 6.8068765993340312e-06, 5.4125439077038407e-06, 4.293514469971858e-06, 3.3976731247300535e-06, 2.6822957796388472e-06, 2.1124547025028419e-06, 1.6596751443714555e-06, 1.3008074539172771e-06, 1.0170832425687032e-06, 7.9332815197558919e-07, 6.1730737200919249e-07, 4.7918327659031855e-07, 3.7106740796333271e-07, 2.8665157187919333e-07, 2.2090503226954194e-07, 1.6982674071475937e-07, 1.3024322953320117e-07, 9.9644263169334701e-08, 7.6049605164887e-08, 5.7901340399645569e-08, 4.3977115940058689e-08, 3.3320448485428448e-08, 2.518491005446105e-08, 1.8989562465887681e-08, 1.4283479893922661e-08, 1.0717590258310852e-08, 8.0223918506634739e-09, 5.9903714010635304e-09, 4.4621724539016108e-09, 3.3157459783261365e-09, 2.4578650618080152e-09, 1.8175078630994235e-09, 1.3407124440918662e-09, 9.8658764503769458e-10, 7.2422917051376055e-10, 5.303423262948808e-10, 3.8741473466756636e-10, 2.8231580370432682e-10, 2.0522634252189396e-10, 1.4882282217622966e-10, 1.0765746385121517e-10, 7.7688475817097756e-11, 5.592507575942645e-11, 4.0160005838590881e-11, 2.8768541736043109e-11, 2.055788909399508e-11, 1.4654650977302715e-11, 1.0420976987965154e-11, 7.3922577780177942e-12, 5.2309575441445253e-12, 3.6924994272355614e-12, 2.600126965638173e-12, 1.8264310619769611e-12, 1.279812543885835e-12, 8.9458895587698439e-13, 6.23784446333152e-13, 4.3388950271780343e-13, 3.0106279811174218e-13, 2.0838581586720548e-13, 1.4388386381575764e-13, 9.9103427495475088e-14, 6.8092248906200155e-14, 4.6670115887190274e-14, 3.1908916729108844e-14, 2.1762912097085575e-14, 1.4806537490047908e-14, 1.0048965656526223e-14, 6.8033115407739012e-15, 4.5946274357785623e-15, 3.095358771958668e-15, 2.0801863521393674e-15, 1.394517146659261e-15, 9.3255757716812045e-16, 6.2209605742717405e-16, 4.1397018162731219e-16, 2.7479593923982212e-16, 1.8196213635266084e-16, 1.2019351542735647e-16, 7.9197263146424757e-17, 5.2055697448902465e-17, 3.4131483264581459e-17, 2.232393197288031e-17, 1.456514112590909e-17, 9.4795348222032499e-18, 6.1544255908503949e-18, 3.985804962848151e-18, 2.5749715380118873e-18, 1.6594208699647519e-18, 1.0667637375474856e-18, 6.840807685935497e-19, 4.3759647993090167e-19, 2.7923343749396233e-19, 1.7774117841455144e-19, 1.1285884059538324e-19, 7.1484170112696837e-20, 4.516591491435403e-20, 2.8466774084602088e-20, 1.7897488120140146e-20, 1.1224633591327901e-20, 7.0222842404415411e-21, 4.3823862990664603e-21, 2.7281535713460872e-21, 1.6941535024881097e-21, 1.0494515075362604e-21, 6.4848144530772079e-22, 3.9972212057261192e-22, 2.4577864834723153e-22, 1.5074931688101589e-22, 9.2234135249393526e-23, 5.6292823113765143e-23, 3.4271987941135974e-23, 2.0813752194932085e-23, 1.2609160670206559e-23], "z": [0.0, 0.050000000000000003, 0.10000000000000001, 0.15000000000000002, 0.20000000000000001, 0.25, 0.30000000000000004, 0.35000000000000003, 0.40000000000000002, 0.45000000000000001, 0.5, 0.55000000000000004, 0.60000000000000009, 0.65000000000000002, 0.70000000000000007, 0.75, 0.80000000000000004, 0.85000000000000009, 0.90000000000000002, 0.95000000000000007, 1.0, 1.05, 1.1000000000000001, 1.1500000000000001, 1.2000000000000002, 1.25, 1.3, 1.3500000000000001, 1.4000000000000001, 1.4500000000000002, 1.5, 1.55, 1.6000000000000001, 1.6500000000000001, 1.7000000000000002, 1.75, 1.8, 1.8500000000000001, 1.9000000000000001, 1.9500000000000002, 2.0, 2.0500000000000003, 2.1000000000000001, 2.1499999999999999, 2.2000000000000002, 2.25, 2.3000000000000003, 2.3500000000000001, 2.4000000000000004, 2.4500000000000002, 2.5, 2.5500000000000003, 2.6000000000000001, 2.6500000000000004, 2.7000000000000002, 2.75, 2.8000000000000003, 2.8500000000000001, 2.9000000000000004, 2.9500000000000002, 3.0, 3.0500000000000003, 3.1000000000000001, 3.1500000000000004, 3.2000000000000002, 3.25, 3.3000000000000003, 3.3500000000000001, 3.4000000000000004, 3.4500000000000002, 3.5, 3.5500000000000003, 3.6000000000000001, 3.6500000000000004, 3.7000000000000002, 3.75, 3.8000000000000003, 3.8500000000000001, 3.9000000000000004, 3.9500000000000002, 4.0, 4.0499999999999998, 4.1000000000000005, 4.1500000000000004, 4.2000000000000002, 4.25, 4.2999999999999998, 4.3500000000000005, 4.4000000000000004, 4.4500000000000002, 4.5, 4.5499999999999998, 4.6000000000000005, 4.6500000000000004, 4.7000000000000002, 4.75, 4.8000000000000007, 4.8500000000000005, 4.9000000000000004, 4.9500000000000002, 5.0, 5.0500000000000007, 5.1000000000000005, 5.1500000000000004, 5.2000000000000002, 5.25, 5.3000000000000007, 5.3500000000000005, 5.4000000000000004, 5.4500000000000002, 5.5, 5.5500000000000007, 5.6000000000000005, 5.6500000000000004, 5.7000000000000002, 5.75, 5.8000000000000007, 5.8500000000000005, 5.9000000000000004, 5.9500000000000002, 6.0, 6.0500000000000007, 6.1000000000000005, 6.1500000000000004, 6.2000000000000002, 6.25, 6.3000000000000007, 6.3500000000000005, 6.4000000000000004, 6.4500000000000002, 6.5, 6.5500000000000007, 6.6000000000000005, 6.6500000000000004, 6.7000000000000002, 6.75, 6.8000000000000007, 6.8500000000000005, 6.9000000000000004, 6.9500000000000002, 7.0, 7.0500000000000007, 7.1000000000000005, 7.1500000000000004, 7.2000000000000002, 7.25, 7.3000000000000007, 7.3500000000000005, 7.4000000000000004, 7.4500000000000002, 7.5, 7.5500000000000007, 7.6000000000000005, 7.6500000000000004, 7.7000000000000002, 7.75, 7.8000000000000007, 7.8500000000000005, 7.9000000000000004, 7.9500000000000002, 8.0, 8.0500000000000007, 8.0999999999999996, 8.1500000000000004, 8.2000000000000011, 8.25, 8.3000000000000007, 8.3499999999999996, 8.4000000000000004, 8.4500000000000011, 8.5, 8.5500000000000007, 8.5999999999999996, 8.6500000000000004, 8.7000000000000011, 8.75, 8.8000000000000007, 8.8499999999999996, 8.9000000000000004, 8.9500000000000011, 9.0, 9.0500000000000007, 9.0999999999999996, 9.1500000000000004, 9.2000000000000011, 9.25, 9.3000000000000007, 9.3499999999999996, 9.4000000000000004, 9.4500000000000011, 9.5, 9.5500000000000007, 9.6000000000000014, 9.6500000000000004, 9.7000000000000011, 9.75, 9.8000000000000007, 9.8500000000000014, 9.9000000000000004, 9.9500000000000011] }; /***/ }, /* 67 */ /***/ function(module, exports, __webpack_require__) { module.exports = __webpack_require__(68); /***/ }, /* 68 */ /***/ function(module, exports, __webpack_require__) { var isFactory = __webpack_require__(69).isFactory; var deepExtend = __webpack_require__(69).deepExtend; var typedFactory = __webpack_require__(70); var emitter = __webpack_require__(74); var importFactory = __webpack_require__(76); var configFactory = __webpack_require__(78); /** * Math.js core. Creates a new, empty math.js instance * @param {Object} [options] Available options: * {number} epsilon * Minimum relative difference between two * compared values, used by all comparison functions. * {string} matrix * A string 'Matrix' (default) or 'Array'. * {string} number * A string 'number' (default), 'BigNumber', or 'Fraction' * {number} precision * The number of significant digits for BigNumbers. * Not applicable for Numbers. * {boolean} predictable * Predictable output type of functions. When true, * output type depends only on the input types. When * false (default), output type can vary depending * on input values. For example `math.sqrt(-2)` * returns `NaN` when predictable is false, and * returns `complex('2i')` when true. * @returns {Object} Returns a bare-bone math.js instance containing * functions: * - `import` to add new functions * - `config` to change configuration * - `on`, `off`, `once`, `emit` for events */ exports.create = function create(options) { // simple test for ES5 support if (typeof Object.create !== 'function') { throw new Error('ES5 not supported by this JavaScript engine. ' + 'Please load the es5-shim and es5-sham library for compatibility.'); } // cached factories and instances var factories = []; var instances = []; // create a namespace for the mathjs instance, and attach emitter functions var math = emitter.mixin({}); math.type = {}; math.expression = { transform: Object.create(math) }; // create a new typed instance math.typed = typedFactory.create(math.type); // create configuration options. These are private var _config = { // minimum relative difference between two compared values, // used by all comparison functions epsilon: 1e-12, // type of default matrix output. Choose 'matrix' (default) or 'array' matrix: 'Matrix', // type of default number output. Choose 'number' (default) 'BigNumber', or 'Fraction number: 'number', // number of significant digits in BigNumbers precision: 64, // predictable output type of functions. When true, output type depends only // on the input types. When false (default), output type can vary depending // on input values. For example `math.sqrt(-2)` returns `NaN` when // predictable is false, and returns `complex('2i')` when true. predictable: false }; /** * Load a function or data type from a factory. * If the function or data type already exists, the existing instance is * returned. * @param {{type: string, name: string, factory: Function}} factory * @returns {*} */ function load(factory) { if (!isFactory(factory)) { throw new Error('Factory object with properties `type`, `name`, and `factory` expected'); } var index = factories.indexOf(factory); var instance; if (index === -1) { // doesn't yet exist if (factory.math === true) { // pass with math namespace instance = factory.factory(math.type, _config, load, math.typed, math); } else { instance = factory.factory(math.type, _config, load, math.typed); } // append to the cache factories.push(factory); instances.push(instance); } else { // already existing function, return the cached instance instance = instances[index]; } return instance; } // load the import and config functions math['import'] = load(importFactory); math['config'] = load(configFactory); // apply options if (options) { math.config(options); } return math; }; /***/ }, /* 69 */ /***/ function(module, exports) { 'use strict'; /** * Clone an object * * clone(x) * * Can clone any primitive type, array, and object. * If x has a function clone, this function will be invoked to clone the object. * * @param {*} x * @return {*} clone */ exports.clone = function clone(x) { var type = typeof x; // immutable primitive types if (type === 'number' || type === 'string' || type === 'boolean' || x === null || x === undefined) { return x; } // use clone function of the object when available if (typeof x.clone === 'function') { return x.clone(); } // array if (Array.isArray(x)) { return x.map(function (value) { return clone(value); }); } if (x instanceof Number) return new Number(x.valueOf()); if (x instanceof String) return new String(x.valueOf()); if (x instanceof Boolean) return new Boolean(x.valueOf()); if (x instanceof Date) return new Date(x.valueOf()); if (x && x.isBigNumber === true) return x; // bignumbers are immutable if (x instanceof RegExp) throw new TypeError('Cannot clone ' + x); // TODO: clone a RegExp // object var m = {}; for (var key in x) { if (x.hasOwnProperty(key)) { m[key] = clone(x[key]); } } return m; }; /** * Extend object a with the properties of object b * @param {Object} a * @param {Object} b * @return {Object} a */ exports.extend = function (a, b) { for (var prop in b) { if (b.hasOwnProperty(prop)) { a[prop] = b[prop]; } } return a; }; /** * Deep extend an object a with the properties of object b * @param {Object} a * @param {Object} b * @returns {Object} */ exports.deepExtend = function deepExtend(a, b) { // TODO: add support for Arrays to deepExtend if (Array.isArray(b)) { throw new TypeError('Arrays are not supported by deepExtend'); } for (var prop in b) { if (b.hasOwnProperty(prop)) { if (b[prop] && b[prop].constructor === Object) { if (a[prop] === undefined) { a[prop] = {}; } if (a[prop].constructor === Object) { deepExtend(a[prop], b[prop]); } else { a[prop] = b[prop]; } } else if (Array.isArray(b[prop])) { throw new TypeError('Arrays are not supported by deepExtend'); } else { a[prop] = b[prop]; } } } return a; }; /** * Deep test equality of all fields in two pairs of arrays or objects. * @param {Array | Object} a * @param {Array | Object} b * @returns {boolean} */ exports.deepEqual = function deepEqual(a, b) { var prop, i, len; if (Array.isArray(a)) { if (!Array.isArray(b)) { return false; } if (a.length != b.length) { return false; } for (i = 0, len = a.length; i < len; i++) { if (!exports.deepEqual(a[i], b[i])) { return false; } } return true; } else if (a instanceof Object) { if (Array.isArray(b) || !(b instanceof Object)) { return false; } for (prop in a) { //noinspection JSUnfilteredForInLoop if (!exports.deepEqual(a[prop], b[prop])) { return false; } } for (prop in b) { //noinspection JSUnfilteredForInLoop if (!exports.deepEqual(a[prop], b[prop])) { return false; } } return true; } else { return typeof a === typeof b && a == b; } }; /** * Test whether the current JavaScript engine supports Object.defineProperty * @returns {boolean} returns true if supported */ exports.canDefineProperty = function () { // test needed for broken IE8 implementation try { if (Object.defineProperty) { Object.defineProperty({}, 'x', { get: function () {} }); return true; } } catch (e) {} return false; }; /** * Attach a lazy loading property to a constant. * The given function `fn` is called once when the property is first requested. * On older browsers (<IE8), the function will fall back to direct evaluation * of the properties value. * @param {Object} object Object where to add the property * @param {string} prop Property name * @param {Function} fn Function returning the property value. Called * without arguments. */ exports.lazy = function (object, prop, fn) { if (exports.canDefineProperty()) { var _uninitialized = true; var _value; Object.defineProperty(object, prop, { get: function () { if (_uninitialized) { _value = fn(); _uninitialized = false; } return _value; }, set: function (value) { _value = value; _uninitialized = false; }, configurable: true, enumerable: true }); } else { // fall back to immediate evaluation object[prop] = fn(); } }; /** * Traverse a path into an object. * When a namespace is missing, it will be created * @param {Object} object * @param {string} path A dot separated string like 'name.space' * @return {Object} Returns the object at the end of the path */ exports.traverse = function (object, path) { var obj = object; if (path) { var names = path.split('.'); for (var i = 0; i < names.length; i++) { var name = names[i]; if (!(name in obj)) { obj[name] = {}; } obj = obj[name]; } } return obj; }; /** * Test whether an object is a factory. a factory has fields: * * - factory: function (type: Object, config: Object, load: function, typed: function [, math: Object]) (required) * - name: string (optional) * - path: string A dot separated path (optional) * - math: boolean If true (false by default), the math namespace is passed * as fifth argument of the factory function * * @param {*} object * @returns {boolean} */ exports.isFactory = function (object) { return object && typeof object.factory === 'function'; }; /***/ }, /* 70 */ /***/ function(module, exports, __webpack_require__) { var typedFunction = __webpack_require__(71); var digits = __webpack_require__(72).digits; // returns a new instance of typed-function var createTyped = function () { // initially, return the original instance of typed-function // consecutively, return a new instance from typed.create. createTyped = typedFunction.create; return typedFunction; }; /** * Factory function for creating a new typed instance * @param {Object} type Object with data types like Complex and BigNumber * @returns {Function} */ exports.create = function create(type) { // TODO: typed-function must be able to silently ignore signatures with unknown data types // get a new instance of typed-function var typed = createTyped(); // define all types. The order of the types determines in which order function // arguments are type-checked (so for performance it's important to put the // most used types first). typed.types = [{ name: 'number', test: function (x) { return typeof x === 'number'; } }, { name: 'Complex', test: function (x) { return x && x.isComplex; } }, { name: 'BigNumber', test: function (x) { return x && x.isBigNumber; } }, { name: 'Fraction', test: function (x) { return x && x.isFraction; } }, { name: 'Unit', test: function (x) { return x && x.isUnit; } }, { name: 'string', test: function (x) { return typeof x === 'string'; } }, { name: 'Array', test: Array.isArray }, { name: 'Matrix', test: function (x) { return x && x.isMatrix; } }, { name: 'DenseMatrix', test: function (x) { return x && x.isDenseMatrix; } }, { name: 'SparseMatrix', test: function (x) { return x && x.isSparseMatrix; } }, { name: 'ImmutableDenseMatrix', test: function (x) { return x && x.isImmutableDenseMatrix; } }, { name: 'Range', test: function (x) { return x && x.isRange; } }, { name: 'Index', test: function (x) { return x && x.isIndex; } }, { name: 'boolean', test: function (x) { return typeof x === 'boolean'; } }, { name: 'ResultSet', test: function (x) { return x && x.isResultSet; } }, { name: 'Help', test: function (x) { return x && x.isHelp; } }, { name: 'function', test: function (x) { return typeof x === 'function'; } }, { name: 'Date', test: function (x) { return x instanceof Date; } }, { name: 'RegExp', test: function (x) { return x instanceof RegExp; } }, { name: 'Object', test: function (x) { return typeof x === 'object'; } }, { name: 'null', test: function (x) { return x === null; } }, { name: 'undefined', test: function (x) { return x === undefined; } }]; // TODO: add conversion from BigNumber to number? typed.conversions = [{ from: 'number', to: 'BigNumber', convert: function (x) { // note: conversion from number to BigNumber can fail if x has >15 digits if (digits(x) > 15) { throw new TypeError('Cannot implicitly convert a number with >15 significant digits to BigNumber ' + '(value: ' + x + '). ' + 'Use function bignumber(x) to convert to BigNumber.'); } return new type.BigNumber(x); } }, { from: 'number', to: 'Complex', convert: function (x) { return new type.Complex(x, 0); } }, { from: 'number', to: 'string', convert: function (x) { return x + ''; } }, { from: 'BigNumber', to: 'Complex', convert: function (x) { return new type.Complex(x.toNumber(), 0); } }, { from: 'Fraction', to: 'Complex', convert: function (x) { return new type.Complex(x.valueOf(), 0); } }, { from: 'number', to: 'Fraction', convert: function (x) { if (digits(x) > 15) { throw new TypeError('Cannot implicitly convert a number with >15 significant digits to Fraction ' + '(value: ' + x + '). ' + 'Use function fraction(x) to convert to Fraction.'); } return new type.Fraction(x); } }, { // FIXME: add conversion from Fraction to number, for example for `sqrt(fraction(1,3))` // from: 'Fraction', // to: 'number', // convert: function (x) { // return x.valueOf(); // } //}, { from: 'string', to: 'number', convert: function (x) { var n = Number(x); if (isNaN(n)) { throw new Error('Cannot convert "' + x + '" to a number'); } return n; } }, { from: 'boolean', to: 'number', convert: function (x) { return +x; } }, { from: 'boolean', to: 'BigNumber', convert: function (x) { return new type.BigNumber(+x); } }, { from: 'boolean', to: 'Fraction', convert: function (x) { return new type.Fraction(+x); } }, { from: 'boolean', to: 'string', convert: function (x) { return +x; } }, { from: 'null', to: 'number', convert: function () { return 0; } }, { from: 'null', to: 'string', convert: function () { return 'null'; } }, { from: 'null', to: 'BigNumber', convert: function () { return new type.BigNumber(0); } }, { from: 'null', to: 'Fraction', convert: function () { return new type.Fraction(0); } }, { from: 'Array', to: 'Matrix', convert: function (array) { // TODO: how to decide on the right type of matrix to create? return new type.DenseMatrix(array); } }, { from: 'Matrix', to: 'Array', convert: function (matrix) { return matrix.valueOf(); } }]; return typed; }; /***/ }, /* 71 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** * typed-function * * Type checking for JavaScript functions * * https://github.com/josdejong/typed-function */ 'use strict'; (function (root, factory) { if (true) { // AMD. Register as an anonymous module. !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if (typeof exports === 'object') { // OldNode. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like OldNode. module.exports = factory(); } else { // Browser globals (root is window) root.typed = factory(); } })(this, function () { // factory function to create a new instance of typed-function // TODO: allow passing configuration, types, tests via the factory function function create() { /** * Get a type test function for a specific data type * @param {string} name Name of a data type like 'number' or 'string' * @returns {Function(obj: *) : boolean} Returns a type testing function. * Throws an error for an unknown type. */ function getTypeTest(name) { var test; for (var i = 0; i < typed.types.length; i++) { var entry = typed.types[i]; if (entry.name === name) { test = entry.test; break; } } if (!test) { var hint; for (i = 0; i < typed.types.length; i++) { entry = typed.types[i]; if (entry.name.toLowerCase() == name.toLowerCase()) { hint = entry.name; break; } } throw new Error('Unknown type "' + name + '"' + (hint ? '. Did you mean "' + hint + '"?' : '')); } return test; } /** * Retrieve the function name from a set of functions, and check * whether the name of all functions match (if given) * @param {Array.<function>} fns */ function getName(fns) { var name = ''; for (var i = 0; i < fns.length; i++) { var fn = fns[i]; // merge function name when this is a typed function if (fn.signatures && fn.name != '') { if (name == '') { name = fn.name; } else if (name != fn.name) { var err = new Error('Function names do not match (expected: ' + name + ', actual: ' + fn.name + ')'); err.data = { actual: fn.name, expected: name }; throw err; } } } return name; } /** * Create an ArgumentsError. Creates messages like: * * Unexpected type of argument (expected: ..., actual: ..., index: ...) * Too few arguments (expected: ..., index: ...) * Too many arguments (expected: ..., actual: ...) * * @param {String} fn Function name * @param {number} argCount Number of arguments * @param {Number} index Current argument index * @param {*} actual Current argument * @param {string} [expected] An optional, comma separated string with * expected types on given index * @extends Error */ function createError(fn, argCount, index, actual, expected) { var actualType = getTypeOf(actual); var _expected = expected ? expected.split(',') : null; var _fn = fn || 'unnamed'; var anyType = _expected && contains(_expected, 'any'); var message; var data = { fn: fn, index: index, actual: actual, expected: _expected }; if (_expected) { if (argCount > index && !anyType) { // unexpected type message = 'Unexpected type of argument in function ' + _fn + ' (expected: ' + _expected.join(' or ') + ', actual: ' + actualType + ', index: ' + index + ')'; } else { // too few arguments message = 'Too few arguments in function ' + _fn + ' (expected: ' + _expected.join(' or ') + ', index: ' + index + ')'; } } else { // too many arguments message = 'Too many arguments in function ' + _fn + ' (expected: ' + index + ', actual: ' + argCount + ')'; } var err = new TypeError(message); err.data = data; return err; } /** * Collection with function references (local shortcuts to functions) * @constructor * @param {string} [name='refs'] Optional name for the refs, used to generate * JavaScript code */ function Refs(name) { this.name = name || 'refs'; this.categories = {}; } /** * Add a function reference. * @param {Function} fn * @param {string} [category='fn'] A function category, like 'fn' or 'signature' * @returns {string} Returns the function name, for example 'fn0' or 'signature2' */ Refs.prototype.add = function (fn, category) { var cat = category || 'fn'; if (!this.categories[cat]) this.categories[cat] = []; var index = this.categories[cat].indexOf(fn); if (index == -1) { index = this.categories[cat].length; this.categories[cat].push(fn); } return cat + index; }; /** * Create code lines for all function references * @returns {string} Returns the code containing all function references */ Refs.prototype.toCode = function () { var code = []; var path = this.name + '.categories'; var categories = this.categories; for (var cat in categories) { if (categories.hasOwnProperty(cat)) { var category = categories[cat]; for (var i = 0; i < category.length; i++) { code.push('var ' + cat + i + ' = ' + path + '[\'' + cat + '\'][' + i + '];'); } } } return code.join('\n'); }; /** * A function parameter * @param {string | string[] | Param} types A parameter type like 'string', * 'number | boolean' * @param {boolean} [varArgs=false] Variable arguments if true * @constructor */ function Param(types, varArgs) { // parse the types, can be a string with types separated by pipe characters | if (typeof types === 'string') { // parse variable arguments operator (ellipses '...number') var _types = types.trim(); var _varArgs = _types.substr(0, 3) === '...'; if (_varArgs) { _types = _types.substr(3); } if (_types === '') { this.types = ['any']; } else { this.types = _types.split('|'); for (var i = 0; i < this.types.length; i++) { this.types[i] = this.types[i].trim(); } } } else if (Array.isArray(types)) { this.types = types; } else if (types instanceof Param) { return types.clone(); } else { throw new Error('String or Array expected'); } // can hold a type to which to convert when handling this parameter this.conversions = []; // TODO: implement better API for conversions, be able to add conversions via constructor (support a new type Object?) // variable arguments this.varArgs = _varArgs || varArgs || false; // check for any type arguments this.anyType = this.types.indexOf('any') !== -1; } /** * Order Params * any type ('any') will be ordered last, and object as second last (as other * types may be an object as well, like Array). * * @param {Param} a * @param {Param} b * @returns {number} Returns 1 if a > b, -1 if a < b, and else 0. */ Param.compare = function (a, b) { // TODO: simplify parameter comparison, it's a mess if (a.anyType) return 1; if (b.anyType) return -1; if (contains(a.types, 'Object')) return 1; if (contains(b.types, 'Object')) return -1; if (a.hasConversions()) { if (b.hasConversions()) { var i, ac, bc; for (i = 0; i < a.conversions.length; i++) { if (a.conversions[i] !== undefined) { ac = a.conversions[i]; break; } } for (i = 0; i < b.conversions.length; i++) { if (b.conversions[i] !== undefined) { bc = b.conversions[i]; break; } } return typed.conversions.indexOf(ac) - typed.conversions.indexOf(bc); } else { return 1; } } else { if (b.hasConversions()) { return -1; } else { // both params have no conversions var ai, bi; for (i = 0; i < typed.types.length; i++) { if (typed.types[i].name === a.types[0]) { ai = i; break; } } for (i = 0; i < typed.types.length; i++) { if (typed.types[i].name === b.types[0]) { bi = i; break; } } return ai - bi; } } }; /** * Test whether this parameters types overlap an other parameters types. * @param {Param} other * @return {boolean} Returns true when there are conflicting types */ Param.prototype.overlapping = function (other) { for (var i = 0; i < this.types.length; i++) { if (contains(other.types, this.types[i])) { return true; } } return false; }; /** * Create a clone of this param * @returns {Param} Returns a cloned version of this param */ Param.prototype.clone = function () { var param = new Param(this.types.slice(), this.varArgs); param.conversions = this.conversions.slice(); return param; }; /** * Test whether this parameter contains conversions * @returns {boolean} Returns true if the parameter contains one or * multiple conversions. */ Param.prototype.hasConversions = function () { return this.conversions.length > 0; }; /** * Tests whether this parameters contains any of the provided types * @param {Object} types A Map with types, like {'number': true} * @returns {boolean} Returns true when the parameter contains any * of the provided types */ Param.prototype.contains = function (types) { for (var i = 0; i < this.types.length; i++) { if (types[this.types[i]]) { return true; } } return false; }; /** * Return a string representation of this params types, like 'string' or * 'number | boolean' or '...number' * @param {boolean} [toConversion] If true, the returned types string * contains the types where the parameter * will convert to. If false (default) * the "from" types are returned * @returns {string} */ Param.prototype.toString = function (toConversion) { var types = []; var keys = {}; for (var i = 0; i < this.types.length; i++) { var conversion = this.conversions[i]; var type = toConversion && conversion ? conversion.to : this.types[i]; if (!(type in keys)) { keys[type] = true; types.push(type); } } return (this.varArgs ? '...' : '') + types.join('|'); }; /** * A function signature * @param {string | string[] | Param[]} params * Array with the type(s) of each parameter, * or a comma separated string with types * @param {Function} fn The actual function * @constructor */ function Signature(params, fn) { var _params; if (typeof params === 'string') { _params = params !== '' ? params.split(',') : []; } else if (Array.isArray(params)) { _params = params; } else { throw new Error('string or Array expected'); } this.params = new Array(_params.length); for (var i = 0; i < _params.length; i++) { var param = new Param(_params[i]); this.params[i] = param; if (i === _params.length - 1) { // the last argument this.varArgs = param.varArgs; } else { // non-last argument if (param.varArgs) { throw new SyntaxError('Unexpected variable arguments operator "..."'); } } } this.fn = fn; } /** * Create a clone of this signature * @returns {Signature} Returns a cloned version of this signature */ Signature.prototype.clone = function () { return new Signature(this.params.slice(), this.fn); }; /** * Expand a signature: split params with union types in separate signatures * For example split a Signature "string | number" into two signatures. * @return {Signature[]} Returns an array with signatures (at least one) */ Signature.prototype.expand = function () { var signatures = []; function recurse(signature, path) { if (path.length < signature.params.length) { var i, newParam, conversion; var param = signature.params[path.length]; if (param.varArgs) { // a variable argument. do not split the types in the parameter newParam = param.clone(); // add conversions to the parameter // recurse for all conversions for (i = 0; i < typed.conversions.length; i++) { conversion = typed.conversions[i]; if (!contains(param.types, conversion.from) && contains(param.types, conversion.to)) { var j = newParam.types.length; newParam.types[j] = conversion.from; newParam.conversions[j] = conversion; } } recurse(signature, path.concat(newParam)); } else { // split each type in the parameter for (i = 0; i < param.types.length; i++) { recurse(signature, path.concat(new Param(param.types[i]))); } // recurse for all conversions for (i = 0; i < typed.conversions.length; i++) { conversion = typed.conversions[i]; if (!contains(param.types, conversion.from) && contains(param.types, conversion.to)) { newParam = new Param(conversion.from); newParam.conversions[0] = conversion; recurse(signature, path.concat(newParam)); } } } } else { signatures.push(new Signature(path, signature.fn)); } } recurse(this, []); return signatures; }; /** * Compare two signatures. * * When two params are equal and contain conversions, they will be sorted * by lowest index of the first conversions. * * @param {Signature} a * @param {Signature} b * @returns {number} Returns 1 if a > b, -1 if a < b, and else 0. */ Signature.compare = function (a, b) { if (a.params.length > b.params.length) return 1; if (a.params.length < b.params.length) return -1; // count the number of conversions var i; var len = a.params.length; // a and b have equal amount of params var ac = 0; var bc = 0; for (i = 0; i < len; i++) { if (a.params[i].hasConversions()) ac++; if (b.params[i].hasConversions()) bc++; } if (ac > bc) return 1; if (ac < bc) return -1; // compare the order per parameter for (i = 0; i < a.params.length; i++) { var cmp = Param.compare(a.params[i], b.params[i]); if (cmp !== 0) { return cmp; } } return 0; }; /** * Test whether any of the signatures parameters has conversions * @return {boolean} Returns true when any of the parameters contains * conversions. */ Signature.prototype.hasConversions = function () { for (var i = 0; i < this.params.length; i++) { if (this.params[i].hasConversions()) { return true; } } return false; }; /** * Test whether this signature should be ignored. * Checks whether any of the parameters contains a type listed in * typed.ignore * @return {boolean} Returns true when the signature should be ignored */ Signature.prototype.ignore = function () { // create a map with ignored types var types = {}; for (var i = 0; i < typed.ignore.length; i++) { types[typed.ignore[i]] = true; } // test whether any of the parameters contains this type for (i = 0; i < this.params.length; i++) { if (this.params[i].contains(types)) { return true; } } return false; }; /** * Generate the code to invoke this signature * @param {Refs} refs * @param {string} prefix * @returns {string} Returns code */ Signature.prototype.toCode = function (refs, prefix) { var code = []; var args = new Array(this.params.length); for (var i = 0; i < this.params.length; i++) { var param = this.params[i]; var conversion = param.conversions[0]; if (param.varArgs) { args[i] = 'varArgs'; } else if (conversion) { args[i] = refs.add(conversion.convert, 'convert') + '(arg' + i + ')'; } else { args[i] = 'arg' + i; } } var ref = this.fn ? refs.add(this.fn, 'signature') : undefined; if (ref) { return prefix + 'return ' + ref + '(' + args.join(', ') + '); // signature: ' + this.params.join(', '); } return code.join('\n'); }; /** * Return a string representation of the signature * @returns {string} */ Signature.prototype.toString = function () { return this.params.join(', '); }; /** * A group of signatures with the same parameter on given index * @param {Param[]} path * @param {Signature} [signature] * @param {Node[]} childs * @constructor */ function Node(path, signature, childs) { this.path = path || []; this.param = path[path.length - 1] || null; this.signature = signature || null; this.childs = childs || []; } /** * Generate code for this group of signatures * @param {Refs} refs * @param {string} prefix * @param {Node | undefined} [anyType] Sibling of this node with any type parameter * @returns {string} Returns the code as string */ Node.prototype.toCode = function (refs, prefix, anyType) { // TODO: split this function in multiple functions, it's too large var code = []; if (this.param) { var index = this.path.length - 1; var conversion = this.param.conversions[0]; var comment = '// type: ' + (conversion ? conversion.from + ' (convert to ' + conversion.to + ')' : this.param); // non-root node (path is non-empty) if (this.param.varArgs) { if (this.param.anyType) { // variable arguments with any type code.push(prefix + 'if (arguments.length > ' + index + ') {'); code.push(prefix + ' var varArgs = [];'); code.push(prefix + ' for (var i = ' + index + '; i < arguments.length; i++) {'); code.push(prefix + ' varArgs.push(arguments[i]);'); code.push(prefix + ' }'); code.push(this.signature.toCode(refs, prefix + ' ')); code.push(prefix + '}'); } else { // variable arguments with a fixed type var getTests = function (types, arg) { var tests = []; for (var i = 0; i < types.length; i++) { tests[i] = refs.add(getTypeTest(types[i]), 'test') + '(' + arg + ')'; } return tests.join(' || '); }.bind(this); var allTypes = this.param.types; var exactTypes = []; for (var i = 0; i < allTypes.length; i++) { if (this.param.conversions[i] === undefined) { exactTypes.push(allTypes[i]); } } code.push(prefix + 'if (' + getTests(allTypes, 'arg' + index) + ') { ' + comment); code.push(prefix + ' var varArgs = [arg' + index + '];'); code.push(prefix + ' for (var i = ' + (index + 1) + '; i < arguments.length; i++) {'); code.push(prefix + ' if (' + getTests(exactTypes, 'arguments[i]') + ') {'); code.push(prefix + ' varArgs.push(arguments[i]);'); for (var i = 0; i < allTypes.length; i++) { var conversion_i = this.param.conversions[i]; if (conversion_i) { var test = refs.add(getTypeTest(allTypes[i]), 'test'); var convert = refs.add(conversion_i.convert, 'convert'); code.push(prefix + ' }'); code.push(prefix + ' else if (' + test + '(arguments[i])) {'); code.push(prefix + ' varArgs.push(' + convert + '(arguments[i]));'); } } code.push(prefix + ' } else {'); code.push(prefix + ' throw createError(name, arguments.length, i, arguments[i], \'' + exactTypes.join(',') + '\');'); code.push(prefix + ' }'); code.push(prefix + ' }'); code.push(this.signature.toCode(refs, prefix + ' ')); code.push(prefix + '}'); } } else { if (this.param.anyType) { // any type code.push(prefix + '// type: any'); code.push(this._innerCode(refs, prefix, anyType)); } else { // regular type var type = this.param.types[0]; var test = type !== 'any' ? refs.add(getTypeTest(type), 'test') : null; code.push(prefix + 'if (' + test + '(arg' + index + ')) { ' + comment); code.push(this._innerCode(refs, prefix + ' ', anyType)); code.push(prefix + '}'); } } } else { // root node (path is empty) code.push(this._innerCode(refs, prefix, anyType)); } return code.join('\n'); }; /** * Generate inner code for this group of signatures. * This is a helper function of Node.prototype.toCode * @param {Refs} refs * @param {string} prefix * @param {Node | undefined} [anyType] Sibling of this node with any type parameter * @returns {string} Returns the inner code as string * @private */ Node.prototype._innerCode = function (refs, prefix, anyType) { var code = []; var i; if (this.signature) { code.push(prefix + 'if (arguments.length === ' + this.path.length + ') {'); code.push(this.signature.toCode(refs, prefix + ' ')); code.push(prefix + '}'); } var nextAnyType; for (i = 0; i < this.childs.length; i++) { if (this.childs[i].param.anyType) { nextAnyType = this.childs[i]; break; } } for (i = 0; i < this.childs.length; i++) { code.push(this.childs[i].toCode(refs, prefix, nextAnyType)); } if (anyType && !this.param.anyType) { code.push(anyType.toCode(refs, prefix, nextAnyType)); } var exceptions = this._exceptions(refs, prefix); if (exceptions) { code.push(exceptions); } return code.join('\n'); }; /** * Generate code to throw exceptions * @param {Refs} refs * @param {string} prefix * @returns {string} Returns the inner code as string * @private */ Node.prototype._exceptions = function (refs, prefix) { var index = this.path.length; if (this.childs.length === 0) { // TODO: can this condition be simplified? (we have a fall-through here) return [prefix + 'if (arguments.length > ' + index + ') {', prefix + ' throw createError(name, arguments.length, ' + index + ', arguments[' + index + ']);', prefix + '}'].join('\n'); } else { var keys = {}; var types = []; for (var i = 0; i < this.childs.length; i++) { var node = this.childs[i]; if (node.param) { for (var j = 0; j < node.param.types.length; j++) { var type = node.param.types[j]; if (!(type in keys) && !node.param.conversions[j]) { keys[type] = true; types.push(type); } } } } return prefix + 'throw createError(name, arguments.length, ' + index + ', arguments[' + index + '], \'' + types.join(',') + '\');'; } }; /** * Split all raw signatures into an array with expanded Signatures * @param {Object.<string, Function>} rawSignatures * @return {Signature[]} Returns an array with expanded signatures */ function parseSignatures(rawSignatures) { // FIXME: need to have deterministic ordering of signatures, do not create via object var signature; var keys = {}; var signatures = []; var i; for (var types in rawSignatures) { if (rawSignatures.hasOwnProperty(types)) { var fn = rawSignatures[types]; signature = new Signature(types, fn); if (signature.ignore()) { continue; } var expanded = signature.expand(); for (i = 0; i < expanded.length; i++) { var signature_i = expanded[i]; var key = signature_i.toString(); var existing = keys[key]; if (!existing) { keys[key] = signature_i; } else { var cmp = Signature.compare(signature_i, existing); if (cmp < 0) { // override if sorted first keys[key] = signature_i; } else if (cmp === 0) { throw new Error('Signature "' + key + '" is defined twice'); } // else: just ignore } } } } // convert from map to array for (key in keys) { if (keys.hasOwnProperty(key)) { signatures.push(keys[key]); } } // order the signatures signatures.sort(function (a, b) { return Signature.compare(a, b); }); // filter redundant conversions from signatures with varArgs // TODO: simplify this loop or move it to a separate function for (i = 0; i < signatures.length; i++) { signature = signatures[i]; if (signature.varArgs) { var index = signature.params.length - 1; var param = signature.params[index]; var t = 0; while (t < param.types.length) { if (param.conversions[t]) { var type = param.types[t]; for (var j = 0; j < signatures.length; j++) { var other = signatures[j]; var p = other.params[index]; if (other !== signature && p && contains(p.types, type) && !p.conversions[index]) { // this (conversion) type already exists, remove it param.types.splice(t, 1); param.conversions.splice(t, 1); t--; break; } } } t++; } } } return signatures; } /** * create a map with normalized signatures as key and the function as value * @param {Signature[]} signatures An array with split signatures * @return {Object.<string, Function>} Returns a map with normalized * signatures as key, and the function * as value. */ function mapSignatures(signatures) { var normalized = {}; for (var i = 0; i < signatures.length; i++) { var signature = signatures[i]; if (signature.fn && !signature.hasConversions()) { var params = signature.params.join(','); normalized[params] = signature.fn; } } return normalized; } /** * Parse signatures recursively in a node tree. * @param {Signature[]} signatures Array with expanded signatures * @param {Param[]} path Traversed path of parameter types * @return {Node} Returns a node tree */ function parseTree(signatures, path) { var i, signature; var index = path.length; var nodeSignature; var filtered = []; for (i = 0; i < signatures.length; i++) { signature = signatures[i]; // filter the first signature with the correct number of params if (signature.params.length === index && !nodeSignature) { nodeSignature = signature; } if (signature.params[index] != undefined) { filtered.push(signature); } } // sort the filtered signatures by param filtered.sort(function (a, b) { return Param.compare(a.params[index], b.params[index]); }); // recurse over the signatures var entries = []; for (i = 0; i < filtered.length; i++) { signature = filtered[i]; // group signatures with the same param at current index var param = signature.params[index]; // TODO: replace the next filter loop var existing = entries.filter(function (entry) { return entry.param.overlapping(param); })[0]; //var existing; //for (var j = 0; j < entries.length; j++) { // if (entries[j].param.overlapping(param)) { // existing = entries[j]; // break; // } //} if (existing) { if (existing.param.varArgs) { throw new Error('Conflicting types "' + existing.param + '" and "' + param + '"'); } existing.signatures.push(signature); } else { entries.push({ param: param, signatures: [signature] }); } } // parse the childs var childs = new Array(entries.length); for (i = 0; i < entries.length; i++) { var entry = entries[i]; childs[i] = parseTree(entry.signatures, path.concat(entry.param)); } return new Node(path, nodeSignature, childs); } /** * Generate an array like ['arg0', 'arg1', 'arg2'] * @param {number} count Number of arguments to generate * @returns {Array} Returns an array with argument names */ function getArgs(count) { // create an array with all argument names var args = []; for (var i = 0; i < count; i++) { args[i] = 'arg' + i; } return args; } /** * Compose a function from sub-functions each handling a single type signature. * Signatures: * typed(signature: string, fn: function) * typed(name: string, signature: string, fn: function) * typed(signatures: Object.<string, function>) * typed(name: string, signatures: Object.<string, function>) * * @param {string | null} name * @param {Object.<string, Function>} signatures * @return {Function} Returns the typed function * @private */ function _typed(name, signatures) { var refs = new Refs(); // parse signatures, expand them var _signatures = parseSignatures(signatures); if (_signatures.length == 0) { throw new Error('No signatures provided'); } // parse signatures into a node tree var node = parseTree(_signatures, []); //var util = require('util'); //console.log('ROOT'); //console.log(util.inspect(node, { depth: null })); // generate code for the typed function var code = []; var _name = name || ''; var _args = getArgs(maxParams(_signatures)); code.push('function ' + _name + '(' + _args.join(', ') + ') {'); code.push(' "use strict";'); code.push(' var name = \'' + _name + '\';'); code.push(node.toCode(refs, ' ')); code.push('}'); // generate body for the factory function var body = [refs.toCode(), 'return ' + code.join('\n')].join('\n'); // evaluate the JavaScript code and attach function references var factory = new Function(refs.name, 'createError', body); var fn = factory(refs, createError); //console.log('FN\n' + fn.toString()); // TODO: cleanup // attach the signatures with sub-functions to the constructed function fn.signatures = mapSignatures(_signatures); return fn; } /** * Calculate the maximum number of parameters in givens signatures * @param {Signature[]} signatures * @returns {number} The maximum number of parameters */ function maxParams(signatures) { var max = 0; for (var i = 0; i < signatures.length; i++) { var len = signatures[i].params.length; if (len > max) { max = len; } } return max; } /** * Get the type of a value * @param {*} x * @returns {string} Returns a string with the type of value */ function getTypeOf(x) { var obj; for (var i = 0; i < typed.types.length; i++) { var entry = typed.types[i]; if (entry.name === 'Object') { // Array and Date are also Object, so test for Object afterwards obj = entry; } else { if (entry.test(x)) return entry.name; } } // at last, test whether an object if (obj && obj.test(x)) return obj.name; return 'unknown'; } /** * Test whether an array contains some entry * @param {Array} array * @param {*} entry * @return {boolean} Returns true if array contains entry, false if not. */ function contains(array, entry) { return array.indexOf(entry) !== -1; } // data type tests var types = [{ name: 'number', test: function (x) { return typeof x === 'number'; } }, { name: 'string', test: function (x) { return typeof x === 'string'; } }, { name: 'boolean', test: function (x) { return typeof x === 'boolean'; } }, { name: 'Function', test: function (x) { return typeof x === 'function'; } }, { name: 'Array', test: Array.isArray }, { name: 'Date', test: function (x) { return x instanceof Date; } }, { name: 'RegExp', test: function (x) { return x instanceof RegExp; } }, { name: 'Object', test: function (x) { return typeof x === 'object'; } }, { name: 'null', test: function (x) { return x === null; } }, { name: 'undefined', test: function (x) { return x === undefined; } }]; // configuration var config = {}; // type conversions. Order is important var conversions = []; // types to be ignored var ignore = []; // temporary object for holding types and conversions, for constructing // the `typed` function itself // TODO: find a more elegant solution for this var typed = { config: config, types: types, conversions: conversions, ignore: ignore }; /** * Construct the typed function itself with various signatures * * Signatures: * * typed(signatures: Object.<string, function>) * typed(name: string, signatures: Object.<string, function>) */ typed = _typed('typed', { 'Object': function (signatures) { var fns = []; for (var signature in signatures) { if (signatures.hasOwnProperty(signature)) { fns.push(signatures[signature]); } } var name = getName(fns); return _typed(name, signatures); }, 'string, Object': _typed, // TODO: add a signature 'Array.<function>' '...Function': function (fns) { var err; var name = getName(fns); var signatures = {}; for (var i = 0; i < fns.length; i++) { var fn = fns[i]; // test whether this is a typed-function if (!(typeof fn.signatures === 'object')) { err = new TypeError('Function is no typed-function (index: ' + i + ')'); err.data = { index: i }; throw err; } // merge the signatures for (var signature in fn.signatures) { if (fn.signatures.hasOwnProperty(signature)) { if (signatures.hasOwnProperty(signature)) { if (fn.signatures[signature] !== signatures[signature]) { err = new Error('Signature "' + signature + '" is defined twice'); err.data = { signature: signature }; throw err; } // else: both signatures point to the same function, that's fine } else { signatures[signature] = fn.signatures[signature]; } } } } return _typed(name, signatures); } }); /** * Find a specific signature from a (composed) typed function, for * example: * * typed.find(fn, ['number', 'string']) * typed.find(fn, 'number, string') * * Function find only only works for exact matches. * * @param {Function} fn A typed-function * @param {string | string[]} signature Signature to be found, can be * an array or a comma separated string. * @return {Function} Returns the matching signature, or * throws an errror when no signature * is found. */ function find(fn, signature) { if (!fn.signatures) { throw new TypeError('Function is no typed-function'); } // normalize input var arr; if (typeof signature === 'string') { arr = signature.split(','); for (var i = 0; i < arr.length; i++) { arr[i] = arr[i].trim(); } } else if (Array.isArray(signature)) { arr = signature; } else { throw new TypeError('String array or a comma separated string expected'); } var str = arr.join(','); // find an exact match var match = fn.signatures[str]; if (match) { return match; } // TODO: extend find to match non-exact signatures throw new TypeError('Signature not found (signature: ' + (fn.name || 'unnamed') + '(' + arr.join(', ') + '))'); } /** * Convert a given value to another data type. * @param {*} value * @param {string} type */ function convert(value, type) { var from = getTypeOf(value); // check conversion is needed if (type === from) { return value; } for (var i = 0; i < typed.conversions.length; i++) { var conversion = typed.conversions[i]; if (conversion.from === from && conversion.to === type) { return conversion.convert(value); } } throw new Error('Cannot convert from ' + from + ' to ' + type); } // attach types and conversions to the final `typed` function typed.config = config; typed.types = types; typed.conversions = conversions; typed.ignore = ignore; typed.create = create; typed.find = find; typed.convert = convert; // add a type typed.addType = function (type) { if (!type || typeof type.name !== 'string' || typeof type.test !== 'function') { throw new TypeError('Object with properties {name: string, test: function} expected'); } typed.types.push(type); }; // add a conversion typed.addConversion = function (conversion) { if (!conversion || typeof conversion.from !== 'string' || typeof conversion.to !== 'string' || typeof conversion.convert !== 'function') { throw new TypeError('Object with properties {from: string, to: string, convert: function} expected'); } typed.conversions.push(conversion); }; return typed; } return create(); }); /***/ }, /* 72 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var NumberFormatter = __webpack_require__(73); /** * Test whether value is a number * @param {*} value * @return {boolean} isNumber */ exports.isNumber = function (value) { return typeof value === 'number'; }; /** * Check if a number is integer * @param {number | boolean} value * @return {boolean} isInteger */ exports.isInteger = function (value) { return isFinite(value) ? value == Math.round(value) : false; // Note: we use ==, not ===, as we can have Booleans as well }; /** * Calculate the sign of a number * @param {number} x * @returns {*} */ exports.sign = Math.sign || function (x) { if (x > 0) { return 1; } else if (x < 0) { return -1; } else { return 0; } }; /** * Convert a number to a formatted string representation. * * Syntax: * * format(value) * format(value, options) * format(value, precision) * format(value, fn) * * Where: * * {number} value The value to be formatted * {Object} options An object with formatting options. Available options: * {string} notation * Number notation. Choose from: * 'fixed' Always use regular number notation. * For example '123.40' and '14000000' * 'exponential' Always use exponential notation. * For example '1.234e+2' and '1.4e+7' * 'engineering' Always use engineering notation. * For example '123.4e+0' and '14.0e+6' * 'auto' (default) Regular number notation for numbers * having an absolute value between * `lower` and `upper` bounds, and uses * exponential notation elsewhere. * Lower bound is included, upper bound * is excluded. * For example '123.4' and '1.4e7'. * {number} precision A number between 0 and 16 to round * the digits of the number. * In case of notations 'exponential' and * 'auto', `precision` defines the total * number of significant digits returned * and is undefined by default. * In case of notation 'fixed', * `precision` defines the number of * significant digits after the decimal * point, and is 0 by default. * {Object} exponential An object containing two parameters, * {number} lower and {number} upper, * used by notation 'auto' to determine * when to return exponential notation. * Default values are `lower=1e-3` and * `upper=1e5`. * Only applicable for notation `auto`. * {Function} fn A custom formatting function. Can be used to override the * built-in notations. Function `fn` is called with `value` as * parameter and must return a string. Is useful for example to * format all values inside a matrix in a particular way. * * Examples: * * format(6.4); // '6.4' * format(1240000); // '1.24e6' * format(1/3); // '0.3333333333333333' * format(1/3, 3); // '0.333' * format(21385, 2); // '21000' * format(12.071, {notation: 'fixed'}); // '12' * format(2.3, {notation: 'fixed', precision: 2}); // '2.30' * format(52.8, {notation: 'exponential'}); // '5.28e+1' * format(12345678, {notation: 'engineering'}); // '12.345678e+6' * * @param {number} value * @param {Object | Function | number} [options] * @return {string} str The formatted value */ exports.format = function (value, options) { if (typeof options === 'function') { // handle format(value, fn) return options(value); } // handle special cases if (value === Infinity) { return 'Infinity'; } else if (value === -Infinity) { return '-Infinity'; } else if (isNaN(value)) { return 'NaN'; } // default values for options var notation = 'auto'; var precision = undefined; if (options) { // determine notation from options if (options.notation) { notation = options.notation; } // determine precision from options if (exports.isNumber(options)) { precision = options; } else if (options.precision) { precision = options.precision; } } // handle the various notations switch (notation) { case 'fixed': return exports.toFixed(value, precision); case 'exponential': return exports.toExponential(value, precision); case 'engineering': return exports.toEngineering(value, precision); case 'auto': return exports.toPrecision(value, precision, options && options.exponential) // remove trailing zeros after the decimal point .replace(/((\.\d*?)(0+))($|e)/, function () { var digits = arguments[2]; var e = arguments[4]; return digits !== '.' ? digits + e : e; }); default: throw new Error('Unknown notation "' + notation + '". ' + 'Choose "auto", "exponential", or "fixed".'); } }; /** * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3' * @param {number} value * @param {number} [precision] Number of digits in formatted output. * If not provided, the maximum available digits * is used. * @returns {string} str */ exports.toExponential = function (value, precision) { return new NumberFormatter(value).toExponential(precision); }; /** * Format a number in engineering notation. Like '1.23e+6', '2.3e+0', '3.500e-3' * @param {number} value * @param {number} [precision] Number of digits in formatted output. * If not provided, the maximum available digits * is used. * @returns {string} str */ exports.toEngineering = function (value, precision) { return new NumberFormatter(value).toEngineering(precision); }; /** * Format a number with fixed notation. * @param {number} value * @param {number} [precision=0] Optional number of decimals after the * decimal point. Zero by default. */ exports.toFixed = function (value, precision) { return new NumberFormatter(value).toFixed(precision); }; /** * Format a number with a certain precision * @param {number} value * @param {number} [precision=undefined] Optional number of digits. * @param {{lower: number, upper: number}} [options] By default: * lower = 1e-3 (excl) * upper = 1e+5 (incl) * @return {string} */ exports.toPrecision = function (value, precision, options) { return new NumberFormatter(value).toPrecision(precision, options); }; /** * Count the number of significant digits of a number. * * For example: * 2.34 returns 3 * 0.0034 returns 2 * 120.5e+30 returns 4 * * @param {number} value * @return {number} digits Number of significant digits */ exports.digits = function (value) { return value.toExponential().replace(/e.*$/, '') // remove exponential notation .replace(/^0\.?0*|\./, '') // remove decimal point and leading zeros .length; }; /** * Minimum number added to one that makes the result different than one */ exports.DBL_EPSILON = Number.EPSILON || 2.2204460492503130808472633361816E-16; /** * Compares two floating point numbers. * @param {number} x First value to compare * @param {number} y Second value to compare * @param {number} [epsilon] The maximum relative difference between x and y * If epsilon is undefined or null, the function will * test whether x and y are exactly equal. * @return {boolean} whether the two numbers are nearly equal */ exports.nearlyEqual = function (x, y, epsilon) { // if epsilon is null or undefined, test whether x and y are exactly equal if (epsilon == null) { return x == y; } // use "==" operator, handles infinities if (x == y) { return true; } // NaN if (isNaN(x) || isNaN(y)) { return false; } // at this point x and y should be finite if (isFinite(x) && isFinite(y)) { // check numbers are very close, needed when comparing numbers near zero var diff = Math.abs(x - y); if (diff < exports.DBL_EPSILON) { return true; } else { // use relative error return diff <= Math.max(Math.abs(x), Math.abs(y)) * epsilon; } } // Infinite and Number or negative Infinite and positive Infinite cases return false; }; /***/ }, /* 73 */ /***/ function(module, exports) { 'use strict'; /** * Format a number using methods toPrecision, toFixed, toExponential. * @param {number | string} value * @constructor */ function NumberFormatter(value) { // parse the input value var match = String(value).toLowerCase().match(/^0*?(-?)(\d+\.?\d*)(e([+-]?\d+))?$/); if (!match) { throw new SyntaxError('Invalid number'); } var sign = match[1]; var coefficients = match[2]; var exponent = parseFloat(match[4] || '0'); var dot = coefficients.indexOf('.'); exponent += dot !== -1 ? dot - 1 : coefficients.length - 1; this.sign = sign; this.coefficients = coefficients.replace('.', '') // remove the dot (must be removed before removing leading zeros) .replace(/^0*/, function (zeros) { // remove leading zeros, add their count to the exponent exponent -= zeros.length; return ''; }).replace(/0*$/, '') // remove trailing zeros .split('').map(function (d) { return parseInt(d); }); if (this.coefficients.length === 0) { this.coefficients.push(0); exponent++; } this.exponent = exponent; } /** * Format a number with engineering notation. * @param {number} [precision=0] Optional number of decimals after the * decimal point. Zero by default. */ NumberFormatter.prototype.toEngineering = function (precision) { var rounded = this.roundDigits(precision); var e = rounded.exponent; var c = rounded.coefficients; // find nearest lower multiple of 3 for exponent var newExp = e % 3 === 0 ? e : e < 0 ? e - 3 - e % 3 : e - e % 3; // concatenate coefficients with necessary zeros var significandsDiff = e >= 0 ? e : Math.abs(newExp); // add zeros if necessary (for ex: 1e+8) if (c.length - 1 < significandsDiff) c = c.concat(zeros(significandsDiff - (c.length - 1))); // find difference in exponents var expDiff = Math.abs(e - newExp); var decimalIdx = 1; var str = ''; // push decimal index over by expDiff times while (--expDiff >= 0) decimalIdx++; // if all coefficient values are zero after the decimal point, don't add a decimal value. // otherwise concat with the rest of the coefficients var decimals = c.slice(decimalIdx).join(''); var decimalVal = decimals.match(/[1-9]/) ? '.' + decimals : ''; str = c.slice(0, decimalIdx).join('') + decimalVal; str += 'e' + (e >= 0 ? '+' : '') + newExp.toString(); return rounded.sign + str; }; /** * Format a number with fixed notation. * @param {number} [precision=0] Optional number of decimals after the * decimal point. Zero by default. */ NumberFormatter.prototype.toFixed = function (precision) { var rounded = this.roundDigits(this.exponent + 1 + (precision || 0)); var c = rounded.coefficients; var p = rounded.exponent + 1; // exponent may have changed // append zeros if needed var pp = p + (precision || 0); if (c.length < pp) { c = c.concat(zeros(pp - c.length)); } // prepend zeros if needed if (p < 0) { c = zeros(-p + 1).concat(c); p = 1; } // insert a dot if needed if (precision) { c.splice(p, 0, p === 0 ? '0.' : '.'); } return this.sign + c.join(''); }; /** * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3' * @param {number} [precision] Number of digits in formatted output. * If not provided, the maximum available digits * is used. */ NumberFormatter.prototype.toExponential = function (precision) { // round if needed, else create a clone var rounded = precision ? this.roundDigits(precision) : this.clone(); var c = rounded.coefficients; var e = rounded.exponent; // append zeros if needed if (c.length < precision) { c = c.concat(zeros(precision - c.length)); } // format as `C.CCCe+EEE` or `C.CCCe-EEE` var first = c.shift(); return this.sign + first + (c.length > 0 ? '.' + c.join('') : '') + 'e' + (e >= 0 ? '+' : '') + e; }; /** * Format a number with a certain precision * @param {number} [precision=undefined] Optional number of digits. * @param {{lower: number | undefined, upper: number | undefined}} [options] * By default: * lower = 1e-3 (excl) * upper = 1e+5 (incl) * @return {string} */ NumberFormatter.prototype.toPrecision = function (precision, options) { // determine lower and upper bound for exponential notation. var lower = options && options.lower !== undefined ? options.lower : 1e-3; var upper = options && options.upper !== undefined ? options.upper : 1e+5; var abs = Math.abs(Math.pow(10, this.exponent)); if (abs < lower || abs >= upper) { // exponential notation return this.toExponential(precision); } else { var rounded = precision ? this.roundDigits(precision) : this.clone(); var c = rounded.coefficients; var e = rounded.exponent; // append trailing zeros if (c.length < precision) { c = c.concat(zeros(precision - c.length)); } // append trailing zeros // TODO: simplify the next statement c = c.concat(zeros(e - c.length + 1 + (c.length < precision ? precision - c.length : 0))); // prepend zeros c = zeros(-e).concat(c); var dot = e > 0 ? e : 0; if (dot < c.length - 1) { c.splice(dot + 1, 0, '.'); } return this.sign + c.join(''); } }; /** * Crete a clone of the NumberFormatter * @return {NumberFormatter} Returns a clone of the NumberFormatter */ NumberFormatter.prototype.clone = function () { var clone = new NumberFormatter('0'); clone.sign = this.sign; clone.coefficients = this.coefficients.slice(0); clone.exponent = this.exponent; return clone; }; /** * Round the number of digits of a number * * @param {number} precision A positive integer * @return {NumberFormatter} Returns a new NumberFormatter with the rounded * digits */ NumberFormatter.prototype.roundDigits = function (precision) { var rounded = this.clone(); var c = rounded.coefficients; // prepend zeros if needed while (precision <= 0) { c.unshift(0); rounded.exponent++; precision++; } if (c.length > precision) { var removed = c.splice(precision, c.length - precision); if (removed[0] >= 5) { var i = precision - 1; c[i]++; while (c[i] === 10) { c.pop(); if (i === 0) { c.unshift(0); rounded.exponent++; i++; } i--; c[i]++; } } } return rounded; }; /** * Create an array filled with zeros. * @param {number} length * @return {Array} */ function zeros(length) { var arr = []; for (var i = 0; i < length; i++) { arr.push(0); } return arr; } module.exports = NumberFormatter; /***/ }, /* 74 */ /***/ function(module, exports, __webpack_require__) { var Emitter = __webpack_require__(75); /** * Extend given object with emitter functions `on`, `off`, `once`, `emit` * @param {Object} obj * @return {Object} obj */ exports.mixin = function (obj) { // create event emitter var emitter = new Emitter(); // bind methods to obj (we don't want to expose the emitter.e Array...) obj.on = emitter.on.bind(emitter); obj.off = emitter.off.bind(emitter); obj.once = emitter.once.bind(emitter); obj.emit = emitter.emit.bind(emitter); return obj; }; /***/ }, /* 75 */ /***/ function(module, exports) { function E() { // Keep this empty so it's easier to inherit from // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) } E.prototype = { on: function (name, callback, ctx) { var e = this.e || (this.e = {}); (e[name] || (e[name] = [])).push({ fn: callback, ctx: ctx }); return this; }, once: function (name, callback, ctx) { var self = this; function listener() { self.off(name, listener); callback.apply(ctx, arguments); }; listener._ = callback; return this.on(name, listener, ctx); }, emit: function (name) { var data = [].slice.call(arguments, 1); var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); var i = 0; var len = evtArr.length; for (i; i < len; i++) { evtArr[i].fn.apply(evtArr[i].ctx, data); } return this; }, off: function (name, callback) { var e = this.e || (this.e = {}); var evts = e[name]; var liveEvents = []; if (evts && callback) { for (var i = 0, len = evts.length; i < len; i++) { if (evts[i].fn !== callback && evts[i].fn._ !== callback) liveEvents.push(evts[i]); } } // Remove event from queue to prevent memory leak // Suggested by https://github.com/lazd // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 liveEvents.length ? e[name] = liveEvents : delete e[name]; return this; } }; module.exports = E; /***/ }, /* 76 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var lazy = __webpack_require__(69).lazy; var isFactory = __webpack_require__(69).isFactory; var traverse = __webpack_require__(69).traverse; var extend = __webpack_require__(69).extend; var ArgumentsError = __webpack_require__(77); function factory(type, config, load, typed, math) { /** * Import functions from an object or a module * * Syntax: * * math.import(object) * math.import(object, options) * * Where: * * - `object: Object` * An object with functions to be imported. * - `options: Object` An object with import options. Available options: * - `override: boolean` * If true, existing functions will be overwritten. False by default. * - `silent: boolean` * If true, the function will not throw errors on duplicates or invalid * types. False by default. * - `wrap: boolean` * If true, the functions will be wrapped in a wrapper function * which converts data types like Matrix to primitive data types like Array. * The wrapper is needed when extending math.js with libraries which do not * support these data type. False by default. * * Examples: * * // define new functions and variables * math.import({ * myvalue: 42, * hello: function (name) { * return 'hello, ' + name + '!'; * } * }); * * // use the imported function and variable * math.myvalue * 2; // 84 * math.hello('user'); // 'hello, user!' * * // import the npm module 'numbers' * // (must be installed first with `npm install numbers`) * math.import(require('numbers'), {wrap: true}); * * math.fibonacci(7); // returns 13 * * @param {Object | Array} object Object with functions to be imported. * @param {Object} [options] Import options. */ function math_import(object, options) { var num = arguments.length; if (num != 1 && num != 2) { throw new ArgumentsError('import', num, 1, 2); } if (!options) { options = {}; } if (isFactory(object)) { _importFactory(object, options); } // TODO: allow a typed-function with name too else if (Array.isArray(object)) { object.forEach(function (entry) { math_import(entry, options); }); } else if (typeof object === 'object') { // a map with functions for (var name in object) { if (object.hasOwnProperty(name)) { var value = object[name]; if (isSupportedType(value)) { _import(name, value, options); } else if (isFactory(object)) { _importFactory(object, options); } else { math_import(value, options); } } } } else { if (!options.silent) { throw new TypeError('Factory, Object, or Array expected'); } } } /** * Add a property to the math namespace and create a chain proxy for it. * @param {string} name * @param {*} value * @param {Object} options See import for a description of the options * @private */ function _import(name, value, options) { if (options.wrap && typeof value === 'function') { // create a wrapper around the function value = _wrap(value); } if (isTypedFunction(math[name]) && isTypedFunction(value)) { if (options.override) { // give the typed function the right name value = typed(name, value.signatures); } else { // merge the existing and typed function value = typed(math[name], value); } math[name] = value; _importTransform(name, value); math.emit('import', name, function resolver() { return value; }); return; } if (math[name] === undefined || options.override) { math[name] = value; _importTransform(name, value); math.emit('import', name, function resolver() { return value; }); return; } if (!options.silent) { throw new Error('Cannot import "' + name + '": already exists'); } } function _importTransform(name, value) { if (value && typeof value.transform === 'function') { math.expression.transform[name] = value.transform; } } /** * Create a wrapper a round an function which converts the arguments * to their primitive values (like convert a Matrix to Array) * @param {Function} fn * @return {Function} Returns the wrapped function * @private */ function _wrap(fn) { var wrapper = function wrapper() { var args = []; for (var i = 0, len = arguments.length; i < len; i++) { var arg = arguments[i]; args[i] = arg && arg.valueOf(); } return fn.apply(math, args); }; if (fn.transform) { wrapper.transform = fn.transform; } return wrapper; } /** * Import an instance of a factory into math.js * @param {{factory: Function, name: string, path: string, math: boolean}} factory * @param {Object} options See import for a description of the options * @private */ function _importFactory(factory, options) { if (typeof factory.name === 'string') { var name = factory.name; var namespace = factory.path ? traverse(math, factory.path) : math; var existing = namespace.hasOwnProperty(name) ? namespace[name] : undefined; var resolver = function () { var instance = load(factory); if (isTypedFunction(existing) && isTypedFunction(instance)) { if (options.override) { // replace the existing typed function (nothing to do) } else { // merge the existing and new typed function instance = typed(existing, instance); } return instance; } if (existing === undefined || options.override) { return instance; } if (!options.silent) { throw new Error('Cannot import "' + name + '": already exists'); } }; if (factory.lazy !== false) { lazy(namespace, name, resolver); } else { namespace[name] = resolver(); } math.emit('import', name, resolver, factory.path); } else { // unnamed factory. // no lazy loading load(factory); } } /** * Check whether given object is a type which can be imported * @param {Function | number | string | boolean | null | Unit | Complex} object * @return {boolean} * @private */ function isSupportedType(object) { return typeof object == 'function' || typeof object === 'number' || typeof object === 'string' || typeof object === 'boolean' || object === null || object && object.isUnit === true || object && object.isComplex === true || object && object.isBigNumber === true || object && object.isFraction === true || object && object.isMatrix === true || object && Array.isArray(object) === true; } /** * Test whether a given thing is a typed-function * @param {*} fn * @return {boolean} Returns true when `fn` is a typed-function */ function isTypedFunction(fn) { return typeof fn === 'function' && typeof fn.signatures === 'object'; } return math_import; } exports.math = true; // request access to the math namespace as 5th argument of the factory function exports.name = 'import'; exports.factory = factory; exports.lazy = true; /***/ }, /* 77 */ /***/ function(module, exports) { 'use strict'; /** * Create a syntax error with the message: * 'Wrong number of arguments in function <fn> (<count> provided, <min>-<max> expected)' * @param {string} fn Function name * @param {number} count Actual argument count * @param {number} min Minimum required argument count * @param {number} [max] Maximum required argument count * @extends Error */ function ArgumentsError(fn, count, min, max) { if (!(this instanceof ArgumentsError)) { throw new SyntaxError('Constructor must be called with the new operator'); } this.fn = fn; this.count = count; this.min = min; this.max = max; this.message = 'Wrong number of arguments in function ' + fn + ' (' + count + ' provided, ' + min + (max != undefined ? '-' + max : '') + ' expected)'; this.stack = new Error().stack; } ArgumentsError.prototype = new Error(); ArgumentsError.prototype.constructor = Error; ArgumentsError.prototype.name = 'ArgumentsError'; ArgumentsError.prototype.isArgumentsError = true; module.exports = ArgumentsError; /***/ }, /* 78 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var object = __webpack_require__(69); function factory(type, config, load, typed, math) { var MATRIX = ['Matrix', 'Array']; // valid values for option matrix var NUMBER = ['number', 'BigNumber', 'Fraction']; // valid values for option number /** * Set configuration options for math.js, and get current options. * Will emit a 'config' event, with arguments (curr, prev). * * Syntax: * * math.config(config: Object): Object * * Examples: * * math.config().number; // outputs 'number' * math.eval('0.4'); // outputs number 0.4 * math.config({number: 'Fraction'}); * math.eval('0.4'); // outputs Fraction 2/5 * * @param {Object} [options] Available options: * {number} epsilon * Minimum relative difference between two * compared values, used by all comparison functions. * {string} matrix * A string 'Matrix' (default) or 'Array'. * {string} number * A string 'number' (default), 'BigNumber', or 'Fraction' * {number} precision * The number of significant digits for BigNumbers. * Not applicable for Numbers. * {string} parenthesis * How to display parentheses in LaTeX and string * output. * @return {Object} Returns the current configuration */ function _config(options) { if (options) { var prev = object.clone(config); // validate some of the options validateOption(options, 'matrix', MATRIX); validateOption(options, 'number', NUMBER); // merge options object.deepExtend(config, options); var curr = object.clone(config); // emit 'config' event math.emit('config', curr, prev); return curr; } else { return object.clone(config); } } // attach the valid options to the function so they can be extended _config.MATRIX = MATRIX; _config.NUMBER = NUMBER; return _config; } /** * Test whether an Array contains a specific item. * @param {Array.<string>} array * @param {string} item * @return {boolean} */ function contains(array, item) { return array.indexOf(item) !== -1; } /** * Find a string in an array. Case insensitive search * @param {Array.<string>} array * @param {string} item * @return {number} Returns the index when found. Returns -1 when not found */ function findIndex(array, item) { return array.map(function (i) { return i.toLowerCase(); }).indexOf(item.toLowerCase()); } /** * Validate an option * @param {Object} options Object with options * @param {string} name Name of the option to validate * @param {Array.<string>} values Array with valid values for this option */ function validateOption(options, name, values) { if (options[name] !== undefined && !contains(values, options[name])) { var index = findIndex(values, options[name]); if (index !== -1) { // right value, wrong casing // TODO: lower case values are deprecated since v3, remove this warning some day. console.warn('Warning: Wrong casing for configuration option "' + name + '", should be "' + values[index] + '" instead of "' + options[name] + '".'); options[name] = values[index]; // change the option to the right casing } else { // unknown value console.warn('Warning: Unknown value "' + options[name] + '" for configuration option "' + name + '". Available options: ' + values.map(JSON.stringify).join(', ') + '.'); } } } exports.name = 'config'; exports.math = true; // request the math namespace as fifth argument exports.factory = factory; /***/ }, /* 79 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var deepMap = __webpack_require__(80); function factory(type, config, load, typed) { var gamma = load(__webpack_require__(81)); var latex = __webpack_require__(89); /** * Compute the factorial of a value * * Factorial only supports an integer value as argument. * For matrices, the function is evaluated element wise. * * Syntax: * * math.factorial(n) * * Examples: * * math.factorial(5); // returns 120 * math.factorial(3); // returns 6 * * See also: * * combinations, gamma, permutations * * @param {number | BigNumber | Array | Matrix} n An integer number * @return {number | BigNumber | Array | Matrix} The factorial of `n` */ var factorial = typed('factorial', { 'number': function (n) { if (n < 0) { throw new Error('Value must be non-negative'); } return gamma(n + 1); }, 'BigNumber': function (n) { if (n.isNegative()) { throw new Error('Value must be non-negative'); } return gamma(n.plus(1)); }, 'Array | Matrix': function (n) { return deepMap(n, factorial); } }); factorial.toTex = { 1: '\\left(${args[0]}\\right)' + latex.operators['factorial'] }; return factorial; } exports.name = 'factorial'; exports.factory = factory; /***/ }, /* 80 */ /***/ function(module, exports) { 'use strict'; /** * Execute the callback function element wise for each element in array and any * nested array * Returns an array with the results * @param {Array | Matrix} array * @param {Function} callback The callback is called with two parameters: * value1 and value2, which contain the current * element of both arrays. * @param {boolean} [skipZeros] Invoke callback function for non-zero values only. * * @return {Array | Matrix} res */ module.exports = function deepMap(array, callback, skipZeros) { if (array && typeof array.map === 'function') { // TODO: replace array.map with a for loop to improve performance return array.map(function (x) { return deepMap(x, callback, skipZeros); }); } else { return callback(array); } }; /***/ }, /* 81 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var deepMap = __webpack_require__(80); var isInteger = __webpack_require__(72).isInteger; function factory(type, config, load, typed) { var multiply = load(__webpack_require__(82)); var pow = load(__webpack_require__(97)); /** * Compute the gamma function of a value using Lanczos approximation for * small values, and an extended Stirling approximation for large values. * * For matrices, the function is evaluated element wise. * * Syntax: * * math.gamma(n) * * Examples: * * math.gamma(5); // returns 24 * math.gamma(-0.5); // returns -3.5449077018110335 * math.gamma(math.i); // returns -0.15494982830180973 - 0.49801566811835596i * * See also: * * combinations, factorial, permutations * * @param {number | Array | Matrix} n A real or complex number * @return {number | Array | Matrix} The gamma of `n` */ var gamma = typed('gamma', { 'number': function (n) { var t, x; if (isInteger(n)) { if (n <= 0) { return isFinite(n) ? Infinity : NaN; } if (n > 171) { return Infinity; // Will overflow } var value = n - 2; var res = n - 1; while (value > 1) { res *= value; value--; } if (res == 0) { res = 1; // 0! is per definition 1 } return res; } if (n < 0.5) { return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n)); } if (n >= 171.35) { return Infinity; // will overflow } if (n > 85.0) { // Extended Stirling Approx var twoN = n * n; var threeN = twoN * n; var fourN = threeN * n; var fiveN = fourN * n; return Math.sqrt(2 * Math.PI / n) * Math.pow(n / Math.E, n) * (1 + 1 / (12 * n) + 1 / (288 * twoN) - 139 / (51840 * threeN) - 571 / (2488320 * fourN) + 163879 / (209018880 * fiveN) + 5246819 / (75246796800 * fiveN * n)); } --n; x = p[0]; for (var i = 1; i < p.length; ++i) { x += p[i] / (n + i); } t = n + g + 0.5; return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x; }, 'Complex': function (n) { var t, x; if (n.im == 0) { return gamma(n.re); } n = new type.Complex(n.re - 1, n.im); x = new type.Complex(p[0], 0); for (var i = 1; i < p.length; ++i) { var real = n.re + i; // x += p[i]/(n+i) var den = real * real + n.im * n.im; if (den != 0) { x.re += p[i] * real / den; x.im += -(p[i] * n.im) / den; } else { x.re = p[i] < 0 ? -Infinity : Infinity; } } t = new type.Complex(n.re + g + 0.5, n.im); var twoPiSqrt = Math.sqrt(2 * Math.PI); n.re += 0.5; var result = pow(t, n); if (result.im == 0) { // sqrt(2*PI)*result result.re *= twoPiSqrt; } else if (result.re == 0) { result.im *= twoPiSqrt; } else { result.re *= twoPiSqrt; result.im *= twoPiSqrt; } var r = Math.exp(-t.re); // exp(-t) t.re = r * Math.cos(-t.im); t.im = r * Math.sin(-t.im); return multiply(multiply(result, t), x); }, 'BigNumber': function (n) { if (n.isInteger()) { return n.isNegative() || n.isZero() ? new type.BigNumber(Infinity) : bigFactorial(n.minus(1)); } if (!n.isFinite()) { return new type.BigNumber(n.isNegative() ? NaN : Infinity); } throw new Error('Integer BigNumber expected'); }, 'Array | Matrix': function (n) { return deepMap(n, gamma); } }); /** * Calculate factorial for a BigNumber * @param {BigNumber} n * @returns {BigNumber} Returns the factorial of n */ function bigFactorial(n) { if (n.isZero()) { return new type.BigNumber(1); // 0! is per definition 1 } var precision = config.precision + (Math.log(n.toNumber()) | 0); var Big = type.BigNumber.clone({ precision: precision }); var res = new Big(n); var value = n.toNumber() - 1; // number while (value > 1) { res = res.times(value); value--; } return new type.BigNumber(res.toPrecision(type.BigNumber.precision)); } gamma.toTex = { 1: '\\Gamma\\left(${args[0]}\\right)' }; return gamma; } // TODO: comment on the variables g and p var g = 4.7421875; var p = [0.99999999999999709182, 57.156235665862923517, -59.597960355475491248, 14.136097974741747174, -0.49191381609762019978, 0.33994649984811888699e-4, 0.46523628927048575665e-4, -0.98374475304879564677e-4, 0.15808870322491248884e-3, -0.21026444172410488319e-3, 0.21743961811521264320e-3, -0.16431810653676389022e-3, 0.84418223983852743293e-4, -0.26190838401581408670e-4, 0.36899182659531622704e-5]; exports.name = 'gamma'; exports.factory = factory; /***/ }, /* 82 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var extend = __webpack_require__(69).extend; var array = __webpack_require__(83); function factory(type, config, load, typed) { var latex = __webpack_require__(89); var matrix = load(__webpack_require__(90)); var addScalar = load(__webpack_require__(91)); var multiplyScalar = load(__webpack_require__(92)); var equalScalar = load(__webpack_require__(93)); var algorithm11 = load(__webpack_require__(95)); var algorithm14 = load(__webpack_require__(96)); var DenseMatrix = type.DenseMatrix; var SparseMatrix = type.SparseMatrix; /** * Multiply two values, `x * y`. * For matrices, the matrix product is calculated. * * Syntax: * * math.multiply(x, y) * * Examples: * * math.multiply(4, 5.2); // returns number 20.8 * * var a = math.complex(2, 3); * var b = math.complex(4, 1); * math.multiply(a, b); // returns Complex 5 + 14i * * var c = [[1, 2], [4, 3]]; * var d = [[1, 2, 3], [3, -4, 7]]; * math.multiply(c, d); // returns Array [[7, -6, 17], [13, -4, 33]] * * var e = math.unit('2.1 km'); * math.multiply(3, e); // returns Unit 6.3 km * * See also: * * divide * * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y` */ var multiply = typed('multiply', extend({ // we extend the signatures of multiplyScalar with signatures dealing with matrices 'Array, Array': function (x, y) { // check dimensions _validateMatrixDimensions(array.size(x), array.size(y)); // use dense matrix implementation var m = multiply(matrix(x), matrix(y)); // return array or scalar return m && m.isMatrix === true ? m.valueOf() : m; }, 'Matrix, Matrix': function (x, y) { // dimensions var xsize = x.size(); var ysize = y.size(); // check dimensions _validateMatrixDimensions(xsize, ysize); // process dimensions if (xsize.length === 1) { // process y dimensions if (ysize.length === 1) { // Vector * Vector return _multiplyVectorVector(x, y, xsize[0]); } // Vector * Matrix return _multiplyVectorMatrix(x, y); } // process y dimensions if (ysize.length === 1) { // Matrix * Vector return _multiplyMatrixVector(x, y); } // Matrix * Matrix return _multiplyMatrixMatrix(x, y); }, 'Matrix, Array': function (x, y) { // use Matrix * Matrix implementation return multiply(x, matrix(y)); }, 'Array, Matrix': function (x, y) { // use Matrix * Matrix implementation return multiply(matrix(x, y.storage()), y); }, 'Matrix, any': function (x, y) { // result var c; // process storage format switch (x.storage()) { case 'sparse': c = algorithm11(x, y, multiplyScalar, false); break; case 'dense': c = algorithm14(x, y, multiplyScalar, false); break; } return c; }, 'any, Matrix': function (x, y) { // result var c; // check storage format switch (y.storage()) { case 'sparse': c = algorithm11(y, x, multiplyScalar, true); break; case 'dense': c = algorithm14(y, x, multiplyScalar, true); break; } return c; }, 'Array, any': function (x, y) { // use matrix implementation return algorithm14(matrix(x), y, multiplyScalar, false).valueOf(); }, 'any, Array': function (x, y) { // use matrix implementation return algorithm14(matrix(y), x, multiplyScalar, true).valueOf(); } }, multiplyScalar.signatures)); var _validateMatrixDimensions = function (size1, size2) { // check left operand dimensions switch (size1.length) { case 1: // check size2 switch (size2.length) { case 1: // Vector x Vector if (size1[0] !== size2[0]) { // throw error throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length'); } break; case 2: // Vector x Matrix if (size1[0] !== size2[0]) { // throw error throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')'); } break; default: throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)'); } break; case 2: // check size2 switch (size2.length) { case 1: // Matrix x Vector if (size1[1] !== size2[0]) { // throw error throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')'); } break; case 2: // Matrix x Matrix if (size1[1] !== size2[0]) { // throw error throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')'); } break; default: throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)'); } break; default: throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)'); } }; /** * C = A * B * * @param {Matrix} a Dense Vector (N) * @param {Matrix} b Dense Vector (N) * * @return {number} Scalar value */ var _multiplyVectorVector = function (a, b, n) { // check empty vector if (n === 0) throw new Error('Cannot multiply two empty vectors'); // a dense var adata = a._data; var adt = a._datatype; // b dense var bdata = b._data; var bdt = b._datatype; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); } // result (do not initialize it with zero) var c = mf(adata[0], bdata[0]); // loop data for (var i = 1; i < n; i++) { // multiply and accumulate c = af(c, mf(adata[i], bdata[i])); } return c; }; /** * C = A * B * * @param {Matrix} a Dense Vector (M) * @param {Matrix} b Matrix (MxN) * * @return {Matrix} Dense Vector (N) */ var _multiplyVectorMatrix = function (a, b) { // process storage switch (b.storage()) { case 'dense': return _multiplyVectorDenseMatrix(a, b); } throw new Error('Not implemented'); }; /** * C = A * B * * @param {Matrix} a Dense Vector (M) * @param {Matrix} b Dense Matrix (MxN) * * @return {Matrix} Dense Vector (N) */ var _multiplyVectorDenseMatrix = function (a, b) { // a dense var adata = a._data; var asize = a._size; var adt = a._datatype; // b dense var bdata = b._data; var bsize = b._size; var bdt = b._datatype; // rows & columns var alength = asize[0]; var bcolumns = bsize[1]; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); } // result var c = []; // loop matrix columns for (var j = 0; j < bcolumns; j++) { // sum (do not initialize it with zero) var sum = mf(adata[0], bdata[0][j]); // loop vector for (var i = 1; i < alength; i++) { // multiply & accumulate sum = af(sum, mf(adata[i], bdata[i][j])); } c[j] = sum; } // return matrix return new DenseMatrix({ data: c, size: [bcolumns], datatype: dt }); }; /** * C = A * B * * @param {Matrix} a Matrix (MxN) * @param {Matrix} b Dense Vector (N) * * @return {Matrix} Dense Vector (M) */ var _multiplyMatrixVector = function (a, b) { // process storage switch (a.storage()) { case 'dense': return _multiplyDenseMatrixVector(a, b); case 'sparse': return _multiplySparseMatrixVector(a, b); } }; /** * C = A * B * * @param {Matrix} a Matrix (MxN) * @param {Matrix} b Matrix (NxC) * * @return {Matrix} Matrix (MxC) */ var _multiplyMatrixMatrix = function (a, b) { // process storage switch (a.storage()) { case 'dense': // process storage switch (b.storage()) { case 'dense': return _multiplyDenseMatrixDenseMatrix(a, b); case 'sparse': return _multiplyDenseMatrixSparseMatrix(a, b); } break; case 'sparse': // process storage switch (b.storage()) { case 'dense': return _multiplySparseMatrixDenseMatrix(a, b); case 'sparse': return _multiplySparseMatrixSparseMatrix(a, b); } break; } }; /** * C = A * B * * @param {Matrix} a DenseMatrix (MxN) * @param {Matrix} b Dense Vector (N) * * @return {Matrix} Dense Vector (M) */ var _multiplyDenseMatrixVector = function (a, b) { // a dense var adata = a._data; var asize = a._size; var adt = a._datatype; // b dense var bdata = b._data; var bdt = b._datatype; // rows & columns var arows = asize[0]; var acolumns = asize[1]; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); } // result var c = []; // loop matrix a rows for (var i = 0; i < arows; i++) { // current row var row = adata[i]; // sum (do not initialize it with zero) var sum = mf(row[0], bdata[0]); // loop matrix a columns for (var j = 1; j < acolumns; j++) { // multiply & accumulate sum = af(sum, mf(row[j], bdata[j])); } c[i] = sum; } // return matrix return new DenseMatrix({ data: c, size: [arows], datatype: dt }); }; /** * C = A * B * * @param {Matrix} a DenseMatrix (MxN) * @param {Matrix} b DenseMatrix (NxC) * * @return {Matrix} DenseMatrix (MxC) */ var _multiplyDenseMatrixDenseMatrix = function (a, b) { // a dense var adata = a._data; var asize = a._size; var adt = a._datatype; // b dense var bdata = b._data; var bsize = b._size; var bdt = b._datatype; // rows & columns var arows = asize[0]; var acolumns = asize[1]; var bcolumns = bsize[1]; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); } // result var c = []; // loop matrix a rows for (var i = 0; i < arows; i++) { // current row var row = adata[i]; // initialize row array c[i] = []; // loop matrix b columns for (var j = 0; j < bcolumns; j++) { // sum (avoid initializing sum to zero) var sum = mf(row[0], bdata[0][j]); // loop matrix a columns for (var x = 1; x < acolumns; x++) { // multiply & accumulate sum = af(sum, mf(row[x], bdata[x][j])); } c[i][j] = sum; } } // return matrix return new DenseMatrix({ data: c, size: [arows, bcolumns], datatype: dt }); }; /** * C = A * B * * @param {Matrix} a DenseMatrix (MxN) * @param {Matrix} b SparseMatrix (NxC) * * @return {Matrix} SparseMatrix (MxC) */ var _multiplyDenseMatrixSparseMatrix = function (a, b) { // a dense var adata = a._data; var asize = a._size; var adt = a._datatype; // b sparse var bvalues = b._values; var bindex = b._index; var bptr = b._ptr; var bsize = b._size; var bdt = b._datatype; // validate b matrix if (!bvalues) throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix'); // rows & columns var arows = asize[0]; var bcolumns = bsize[1]; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // equalScalar signature to use var eq = equalScalar; // zero value var zero = 0; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype zero = typed.convert(0, dt); } // result var cvalues = []; var cindex = []; var cptr = []; // c matrix var c = new SparseMatrix({ values: cvalues, index: cindex, ptr: cptr, size: [arows, bcolumns], datatype: dt }); // loop b columns for (var jb = 0; jb < bcolumns; jb++) { // update ptr cptr[jb] = cindex.length; // indeces in column jb var kb0 = bptr[jb]; var kb1 = bptr[jb + 1]; // do not process column jb if no data exists if (kb1 > kb0) { // last row mark processed var last = 0; // loop a rows for (var i = 0; i < arows; i++) { // column mark var mark = i + 1; // C[i, jb] var cij; // values in b column j for (var kb = kb0; kb < kb1; kb++) { // row var ib = bindex[kb]; // check value has been initialized if (last !== mark) { // first value in column jb cij = mf(adata[i][ib], bvalues[kb]); // update mark last = mark; } else { // accumulate value cij = af(cij, mf(adata[i][ib], bvalues[kb])); } } // check column has been processed and value != 0 if (last === mark && !eq(cij, zero)) { // push row & value cindex.push(i); cvalues.push(cij); } } } } // update ptr cptr[bcolumns] = cindex.length; // return sparse matrix return c; }; /** * C = A * B * * @param {Matrix} a SparseMatrix (MxN) * @param {Matrix} b Dense Vector (N) * * @return {Matrix} SparseMatrix (M, 1) */ var _multiplySparseMatrixVector = function (a, b) { // a sparse var avalues = a._values; var aindex = a._index; var aptr = a._ptr; var adt = a._datatype; // validate a matrix if (!avalues) throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix'); // b dense var bdata = b._data; var bdt = b._datatype; // rows & columns var arows = a._size[0]; var brows = b._size[0]; // result var cvalues = []; var cindex = []; var cptr = []; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // equalScalar signature to use var eq = equalScalar; // zero value var zero = 0; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype zero = typed.convert(0, dt); } // workspace var x = []; // vector with marks indicating a value x[i] exists in a given column var w = []; // update ptr cptr[0] = 0; // rows in b for (var ib = 0; ib < brows; ib++) { // b[ib] var vbi = bdata[ib]; // check b[ib] != 0, avoid loops if (!eq(vbi, zero)) { // A values & index in ib column for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) { // a row var ia = aindex[ka]; // check value exists in current j if (!w[ia]) { // ia is new entry in j w[ia] = true; // add i to pattern of C cindex.push(ia); // x(ia) = A x[ia] = mf(vbi, avalues[ka]); } else { // i exists in C already x[ia] = af(x[ia], mf(vbi, avalues[ka])); } } } } // copy values from x to column jb of c for (var p1 = cindex.length, p = 0; p < p1; p++) { // row var ic = cindex[p]; // copy value cvalues[p] = x[ic]; } // update ptr cptr[1] = cindex.length; // return sparse matrix return new SparseMatrix({ values: cvalues, index: cindex, ptr: cptr, size: [arows, 1], datatype: dt }); }; /** * C = A * B * * @param {Matrix} a SparseMatrix (MxN) * @param {Matrix} b DenseMatrix (NxC) * * @return {Matrix} SparseMatrix (MxC) */ var _multiplySparseMatrixDenseMatrix = function (a, b) { // a sparse var avalues = a._values; var aindex = a._index; var aptr = a._ptr; var adt = a._datatype; // validate a matrix if (!avalues) throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix'); // b dense var bdata = b._data; var bdt = b._datatype; // rows & columns var arows = a._size[0]; var brows = b._size[0]; var bcolumns = b._size[1]; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // equalScalar signature to use var eq = equalScalar; // zero value var zero = 0; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype zero = typed.convert(0, dt); } // result var cvalues = []; var cindex = []; var cptr = []; // c matrix var c = new SparseMatrix({ values: cvalues, index: cindex, ptr: cptr, size: [arows, bcolumns], datatype: dt }); // workspace var x = []; // vector with marks indicating a value x[i] exists in a given column var w = []; // loop b columns for (var jb = 0; jb < bcolumns; jb++) { // update ptr cptr[jb] = cindex.length; // mark in workspace for current column var mark = jb + 1; // rows in jb for (var ib = 0; ib < brows; ib++) { // b[ib, jb] var vbij = bdata[ib][jb]; // check b[ib, jb] != 0, avoid loops if (!eq(vbij, zero)) { // A values & index in ib column for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) { // a row var ia = aindex[ka]; // check value exists in current j if (w[ia] !== mark) { // ia is new entry in j w[ia] = mark; // add i to pattern of C cindex.push(ia); // x(ia) = A x[ia] = mf(vbij, avalues[ka]); } else { // i exists in C already x[ia] = af(x[ia], mf(vbij, avalues[ka])); } } } } // copy values from x to column jb of c for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) { // row var ic = cindex[p]; // copy value cvalues[p] = x[ic]; } } // update ptr cptr[bcolumns] = cindex.length; // return sparse matrix return c; }; /** * C = A * B * * @param {Matrix} a SparseMatrix (MxN) * @param {Matrix} b SparseMatrix (NxC) * * @return {Matrix} SparseMatrix (MxC) */ var _multiplySparseMatrixSparseMatrix = function (a, b) { // a sparse var avalues = a._values; var aindex = a._index; var aptr = a._ptr; var adt = a._datatype; // b sparse var bvalues = b._values; var bindex = b._index; var bptr = b._ptr; var bdt = b._datatype; // rows & columns var arows = a._size[0]; var bcolumns = b._size[1]; // flag indicating both matrices (a & b) contain data var values = avalues && bvalues; // datatype var dt; // addScalar signature to use var af = addScalar; // multiplyScalar signature to use var mf = multiplyScalar; // process data types if (adt && bdt && adt === bdt && typeof adt === 'string') { // datatype dt = adt; // find signatures that matches (dt, dt) af = typed.find(addScalar, [dt, dt]); mf = typed.find(multiplyScalar, [dt, dt]); } // result var cvalues = values ? [] : undefined; var cindex = []; var cptr = []; // c matrix var c = new SparseMatrix({ values: cvalues, index: cindex, ptr: cptr, size: [arows, bcolumns], datatype: dt }); // workspace var x = values ? [] : undefined; // vector with marks indicating a value x[i] exists in a given column var w = []; // variables var ka, ka0, ka1, kb, kb0, kb1, ia, ib; // loop b columns for (var jb = 0; jb < bcolumns; jb++) { // update ptr cptr[jb] = cindex.length; // mark in workspace for current column var mark = jb + 1; // B values & index in j for (kb0 = bptr[jb], kb1 = bptr[jb + 1], kb = kb0; kb < kb1; kb++) { // b row ib = bindex[kb]; // check we need to process values if (values) { // loop values in a[:,ib] for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) { // row ia = aindex[ka]; // check value exists in current j if (w[ia] !== mark) { // ia is new entry in j w[ia] = mark; // add i to pattern of C cindex.push(ia); // x(ia) = A x[ia] = mf(bvalues[kb], avalues[ka]); } else { // i exists in C already x[ia] = af(x[ia], mf(bvalues[kb], avalues[ka])); } } } else { // loop values in a[:,ib] for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) { // row ia = aindex[ka]; // check value exists in current j if (w[ia] !== mark) { // ia is new entry in j w[ia] = mark; // add i to pattern of C cindex.push(ia); } } } } // check we need to process matrix values (pattern matrix) if (values) { // copy values from x to column jb of c for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) { // row var ic = cindex[p]; // copy value cvalues[p] = x[ic]; } } } // update ptr cptr[bcolumns] = cindex.length; // return sparse matrix return c; }; multiply.toTex = { 2: '\\left(${args[0]}' + latex.operators['multiply'] + '${args[1]}\\right)' }; return multiply; } exports.name = 'multiply'; exports.factory = factory; /***/ }, /* 83 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var number = __webpack_require__(72); var string = __webpack_require__(84); var object = __webpack_require__(69); var types = __webpack_require__(86); var DimensionError = __webpack_require__(87); var IndexError = __webpack_require__(88); /** * Calculate the size of a multi dimensional array. * This function checks the size of the first entry, it does not validate * whether all dimensions match. (use function `validate` for that) * @param {Array} x * @Return {Number[]} size */ exports.size = function (x) { var s = []; while (Array.isArray(x)) { s.push(x.length); x = x[0]; } return s; }; /** * Recursively validate whether each element in a multi dimensional array * has a size corresponding to the provided size array. * @param {Array} array Array to be validated * @param {number[]} size Array with the size of each dimension * @param {number} dim Current dimension * @throws DimensionError * @private */ function _validate(array, size, dim) { var i; var len = array.length; if (len != size[dim]) { throw new DimensionError(len, size[dim]); } if (dim < size.length - 1) { // recursively validate each child array var dimNext = dim + 1; for (i = 0; i < len; i++) { var child = array[i]; if (!Array.isArray(child)) { throw new DimensionError(size.length - 1, size.length, '<'); } _validate(array[i], size, dimNext); } } else { // last dimension. none of the childs may be an array for (i = 0; i < len; i++) { if (Array.isArray(array[i])) { throw new DimensionError(size.length + 1, size.length, '>'); } } } } /** * Validate whether each element in a multi dimensional array has * a size corresponding to the provided size array. * @param {Array} array Array to be validated * @param {number[]} size Array with the size of each dimension * @throws DimensionError */ exports.validate = function (array, size) { var isScalar = size.length == 0; if (isScalar) { // scalar if (Array.isArray(array)) { throw new DimensionError(array.length, 0); } } else { // array _validate(array, size, 0); } }; /** * Test whether index is an integer number with index >= 0 and index < length * when length is provided * @param {number} index Zero-based index * @param {number} [length] Length of the array */ exports.validateIndex = function (index, length) { if (!number.isNumber(index) || !number.isInteger(index)) { throw new TypeError('Index must be an integer (value: ' + index + ')'); } if (index < 0 || typeof length === 'number' && index >= length) { throw new IndexError(index, length); } }; // a constant used to specify an undefined defaultValue exports.UNINITIALIZED = {}; /** * Resize a multi dimensional array. The resized array is returned. * @param {Array} array Array to be resized * @param {Array.<number>} size Array with the size of each dimension * @param {*} [defaultValue=0] Value to be filled in in new entries, * zero by default. To leave new entries undefined, * specify array.UNINITIALIZED as defaultValue * @return {Array} array The resized array */ exports.resize = function (array, size, defaultValue) { // TODO: add support for scalars, having size=[] ? // check the type of the arguments if (!Array.isArray(array) || !Array.isArray(size)) { throw new TypeError('Array expected'); } if (size.length === 0) { throw new Error('Resizing to scalar is not supported'); } // check whether size contains positive integers size.forEach(function (value) { if (!number.isNumber(value) || !number.isInteger(value) || value < 0) { throw new TypeError('Invalid size, must contain positive integers ' + '(size: ' + string.format(size) + ')'); } }); // recursively resize the array var _defaultValue = defaultValue !== undefined ? defaultValue : 0; _resize(array, size, 0, _defaultValue); return array; }; /** * Recursively resize a multi dimensional array * @param {Array} array Array to be resized * @param {number[]} size Array with the size of each dimension * @param {number} dim Current dimension * @param {*} [defaultValue] Value to be filled in in new entries, * undefined by default. * @private */ function _resize(array, size, dim, defaultValue) { var i; var elem; var oldLen = array.length; var newLen = size[dim]; var minLen = Math.min(oldLen, newLen); // apply new length array.length = newLen; if (dim < size.length - 1) { // non-last dimension var dimNext = dim + 1; // resize existing child arrays for (i = 0; i < minLen; i++) { // resize child array elem = array[i]; if (!Array.isArray(elem)) { elem = [elem]; // add a dimension array[i] = elem; } _resize(elem, size, dimNext, defaultValue); } // create new child arrays for (i = minLen; i < newLen; i++) { // get child array elem = []; array[i] = elem; // resize new child array _resize(elem, size, dimNext, defaultValue); } } else { // last dimension // remove dimensions of existing values for (i = 0; i < minLen; i++) { while (Array.isArray(array[i])) { array[i] = array[i][0]; } } if (defaultValue !== exports.UNINITIALIZED) { // fill new elements with the default value for (i = minLen; i < newLen; i++) { array[i] = defaultValue; } } } } /** * Squeeze a multi dimensional array * @param {Array} array * @param {Array} [size] * @returns {Array} returns the array itself */ exports.squeeze = function (array, size) { var s = size || exports.size(array); // squeeze outer dimensions while (Array.isArray(array) && array.length === 1) { array = array[0]; s.shift(); } // find the first dimension to be squeezed var dims = s.length; while (s[dims - 1] === 1) { dims--; } // squeeze inner dimensions if (dims < s.length) { array = _squeeze(array, dims, 0); s.length = dims; } return array; }; /** * Recursively squeeze a multi dimensional array * @param {Array} array * @param {number} dims Required number of dimensions * @param {number} dim Current dimension * @returns {Array | *} Returns the squeezed array * @private */ function _squeeze(array, dims, dim) { var i, ii; if (dim < dims) { var next = dim + 1; for (i = 0, ii = array.length; i < ii; i++) { array[i] = _squeeze(array[i], dims, next); } } else { while (Array.isArray(array)) { array = array[0]; } } return array; } /** * Unsqueeze a multi dimensional array: add dimensions when missing * * Paramter `size` will be mutated to match the new, unqueezed matrix size. * * @param {Array} array * @param {number} dims Desired number of dimensions of the array * @param {number} [outer] Number of outer dimensions to be added * @param {Array} [size] Current size of array. * @returns {Array} returns the array itself * @private */ exports.unsqueeze = function (array, dims, outer, size) { var s = size || exports.size(array); // unsqueeze outer dimensions if (outer) { for (var i = 0; i < outer; i++) { array = [array]; s.unshift(1); } } // unsqueeze inner dimensions array = _unsqueeze(array, dims, 0); while (s.length < dims) { s.push(1); } return array; }; /** * Recursively unsqueeze a multi dimensional array * @param {Array} array * @param {number} dims Required number of dimensions * @param {number} dim Current dimension * @returns {Array | *} Returns the squeezed array * @private */ function _unsqueeze(array, dims, dim) { var i, ii; if (Array.isArray(array)) { var next = dim + 1; for (i = 0, ii = array.length; i < ii; i++) { array[i] = _unsqueeze(array[i], dims, next); } } else { for (var d = dim; d < dims; d++) { array = [array]; } } return array; } /** * Flatten a multi dimensional array, put all elements in a one dimensional * array * @param {Array} array A multi dimensional array * @return {Array} The flattened array (1 dimensional) */ exports.flatten = function (array) { if (!Array.isArray(array)) { //if not an array, return as is return array; } var flat = []; array.forEach(function callback(value) { if (Array.isArray(value)) { value.forEach(callback); //traverse through sub-arrays recursively } else { flat.push(value); } }); return flat; }; /** * Test whether an object is an array * @param {*} value * @return {boolean} isArray */ exports.isArray = Array.isArray; /***/ }, /* 84 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var formatNumber = __webpack_require__(72).format; var formatBigNumber = __webpack_require__(85).format; /** * Test whether value is a string * @param {*} value * @return {boolean} isString */ exports.isString = function (value) { return typeof value === 'string'; }; /** * Check if a text ends with a certain string. * @param {string} text * @param {string} search */ exports.endsWith = function (text, search) { var start = text.length - search.length; var end = text.length; return text.substring(start, end) === search; }; /** * Format a value of any type into a string. * * Usage: * math.format(value) * math.format(value, precision) * * When value is a function: * * - When the function has a property `syntax`, it returns this * syntax description. * - In other cases, a string `'function'` is returned. * * When `value` is an Object: * * - When the object contains a property `format` being a function, this * function is invoked as `value.format(options)` and the result is returned. * - When the object has its own `toString` method, this method is invoked * and the result is returned. * - In other cases the function will loop over all object properties and * return JSON object notation like '{"a": 2, "b": 3}'. * * Example usage: * math.format(2/7); // '0.2857142857142857' * math.format(math.pi, 3); // '3.14' * math.format(new Complex(2, 3)); // '2 + 3i' * math.format('hello'); // '"hello"' * * @param {*} value Value to be stringified * @param {Object | number | Function} [options] Formatting options. See * lib/utils/number:format for a * description of the available * options. * @return {string} str */ exports.format = function (value, options) { if (typeof value === 'number') { return formatNumber(value, options); } if (value && value.isBigNumber === true) { return formatBigNumber(value, options); } if (value && value.isFraction === true) { if (!options || options.fraction !== 'decimal') { // output as ratio, like '1/3' return value.s * value.n + '/' + value.d; } else { // output as decimal, like '0.(3)' return value.toString(); } } if (Array.isArray(value)) { return formatArray(value, options); } if (exports.isString(value)) { return '"' + value + '"'; } if (typeof value === 'function') { return value.syntax ? String(value.syntax) : 'function'; } if (value && typeof value === 'object') { if (typeof value.format === 'function') { return value.format(options); } else if (value && value.toString() !== {}.toString()) { // this object has a non-native toString method, use that one return value.toString(); } else { var entries = []; for (var key in value) { if (value.hasOwnProperty(key)) { entries.push('"' + key + '": ' + exports.format(value[key], options)); } } return '{' + entries.join(', ') + '}'; } } return String(value); }; /** * Recursively format an n-dimensional matrix * Example output: "[[1, 2], [3, 4]]" * @param {Array} array * @param {Object | number | Function} [options] Formatting options. See * lib/utils/number:format for a * description of the available * options. * @returns {string} str */ function formatArray(array, options) { if (Array.isArray(array)) { var str = '['; var len = array.length; for (var i = 0; i < len; i++) { if (i != 0) { str += ', '; } str += formatArray(array[i], options); } str += ']'; return str; } else { return exports.format(array, options); } } /***/ }, /* 85 */ /***/ function(module, exports) { /** * Convert a BigNumber to a formatted string representation. * * Syntax: * * format(value) * format(value, options) * format(value, precision) * format(value, fn) * * Where: * * {number} value The value to be formatted * {Object} options An object with formatting options. Available options: * {string} notation * Number notation. Choose from: * 'fixed' Always use regular number notation. * For example '123.40' and '14000000' * 'exponential' Always use exponential notation. * For example '1.234e+2' and '1.4e+7' * 'auto' (default) Regular number notation for numbers * having an absolute value between * `lower` and `upper` bounds, and uses * exponential notation elsewhere. * Lower bound is included, upper bound * is excluded. * For example '123.4' and '1.4e7'. * {number} precision A number between 0 and 16 to round * the digits of the number. * In case of notations 'exponential' and * 'auto', `precision` defines the total * number of significant digits returned * and is undefined by default. * In case of notation 'fixed', * `precision` defines the number of * significant digits after the decimal * point, and is 0 by default. * {Object} exponential An object containing two parameters, * {number} lower and {number} upper, * used by notation 'auto' to determine * when to return exponential notation. * Default values are `lower=1e-3` and * `upper=1e5`. * Only applicable for notation `auto`. * {Function} fn A custom formatting function. Can be used to override the * built-in notations. Function `fn` is called with `value` as * parameter and must return a string. Is useful for example to * format all values inside a matrix in a particular way. * * Examples: * * format(6.4); // '6.4' * format(1240000); // '1.24e6' * format(1/3); // '0.3333333333333333' * format(1/3, 3); // '0.333' * format(21385, 2); // '21000' * format(12.071, {notation: 'fixed'}); // '12' * format(2.3, {notation: 'fixed', precision: 2}); // '2.30' * format(52.8, {notation: 'exponential'}); // '5.28e+1' * * @param {BigNumber} value * @param {Object | Function | number} [options] * @return {string} str The formatted value */ exports.format = function (value, options) { if (typeof options === 'function') { // handle format(value, fn) return options(value); } // handle special cases if (!value.isFinite()) { return value.isNaN() ? 'NaN' : value.gt(0) ? 'Infinity' : '-Infinity'; } // default values for options var notation = 'auto'; var precision = undefined; if (options !== undefined) { // determine notation from options if (options.notation) { notation = options.notation; } // determine precision from options if (typeof options === 'number') { precision = options; } else if (options.precision) { precision = options.precision; } } // handle the various notations switch (notation) { case 'fixed': return exports.toFixed(value, precision); case 'exponential': return exports.toExponential(value, precision); case 'auto': // determine lower and upper bound for exponential notation. // TODO: implement support for upper and lower to be BigNumbers themselves var lower = 1e-3; var upper = 1e5; if (options && options.exponential) { if (options.exponential.lower !== undefined) { lower = options.exponential.lower; } if (options.exponential.upper !== undefined) { upper = options.exponential.upper; } } // adjust the configuration of the BigNumber constructor (yeah, this is quite tricky...) var oldConfig = { toExpNeg: value.constructor.toExpNeg, toExpPos: value.constructor.toExpPos }; value.constructor.config({ toExpNeg: Math.round(Math.log(lower) / Math.LN10), toExpPos: Math.round(Math.log(upper) / Math.LN10) }); // handle special case zero if (value.isZero()) return '0'; // determine whether or not to output exponential notation var str; var abs = value.abs(); if (abs.gte(lower) && abs.lt(upper)) { // normal number notation str = value.toSignificantDigits(precision).toFixed(); } else { // exponential notation str = exports.toExponential(value, precision); } // remove trailing zeros after the decimal point return str.replace(/((\.\d*?)(0+))($|e)/, function () { var digits = arguments[2]; var e = arguments[4]; return digits !== '.' ? digits + e : e; }); default: throw new Error('Unknown notation "' + notation + '". ' + 'Choose "auto", "exponential", or "fixed".'); } }; /** * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3' * @param {BigNumber} value * @param {number} [precision] Number of digits in formatted output. * If not provided, the maximum available digits * is used. * @returns {string} str */ exports.toExponential = function (value, precision) { if (precision !== undefined) { return value.toExponential(precision - 1); // Note the offset of one } else { return value.toExponential(); } }; /** * Format a number with fixed notation. * @param {BigNumber} value * @param {number} [precision=0] Optional number of decimals after the * decimal point. Zero by default. */ exports.toFixed = function (value, precision) { return value.toFixed(precision || 0); // Note: the (precision || 0) is needed as the toFixed of BigNumber has an // undefined default precision instead of 0. }; /***/ }, /* 86 */ /***/ function(module, exports) { 'use strict'; /** * Determine the type of a variable * * type(x) * * The following types are recognized: * * 'undefined' * 'null' * 'boolean' * 'number' * 'string' * 'Array' * 'Function' * 'Date' * 'RegExp' * 'Object' * * @param {*} x * @return {string} Returns the name of the type. Primitive types are lower case, * non-primitive types are upper-camel-case. * For example 'number', 'string', 'Array', 'Date'. */ exports.type = function (x) { var type = typeof x; if (type === 'object') { if (x === null) return 'null'; if (x instanceof Boolean) return 'boolean'; if (x instanceof Number) return 'number'; if (x instanceof String) return 'string'; if (Array.isArray(x)) return 'Array'; if (x instanceof Date) return 'Date'; if (x instanceof RegExp) return 'RegExp'; return 'Object'; } if (type === 'function') return 'Function'; return type; }; /** * Test whether a value is a scalar * @param x * @return {boolean} Returns true when x is a scalar, returns false when * x is a Matrix or Array. */ exports.isScalar = function (x) { return !(x && x.isMatrix || Array.isArray(x)); }; /***/ }, /* 87 */ /***/ function(module, exports) { 'use strict'; /** * Create a range error with the message: * 'Dimension mismatch (<actual size> != <expected size>)' * @param {number | number[]} actual The actual size * @param {number | number[]} expected The expected size * @param {string} [relation='!='] Optional relation between actual * and expected size: '!=', '<', etc. * @extends RangeError */ function DimensionError(actual, expected, relation) { if (!(this instanceof DimensionError)) { throw new SyntaxError('Constructor must be called with the new operator'); } this.actual = actual; this.expected = expected; this.relation = relation; this.message = 'Dimension mismatch (' + (Array.isArray(actual) ? '[' + actual.join(', ') + ']' : actual) + ' ' + (this.relation || '!=') + ' ' + (Array.isArray(expected) ? '[' + expected.join(', ') + ']' : expected) + ')'; this.stack = new Error().stack; } DimensionError.prototype = new RangeError(); DimensionError.prototype.constructor = RangeError; DimensionError.prototype.name = 'DimensionError'; DimensionError.prototype.isDimensionError = true; module.exports = DimensionError; /***/ }, /* 88 */ /***/ function(module, exports) { 'use strict'; /** * Create a range error with the message: * 'Index out of range (index < min)' * 'Index out of range (index < max)' * * @param {number} index The actual index * @param {number} [min=0] Minimum index (included) * @param {number} [max] Maximum index (excluded) * @extends RangeError */ function IndexError(index, min, max) { if (!(this instanceof IndexError)) { throw new SyntaxError('Constructor must be called with the new operator'); } this.index = index; if (arguments.length < 3) { this.min = 0; this.max = min; } else { this.min = min; this.max = max; } if (this.min !== undefined && this.index < this.min) { this.message = 'Index out of range (' + this.index + ' < ' + this.min + ')'; } else if (this.max !== undefined && this.index >= this.max) { this.message = 'Index out of range (' + this.index + ' > ' + (this.max - 1) + ')'; } else { this.message = 'Index out of range (' + this.index + ')'; } this.stack = new Error().stack; } IndexError.prototype = new RangeError(); IndexError.prototype.constructor = RangeError; IndexError.prototype.name = 'IndexError'; IndexError.prototype.isIndexError = true; module.exports = IndexError; /***/ }, /* 89 */ /***/ function(module, exports) { 'use strict'; exports.symbols = { // GREEK LETTERS Alpha: 'A', alpha: '\\alpha', Beta: 'B', beta: '\\beta', Gamma: '\\Gamma', gamma: '\\gamma', Delta: '\\Delta', delta: '\\delta', Epsilon: 'E', epsilon: '\\epsilon', varepsilon: '\\varepsilon', Zeta: 'Z', zeta: '\\zeta', Eta: 'H', eta: '\\eta', Theta: '\\Theta', theta: '\\theta', vartheta: '\\vartheta', Iota: 'I', iota: '\\iota', Kappa: 'K', kappa: '\\kappa', varkappa: '\\varkappa', Lambda: '\\Lambda', lambda: '\\lambda', Mu: 'M', mu: '\\mu', Nu: 'N', nu: '\\nu', Xi: '\\Xi', xi: '\\xi', Omicron: 'O', omicron: 'o', Pi: '\\Pi', pi: '\\pi', varpi: '\\varpi', Rho: 'P', rho: '\\rho', varrho: '\\varrho', Sigma: '\\Sigma', sigma: '\\sigma', varsigma: '\\varsigma', Tau: 'T', tau: '\\tau', Upsilon: '\\Upsilon', upsilon: '\\upsilon', Phi: '\\Phi', phi: '\\phi', varphi: '\\varphi', Chi: 'X', chi: '\\chi', Psi: '\\Psi', psi: '\\psi', Omega: '\\Omega', omega: '\\omega', //logic 'true': '\\mathrm{True}', 'false': '\\mathrm{False}', //other i: 'i', //TODO use \i ?? inf: '\\infty', Inf: '\\infty', infinity: '\\infty', Infinity: '\\infty', oo: '\\infty', lim: '\\lim', 'undefined': '\\mathbf{?}' }; exports.operators = { 'transpose': '^\\top', 'factorial': '!', 'pow': '^', 'dotPow': '.^\\wedge', //TODO find ideal solution 'unaryPlus': '+', 'unaryMinus': '-', 'bitNot': '~', //TODO find ideal solution 'not': '\\neg', 'multiply': '\\cdot', 'divide': '\\frac', //TODO how to handle that properly? 'dotMultiply': '.\\cdot', //TODO find ideal solution 'dotDivide': '.:', //TODO find ideal solution 'mod': '\\mod', 'add': '+', 'subtract': '-', 'to': '\\rightarrow', 'leftShift': '<<', 'rightArithShift': '>>', 'rightLogShift': '>>>', 'equal': '=', 'unequal': '\\neq', 'smaller': '<', 'larger': '>', 'smallerEq': '\\leq', 'largerEq': '\\geq', 'bitAnd': '\\&', 'bitXor': '\\underline{|}', 'bitOr': '|', 'and': '\\wedge', 'xor': '\\veebar', 'or': '\\vee' }; exports.defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)'; var units = { deg: '^\\circ' }; //@param {string} name //@param {boolean} isUnit exports.toSymbol = function (name, isUnit) { isUnit = typeof isUnit === 'undefined' ? false : isUnit; if (isUnit) { if (units.hasOwnProperty(name)) { return units[name]; } return '\\mathrm{' + name + '}'; } if (exports.symbols.hasOwnProperty(name)) { return exports.symbols[name]; } else if (name.indexOf('_') !== -1) { //symbol with index (eg. alpha_1) var index = name.indexOf('_'); return exports.toSymbol(name.substring(0, index)) + '_{' + exports.toSymbol(name.substring(index + 1)) + '}'; } return name; }; /***/ }, /* 90 */ /***/ function(module, exports) { 'use strict'; function factory(type, config, load, typed) { /** * Create a Matrix. The function creates a new `math.type.Matrix` object from * an `Array`. A Matrix has utility functions to manipulate the data in the * matrix, like getting the size and getting or setting values in the matrix. * Supported storage formats are 'dense' and 'sparse'. * * Syntax: * * math.matrix() // creates an empty matrix using default storage format (dense). * math.matrix(data) // creates a matrix with initial data using default storage format (dense). * math.matrix('dense') // creates an empty matrix using the given storage format. * math.matrix(data, 'dense') // creates a matrix with initial data using the given storage format. * math.matrix(data, 'sparse') // creates a sparse matrix with initial data. * math.matrix(data, 'sparse', 'number') // creates a sparse matrix with initial data, number data type. * * Examples: * * var m = math.matrix([[1, 2], [3, 4]]); * m.size(); // Array [2, 2] * m.resize([3, 2], 5); * m.valueOf(); // Array [[1, 2], [3, 4], [5, 5]] * m.get([1, 0]) // number 3 * * See also: * * bignumber, boolean, complex, index, number, string, unit, sparse * * @param {Array | Matrix} [data] A multi dimensional array * @param {string} [format] The Matrix storage format * * @return {Matrix} The created matrix */ var matrix = typed('matrix', { '': function () { return _create([]); }, 'string': function (format) { return _create([], format); }, 'string, string': function (format, datatype) { return _create([], format, datatype); }, 'Array': function (data) { return _create(data); }, 'Matrix': function (data) { return _create(data, data.storage()); }, 'Array | Matrix, string': _create, 'Array | Matrix, string, string': _create }); matrix.toTex = { 0: '\\begin{bmatrix}\\end{bmatrix}', 1: '\\left(${args[0]}\\right)', 2: '\\left(${args[0]}\\right)' }; return matrix; /** * Create a new Matrix with given storage format * @param {Array} data * @param {string} [format] * @param {string} [datatype] * @returns {Matrix} Returns a new Matrix * @private */ function _create(data, format, datatype) { // get storage format constructor var M = type.Matrix.storage(format || 'default'); // create instance return new M(data, datatype); } } exports.name = 'matrix'; exports.factory = factory; /***/ }, /* 91 */ /***/ function(module, exports) { 'use strict'; function factory(type, config, load, typed) { /** * Add two scalar values, `x + y`. * This function is meant for internal use: it is used by the public function * `add` * * This function does not support collections (Array or Matrix), and does * not validate the number of of inputs. * * @param {number | BigNumber | Fraction | Complex | Unit} x First value to add * @param {number | BigNumber | Fraction | Complex} y Second value to add * @return {number | BigNumber | Fraction | Complex | Unit} Sum of `x` and `y` * @private */ var add = typed('add', { 'number, number': function (x, y) { return x + y; }, 'Complex, Complex': function (x, y) { return x.add(y); }, 'BigNumber, BigNumber': function (x, y) { return x.plus(y); }, 'Fraction, Fraction': function (x, y) { return x.add(y); }, 'Unit, Unit': function (x, y) { if (x.value == null) throw new Error('Parameter x contains a unit with undefined value'); if (y.value == null) throw new Error('Parameter y contains a unit with undefined value'); if (!x.equalBase(y)) throw new Error('Units do not match'); var res = x.clone(); res.value = add(res.value, y.value); res.fixPrefix = false; return res; } }); return add; } exports.factory = factory; /***/ }, /* 92 */ /***/ function(module, exports) { 'use strict'; function factory(type, config, load, typed) { /** * Multiply two scalar values, `x * y`. * This function is meant for internal use: it is used by the public function * `multiply` * * This function does not support collections (Array or Matrix), and does * not validate the number of of inputs. * * @param {number | BigNumber | Fraction | Complex | Unit} x First value to multiply * @param {number | BigNumber | Fraction | Complex} y Second value to multiply * @return {number | BigNumber | Fraction | Complex | Unit} Multiplication of `x` and `y` * @private */ var multiplyScalar = typed('multiplyScalar', { 'number, number': function (x, y) { return x * y; }, 'Complex, Complex': function (x, y) { return x.mul(y); }, 'BigNumber, BigNumber': function (x, y) { return x.times(y); }, 'Fraction, Fraction': function (x, y) { return x.mul(y); }, 'number | Fraction | BigNumber | Complex, Unit': function (x, y) { var res = y.clone(); res.value = res.value === null ? res._normalize(x) : multiplyScalar(res.value, x); return res; }, 'Unit, number | Fraction | BigNumber | Complex': function (x, y) { var res = x.clone(); res.value = res.value === null ? res._normalize(y) : multiplyScalar(res.value, y); return res; }, 'Unit, Unit': function (x, y) { return x.multiply(y); } }); return multiplyScalar; } exports.factory = factory; /***/ }, /* 93 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var nearlyEqual = __webpack_require__(72).nearlyEqual; var bigNearlyEqual = __webpack_require__(94); function factory(type, config, load, typed) { /** * Test whether two values are equal. * * @param {number | BigNumber | Fraction | boolean | Complex | Unit} x First value to compare * @param {number | BigNumber | Fraction | boolean | Complex} y Second value to compare * @return {boolean} Returns true when the compared values are equal, else returns false * @private */ var equalScalar = typed('equalScalar', { 'boolean, boolean': function (x, y) { return x === y; }, 'number, number': function (x, y) { return x === y || nearlyEqual(x, y, config.epsilon); }, 'BigNumber, BigNumber': function (x, y) { return x.eq(y) || bigNearlyEqual(x, y, config.epsilon); }, 'Fraction, Fraction': function (x, y) { return x.equals(y); }, 'Complex, Complex': function (x, y) { return x.equals(y); }, 'Unit, Unit': function (x, y) { if (!x.equalBase(y)) { throw new Error('Cannot compare units with different base'); } return equalScalar(x.value, y.value); }, 'string, string': function (x, y) { return x === y; } }); return equalScalar; } exports.factory = factory; /***/ }, /* 94 */ /***/ function(module, exports) { 'use strict'; /** * Compares two BigNumbers. * @param {BigNumber} x First value to compare * @param {BigNumber} y Second value to compare * @param {number} [epsilon] The maximum relative difference between x and y * If epsilon is undefined or null, the function will * test whether x and y are exactly equal. * @return {boolean} whether the two numbers are nearly equal */ module.exports = function nearlyEqual(x, y, epsilon) { // if epsilon is null or undefined, test whether x and y are exactly equal if (epsilon == null) { return x.eq(y); } // use "==" operator, handles infinities if (x.eq(y)) { return true; } // NaN if (x.isNaN() || y.isNaN()) { return false; } // at this point x and y should be finite if (x.isFinite() && y.isFinite()) { // check numbers are very close, needed when comparing numbers near zero var diff = x.minus(y).abs(); if (diff.isZero()) { return true; } else { // use relative error var max = x.constructor.max(x.abs(), y.abs()); return diff.lte(max.times(epsilon)); } } // Infinite and Number or negative Infinite and positive Infinite cases return false; }; /***/ }, /* 95 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; function factory(type, config, load, typed) { var equalScalar = load(__webpack_require__(93)); var SparseMatrix = type.SparseMatrix; /** * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b). * Callback function invoked NZ times (number of nonzero items in S). * * * ┌ f(Sij, b) ; S(i,j) !== 0 * C(i,j) = ┤ * â”” 0 ; otherwise * * * @param {Matrix} s The SparseMatrix instance (S) * @param {Scalar} b The Scalar value * @param {Function} callback The f(Aij,b) operation to invoke * @param {boolean} inverse A true value indicates callback should be invoked f(b,Sij) * * @return {Matrix} SparseMatrix (C) * * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813 */ var algorithm11 = function (s, b, callback, inverse) { // sparse matrix arrays var avalues = s._values; var aindex = s._index; var aptr = s._ptr; var asize = s._size; var adt = s._datatype; // sparse matrix cannot be a Pattern matrix if (!avalues) throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value'); // rows & columns var rows = asize[0]; var columns = asize[1]; // datatype var dt; // equal signature to use var eq = equalScalar; // zero value var zero = 0; // callback signature to use var cf = callback; // process data types if (typeof adt === 'string') { // datatype dt = adt; // find signature that matches (dt, dt) eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype zero = typed.convert(0, dt); // convert b to the same datatype b = typed.convert(b, dt); // callback cf = typed.find(callback, [dt, dt]); } // result arrays var cvalues = []; var cindex = []; var cptr = []; // matrix var c = new SparseMatrix({ values: cvalues, index: cindex, ptr: cptr, size: [rows, columns], datatype: dt }); // loop columns for (var j = 0; j < columns; j++) { // initialize ptr cptr[j] = cindex.length; // values in j for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) { // row var i = aindex[k]; // invoke callback var v = inverse ? cf(b, avalues[k]) : cf(avalues[k], b); // check value is zero if (!eq(v, zero)) { // push index & value cindex.push(i); cvalues.push(v); } } } // update ptr cptr[columns] = cindex.length; // return sparse matrix return c; }; return algorithm11; } exports.name = 'algorithm11'; exports.factory = factory; /***/ }, /* 96 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var clone = __webpack_require__(69).clone; function factory(type, config, load, typed) { var DenseMatrix = type.DenseMatrix; /** * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, b). * Callback function invoked MxN times. * * C(i,j,...z) = f(Aij..z, b) * * @param {Matrix} a The DenseMatrix instance (A) * @param {Scalar} b The Scalar value * @param {Function} callback The f(Aij..z,b) operation to invoke * @param {boolean} inverse A true value indicates callback should be invoked f(b,Aij..z) * * @return {Matrix} DenseMatrix (C) * * https://github.com/josdejong/mathjs/pull/346#issuecomment-97659042 */ var algorithm14 = function (a, b, callback, inverse) { // a arrays var adata = a._data; var asize = a._size; var adt = a._datatype; // datatype var dt; // callback signature to use var cf = callback; // process data types if (typeof adt === 'string') { // datatype dt = adt; // convert b to the same datatype b = typed.convert(b, dt); // callback cf = typed.find(callback, [dt, dt]); } // populate cdata, iterate through dimensions var cdata = asize.length > 0 ? _iterate(cf, 0, asize, asize[0], adata, b, inverse) : []; // c matrix return new DenseMatrix({ data: cdata, size: clone(asize), datatype: dt }); }; // recursive function var _iterate = function (f, level, s, n, av, bv, inverse) { // initialize array for this level var cv = []; // check we reach the last level if (level === s.length - 1) { // loop arrays in last level for (var i = 0; i < n; i++) { // invoke callback and store value cv[i] = inverse ? f(bv, av[i]) : f(av[i], bv); } } else { // iterate current level for (var j = 0; j < n; j++) { // iterate next level cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv, inverse); } } return cv; }; return algorithm14; } exports.name = 'algorithm14'; exports.factory = factory; /***/ }, /* 97 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var isInteger = __webpack_require__(72).isInteger; var size = __webpack_require__(83).size; function factory(type, config, load, typed) { var latex = __webpack_require__(89); var eye = load(__webpack_require__(98)); var multiply = load(__webpack_require__(82)); var matrix = load(__webpack_require__(90)); var fraction = load(__webpack_require__(99)); var number = load(__webpack_require__(100)); /** * Calculates the power of x to y, `x ^ y`. * Matrix exponentiation is supported for square matrices `x`, and positive * integer exponents `y`. * * For cubic roots of negative numbers, the function returns the principal * root by default. In order to let the function return the real root, * math.js can be configured with `math.config({predictable: true})`. * To retrieve all cubic roots of a value, use `math.cbrt(x, true)`. * * Syntax: * * math.pow(x, y) * * Examples: * * math.pow(2, 3); // returns number 8 * * var a = math.complex(2, 3); * math.pow(a, 2) // returns Complex -5 + 12i * * var b = [[1, 2], [4, 3]]; * math.pow(b, 2); // returns Array [[9, 8], [16, 17]] * * See also: * * multiply, sqrt, cbrt, nthRoot * * @param {number | BigNumber | Complex | Array | Matrix} x The base * @param {number | BigNumber | Complex} y The exponent * @return {number | BigNumber | Complex | Array | Matrix} The value of `x` to the power `y` */ var pow = typed('pow', { 'number, number': _pow, 'Complex, Complex': function (x, y) { return x.pow(y); }, 'BigNumber, BigNumber': function (x, y) { if (y.isInteger() || x >= 0 || config.predictable) { return x.pow(y); } else { return new type.Complex(x.toNumber(), 0).pow(y.toNumber(), 0); } }, 'Fraction, Fraction': function (x, y) { if (y.d !== 1) { if (config.predictable) { throw new Error('Function pow does not support non-integer exponents for fractions.'); } else { return _pow(x.valueOf(), y.valueOf()); } } else { return x.pow(y); } }, 'Array, number': _powArray, 'Array, BigNumber': function (x, y) { return _powArray(x, y.toNumber()); }, 'Matrix, number': _powMatrix, 'Matrix, BigNumber': function (x, y) { return _powMatrix(x, y.toNumber()); }, 'Unit, number': function (x, y) { return x.pow(y); } }); /** * Calculates the power of x to y, x^y, for two numbers. * @param {number} x * @param {number} y * @return {number | Complex} res * @private */ function _pow(x, y) { // Alternatively could define a 'realmode' config option or something, but // 'predictable' will work for now if (config.predictable && !isInteger(y) && x < 0) { // Check to see if y can be represented as a fraction try { var yFrac = fraction(y); var yNum = number(yFrac); if (y === yNum || Math.abs((y - yNum) / y) < 1e-14) { if (yFrac.d % 2 === 1) { return (yFrac.n % 2 === 0 ? 1 : -1) * Math.pow(-x, y); } } } catch (ex) {} // fraction() throws an error if y is Infinity, etc. // Unable to express y as a fraction, so continue on } if (isInteger(y) || x >= 0 || config.predictable) { return Math.pow(x, y); } else { return new type.Complex(x, 0).pow(y, 0); } } /** * Calculate the power of a 2d array * @param {Array} x must be a 2 dimensional, square matrix * @param {number} y a positive, integer value * @returns {Array} * @private */ function _powArray(x, y) { if (!isInteger(y) || y < 0) { throw new TypeError('For A^b, b must be a positive integer (value is ' + y + ')'); } // verify that A is a 2 dimensional square matrix var s = size(x); if (s.length != 2) { throw new Error('For A^b, A must be 2 dimensional (A has ' + s.length + ' dimensions)'); } if (s[0] != s[1]) { throw new Error('For A^b, A must be square (size is ' + s[0] + 'x' + s[1] + ')'); } var res = eye(s[0]).valueOf(); var px = x; while (y >= 1) { if ((y & 1) == 1) { res = multiply(px, res); } y >>= 1; px = multiply(px, px); } return res; } /** * Calculate the power of a 2d matrix * @param {Matrix} x must be a 2 dimensional, square matrix * @param {number} y a positive, integer value * @returns {Matrix} * @private */ function _powMatrix(x, y) { return matrix(_powArray(x.valueOf(), y)); } pow.toTex = { 2: '\\left(${args[0]}\\right)' + latex.operators['pow'] + '{${args[1]}}' }; return pow; } exports.name = 'pow'; exports.factory = factory; /***/ }, /* 98 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var array = __webpack_require__(83); var isInteger = __webpack_require__(72).isInteger; function factory(type, config, load, typed) { var matrix = load(__webpack_require__(90)); /** * Create a 2-dimensional identity matrix with size m x n or n x n. * The matrix has ones on the diagonal and zeros elsewhere. * * Syntax: * * math.eye(n) * math.eye(n, format) * math.eye(m, n) * math.eye(m, n, format) * math.eye([m, n]) * math.eye([m, n], format) * * Examples: * * math.eye(3); // returns [[1, 0, 0], [0, 1, 0], [0, 0, 1]] * math.eye(3, 2); // returns [[1, 0], [0, 1], [0, 0]] * * var A = [[1, 2, 3], [4, 5, 6]]; * math.eye(math.size(A)); // returns [[1, 0, 0], [0, 1, 0]] * * See also: * * diag, ones, zeros, size, range * * @param {...number | Matrix | Array} size The size for the matrix * @param {string} [format] The Matrix storage format * * @return {Matrix | Array | number} A matrix with ones on the diagonal. */ var eye = typed('eye', { '': function () { return config.matrix === 'Matrix' ? matrix([]) : []; }, 'string': function (format) { return matrix(format); }, 'number | BigNumber': function (rows) { return _eye(rows, rows, config.matrix === 'Matrix' ? 'default' : undefined); }, 'number | BigNumber, string': function (rows, format) { return _eye(rows, rows, format); }, 'number | BigNumber, number | BigNumber': function (rows, cols) { return _eye(rows, cols, config.matrix === 'Matrix' ? 'default' : undefined); }, 'number | BigNumber, number | BigNumber, string': function (rows, cols, format) { return _eye(rows, cols, format); }, 'Array': function (size) { return _eyeVector(size); }, 'Array, string': function (size, format) { return _eyeVector(size, format); }, 'Matrix': function (size) { return _eyeVector(size.valueOf(), size.storage()); }, 'Matrix, string': function (size, format) { return _eyeVector(size.valueOf(), format); } }); eye.toTex = undefined; // use default template return eye; function _eyeVector(size, format) { switch (size.length) { case 0: return format ? matrix(format) : []; case 1: return _eye(size[0], size[0], format); case 2: return _eye(size[0], size[1], format); default: throw new Error('Vector containing two values expected'); } } /** * Create an identity matrix * @param {number | BigNumber} rows * @param {number | BigNumber} cols * @param {string} [format] * @returns {Matrix} * @private */ function _eye(rows, cols, format) { // BigNumber constructor with the right precision var Big = rows && rows.isBigNumber === true ? type.BigNumber : cols && cols.isBigNumber === true ? type.BigNumber : null; if (rows && rows.isBigNumber === true) rows = rows.toNumber(); if (cols && cols.isBigNumber === true) cols = cols.toNumber(); if (!isInteger(rows) || rows < 1) { throw new Error('Parameters in function eye must be positive integers'); } if (!isInteger(cols) || cols < 1) { throw new Error('Parameters in function eye must be positive integers'); } var one = Big ? new type.BigNumber(1) : 1; var defaultValue = Big ? new Big(0) : 0; var size = [rows, cols]; // check we need to return a matrix if (format) { // get matrix storage constructor var F = type.Matrix.storage(format); // create diagonal matrix (use optimized implementation for storage format) return F.diagonal(size, one, 0, defaultValue); } // create and resize array var res = array.resize([], size, defaultValue); // fill in ones on the diagonal var minimum = rows < cols ? rows : cols; // fill diagonal for (var d = 0; d < minimum; d++) { res[d][d] = one; } return res; } } exports.name = 'eye'; exports.factory = factory; /***/ }, /* 99 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var deepMap = __webpack_require__(80); function factory(type, config, load, typed) { /** * Create a fraction convert a value to a fraction. * * Syntax: * math.fraction(numerator, denominator) * math.fraction({n: numerator, d: denominator}) * math.fraction(matrix: Array | Matrix) Turn all matrix entries * into fractions * * Examples: * * math.fraction(1, 3); * math.fraction('2/3'); * math.fraction({n: 2, d: 3}); * math.fraction([0.2, 0.25, 1.25]); * * See also: * * bignumber, number, string, unit * * @param {number | string | Fraction | BigNumber | Array | Matrix} [args] * Arguments specifying the numerator and denominator of * the fraction * @return {Fraction | Array | Matrix} Returns a fraction */ var fraction = typed('fraction', { 'number': function (x) { if (!isFinite(x) || isNaN(x)) { throw new Error(x + ' cannot be represented as a fraction'); } return new type.Fraction(x); }, 'string': function (x) { return new type.Fraction(x); }, 'number, number': function (numerator, denominator) { return new type.Fraction(numerator, denominator); }, 'BigNumber': function (x) { return new type.Fraction(x.toString()); }, 'Fraction': function (x) { return x; // fractions are immutable }, 'Object': function (x) { return new type.Fraction(x); }, 'Array | Matrix': function (x) { return deepMap(x, fraction); } }); return fraction; } exports.name = 'fraction'; exports.factory = factory; /***/ }, /* 100 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var deepMap = __webpack_require__(80); function factory(type, config, load, typed) { /** * Create a number or convert a string, boolean, or unit to a number. * When value is a matrix, all elements will be converted to number. * * Syntax: * * math.number(value) * math.number(unit, valuelessUnit) * * Examples: * * math.number(2); // returns number 2 * math.number('7.2'); // returns number 7.2 * math.number(true); // returns number 1 * math.number([true, false, true, true]); // returns [1, 0, 1, 1] * math.number(math.unit('52cm'), 'm'); // returns 0.52 * * See also: * * bignumber, boolean, complex, index, matrix, string, unit * * @param {string | number | BigNumber | Fraction | boolean | Array | Matrix | Unit | null} [value] Value to be converted * @param {Unit | string} [valuelessUnit] A valueless unit, used to convert a unit to a number * @return {number | Array | Matrix} The created number */ var number = typed('number', { '': function () { return 0; }, 'number': function (x) { return x; }, 'string': function (x) { var num = Number(x); if (isNaN(num)) { throw new SyntaxError('String "' + x + '" is no valid number'); } return num; }, 'BigNumber': function (x) { return x.toNumber(); }, 'Fraction': function (x) { return x.valueOf(); }, 'Unit': function (x) { throw new Error('Second argument with valueless unit expected'); }, 'Unit, string | Unit': function (unit, valuelessUnit) { return unit.toNumber(valuelessUnit); }, 'Array | Matrix': function (x) { return deepMap(x, number); } }); number.toTex = { 0: '0', 1: '\\left(${args[0]}\\right)', 2: '\\left(\\left(${args[0]}\\right)${args[1]}\\right)' }; return number; } exports.name = 'number'; exports.factory = factory; /***/ }, /* 101 */ /***/ function(module, exports) { module.exports = function get_previous_zoom(params) { var prev_zoom = {}; var inst_trans = d3.select(params.root + ' .clust_group').attr('transform'); if (inst_trans != null) { // prevent from crashing if no scaling was done if (inst_trans.indexOf('scale') > 0) { prev_zoom.zoom_x = parseFloat(inst_trans.split('scale')[1].replace('(', '').replace(')', '').split(',')[0]); prev_zoom.zoom_y = parseFloat(inst_trans.split('scale')[1].replace('(', '').replace(')', '').split(',')[1]); } else { prev_zoom.zoom_x = 1; prev_zoom.zoom_y = 1; } } else { prev_zoom.zoom_x = 1; prev_zoom.zoom_y = 1; } return prev_zoom; }; /***/ }, /* 102 */ /***/ function(module, exports, __webpack_require__) { var d3_tip_custom = __webpack_require__(48); module.exports = function make_row_tooltips(params) { if (params.labels.show_label_tooltips) { // remove old tooltips d3.selectAll(params.viz.root_tips + '_row_tip').remove(); var root_tip_selector = params.viz.root_tips.replace('.', ''); // d3-tooltip var row_tip = d3_tip_custom().attr('class', function () { var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_tip'; return class_string; }).direction('e').offset([0, 10]).style('display', 'none').html(function (d) { var inst_name = d.name.replace(/_/g, ' ').split('#')[0]; return "<span>" + inst_name + "</span>"; }); d3.select(params.viz.viz_wrapper).select(params.root + ' .row_container').call(row_tip); d3.select(params.root + ' .row_label_zoom_container').selectAll('g').on('mouseover', function (d) { d3.select(params.viz.root_tips + '_row_tip').classed(d.name, true); d3.selectAll(params.viz.root_tips + '_row_tip').style('display', 'block'); d3.select(this).select('text').classed('active', true); row_tip.show(d); if (params.row_tip_callback != null) { params.row_tip_callback(params.viz.root_tips, d); } }).on('mouseout', function mouseout(d) { d3.selectAll(params.viz.root_tips + '_row_tip').style('display', 'none').classed(d.name, false); d3.select(this).select('text').classed('active', false); row_tip.hide(d); }); } else { d3.select(params.root + ' .row_label_zoom_container').selectAll('g').on('mouseover', function () { d3.select(this).select('text').classed('active', true); }).on('mouseout', function mouseout() { d3.select(this).select('text').classed('active', false); }); } }; /***/ }, /* 103 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var add_col_click_hlight = __webpack_require__(104); var col_reorder = __webpack_require__(105); var row_reorder = __webpack_require__(52); var make_col_tooltips = __webpack_require__(109); var col_viz_aid_triangle = __webpack_require__(110); module.exports = function make_col_label_container(cgm, text_delay = 0) { var params = cgm.params; var col_container; var col_nodes = params.network_data.col_nodes; // offset click group column label var x_offset_click = params.viz.x_scale.rangeBand() / 2 + params.viz.border_width.x; // reduce width of rotated rects // make container to pre-position zoomable elements if (d3.select(params.root + ' .col_container').empty()) { col_container = d3.select(params.viz.viz_svg).append('g').attr('class', 'col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')'); // white background rect for col labels col_container.append('rect').attr('fill', params.viz.background_color) //!! prog_colors .attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col).attr('class', 'white_bars'); // col labels col_container.append('g').attr('class', 'col_label_outer_container') // position the outer col label group .attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')').append('g').attr('class', 'col_zoom_container'); } else { col_container = d3.select(params.root + ' .col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')'); // white background rect for col labels col_container.select('.white_bars').attr('fill', params.viz.background_color) //!! prog_colors .attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col); // col labels col_container.select(params.root + ' .col_label_outer_container'); } // add main column label group var col_label_obj = d3.select(params.root + ' .col_zoom_container').selectAll('.col_label_text').data(col_nodes, function (d) { return d.name; }).enter().append('g').attr('class', 'col_label_text').attr('transform', function (d) { var inst_index = d.col_index; return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)'; }); // append group for individual column label var col_label_group = col_label_obj // append new group for rect and label (not white lines) .append('g').attr('class', 'col_label_group') // rotate column labels .attr('transform', 'translate(' + params.viz.x_scale.rangeBand() / 2 + ',' + x_offset_click + ') rotate(45)').on('mouseover', function () { d3.select(this).select('text').classed('active', true); }).on('mouseout', function () { d3.select(this).select('text').classed('active', false); }); // append column value bars if (utils.has(params.network_data.col_nodes[0], 'value')) { col_label_group.append('rect').attr('class', 'col_bars').attr('width', function (d) { var inst_value = 0; if (d.value > 0) { inst_value = params.labels.bar_scale_col(d.value); } return inst_value; }) // rotate labels - reduce width if rotating .attr('height', params.viz.x_scale.rangeBand() * 0.66).style('fill', function (d) { return d.value > 0 ? params.matrix.bar_colors[0] : params.matrix.bar_colors[1]; }).attr('opacity', 0.6); } // add column label col_label_group.append('text').attr('x', 0) // manually tuned .attr('y', params.viz.x_scale.rangeBand() * 0.64).attr('dx', params.viz.border_width.x).attr('text-anchor', 'start').attr('full_name', function (d) { return d.name; }) // original font size .style('font-size', params.labels.default_fs_col + 'px').style('cursor', 'default').text(function (d) { return utils.normal_name(d); }) // .attr('pointer-events','none') .style('opacity', 0).transition().delay(text_delay).duration(text_delay).style('opacity', 1); make_col_tooltips(params); // add triangle under rotated labels col_label_group.append('path').style('stroke-width', 0).attr('d', function () { return col_viz_aid_triangle(params); }).attr('fill', '#eee').style('opacity', 0).transition().delay(text_delay).duration(text_delay).style('opacity', params.viz.triangle_opacity); // add col callback function d3.selectAll(params.root + ' .col_label_text').on('click', function (d) { if (typeof params.click_label == 'function') { params.click_label(d.name, 'col'); add_col_click_hlight(params, this, d.ini); } else { if (params.tile_click_hlight) { add_col_click_hlight(params, this, d.ini); } } }).on('dblclick', function (d) { var data_attr = '__data__'; var col_name = this[data_attr].name; if (params.sim_mat) { col_reorder(cgm, this, col_name); var row_selection = d3.selectAll(params.root + ' .row_label_group').filter(function (d) { return d.name == col_name; })[0][0]; row_reorder(cgm, row_selection, col_name); } else { col_reorder(cgm, this, col_name); } if (params.tile_click_hlight) { add_col_click_hlight(params, this, d.ini); } }); }; /***/ }, /* 104 */ /***/ function(module, exports) { module.exports = function (params, clicked_col, id_clicked_col) { if (id_clicked_col != params.click_hlight_col) { params.click_hlight_col = id_clicked_col; var rel_width_hlight = 6; var opacity_hlight = 0.85; var hlight_width = rel_width_hlight * params.viz.border_width.x; d3.selectAll(params.root + ' .click_hlight').remove(); // // highlight selected column // /////////////////////////////// // // unhilight and unbold all columns (already unbolded earlier) // d3.selectAll('.col_label_text') // .select('rect') // .style('opacity', 0); // // highlight column name // d3.select(clicked_col) // .select('rect') // .style('opacity', 1); d3.select(clicked_col).append('rect').classed('click_hlight', true).classed('col_top_hlight', true).attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () { var tmp_translate_y = 0; var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin); return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')'; }); d3.select(clicked_col).append('rect').classed('click_hlight', true).classed('col_bottom_hlight', true).attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () { // reverse x and y since rotated var tmp_translate_y = params.viz.x_scale.rangeBand() - hlight_width; var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin); return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')'; }); } else { d3.selectAll(params.root + ' .click_hlight').remove(); params.click_hlight_col = -666; } }; /***/ }, /* 105 */ /***/ function(module, exports, __webpack_require__) { // var utils = require('../Utils_clust'); var reposition_tile_highlight = __webpack_require__(53); var toggle_dendro_view = __webpack_require__(54); var show_visible_area = __webpack_require__(106); var ini_zoom_info = __webpack_require__(36); var get_previous_zoom = __webpack_require__(101); var calc_downsampled_levels = __webpack_require__(27); module.exports = function col_reorder(cgm, col_selection, inst_term) { var params = cgm.params; var prev_zoom = get_previous_zoom(params); if (prev_zoom.zoom_y === 1 && prev_zoom.zoom_x === 1) { params.viz.inst_order.col = 'custom'; toggle_dendro_view(cgm, 'col'); d3.selectAll(params.root + ' .toggle_row_order .btn').classed('active', false); params.viz.run_trans = true; var mat = $.extend(true, {}, params.matrix.matrix); var row_nodes = params.network_data.row_nodes; var col_nodes = params.network_data.col_nodes; // find the column number of col_selection term from col_nodes // gather column node names var tmp_arr = []; col_nodes.forEach(function (node) { tmp_arr.push(node.name); }); // find index var inst_col = _.indexOf(tmp_arr, inst_term); // gather the values of the input genes tmp_arr = []; row_nodes.forEach(function (node, index) { tmp_arr.push(mat[index].row_data[inst_col].value); }); // sort the cols var tmp_sort = d3.range(tmp_arr.length).sort(function (a, b) { return tmp_arr[b] - tmp_arr[a]; }); // resort rows (rows are reorderd by double clicking a col) params.viz.y_scale.domain(tmp_sort); // save to custom row order params.matrix.orders.custom_col = tmp_sort; var t; var row_nodes_names = params.network_data.row_nodes_names; // reorder if (params.network_data.links.length > params.matrix.def_large_matrix) { t = d3.select(params.root + ' .viz_svg'); } else { t = d3.select(params.root + ' .viz_svg').transition().duration(2500); } // reorder row_label_triangle groups t.selectAll('.row_cat_group').attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }); // Move Row Labels t.select('.row_label_zoom_container').selectAll('.row_label_group').attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }); // only update matri if not downsampled if (params.viz.ds_level === -1) { // reorder matrix rows t.selectAll('.row').attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }); } // highlight selected column /////////////////////////////// // unhilight and unbold all columns (already unbolded earlier) d3.selectAll(params.root + ' .col_label_text').select('.highlight_rect').style('opacity', 0); // highlight column name d3.select(col_selection).select('.highlight_rect').style('opacity', 1); // redefine x and y positions params.network_data.links.forEach(function (d) { d.x = params.viz.x_scale(d.target); d.y = params.viz.y_scale(d.source); }); reposition_tile_highlight(params); params.zoom_info = ini_zoom_info(); setTimeout(function () { params.viz.run_trans = false; }, 2500); // calculate downsmapling if necessary if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) { calc_downsampled_levels(params); var zooming_stopped = true; var zooming_out = true; var make_all_rows = true; // show_visible_area is also run with two_translate_zoom, but at that point // the parameters were not updated and two_translate_zoom if only run // if needed to reset zoom show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows); } } }; /***/ }, /* 106 */ /***/ function(module, exports, __webpack_require__) { var find_viz_rows = __webpack_require__(107); var make_matrix_rows = __webpack_require__(41); var make_row_labels = __webpack_require__(50); var make_row_visual_aid_triangles = __webpack_require__(108); module.exports = function show_visible_area(cgm, zooming_stopped = false, zooming_out = false, make_all_rows = false) { // console.log('show_visible_area stopped: ' + String(zooming_stopped)); var params = cgm.params; var zoom_info = params.zoom_info; // update ds_level if necessary ////////////////////////////////////////////// var check_ds_level = params.viz.ds_level; var old_ds_level = params.viz.ds_level; // toggle the downsampling level (if necessary) if (params.viz.ds === null) { check_ds_level = -1; } else { check_ds_level = Math.floor(Math.log(zoom_info.zoom_y) / Math.log(params.viz.ds_zt)); if (check_ds_level > params.viz.ds_num_levels - 1) { check_ds_level = -1; } } // check if override_ds is necessary ////////////////////////////////////////////// // force update of view if moving to more coarse view var override_ds = false; if (old_ds_level == -1) { // transitioning to more coarse downsampling view (from real data) if (check_ds_level >= 0) { override_ds = true; } } else { // transitioning to more coarse downsampling view if (check_ds_level < old_ds_level) { override_ds = true; } } // update level if zooming has stopped or if transitioning to more coarse view var new_ds_level; if (zooming_stopped === true || override_ds === true) { // update new_ds_level if necessary (if decreasing detail, zooming out) new_ds_level = check_ds_level; // set zooming_stopped to true in case of override_ds zooming_stopped = true; params.viz.ds_level = new_ds_level; } else { // keep the old level (zooming is still occuring and not zooming out) new_ds_level = old_ds_level; } var viz_area = {}; var buffer_size = 5; // get translation vector absolute values viz_area.min_x = Math.abs(zoom_info.trans_x) / zoom_info.zoom_x - (buffer_size + 1) * params.viz.rect_width; viz_area.min_y = Math.abs(zoom_info.trans_y) / zoom_info.zoom_y - (buffer_size + 1) * params.viz.rect_height; viz_area.max_x = Math.abs(zoom_info.trans_x) / zoom_info.zoom_x + params.viz.clust.dim.width / zoom_info.zoom_x + buffer_size * params.viz.rect_width; viz_area.max_y = Math.abs(zoom_info.trans_y) / zoom_info.zoom_y + params.viz.clust.dim.height / zoom_info.zoom_y + buffer_size * params.viz.rect_height; // generate lists of visible rows/cols find_viz_rows(params, viz_area); var missing_rows; if (make_all_rows === false) { missing_rows = _.difference(params.viz.viz_nodes.row, params.viz.viz_nodes.curr_row); } else { // make all rows (reordering) missing_rows = 'all'; // remove downsampled rows d3.selectAll(params.root + ' .ds' + String(new_ds_level) + '_row').remove(); } if (params.viz.ds != null) { var ds_row_class = '.ds' + String(params.viz.ds_level) + '_row'; d3.selectAll(ds_row_class).style('display', 'block'); } // if downsampling if (new_ds_level >= 0) { // remove old rows d3.selectAll(params.root + ' .row').remove(); // remove tile tooltips and row tooltips d3.selectAll(params.viz.root_tips + '_tile_tip').remove(); d3.selectAll(params.viz.root_tips + '_row_tip').remove(); } // default state for downsampling var inst_matrix; if (new_ds_level < 0) { // set matrix to default matrix inst_matrix = params.matrix.matrix; // make row visual-aid triangles make_row_visual_aid_triangles(params); } else { // set matrix to downsampled matrix inst_matrix = params.matrix.ds_matrix[new_ds_level]; d3.selectAll(params.root + ' .row_cat_group path').remove(); } // also remove row visual aid triangles if zooming out if (zooming_out === true) { d3.selectAll(params.root + ' .row_cat_group path').remove(); } // remove rows and labels that are not visible and change ds_level /* run when zooming has stopped */ if (zooming_stopped === true) { // remove not visible matrix rows if (new_ds_level >= 0) { // remove downsampled rows d3.selectAll(params.root + ' .ds' + String(new_ds_level) + '_row').each(function (d) { if (_.contains(params.viz.viz_nodes.row, d.name) === false) { d3.select(this).remove(); } }); } else { // remove real data rows d3.selectAll(params.root + ' .row').each(function (d) { if (_.contains(params.viz.viz_nodes.row, d.name) === false) { d3.select(this).remove(); } }); } // remove not visible row labels d3.selectAll(params.root + ' .row_label_group').each(function (d) { if (_.contains(params.viz.viz_nodes.row, d.name) === false) { d3.select(this).remove(); } }); // level change if (new_ds_level != old_ds_level) { // console.log('old: ' + String(old_ds_level) + ' new: '+ String(new_ds_level)); // all visible rows are missing at new downsampling level missing_rows = params.viz.viz_nodes.row; // remove old level rows d3.selectAll(params.root + ' .ds' + String(old_ds_level) + '_row').remove(); } } // console.log('missing_rows: ' + String(missing_rows)) // console.log(missing_rows) // only make new matrix_rows if there are missing rows if (missing_rows.length >= 1 || missing_rows === 'all') { make_matrix_rows(params, inst_matrix, missing_rows, new_ds_level); } // only make new row_labels if there are missing row_labels, downsampled, and // not zooming out or zooming has stopped if (new_ds_level === -1) { if (zooming_out === false || zooming_stopped) { // check if labels need to be made /////////////////////////////////// // get the names visible row_labels var visible_row_labels = []; d3.selectAll(params.root + ' .row_label_group').each(function (d) { visible_row_labels.push(d.name); }); // find missing labels var missing_row_labels = _.difference(params.viz.viz_nodes.row, visible_row_labels); // make labels ////////////////////////////////// // only make row labels if there are any missing var addback_thresh = 1; if (missing_row_labels.length > addback_thresh) { make_row_labels(cgm, missing_row_labels); } } } }; /***/ }, /* 107 */ /***/ function(module, exports) { module.exports = function find_viz_rows(params, viz_area) { var should_be_rows = []; var curr_rows = []; // find rows that should be visible var y_trans; // default y_scale (no downsampling) var y_scale = params.viz.y_scale; var ds_level = params.viz.ds_level; var row_names = params.network_data.row_nodes_names; var row_class = '.row'; // if downsampling redefine variables if (ds_level >= 0) { y_scale = params.viz.ds[ds_level].y_scale; row_names = d3.range(params.matrix.ds_matrix[ds_level].length).map(String); row_class = '.ds' + String(ds_level) + '_row'; } // find rows that should be visible for (var i = 0; i < row_names.length; i++) { y_trans = y_scale(i); if (y_trans < viz_area.max_y && y_trans > viz_area.min_y) { should_be_rows.push(row_names[i]); } } // find currently visible rows d3.selectAll(params.root + ' ' + row_class).each(function (d) { curr_rows.push(d.name); }); // nodes that should be visible params.viz.viz_nodes.row = should_be_rows; // nodes that are visible params.viz.viz_nodes.curr_row = curr_rows; }; /***/ }, /* 108 */ /***/ function(module, exports) { module.exports = function make_row_visual_aid_triangles(params) { if (d3.select(params.root + ' .row_cat_group path').empty() === true) { d3.selectAll(params.root + ' .row_cat_group').append('path').attr('d', function () { var origin_x = params.viz.cat_room.symbol_width - 1; var origin_y = 0; var mid_x = 1; var mid_y = params.viz.y_scale.rangeBand() / 2; var final_x = params.viz.cat_room.symbol_width - 1; var final_y = params.viz.y_scale.rangeBand(); var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z'; return output_string; }).attr('fill', '#eee').style('opacity', params.viz.triangle_opacity); } }; /***/ }, /* 109 */ /***/ function(module, exports, __webpack_require__) { var d3_tip_custom = __webpack_require__(48); module.exports = function make_col_tooltips(params) { if (params.labels.show_label_tooltips) { // remove old col tooltips d3.selectAll(params.viz.root_tips + '_col_tip').remove(); // d3-tooltip var col_tip = d3_tip_custom().attr('class', function () { var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_col_tip'; return class_string; }).direction('w').offset([20, 0]).style('display', 'none').html(function (d) { var inst_name = d.name.replace(/_/g, ' ').split('#')[0]; return "<span>" + inst_name + "</span>"; }); d3.select(params.viz.viz_wrapper).select('svg').select(params.root + ' .col_zoom_container').selectAll('.col_label_group').select('text').call(col_tip); d3.select(params.root + ' .col_zoom_container').selectAll('.col_label_group').on('mouseover', function (d) { d3.selectAll(params.viz.root_tips + '_col_tip').style('display', 'block'); col_tip.show(d); if (params.col_tip_callback != null) { params.col_tip_callback(d); } }).on('mouseout', function () { col_tip.hide(this); d3.selectAll(params.viz.root_tips + '_col_tip').style('display', 'none'); }); } }; /***/ }, /* 110 */ /***/ function(module, exports) { module.exports = function col_viz_aid_triangle(params) { // x and y are flipped since its rotated var reduce_rect_width = params.viz.x_scale.rangeBand() * 0.36; var origin_y = -params.viz.border_width.x; var start_x = 0; var final_x = params.viz.x_scale.rangeBand() - reduce_rect_width; var start_y = -(params.viz.x_scale.rangeBand() - reduce_rect_width + params.viz.border_width.x); var final_y = -params.viz.border_width.x; var output_string = 'M ' + origin_y + ',0 L ' + start_y + ',' + start_x + ', L ' + final_y + ',' + final_x + ' Z'; return output_string; }; /***/ }, /* 111 */ /***/ function(module, exports) { module.exports = function (params) { d3.select(params.viz.viz_svg).append('rect').attr('fill', params.viz.background_color).attr('height', params.viz.super_labels.dim.width + 'px').attr('width', '3000px').classed('super_col_bkg', true).classed('white_bars', true).attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.super_labels.margin.top + ')'); d3.select(params.viz.viz_svg).append('text').attr('class', 'super_col').text(params.labels.super.col).attr('text-anchor', 'center').attr('transform', function () { var inst_text_width = d3.select(this)[0][0].getBBox().width; var inst_x = params.viz.clust.dim.width / 2 + params.viz.norm_labels.width.row - inst_text_width / 2; var inst_y = params.viz.super_labels.dim.width; return 'translate(' + inst_x + ',' + inst_y + ')'; }).style('font-size', function () { var inst_font_size = params.labels.super_label_fs * params.labels.super_label_scale; return inst_font_size + 'px'; }).style('font-weight', 300); d3.select(params.viz.viz_svg).append('rect').attr('fill', params.viz.background_color).attr('width', params.viz.super_labels.dim.width + 'px').attr('height', '3000px').classed('super_row_bkg', true).classed('white_bars', true).attr('transform', 'translate(' + params.viz.super_labels.margin.left + ',0)'); // append super title row group - used to separate translation from rotation d3.select(params.viz.viz_svg).append('g').classed('super_row', true).attr('transform', function () { // position in the middle of the clustergram var inst_x = params.viz.super_labels.dim.width; var inst_y = params.viz.clust.dim.height / 2 + params.viz.norm_labels.width.col; return 'translate(' + inst_x + ',' + inst_y + ')'; }); // super row label (rotate the already translated title ) d3.select(params.root + ' .super_row').append('text').text(params.labels.super.row).attr('text-anchor', 'center').attr('transform', function () { var inst_text_width = d3.select(this)[0][0].getBBox().width; var inst_x_offset = inst_text_width / 2 + params.viz.norm_labels.width.col; var inst_offset = 'translate(0,' + inst_x_offset + '), rotate(-90)'; return inst_offset; }).style('font-size', function () { var inst_font_size = params.labels.super_label_fs * params.labels.super_label_scale; return inst_font_size + 'px'; }).style('font-weight', 300) .attr("dy", "1em"); }; /***/ }, /* 112 */ /***/ function(module, exports, __webpack_require__) { var get_cat_title = __webpack_require__(113); var ini_cat_reorder = __webpack_require__(114); var make_row_cat_super_labels = __webpack_require__(122); var make_dendro_crop_buttons = __webpack_require__(60); module.exports = function Spillover(cgm) { var params = cgm.params; var viz = params.viz; // hide spillover from slanted column labels on right side d3.select(viz.root + ' .col_container').append('path').style('stroke-width', '0').attr('d', 'M 0,0 L 1000,-1000, L 1000,0 Z').attr('fill', viz.background_color) //!! prog_colors .attr('class', 'right_slant_triangle').attr('transform', 'translate(' + viz.clust.dim.width + ',' + viz.norm_labels.width.col + ')'); // hide spillover from slanted column labels on left side d3.select(viz.root + ' .col_container').append('path').style('stroke-width', '0').attr('d', 'M 0,0 L 500,-500, L 0,-500 Z').attr('fill', viz.background_color).attr('class', 'left_slant_triangle') // shift left by 1 px to prevent cutting off labels .attr('transform', 'translate(-1,' + viz.norm_labels.width.col + ')'); var rect_height = viz.clust.margin.top + viz.uni_margin / 5; // white rect to cover excess labels d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color) //!! prog_colors .attr('width', viz.clust.margin.left).attr('height', rect_height).attr('class', 'top_left_white'); var inst_height = viz.cat_room.col + 1.5 * viz.uni_margin; // white rect to cover excess labels d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', 2 * viz.clust.dim.width).attr('height', inst_height).attr('class', 'top_right_white').attr('transform', function () { var tmp_left = viz.clust.margin.left + viz.clust.dim.width; var tmp_top = viz.norm_labels.width.col + viz.norm_labels.margin.top - viz.uni_margin; return 'translate(' + tmp_left + ', ' + tmp_top + ')'; }); x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin; y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin; var cat_text_size = 1.15 * viz.cat_room.symbol_width; var cat_super_opacity = 0.65; var extra_y_room = 1.25; // col category super labels if (viz.show_categories.col) { d3.select(viz.viz_svg).selectAll().data(viz.all_cats.col).enter().append('text').classed('col_cat_super', true).style('font-size', cat_text_size + 'px').style('opacity', cat_super_opacity).style('cursor', 'default').attr('transform', function (d) { var inst_cat = parseInt(d.split('-')[1], 10); var inst_y = y_offset + extra_y_room * viz.cat_room.symbol_width * inst_cat; return 'translate(' + x_offset + ',' + inst_y + ')'; }).text(function (d) { return get_cat_title(viz, d, 'col'); }); } // row category super labels make_row_cat_super_labels(cgm); // white border bottom - prevent clustergram from hitting border if (viz.show_dendrogram) { // quick fix to make room for crop buttons y_offset = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin; } else { y_offset = viz.clust.margin.top + viz.clust.dim.height; } var b_spill_container = d3.select(viz.viz_svg).append('g').classed('bottom_spillover_container', true).attr('transform', function () { // shift up enough to show the entire border width return 'translate(0,' + y_offset + ')'; }); b_spill_container.append('rect').attr('class', 'bottom_spillover').attr('fill', viz.background_color) //!! prog_colors .attr('width', viz.svg_dim.width).attr('height', 2 * viz.svg_dim.height); x_offset = viz.clust.margin.left; y_offset = 0; b_spill_container.append('g').classed('col_dendro_icons_container', true).attr('transform', 'translate(' + x_offset + ',' + y_offset + ')').append('g').classed('col_dendro_icons_group', true); make_dendro_crop_buttons(cgm, 'col'); var x_offset = viz.clust.margin.left + viz.clust.dim.width; var y_offset = viz.clust.margin.top + viz.clust.dim.height; var tmp_width = viz.cat_room.col + viz.clust.dim.width; var tmp_height = viz.cat_room.row + 10 * viz.uni_margin; d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () { return 'translate(' + x_offset + ',' + y_offset + ')'; }).classed('white_bars', true).classed('dendro_corner_spillover', true); // hide spillover left top of col dendrogram x_offset = 0; y_offset = viz.clust.margin.top + viz.clust.dim.height; tmp_width = viz.clust.margin.left; tmp_height = viz.clust.dim.height * 10; d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () { return 'translate(' + x_offset + ',' + y_offset + ')'; }).classed('white_bars', true).classed('dendro_col_spillover', true); ini_cat_reorder(cgm); }; /***/ }, /* 113 */ /***/ function(module, exports) { module.exports = function get_cat_title(viz, inst_cat, inst_rc) { var cat_title; // make default title if none is given if (viz.cat_names[inst_rc][inst_cat] === inst_cat) { var inst_num = parseInt(inst_cat.split('-')[1], 10) + 1; // generate placeholder title cat_title = 'Category ' + inst_num; } else { // make real title cat_title = viz.cat_names[inst_rc][inst_cat]; } return cat_title; }; /***/ }, /* 114 */ /***/ function(module, exports, __webpack_require__) { var all_reorder = __webpack_require__(115); module.exports = function ini_cat_reorder(cgm) { /* eslint-disable */ var params = cgm.params; _.each(['row', 'col'], function (inst_rc) { if (params.viz.show_categories[inst_rc]) { d3.selectAll(params.root + ' .' + inst_rc + '_cat_super').on('dblclick', function () { if (params.sim_mat) { inst_rc = 'both'; } d3.selectAll(params.root + ' .toggle_' + inst_rc + '_order .btn').classed('active', false); var order_id = this.__data__.replace('-', '_') + '_index'; if (params.viz.sim_mat) { all_reorder(cgm, order_id, 'row'); all_reorder(cgm, order_id, 'col'); } else { all_reorder(cgm, order_id, inst_rc); } }); } }); }; /***/ }, /* 115 */ /***/ function(module, exports, __webpack_require__) { var toggle_dendro_view = __webpack_require__(54); var show_visible_area = __webpack_require__(106); var ini_zoom_info = __webpack_require__(36); var calc_downsampled_levels = __webpack_require__(27); var two_translate_zoom = __webpack_require__(116); var get_previous_zoom = __webpack_require__(101); module.exports = function (cgm, inst_order, inst_rc) { var params = cgm.params; var prev_zoom = get_previous_zoom(params); var delay_reorder = 0; if (prev_zoom.zoom_y != 1 || prev_zoom.zoom_x != 1) { // reset zoom before reordering two_translate_zoom(cgm, 0, 0, 1); delay_reorder = 1200; } // row/col names are swapped, will improve later var other_rc; if (inst_rc === 'row') { other_rc = 'col'; } else if (inst_rc === 'col') { other_rc = 'row'; } params.viz.run_trans = true; // save order state if (other_rc === 'row') { params.viz.inst_order.row = inst_order; } else if (other_rc === 'col') { params.viz.inst_order.col = inst_order; } if (params.viz.show_dendrogram) { toggle_dendro_view(cgm, inst_rc); } if (other_rc === 'row') { params.viz.x_scale.domain(params.matrix.orders[params.viz.inst_order.row + '_row']); } else if (other_rc == 'col') { params.viz.y_scale.domain(params.matrix.orders[params.viz.inst_order.col + '_col']); } // only animate transition if there are a small number of tiles var t; if (d3.selectAll(params.root + ' .tile')[0].length < params.matrix.def_large_matrix) { t = d3.select(params.root + ' .viz_svg').transition().duration(2500).delay(delay_reorder); } else { t = d3.select(params.root + ' .viz_svg'); } var row_nodes_names = params.network_data.row_nodes_names; var col_nodes_names = params.network_data.col_nodes_names; // only update matrix if not downsampled (otherwise rows are updated) if (params.viz.ds_level === -1) { t.selectAll('.row').attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }).selectAll('.tile').attr('transform', function (d) { return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)'; }); t.selectAll('.tile_up').attr('transform', function (d) { return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)'; }); t.selectAll('.tile_dn').attr('transform', function (d) { return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)'; }); } // Move Row Labels t.select('.row_label_zoom_container').selectAll('.row_label_group').attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }); // Move Col Labels t.select('.col_zoom_container').selectAll('.col_label_text').attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ') rotate(-90)'; }); // reorder row categories t.selectAll('.row_cat_group').attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }); // reorder col_class groups t.selectAll('.col_cat_group').attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ',0)'; }); // redefine x and y positions params.network_data.links.forEach(function (d) { d.x = params.viz.x_scale(d.target); d.y = params.viz.y_scale(d.source); }); params.zoom_info = ini_zoom_info(); // calculate downsmapling if necessary if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) { calc_downsampled_levels(params); var zooming_stopped = true; var zooming_out = true; var make_all_rows = true; // show_visible_area is also run with two_translate_zoom, but at that point // the parameters were not updated and two_translate_zoom if only run // if needed to reset zoom show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows); } setTimeout(function () { params.viz.run_trans = false; }, 2500); }; /***/ }, /* 116 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var label_constrain_and_trim = __webpack_require__(117); var show_visible_area = __webpack_require__(106); var ini_zoom_info = __webpack_require__(36); var toggle_grid_lines = __webpack_require__(121); module.exports = function two_translate_zoom(cgm, pan_dx, pan_dy, fin_zoom) { // console.log('pan_dy: ' + String(pan_dy)) var params = cgm.params; d3.selectAll(params.viz.root_tips).style('display', 'none'); params.zoom_info = ini_zoom_info(); show_visible_area(cgm); // do not allow while transitioning, e.g. reordering if (!params.viz.run_trans) { // define the commonly used variable half_height var half_height = params.viz.clust.dim.height / 2; // y pan room, the pan room has to be less than half_height since // zooming in on a gene that is near the top of the clustergram also causes // panning out of the visible region var y_pan_room = half_height / fin_zoom; // prevent visualization from panning down too much // when zooming into genes near the top of the clustergram if (pan_dy >= half_height - y_pan_room) { // console.log(' prevent visualization from panning down too much') // explanation of panning rules ///////////////////////////////// /* prevent the clustergram from panning down too much if the amount of panning is equal to the half_height then it needs to be reduced effectively, the the visualization needs to be moved up (negative) by some factor of the half-width-of-the-visualization. If there was no zooming involved, then the visualization would be centered first, then panned to center the top term this would require a correction to re-center it. However, because of the zooming the offset is reduced by the zoom factor (this is because the panning is occurring on something that will be zoomed into - this is why the pan_dy value is not scaled in the two translate transformations, but it has to be scaled afterwards to set the translate vector) pan_dy = half_height - (half_height)/fin_zoom if pan_dy is greater than the pan room, then panning has to be restricted start by shifting back up (negative) by half_height/fin_zoom then shift back down by the difference between half_height and pan_dy (so that the top of the clustergram is visible) */ var shift_top_viz = half_height - pan_dy; var shift_up_viz = -half_height / fin_zoom + shift_top_viz; // reduce pan_dy so that the visualization does not get panned to far down pan_dy = pan_dy + shift_up_viz; } // prevent visualization from panning up too much // when zooming into genes at the bottom of the clustergram if (pan_dy < -(half_height - y_pan_room)) { shift_top_viz = half_height + pan_dy; shift_up_viz = half_height / fin_zoom - shift_top_viz; //- move_up_one_row; // reduce pan_dy so that the visualization does not get panned to far down pan_dy = pan_dy + shift_up_viz; } // will improve this !! var zoom_y = fin_zoom; var zoom_x = 1; // search duration - the duration of zooming and panning var search_duration = 700; // center_y var center_y = -(zoom_y - 1) * half_height; // transform clust group //////////////////////////// d3.select(params.root + ' .clust_group').transition().duration(search_duration) // first apply the margin transformation // then zoom, then apply the final transformation .attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')'); // transform row labels d3.select(params.root + ' .row_label_zoom_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')'); // transform row_cat_container // use the offset saved in params, only zoom in the y direction d3.select(params.root + ' .row_cat_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')'); d3.select(params.root + ' .row_dendro_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [params.viz.uni_margin / 2, pan_dy] + ')'); // toggle crop buttons var inst_button_opacity; _.each(['row', 'col'], function (inst_rc) { inst_button_opacity = d3.select(params.root + ' .' + inst_rc + '_dendro_crop_buttons').style('opacity'); d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').style('opacity', 0); setTimeout(show_crop_buttons, 700, inst_rc, inst_button_opacity); }); // transform col labels d3.select(params.root + ' .col_zoom_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + zoom_x + ')' + 'translate(' + [pan_dx, 0] + ')'); // transform col_class d3.select(params.root + ' .col_cat_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')'); d3.select(params.root + ' .col_dendro_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + 1 + ')' + 'translate(' + [pan_dx, params.viz.uni_margin / 2] + ')'); // set y translate: center_y is positive, positive moves the visualization down // the translate vector has the initial margin, the first y centering, and pan_dy // times the scaling zoom_y var net_y_offset = params.viz.clust.margin.top + center_y + pan_dy * zoom_y; var net_x_offset = params.viz.clust.margin.left + pan_dx; // reset the zoom and translate params.zoom_behavior.scale(zoom_y).translate([net_x_offset, net_y_offset]); label_constrain_and_trim(params); // re-size of the highlighting rects ///////////////////////////////////////// if (d3.select(params.root + ' .row_label_zoom_container text').empty() === false) { d3.select(params.root + ' .row_label_zoom_container').each(function () { // get the bounding box of the row label text var bbox = d3.select(this).select('text')[0][0].getBBox(); // use the bounding box to set the size of the rect d3.select(this).select('rect').attr('x', bbox.x * 0.5).attr('y', 0).attr('width', bbox.width * 0.5).attr('height', params.viz.y_scale.rangeBand()).style('fill', 'yellow'); }); } // reset crop button zooming d3.select(params.root + ' .row_dendro_icons_group').attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')'); d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) { var inst_x = params.viz.uni_margin; var inst_y = d.pos_mid; return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, ' + 1 / zoom_y + ')'; }); // console.log('zooming x and y') // console.log(zoom_x) // console.log(zoom_y) // need to improve behavior d3.select(params.root + ' .col_dendro_icons_group').attr('transform', function () { var inst_trans = // 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')'; // + 'translate(' + [pan_dx, pan_dy ] + ')'; return inst_trans; }); d3.select(params.root + ' .col_dendro_icons_group').selectAll('path').attr('transform', function (d) { var inst_x = d.pos_mid; var inst_y = params.viz.uni_margin; // return 'translate('+ inst_x +',' + inst_y + ') ' + 'scale('+1/zoom_x+',1)'; return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1,1)'; }); // column value bars /////////////////////// // reduce the height of the column value bars based on the zoom applied // recalculate the height and divide by the zooming scale // col_label_obj.select('rect') if (utils.has(params.network_data.col_nodes[0], 'value')) { d3.selectAll(params.root + ' .col_bars').attr('width', function (d) { var inst_value = 0; if (d.value > 0) { inst_value = params.labels.bar_scale_col(d.value) / zoom_x; } return inst_value; }); } if (utils.has(params.network_data.row_nodes[0], 'value')) { d3.selectAll(params.root + ' .row_bars').transition().duration(search_duration).attr('width', function (d) { var inst_value = 0; inst_value = params.labels.bar_scale_row(Math.abs(d.value)) / zoom_y; return inst_value; }).attr('x', function (d) { var inst_value = 0; inst_value = -params.labels.bar_scale_row(Math.abs(d.value)) / zoom_y; return inst_value; }); } toggle_grid_lines(params); } function show_crop_buttons(inst_rc, inst_button_opacity) { d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').transition().duration(search_duration).style('opacity', inst_button_opacity); } }; /***/ }, /* 117 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var trim_text = __webpack_require__(118); var constrain_font_size = __webpack_require__(119); module.exports = function label_constrain_and_trim(params) { // console.log('label_constrain_and_trim'); // reset text in rows and columns d3.selectAll(params.root + ' .row_label_group').select('text').text(function (d) { return utils.normal_name(d); }); d3.selectAll(params.root + ' .col_label_text').select('text').text(function (d) { return utils.normal_name(d); }); constrain_font_size(params); d3.selectAll(params.root + ' .row_label_group').each(function () { trim_text(params, this, 'row'); }); d3.selectAll(params.root + ' .col_label_group').each(function () { trim_text(params, this, 'col'); }); }; /***/ }, /* 118 */ /***/ function(module, exports) { module.exports = function (params, inst_selection, inst_rc) { if (d3.select(inst_selection).style('display') != 'none') { // trim text that is longer than the container var inst_zoom; var inst_width; var trimmed_text; var current_num_char; var inst_text; var original_text; var keep_num_char; var i; var max_width = params.viz.norm_labels.width[inst_rc]; if (inst_rc === 'row') { if (params.viz.zoom_ratio.y) { inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.y; } else { inst_zoom = params.zoom_behavior.scale(); } // num_trims = params.labels.row_max_char; } else { if (params.viz.zoom_ratio.x > 1) { inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.x; } else { inst_zoom = params.zoom_behavior.scale(); } // num_trims = params.labels.col_max_char; } var num_trims; d3.select(inst_selection).select('text').each(function (d) { num_trims = d.name.length; }); var tmp_width = d3.select(inst_selection).select('text').node().getBBox().width; inst_width = calc_width(tmp_width, inst_zoom); if (inst_width > max_width) { for (i = 1; i < num_trims; i++) { if (inst_width > max_width) { d3.select(inst_selection).select('text').text(trim); tmp_width = d3.select(inst_selection).select('text').node().getBBox().width; inst_width = calc_width(tmp_width, inst_zoom); } } } else if (inst_width < max_width * 0.75) { for (i = 1; i < num_trims; i++) { if (inst_width < max_width * 0.75) { d3.select(inst_selection).select('text').text(add_back); tmp_width = d3.select(inst_selection).select('text').node().getBBox().width; inst_width = calc_width(tmp_width, inst_zoom); } } } } function trim() { inst_text = d3.select(this).text(); current_num_char = inst_text.length; keep_num_char = current_num_char - 3; trimmed_text = inst_text.substring(0, keep_num_char) + '..'; return trimmed_text; } function add_back(d) { inst_text = d3.select(this).text(); if (inst_text.slice(-2) === '..') { current_num_char = inst_text.length - 2; } else { current_num_char = inst_text.length; } original_text = d.name; keep_num_char = current_num_char + 2; trimmed_text = original_text.substring(0, keep_num_char) + '..'; // if '..' was added to original text if (trimmed_text.length > original_text.length) { trimmed_text = original_text; } return trimmed_text; } function calc_width(tmp_width, inst_zoom) { if (inst_zoom < 1) { inst_width = tmp_width; } else { inst_width = tmp_width * inst_zoom; } return inst_width; } }; /***/ }, /* 119 */ /***/ function(module, exports, __webpack_require__) { var calc_real_font_size = __webpack_require__(120); module.exports = function constrain_font_size(params) { var tmp_font_size = params.labels.default_fs_row; var inst_zoom; var min_font_size = 3; var real_font_size = calc_real_font_size(params); // rows //////////////////////////////////// if (real_font_size.row > min_font_size) { if (real_font_size.row > params.labels.max_allow_fs) { if (params.viz.zoom_ratio.y) { inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.y; } else { inst_zoom = params.zoom_behavior.scale(); } if (inst_zoom < 1) { inst_zoom = 1; } tmp_font_size = params.labels.max_allow_fs / inst_zoom; d3.selectAll(params.root + ' .row_label_group').select('text').style('font-size', tmp_font_size + 'px').attr('y', params.viz.rect_height * 0.5 + tmp_font_size * 0.35); } else { d3.selectAll(params.root + ' .row_label_group').select('text').style('font-size', params.labels.default_fs_row + 'px').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35); } } // columns ////////////////////////////////////// if (real_font_size.col > min_font_size) { if (real_font_size.col > params.labels.max_allow_fs) { if (params.viz.zoom_ratio.x > 1) { inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.x; } else { inst_zoom = params.zoom_behavior.scale(); } if (inst_zoom < 1) { inst_zoom = 1; } tmp_font_size = params.labels.max_allow_fs / inst_zoom; if (tmp_font_size > 0.7 * params.viz.rect_width) { tmp_font_size = 0.7 * params.viz.rect_width; } d3.selectAll(params.root + ' .col_label_text').select('text').style('font-size', tmp_font_size + 'px'); } else { d3.selectAll(params.root + ' .col_label_text').select('text').style('font-size', params.labels.default_fs_col + 'px'); } } }; /***/ }, /* 120 */ /***/ function(module, exports) { module.exports = function calc_real_font_size(params) { var real_font_size = {}; // zoom_switch behavior has to change with zoom_ratio.y if (params.viz.zoom_ratio.x > 1) { real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale(); real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale(); } else { real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale() / params.viz.zoom_ratio.y; real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale(); } return real_font_size; }; /***/ }, /* 121 */ /***/ function(module, exports) { module.exports = function toggle_grid_lines(params) { if (params.zoom_info.zoom_x * params.viz.border_width.x > 1) { d3.selectAll(params.root + ' .vert_lines').select('line').style('display', 'block').style('opacity', 0).transition().style('opacity', 1); } else { d3.selectAll(params.root + ' .vert_lines').select('line').style('display', 'none'); } if (params.zoom_info.zoom_y * params.viz.border_width.y > 1) { d3.selectAll(params.root + ' .horz_lines').select('line').style('display', 'block').style('opacity', 0).transition().style('opacity', 1); } else { d3.selectAll(params.root + ' .horz_lines').select('line').style('display', 'none'); } }; /***/ }, /* 122 */ /***/ function(module, exports, __webpack_require__) { var get_cat_title = __webpack_require__(113); var d3_tip_custom = __webpack_require__(48); module.exports = function make_row_cat_super_labels(cgm) { var params = cgm.params; var viz = params.viz; var extra_x_room = 2.75; if (d3.select(params.root + ' .row_cat_label_container').empty()) { d3.select(cgm.params.viz.viz_svg).append('g').classed('row_cat_label_container', true); // append background section for optional value-bars (e.g. enrichment pvals) d3.select(cgm.params.viz.viz_svg + ' .row_cat_label_container').append('g').classed('row_cat_label_bar_container', true); } var x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin; var y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin; var cat_text_size = 1.15 * viz.cat_room.symbol_width; var cat_super_opacity = 0.65; var extra_y_room = 1.25; d3.select(params.root + ' .row_cat_label_container').attr('transform', function () { x_offset = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.symbol_width + extra_x_room * viz.uni_margin; y_offset = viz.clust.margin.top - viz.uni_margin; return 'translate(' + x_offset + ',' + y_offset + ') rotate(-90)'; }); // clear old categories d3.selectAll(params.root + ' .row_cat_label_container text').remove(); d3.selectAll(params.root + ' .row_cat_selection_bar').remove(); // d3.selectAll(params.root+' .row_cat_label_bar_container rect').remove(); // remove any old row_cat_super tooltips from this visualization d3.selectAll(cgm.params.viz.root_tips + '_row_cat_super').remove(); // d3-tooltip var tmp_y_offset = 50; // viz.clust.margin.top - viz.uni_margin; var tmp_x_offset = -75; var cat_tip = d3_tip_custom().attr('class', function () { var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_cat_super'; return class_string; }).direction('south_custom').offset([tmp_y_offset, tmp_x_offset]).style('display', 'none').style('opacity', 0).html(function (d) { var full_string; var tmp_string = params.network_data.row_nodes[0][d]; if (tmp_string.indexOf('<p>') > -1) { var start_string = tmp_string.split(': ')[0]; var end_string = tmp_string.split('<p>')[1]; full_string = start_string + '<p>' + end_string; } else { full_string = get_cat_title(viz, d, 'row'); } return full_string; }); var unit_length = extra_y_room * viz.cat_room.symbol_width; var bar_width = unit_length * 0.9; // show row label categories even if viewing a simmilarity matrix d3.select(params.root + ' .row_cat_label_container').selectAll().data(viz.all_cats.row).enter().append('text').style('width', '100px').style('height', bar_width + 'px').classed('row_cat_super', true).style('font-size', cat_text_size + 'px').style('opacity', cat_super_opacity).style('cursor', 'default').attr('transform', function (d) { var inst_y = extra_y_room * viz.cat_room.symbol_width * parseInt(d.split('-')[1], 10); return 'translate(0,' + inst_y + ')'; }).text(function (d) { return get_cat_title(viz, d, 'row'); }); // selection bar /////////////////////////////// d3.select(params.root + ' .row_cat_label_container').selectAll().data(viz.all_cats.row).enter().append('rect').classed('row_cat_super', true).classed('row_cat_selection_bar', true).style('height', bar_width + 'px').style('fill', 'green').style('width', '120px').style('opacity', 0).attr('transform', function (d) { var inst_y = unit_length * (parseInt(d.split('-')[1], 10) - 0.75); return 'translate(0,' + inst_y + ')'; }).on('mouseover', function (d) { d3.selectAll(params.viz.root_tips + '_row_cat_super').style('display', 'block').style('opacity', 1); cat_tip.show(d); }).on('mouseout', function () { cat_tip.hide(this); // might not need d3.selectAll('.d3-tip').style('display', 'none'); d3.selectAll(params.viz.root_tips + '_row_cat_super').style('display', 'none').style('opacity', 0); }); // row category super-label mouseover ////////////////////////////////////// if (d3.select(params.root + ' .row_cat_selection_bar').empty() === false) { d3.selectAll(params.root + ' .row_cat_selection_bar').call(cat_tip); } if (_.has(params.network_data, 'row_cat_bars')) { // Enrichrgram title ///////////////////// d3.select(params.root + ' .enr_title').remove(); var enr_title = d3.select(params.root + ' .viz_svg').append('g').classed('enr_title', true).attr('transform', function () { var trans = d3.select(params.root + ' .row_cat_label_container').attr('transform').split('(')[1].split(')')[0]; var x_offset = Number(trans.split(',')[0]) - 10; return 'translate(' + String(x_offset) + ', 0)'; }); enr_title.append('rect').attr('width', params.viz.cat_room.row).attr('height', 25).attr('fill', 'white'); var library_string = params.network_data.enrichrgram_lib.substring(0, 40); enr_title.append('text').attr('transform', 'translate(0, 17)').text(library_string.replace(/_/g, ' ')).style('font-size', '15px').attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif'); // Enrichr bars //////////////////// d3.selectAll(params.root + ' .enrichr_bars').remove(); var bar_height = params.viz.clust.margin.top - 35; var max_score = params.network_data.row_cat_bars[0]; var bar_scale = d3.scale.linear().domain([0, max_score]).range([0, bar_height]); d3.select(params.root + ' .row_cat_label_bar_container').selectAll().data(params.network_data.row_cat_bars).enter().append('rect').classed('enrichr_bars', true).attr('height', bar_width + 'px').attr('fill', 'red').attr('width', function (d) { var bar_length = bar_scale(d); return bar_length + 'px'; }).attr('opacity', 0.4).attr('transform', function (d, i) { var inst_y = unit_length * (i - 0.75); return 'translate(0, ' + inst_y + ')'; }); } }; /***/ }, /* 123 */ /***/ function(module, exports, __webpack_require__) { var resize_viz = __webpack_require__(124); module.exports = function initialize_resizing(cgm) { var params = cgm.params; var exp_button; // d3.select(window).on('resize', null); // // resize window // if (params.viz.resize) { // d3.select(window).on('resize', function () { // d3.select(params.viz.viz_svg).style('opacity', 0.5); // var wait_time = 500; // if (params.viz.run_trans === true) { // wait_time = 2500; // } // setTimeout(resize_viz, wait_time, params); // }); // } // if (params.viz.expand_button) { d3.select(params.root + ' .expand_button').on('click', null); var expand_opacity = 0.4; if (d3.select(params.root + ' .expand_button').empty()) { exp_button = d3.select(params.viz.viz_svg).append('text').attr('class', 'expand_button'); } else { exp_button = d3.select(params.root + ' .expand_button'); } exp_button.attr('text-anchor', 'middle').attr('dominant-baseline', 'central').attr('font-family', 'FontAwesome').attr('font-size', '30px').text(function () { if (params.viz.is_expand === false) { // expand button return '\uf0b2'; } else { // menu button return '\uf0c9'; } }).attr('y', '25px').attr('x', '25px').style('cursor', 'pointer').style('opacity', expand_opacity).on('mouseover', function () { d3.select(this).style('opacity', 0.75); }).on('mouseout', function () { d3.select(this).style('opacity', expand_opacity); }).on('click', function () { // expand view if (params.viz.is_expand === false) { d3.select(this).text(function () { // menu button return '\uf0c9'; }); params.viz.is_expand = true; d3.selectAll(params.root + ' .borders').style('fill', 'white'); // d3.select(params.root+' .footer_section').style('display', 'none'); d3.select(params.root + ' .sidebar_wrapper').style('display', 'none'); // contract view } else { d3.select(this).text(function () { // expand button return '\uf0b2'; }); params.viz.is_expand = false; d3.selectAll(params.root + ' .borders').style('fill', '#eee'); // d3.select(params.root+' .footer_section').style('display', 'block'); d3.select(params.root + ' .viz_wrapper').style('width', '100px'); d3.select(params.root + ' .sidebar_wrapper').style('display', 'block'); } // // resize parent div // set_viz_wrapper_size(params); d3.select(params.viz.viz_svg).style('opacity', 0.5); var wait_time = 500; if (params.viz.run_trans == true) { wait_time = 2500; } setTimeout(resize_viz, wait_time, cgm); }); // } }; /***/ }, /* 124 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var run_zoom = __webpack_require__(125); var ini_doubleclick = __webpack_require__(133); var reset_zoom = __webpack_require__(134); var resize_dendro = __webpack_require__(135); var resize_super_labels = __webpack_require__(136); var resize_spillover = __webpack_require__(137); var resize_borders = __webpack_require__(138); var resize_row_labels = __webpack_require__(139); var resize_highlights = __webpack_require__(140); var resize_row_viz = __webpack_require__(141); var resize_col_labels = __webpack_require__(142); var resize_col_text = __webpack_require__(143); var resize_col_triangle = __webpack_require__(144); var resize_col_hlight = __webpack_require__(145); var recalc_params_for_resize = __webpack_require__(146); var resize_row_tiles = __webpack_require__(147); var resize_label_bars = __webpack_require__(148); var label_constrain_and_trim = __webpack_require__(117); var make_dendro_triangles = __webpack_require__(55); var toggle_dendro_view = __webpack_require__(54); var show_visible_area = __webpack_require__(106); var calc_viz_dimensions = __webpack_require__(18); var position_play_button = __webpack_require__(149); var make_row_cat_super_labels = __webpack_require__(122); var ini_cat_reorder = __webpack_require__(114); var position_svg_dendro_slider = __webpack_require__(150); var ini_zoom_info = __webpack_require__(36); var grid_lines_viz = __webpack_require__(151); module.exports = function resize_viz(cgm) { var params = cgm.params; var cont_dim = calc_viz_dimensions(params); d3.select(params.root + ' .play_button'); // .style('opacity', 0.2); d3.select(params.root + ' .sidebar_wrapper').style('height', cont_dim.height + 'px'); d3.select(params.viz.viz_wrapper) // .style('float', 'left') .style('margin-top', cont_dim.top + 'px').style('width', cont_dim.width + 'px').style('height', cont_dim.height + 'px'); params = recalc_params_for_resize(params); params.zoom_info = ini_zoom_info(); reset_zoom(params); var svg_group = d3.select(params.viz.viz_svg); // redefine x and y positions _.each(params.network_data.links, function (d) { d.x = params.viz.x_scale(d.target); d.y = params.viz.y_scale(d.source); }); // disable zoom while transitioning svg_group.on('.zoom', null); params.zoom_behavior.scaleExtent([1, params.viz.square_zoom * params.viz.zoom_ratio.x]).on('zoom', function () { run_zoom(cgm); }); // reenable zoom after transition if (params.viz.do_zoom) { svg_group.call(params.zoom_behavior); } // prevent normal double click zoom etc ini_doubleclick(cgm); svg_group.attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height); svg_group.select('.super_background').style('width', params.viz.svg_dim.width).style('height', params.viz.svg_dim.height); svg_group.select('.grey_background').attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height); setTimeout(position_play_button, 100, params); var row_nodes = params.network_data.row_nodes; var row_nodes_names = utils.pluck(row_nodes, 'name'); resize_row_tiles(params, svg_group); svg_group.selectAll('.highlighting_rect').attr('width', params.viz.x_scale.rangeBand() * 0.80).attr('height', params.viz.y_scale.rangeBand() * 0.80); resize_highlights(params); // resize row labels /////////////////////////// resize_row_labels(params, svg_group); resize_row_viz(params, svg_group); // change the size of the highlighting rects svg_group.selectAll('.row_label_group').each(function () { var bbox = d3.select(this).select('text')[0][0].getBBox(); d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.rect_height).style('fill', 'yellow').style('opacity', function (d) { var inst_opacity = 0; // highlight target genes if (d.target === 1) { inst_opacity = 1; } return inst_opacity; }); }); // necessary to properly position row labels vertically svg_group.selectAll('.row_label_group').select('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35); if (utils.has(params.network_data.row_nodes[0], 'value')) { resize_label_bars(cgm, svg_group); } svg_group.selectAll('.row_cat_group').attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0, ' + params.viz.y_scale(inst_index) + ')'; }); svg_group.selectAll('.row_cat_group').select('path').attr('d', function () { var origin_x = params.viz.cat_room.symbol_width - 1; var origin_y = 0; var mid_x = 1; var mid_y = params.viz.rect_height / 2; var final_x = params.viz.cat_room.symbol_width - 1; var final_y = params.viz.rect_height; var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z'; return output_string; }); var is_resize = true; if (params.viz.show_dendrogram) { make_dendro_triangles(cgm, 'row', is_resize); make_dendro_triangles(cgm, 'col', is_resize); resize_dendro(params, svg_group); toggle_dendro_view(cgm, 'row', 0); toggle_dendro_view(cgm, 'col', 0); } else { resize_dendro(params, svg_group); } resize_col_labels(params, svg_group); resize_col_text(params, svg_group); resize_col_triangle(params, svg_group); resize_col_hlight(params, svg_group); resize_super_labels(params, svg_group); resize_spillover(params.viz, svg_group); grid_lines_viz(params); resize_borders(params, svg_group); // reset zoom and translate params.zoom_behavior.scale(1).translate([params.viz.clust.margin.left, params.viz.clust.margin.top]); label_constrain_and_trim(params); // reposition matrix d3.select(params.root + ' .clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')'); // removed, this was causing bugs if (cgm.params.viz.ds_level === -1) { show_visible_area(cgm); } make_row_cat_super_labels(cgm); d3.select(params.viz.viz_svg).style('opacity', 1); ini_cat_reorder(cgm); d3.select(cgm.params.root + ' .row_slider_group').style('opacity', 0); d3.select(cgm.params.root + ' .col_slider_group').style('opacity', 0); setTimeout(position_svg_dendro_slider, 500, cgm, 'row'); setTimeout(position_svg_dendro_slider, 500, cgm, 'col'); }; /***/ }, /* 125 */ /***/ function(module, exports, __webpack_require__) { var run_transformation = __webpack_require__(126); var zoom_rules_y = __webpack_require__(131); var zoom_rules_x = __webpack_require__(132); module.exports = function zoomed(cgm) { var params = cgm.params; var zoom_info = {}; zoom_info.zoom_x = d3.event.scale; zoom_info.zoom_y = d3.event.scale; // subtract away the margin to easily calculate pan_room etc. zoom_info.trans_x = params.zoom_behavior.translate()[0] - params.viz.clust.margin.left; zoom_info.trans_y = params.zoom_behavior.translate()[1] - params.viz.clust.margin.top; d3.selectAll(params.viz.root_tips).style('display', 'none'); // transfer zoom_info to params params.zoom_info = zoom_rules_y(params, zoom_info); params.zoom_info = zoom_rules_x(params, zoom_info); // do not run transformation if moving slider if (params.is_slider_drag === false && params.is_cropping === false) { // reset translate vector - add back margins to trans_x and trans_y var new_x = params.zoom_info.trans_x + params.viz.clust.margin.left; var new_y = params.zoom_info.trans_y + params.viz.clust.margin.top; params.zoom_behavior.translate([new_x, new_y]); cgm.params = params; run_transformation(cgm); } }; /***/ }, /* 126 */ /***/ function(module, exports, __webpack_require__) { var constrain_font_size = __webpack_require__(119); var show_visible_area = __webpack_require__(106); var resize_label_val_bars = __webpack_require__(127); var zoom_crop_triangles = __webpack_require__(62); var get_previous_zoom = __webpack_require__(101); var run_when_zoom_stopped = __webpack_require__(128); var check_zoom_stop_status = __webpack_require__(130); module.exports = function run_transformation(cgm) { var params = cgm.params; var zoom_info = params.zoom_info; var prev_zoom = get_previous_zoom(params); d3.select(params.root + ' .clust_group').attr('transform', 'translate(' + [zoom_info.trans_x, zoom_info.trans_y] + ') scale(' + zoom_info.zoom_x + ',' + zoom_info.zoom_y + ')'); d3.select(params.root + ' .row_label_zoom_container').attr('transform', 'translate(' + [0, zoom_info.trans_y] + ') scale(' + zoom_info.zoom_y + ')'); d3.select(params.root + ' .col_zoom_container').attr('transform', 'translate(' + [zoom_info.trans_x, 0] + ') scale(' + zoom_info.zoom_x + ')'); d3.select(params.root + ' .row_cat_container').attr('transform', 'translate(' + [0, zoom_info.trans_y] + ') scale( 1,' + zoom_info.zoom_y + ')'); d3.select(params.root + ' .row_dendro_container').attr('transform', 'translate(' + [params.viz.uni_margin / 2, zoom_info.trans_y] + ') ' + 'scale( 1,' + zoom_info.zoom_y + ')'); d3.select(params.root + ' .row_dendro_icons_group').attr('transform', function () { var inst_y = zoom_info.trans_y; var inst_translate = 'translate(' + [0, inst_y] + ') '; var inst_zoom = 'scale(1, ' + zoom_info.zoom_y + ')'; var transform_string = inst_translate + inst_zoom; return transform_string; }); d3.select(params.root + ' .col_dendro_icons_group').attr('transform', function () { var inst_x = zoom_info.trans_x; var inst_translate = 'translate(' + [inst_x, 0] + ')'; var inst_zoom = 'scale(' + zoom_info.zoom_x + ', 1)'; var transform_string = inst_translate + inst_zoom; return transform_string; }); zoom_crop_triangles(params, zoom_info, 'row'); zoom_crop_triangles(params, zoom_info, 'col'); d3.select(params.root + ' .col_cat_container').attr('transform', 'translate(' + [zoom_info.trans_x, 0] + ') scale(' + zoom_info.zoom_x + ',1)'); d3.select(params.root + ' .col_dendro_container').attr('transform', 'translate(' + [zoom_info.trans_x, params.viz.uni_margin / 2] + ') scale(' + zoom_info.zoom_x + ',1)'); resize_label_val_bars(params, zoom_info); d3.select(params.root + ' .viz_svg').attr('is_zoom', function () { var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom')); d3.select(params.root + ' .viz_svg').attr('stopped_zoom', 1); return inst_zoom + 1; }); // this function runs with a slight delay and tells the visualization that // this particular zoom event is over, reducing the total number of zoom // events that need to finish var not_zooming = function () { d3.select(params.root + ' .viz_svg').attr('is_zoom', function () { var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom')); return inst_zoom - 1; }); }; constrain_font_size(params); if (zoom_info.zoom_y <= prev_zoom.zoom_y) { var zooming_out = false; if (zoom_info.zoom_y < prev_zoom.zoom_y) { zooming_out = true; } // zooming has not stopped and zooming out is true var zooming_stopped = false; show_visible_area(cgm, zooming_stopped, zooming_out); } setTimeout(not_zooming, 50); setTimeout(check_if_zooming_has_stopped, 100, cgm); function check_if_zooming_has_stopped(cgm) { var params = cgm.params; var stop_attributes = check_zoom_stop_status(params); if (stop_attributes === true) { // wait and double check that zooming has stopped setTimeout(run_when_zoom_stopped, 50, cgm); } } }; /***/ }, /* 127 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); module.exports = function resize_label_val_bars(params) { var zoom_info = params.zoom_info; // resize label bars if necessary if (utils.has(params.network_data.row_nodes[0], 'value')) { d3.selectAll(params.root + ' .row_bars').attr('width', function (d) { var inst_value = 0; inst_value = params.labels.bar_scale_row(Math.abs(d.value)) / zoom_info.zoom_y; return inst_value; }).attr('x', function (d) { var inst_value = 0; inst_value = -params.labels.bar_scale_row(Math.abs(d.value)) / zoom_info.zoom_y; return inst_value; }); } if (utils.has(params.network_data.col_nodes[0], 'value')) { d3.selectAll(params.root + ' .col_bars').attr('width', function (d) { var inst_value = 0; if (d.value > 0) { inst_value = params.labels.bar_scale_col(d.value) / zoom_info.zoom_x; } return inst_value; }); } }; /***/ }, /* 128 */ /***/ function(module, exports, __webpack_require__) { var constrain_font_size = __webpack_require__(119); var trim_text = __webpack_require__(118); var num_visible_labels = __webpack_require__(129); var toggle_grid_lines = __webpack_require__(121); var show_visible_area = __webpack_require__(106); var check_zoom_stop_status = __webpack_require__(130); module.exports = function run_when_zoom_stopped(cgm) { var params = cgm.params; var stop_attributes = check_zoom_stop_status(params); if (stop_attributes === true) { // /////////////////////////////////////////////// // // zooming has stopped // /////////////////////////////////////////////// // console.log('\nZOOMING HAS ACTUALLY STOPPED\n============================'); // console.log(params.zoom_info.zoom_y) _.each(['row', 'col'], function (inst_rc) { d3.selectAll(params.root + ' .' + inst_rc + '_label_group').select('text').style('opacity', 1); d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').select('path').style('display', 'block'); }); show_visible_area(cgm, true); d3.selectAll(params.viz.root_tips).style('display', 'block'); d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'none'); d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'block'); d3.select(params.root + ' .viz_svg').attr('stopped_zoom', 0); d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'block'); d3.selectAll(params.root + ' .col_label_group').select('text').style('display', 'block'); toggle_grid_lines(params); // reset x_offset cgm.params.viz.x_offset = 0; var max_labels_to_trim = 150; // probably do not need ///////////////////////// _.each(['row', 'col'], function (inst_rc) { var inst_num_visible = num_visible_labels(params, inst_rc); if (inst_num_visible < max_labels_to_trim) { d3.selectAll(params.root + ' .' + inst_rc + '_label_group').each(function () { trim_text(params, this, inst_rc); }); } }); text_patch(); constrain_font_size(params); // this makes sure that the text is visible after zooming and trimming // there is buggy behavior in chrome when zooming into large matrices // I'm running it twice in quick succession setTimeout(text_patch, 100); } function text_patch() { _.each(['row', 'col'], function (inst_rc) { d3.selectAll(params.root + ' .' + inst_rc + '_label_group').filter(function () { return d3.select(this).style('display') != 'none'; }).select('text').style('font-size', function () { var inst_fs = Number(d3.select(this).style('font-size').replace('px', '')); return inst_fs; }); }); } }; /***/ }, /* 129 */ /***/ function(module, exports) { module.exports = function num_visible_labels(params, inst_rc) { // counting the number of visible labels, probably not necessary var num_visible; if (inst_rc === 'row') { // initialize at high number num_visible = 10000; // only count visible rows if no downsampling if (params.viz.ds_level === -1) { num_visible = d3.selectAll(params.root + ' .row')[0].length; } } else if (inst_rc === 'col') { num_visible = d3.selectAll(params.root + ' .' + inst_rc + '_label_text').filter(function () { return d3.select(this).style('display') != 'none'; })[0].length; } return num_visible; }; /***/ }, /* 130 */ /***/ function(module, exports) { module.exports = function check_zoom_stop_status(params) { var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom')); var check_stop = Number(d3.select(params.root + ' .viz_svg').attr('stopped_zoom')); var stop_attributes = false; if (inst_zoom === 0 && check_stop != 0) { stop_attributes = true; } return stop_attributes; }; /***/ }, /* 131 */ /***/ function(module, exports) { module.exports = function zoom_rules_y(params, zoom_info) { var viz = params.viz; // zoom in the x direction before zooming in the y direction if (viz.zoom_ratio.y > 1) { if (zoom_info.zoom_y < viz.zoom_ratio.y) { zoom_info.trans_y = 0; zoom_info.zoom_y = 1; } else { zoom_info.zoom_y = zoom_info.zoom_y / viz.zoom_ratio.y; } } // calculate panning room available in the y direction zoom_info.pan_room_y = (zoom_info.zoom_y - 1) * viz.clust.dim.height; // console.log( 'pan_room_y: ' + String(zoom_info.pan_room_y) + ' ' + String(-zoom_info.trans_y)) // no positive panning or panning more than pan_room if (zoom_info.trans_y >= 0) { zoom_info.trans_y = 0; // console.log('y no positive panning\n\n') } else if (zoom_info.trans_y <= -zoom_info.pan_room_y) { zoom_info.trans_y = -zoom_info.pan_room_y; // console.log('y restrict pan room \n\n') } return zoom_info; }; /***/ }, /* 132 */ /***/ function(module, exports) { module.exports = function zoom_rules_x(params, zoom_info) { var viz = params.viz; // zoom in the y direction before zooming in the x direction if (viz.zoom_ratio.x > 1) { if (zoom_info.zoom_x < viz.zoom_ratio.x) { // remove this // zoom_info.trans_x = - params.viz.clust.margin.left; zoom_info.zoom_x = 1; } else { zoom_info.zoom_x = zoom_info.zoom_x / viz.zoom_ratio.x; // console.log('********* zoom_x: ' + String(zoom_info.zoom_x)) // zoom_info.trans_x = zoom_info.trans_x + params.viz.x_offset; // zoom_info.trans_x = zoom_info.trans_x * (params.zoom_info.zoom_x/params.zoom_info.zoom_y); } } // calculate panning room available in the x direction zoom_info.pan_room_x = (zoom_info.zoom_x - 1) * viz.clust.dim.width; // console.log( 'pan_room_x: ' + String(zoom_info.pan_room_x) + ' trans_x: ' + String(-zoom_info.trans_x)) // no positive panning or panning more than pan_room if (zoom_info.trans_x > 0) { zoom_info.trans_x = 0; // console.log('no positive panning\n\n') } else if (zoom_info.trans_x <= -zoom_info.pan_room_x) { zoom_info.trans_x = -zoom_info.pan_room_x; // console.log('******* restrict pan room\n\n') } return zoom_info; }; /***/ }, /* 133 */ /***/ function(module, exports, __webpack_require__) { var two_translate_zoom = __webpack_require__(116); module.exports = function ini_doubleclick(cgm) { var params = cgm.params; // disable double-click zoom d3.selectAll(params.viz.zoom_element).on('dblclick.zoom', null); d3.select(params.viz.zoom_element).on('dblclick', function () { two_translate_zoom(cgm, 0, 0, 1); }); }; /***/ }, /* 134 */ /***/ function(module, exports) { module.exports = function (params) { // reset zoom ////////////////////////////// var zoom_y = 1; // var zoom_x = 1; var pan_dx = 0; var pan_dy = 0; var half_height = params.viz.clust.dim.height / 2; var center_y = -(zoom_y - 1) * half_height; d3.select(params.root + ' .clust_group').attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')'); d3.select(params.root + ' .row_label_zoom_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')'); d3.select(params.root + ' .row_cat_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')'); d3.select(params.root + ' .row_dendro_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [params.viz.uni_margin / 2, pan_dy] + ')'); d3.select(params.root + ' .col_zoom_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')'); d3.select(params.root + ' .col_cat_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')'); d3.select(params.root + ' .col_dendro_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, params.viz.uni_margin / 2] + ')'); // reset crop button zooming d3.select(params.root + ' .row_dendro_icons_group').attr('transform', function () { return 'translate(0,0) scale(1)'; }); d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) { var inst_x = 7; var inst_y = d.pos_mid; return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, 1)'; }); }; /***/ }, /* 135 */ /***/ function(module, exports) { module.exports = function resize_dendro(params, svg_group, delay_info = false) { // resize dendrogram /////////////////// var delays = {}; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } var duration = params.viz.duration; var col_nodes = params.network_data.col_nodes; var col_nodes_names = params.network_data.col_nodes_names; var dendro_group; if (delays.run_transition) { dendro_group = svg_group.transition().delay(delays.update).duration(duration); svg_group.selectAll('.col_cat_group') // data binding needed for loss/gain of columns .data(col_nodes, function (d) { return d.name; }).transition().delay(delays.update).duration(duration).attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ',0)'; }); svg_group.selectAll('.col_dendro_group') // data binding needed for loss/gain of columns .data(col_nodes, function (d) { return d.name; }).transition().delay(delays.update).duration(duration).attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ',0)'; }); } else { dendro_group = svg_group; svg_group.selectAll('.col_cat_group') // data binding needed for loss/gain of columns .data(col_nodes, function (d) { return d.name; }).attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ',0)'; }); d3.select(params.root).selectAll('.col_dendro_group') // data binding needed for loss/gain of columns .data(col_nodes, function (d) { return d.name; }).attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ',0)'; }); } var i; var inst_class; _.each(['row', 'col'], function (inst_rc) { var num_cats = params.viz.all_cats[inst_rc].length; for (i = 0; i < num_cats; i++) { inst_class = '.' + inst_rc + '_cat_rect_' + String(i); if (inst_rc === 'row') { dendro_group.selectAll(inst_class).attr('height', params.viz.y_scale.rangeBand()); } else { dendro_group.selectAll(inst_class).attr('width', params.viz.x_scale.rangeBand()); } } }); // position row_dendro_outer_container var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width; var y_offset = params.viz.clust.margin.top; var spillover_width = params.viz.dendro_room.row + params.viz.uni_margin; d3.select(params.root + ' .viz_svg').select('row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')'); d3.select(params.root + ' .row_dendro_outer_container').select('.row_dendro_spillover').attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height); x_offset = params.viz.clust.margin.left; y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height; var spillover_height = params.viz.dendro_room.col + params.viz.uni_margin; d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover').attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px'); d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover_top').attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,' + params.viz.dendro_room.col + ')'); x_offset = params.viz.clust.margin.left; y_offset = 0; d3.select(params.root + ' .col_dendro_icons_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')'); }; /***/ }, /* 136 */ /***/ function(module, exports) { module.exports = function resize_super_labels(params, ini_svg_group, delay_info = false) { var delays = {}; var duration = params.viz.duration; var svg_group; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } if (delays.run_transition) { svg_group = ini_svg_group.transition().delay(delays.update).duration(duration); } else { svg_group = ini_svg_group; } svg_group.select('.super_col_bkg').attr('height', params.viz.super_labels.dim.width + 'px').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.grey_border_width + ')'); // super col title svg_group.select('.super_col').attr('transform', function () { var inst_x = params.viz.clust.dim.width / 2 + params.viz.norm_labels.width.row; var inst_y = params.viz.super_labels.dim.width; return 'translate(' + inst_x + ',' + inst_y + ')'; }); svg_group.select('.super_row_bkg').attr('width', params.viz.super_labels.dim.width + 'px').attr('transform', 'translate(' + params.viz.grey_border_width + ',0)'); svg_group.select('.super_row').attr('transform', function () { var inst_x = params.viz.super_labels.dim.width; var inst_y = params.viz.clust.dim.height / 2 + params.viz.norm_labels.width.col; return 'translate(' + inst_x + ',' + inst_y + ')'; }); }; /***/ }, /* 137 */ /***/ function(module, exports) { module.exports = function resize_spillover(viz, ini_svg_group, delay_info = false) { var delays = {}; var duration = viz.duration; var svg_group; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } if (delays.run_transition) { svg_group = ini_svg_group.transition().delay(delays.update).duration(duration); } else { svg_group = ini_svg_group; } svg_group.select(viz.root + ' .right_slant_triangle').attr('transform', 'translate(' + viz.clust.dim.width + ',' + viz.norm_labels.width.col + ')'); svg_group.select(viz.root + ' .left_slant_triangle').attr('transform', 'translate(-1,' + viz.norm_labels.width.col + ')'); var rect_height = viz.clust.margin.top + viz.uni_margin / 5; svg_group.select(viz.root + ' .top_left_white').attr('width', viz.clust.margin.left).attr('height', rect_height); var tmp_left = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin + viz.dendro_room.row; var tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col; svg_group.select(viz.root + ' .right_spillover_container').attr('transform', function () { return 'translate(' + tmp_left + ', 0)'; }); tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col; svg_group.select(viz.root + ' .right_spillover_container rect').attr('transform', function () { return 'translate( 0,' + tmp_top + ')'; }); svg_group.select(viz.root + ' .right_spillover').attr('height', viz.svg_dim.height + 'px'); // resize dendro spillovers var x_offset = viz.clust.margin.left + viz.clust.dim.width; var y_offset = tmp_top; var tmp_width = viz.dendro_room.row + viz.uni_margin; var tmp_height = viz.cat_room.col + viz.uni_margin; d3.select(viz.root + ' .dendro_row_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () { return 'translate(' + x_offset + ',' + y_offset + ')'; }); // hide spillover left top of col dendrogram x_offset = 0; y_offset = viz.clust.margin.top + viz.clust.dim.height; tmp_width = viz.clust.margin.left; tmp_height = viz.clust.dim.height * 10; svg_group.select('.dendro_col_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () { return 'translate(' + x_offset + ',' + y_offset + ')'; }); x_offset = viz.clust.margin.left + viz.clust.dim.width; y_offset = viz.clust.margin.top + viz.clust.dim.height; tmp_width = viz.cat_room.col + viz.clust.dim.width; tmp_height = viz.cat_room.row + viz.uni_margin; svg_group.select('.dendro_corner_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () { return 'translate(' + x_offset + ',' + y_offset + ')'; }); x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin; y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin; var extra_x_room = 2.75; var extra_y_room = 1.2; // reposition category superlabels if (viz.show_categories.col) { d3.selectAll(viz.root + ' .col_cat_super').attr('transform', function (d) { var inst_cat = parseInt(d.split('-')[1], 10); var inst_y = y_offset + extra_y_room * viz.cat_room.symbol_width * inst_cat; return 'translate(' + x_offset + ',' + inst_y + ')'; }); } if (viz.show_categories.row) { d3.select(viz.root + ' .row_cat_label_container').attr('transform', function () { x_offset = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.symbol_width + extra_x_room * viz.uni_margin; y_offset = viz.clust.margin.top - viz.uni_margin; return 'translate(' + x_offset + ',' + y_offset + ') rotate(-90)'; }); } // white border bottom - prevent clustergram from hitting border if (viz.show_dendrogram) { y_offset = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin; } else { y_offset = viz.clust.margin.top + viz.clust.dim.height; } d3.select(viz.root + ' .bottom_spillover_container').attr('transform', function () { // shift up enough to show the entire border width return 'translate(0,' + y_offset + ')'; }); svg_group.select(viz.root + ' .bottom_spillover').attr('width', viz.svg_dim.width).attr('height', 2 * viz.svg_dim.height); var inst_height = viz.cat_room.col + 1.5 * viz.uni_margin; // white rect to cover excess labels d3.select(viz.viz_svg + ' .top_right_white').attr('fill', viz.background_color).attr('width', 2 * viz.clust.dim.width).attr('height', inst_height).attr('transform', function () { var tmp_left = viz.clust.margin.left + viz.clust.dim.width; var tmp_top = viz.norm_labels.width.col + viz.norm_labels.margin.top - viz.uni_margin; return 'translate(' + tmp_left + ', ' + tmp_top + ')'; }); }; /***/ }, /* 138 */ /***/ function(module, exports) { module.exports = function resize_borders(params, svg_group) { // left border svg_group.select('.left_border').attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,0)'); // right border svg_group.select('.right_border').attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', function () { var inst_offset = params.viz.svg_dim.width - params.viz.grey_border_width; return 'translate(' + inst_offset + ',0)'; }); // top border svg_group.select('.top_border').attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () { var inst_offset = 0; return 'translate(' + inst_offset + ',0)'; }); // bottom border svg_group.select('.bottom_border').attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () { var inst_offset = params.viz.svg_dim.height - params.viz.grey_border_width; return 'translate(0,' + inst_offset + ')'; }); }; /***/ }, /* 139 */ /***/ function(module, exports) { module.exports = function resize_row_labels(params, ini_svg_group, delay_info = false) { var delays = {}; var duration = params.viz.duration; var svg_group; var row_nodes = params.network_data.row_nodes; var row_nodes_names = params.network_data.row_nodes_names; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } if (delays.run_transition) { ini_svg_group.selectAll('.row_label_group') // data bind necessary for loss/gain of rows .data(row_nodes, function (d) { return d.name; }).transition().delay(delays.update).duration(duration).attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35); svg_group = ini_svg_group.transition().delay(delays.update).duration(duration); } else { ini_svg_group.selectAll('.row_label_group') // data bind necessary for loss/gain of rows .data(row_nodes, function (d) { return d.name; }).attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0,' + params.viz.y_scale(inst_index) + ')'; }).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35); svg_group = ini_svg_group; } svg_group.select(params.root + ' .row_container').attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')'); svg_group.select(params.root + ' .row_container').select('.white_bars').attr('width', params.viz.label_background.row).attr('height', 30 * params.viz.clust.dim.height + 'px'); svg_group.select(params.root + ' .row_container').select('.row_label_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)'); }; /***/ }, /* 140 */ /***/ function(module, exports) { module.exports = function resize_highlights(params) { // reposition tile highlight //////////////////////////////// var rel_width_hlight = 6; // var opacity_hlight = 0.85; var hlight_width = rel_width_hlight * params.viz.border_width.x; var hlight_height = rel_width_hlight * params.viz.border_width.y; // top highlight d3.select(params.root + ' .top_hlight').attr('width', params.viz.rect_width).attr('height', hlight_height).attr('transform', function () { return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',0)'; }); // left highlight d3.select(params.root + ' .left_hlight').attr('width', hlight_width).attr('height', params.viz.rect_width - hlight_height * 0.99).attr('transform', function () { return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',' + hlight_height * 0.99 + ')'; }); // right highlight d3.select(params.root + ' .right_hlight').attr('width', hlight_width).attr('height', params.viz.rect_height - hlight_height * 0.99).attr('transform', function () { var tmp_translate = params.viz.x_scale(params.matrix.click_hlight_x) + params.viz.rect_width - hlight_width; return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')'; }); // bottom highlight d3.select(params.root + ' .bottom_hlight').attr('width', function () { return params.viz.rect_width - 1.98 * hlight_width; }).attr('height', hlight_height).attr('transform', function () { var tmp_translate_x = params.viz.x_scale(params.matrix.click_hlight_x) + hlight_width * 0.99; var tmp_translate_y = params.viz.rect_height - hlight_height; return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')'; }); // resize row highlight ///////////////////////// d3.select(params.root + ' .row_top_hlight').attr('width', params.viz.svg_dim.width).attr('height', hlight_height); d3.select(params.root + ' .row_bottom_hlight').attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('transform', function () { var tmp_translate_y = params.viz.rect_height - hlight_height; return 'translate(0,' + tmp_translate_y + ')'; }); // resize col highlight ///////////////////////// d3.select(params.root + ' .col_top_hlight').attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('transform', function () { var tmp_translate_y = 0; var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin); return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')'; }); d3.select(params.root + ' .col_bottom_hlight').attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('transform', function () { var tmp_translate_y = params.viz.rect_width - hlight_width; var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin); return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')'; }); }; /***/ }, /* 141 */ /***/ function(module, exports) { module.exports = function resize_row_viz(params, ini_svg_group, delay_info = false) { var delays = {}; var duration = params.viz.duration; var svg_group; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } if (delays.run_transition) { svg_group = ini_svg_group.transition().delay(delays.update).duration(duration); } else { svg_group = ini_svg_group; } svg_group.select('.row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').select('white_bars').attr('width', params.viz.cat_room.row + 'px').attr('height', function () { var inst_height = params.viz.clust.dim.height; return inst_height; }); var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width; var y_offset = params.viz.clust.margin.top; svg_group.select('.row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')'); // !! tmp resize col dendro x_offset = params.viz.clust.margin.left; y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height; svg_group.select(' .col_dendro_outer_container').attr('transform', function () { return 'translate(' + x_offset + ',' + y_offset + ')'; }); }; /***/ }, /* 142 */ /***/ function(module, exports) { module.exports = function (params, ini_svg_group, delay_info = false) { var delays = {}; var duration = params.viz.duration; var svg_group; var col_nodes = params.network_data.col_nodes; var col_nodes_names = params.network_data.col_nodes_names; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } if (delays.run_transition) { svg_group = ini_svg_group.transition().delay(delays.update).duration(duration); ini_svg_group.selectAll('.col_label_text').data(col_nodes, function (d) { return d.name; }).transition().delay(delays.update).duration(duration).attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)'; }); } else { svg_group = ini_svg_group; ini_svg_group.selectAll('.col_label_text').data(col_nodes, function (d) { return d.name; }).attr('transform', function (d) { var inst_index = _.indexOf(col_nodes_names, d.name); return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)'; }); } // offset click group column label var x_offset_click = params.viz.x_scale.rangeBand() / 2 + params.viz.border_width.x; svg_group.select(params.root + ' .col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')'); svg_group.select(params.root + ' .col_container').select('.white_bars').attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col); svg_group.select(params.root + ' .col_container').select('.col_label_outer_container').attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')'); svg_group.selectAll('.col_label_group').attr('transform', 'translate(' + params.viz.x_scale.rangeBand() / 2 + ',' + x_offset_click + ') rotate(45)'); svg_group.selectAll('.col_label_group').select('text').attr('y', params.viz.x_scale.rangeBand() * 0.60).attr('dx', 2 * params.viz.border_width.x); }; /***/ }, /* 143 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); module.exports = function resize_col_text(params, svg_group) { svg_group.selectAll('.col_label_group').select('text').style('font-size', params.labels.default_fs_col + 'px').text(function (d) { return utils.normal_name(d); }); svg_group.selectAll('.col_label_group').each(function () { d3.select(this).select('text')[0][0].getBBox(); }); }; /***/ }, /* 144 */ /***/ function(module, exports, __webpack_require__) { var col_viz_aid_triangle = __webpack_require__(110); module.exports = function resize_col_triangle(params, ini_svg_group, delay_info = false) { // resize column triangle var ini_triangle_group = ini_svg_group.selectAll('.col_label_group').select('path'); var delays = {}; var duration = params.viz.duration; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } var triangle_group; if (delays.run_transition) { triangle_group = ini_triangle_group.transition().delay(delays.update).duration(duration); } else { triangle_group = ini_triangle_group; } triangle_group.attr('d', function () { return col_viz_aid_triangle(params); }).attr('fill', '#eee'); }; /***/ }, /* 145 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); module.exports = function resize_col_hlight(params, svg_group, delay_info = false) { var delays = {}; // var duration = params.viz.duration; if (delay_info === false) { delays.run_transition = false; } else { delays = delay_info; } if (utils.has(params.network_data.col_nodes[0], 'value')) { svg_group.selectAll('.col_bars').data(params.network_data.col_nodes, function (d) { return d.name; }).attr('width', function (d) { var inst_value = 0; if (d.value > 0) { inst_value = params.labels.bar_scale_col(d.value); } return inst_value; }) // rotate labels - reduce width if rotating .attr('height', params.viz.rect_width * 0.66); } }; /***/ }, /* 146 */ /***/ function(module, exports, __webpack_require__) { var get_svg_dim = __webpack_require__(19); var calc_clust_height = __webpack_require__(22); var calc_clust_width = __webpack_require__(21); var calc_default_fs = __webpack_require__(31); var calc_zoom_switching = __webpack_require__(30); module.exports = function recalc_params_for_resize(params) { // Resetting some visualization parameters params = get_svg_dim(params); 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.viz = calc_zoom_switching(params.viz); // redefine x_scale and y_scale rangeBands params.viz.x_scale.rangeBands([0, params.viz.clust.dim.width]); params.viz.y_scale.rangeBands([0, params.viz.clust.dim.height]); // redefine 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; params.viz.rect_width = params.viz.x_scale.rangeBand() - params.viz.border_width.x; params.viz.rect_height = params.viz.y_scale.rangeBand() - params.viz.border_width.y; // for downsampling if (params.viz.ds != null) { for (var i; i < params.viz.ds.length; i++) { params.viz.ds[i].rect_height = params.viz.ds[i].y_scale.rangeBand() - params.viz.border_width.y; } } // recalc downsampled y_scale if necessary if (params.viz.ds_num_levels > 0) { _.each(params.viz.ds, function (inst_ds) { // y_scale ///////////////////////// inst_ds.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]); inst_ds.y_scale.domain(d3.range(inst_ds.num_rows + 1)); inst_ds.rect_height = inst_ds.y_scale.rangeBand() - params.viz.border_width.y; }); } // redefine zoom extent params.viz.square_zoom = params.viz.norm_labels.width.col / (params.viz.rect_width / 2); // the default font sizes are set here params = calc_default_fs(params); return params; }; /***/ }, /* 147 */ /***/ function(module, exports, __webpack_require__) { var draw_up_tile = __webpack_require__(43); var draw_dn_tile = __webpack_require__(44); var fine_position_tile = __webpack_require__(47); module.exports = function resize_row_tiles(params, svg_group) { var row_nodes_names = params.network_data.row_nodes_names; if (params.viz.ds_level === -1) { // no downsampling /////////////////////// // resize rows svg_group.selectAll('.row').attr('transform', function (d) { var tmp_index = _.indexOf(row_nodes_names, d.name); var inst_y = params.viz.y_scale(tmp_index); return 'translate(0,' + inst_y + ')'; }); // resize tiles svg_group.selectAll('.row').selectAll('.tile').attr('transform', function (d) { return fine_position_tile(params, d); }).attr('width', params.viz.rect_width).attr('height', params.viz.rect_height); // resize tile_up svg_group.selectAll('.row').selectAll('.tile_up').attr('d', function () { return draw_up_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }); // resize tile_dn svg_group.selectAll('.row').selectAll('.tile_dn').attr('d', function () { return draw_dn_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }); } else { // downsampling ///////////////////////// var ds_level = params.viz.ds_level; var row_class = '.ds' + String(ds_level) + '_row'; var ds_rect_height = params.viz.ds[ds_level].rect_height; svg_group.selectAll(row_class).attr('transform', function (d) { var inst_y = params.viz.ds[ds_level].y_scale(d.row_index); return 'translate(0,' + inst_y + ')'; }); // reset ds-tiles svg_group.selectAll(row_class).selectAll('.tile').attr('transform', function (d) { return fine_position_tile(params, d); }).attr('width', params.viz.rect_width).attr('height', ds_rect_height); } }; /***/ }, /* 148 */ /***/ function(module, exports, __webpack_require__) { var calc_val_max = __webpack_require__(23); module.exports = function resize_label_bars(cgm, svg_group) { var params = cgm.params; // // set bar scale // var 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 ]); params = calc_val_max(params); svg_group.selectAll('.row_bars') // .transition().delay(delays.update).duration(duration) .attr('width', function (d) { var inst_value = 0; inst_value = params.labels.bar_scale_row(Math.abs(d.value)); return inst_value; }).attr('x', function (d) { var inst_value = 0; inst_value = -params.labels.bar_scale_row(Math.abs(d.value)); return inst_value; }).attr('height', params.viz.y_scale.rangeBand()); }; /***/ }, /* 149 */ /***/ function(module, exports) { module.exports = function position_play_button(params) { var clust_transform = d3.select(params.root + ' .clust_container').attr('transform'); var clust_x = Number(clust_transform.split('(')[1].split(',')[0]); var clust_y = Number(clust_transform.split(',')[1].replace(')', '')); var trans_x = clust_x + params.viz.clust.dim.width / 2; var trans_y = clust_y + params.viz.clust.dim.height / 2; d3.select(params.root + ' .play_button').attr('transform', function () { return 'translate(' + trans_x + ',' + trans_y + ')'; }); }; /***/ }, /* 150 */ /***/ function(module, exports) { module.exports = function position_svg_dendro_slider(cgm, inst_rc) { var viz = cgm.params.viz; var tmp_left; var tmp_top; if (inst_rc === 'row') { // row dendrogram /////////////////////// // keep slider near clustergram var max_room = viz.svg_dim.width - 3 * viz.uni_margin; // position close to row dendrogram trapezoids tmp_left = viz.clust.margin.left + viz.clust.dim.width + 5 * viz.dendro_room.row; if (tmp_left > max_room) { tmp_left = max_room; } tmp_top = viz.clust.margin.top + 3 * viz.uni_margin; } else { // column dendrogram /////////////////////// tmp_left = 2 * viz.uni_margin; // tmp_top = viz.svg_dim.height - 2.5 * viz.uni_margin; tmp_top = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin; } d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').attr('transform', function () { var inst_translation; if (inst_rc === 'row') { inst_translation = 'translate(' + tmp_left + ',' + tmp_top + ')'; } else { inst_translation = 'translate(' + tmp_left + ',' + tmp_top + '), rotate(-90)'; } return inst_translation; }).style('opacity', 1); }; /***/ }, /* 151 */ /***/ function(module, exports) { module.exports = function grid_lines_viz(params, duration = 0) { var delay = 0; if (duration > 0) { delay = 2000; } var horz_lines = d3.selectAll(params.root + ' .horz_lines'); var vert_lines = d3.selectAll(params.root + ' .vert_lines'); horz_lines.style('opacity', 0).attr('transform', function (d) { var inst_index = d.row_index; var inst_trans = params.viz.y_scale(inst_index); return 'translate( 0,' + inst_trans + ') rotate(0)'; }).transition().duration(duration).delay(delay).style('opacity', 1); horz_lines.append('line').attr('x1', 0).attr('x2', params.viz.clust.dim.width).style('stroke-width', function () { var inst_width = params.viz.border_width.y; return inst_width + 'px'; }); vert_lines.style('opacity', 0).attr('transform', function (d) { var inst_index = d.col_index; var inst_trans = params.viz.x_scale(inst_index); return 'translate(' + inst_trans + ') rotate(-90)'; }).transition().duration(duration).delay(delay).style('opacity', 1); vert_lines.append('line').attr('x1', 0).attr('x2', -params.viz.clust.dim.height).style('stroke-width', function () { var inst_width = params.viz.border_width.x; return inst_width + 'px'; }); }; /***/ }, /* 152 */ /***/ function(module, exports, __webpack_require__) { var cat_tooltip_text = __webpack_require__(153); var d3_tip_custom = __webpack_require__(48); var reset_cat_opacity = __webpack_require__(154); var ini_cat_opacity = __webpack_require__(155); var click_filter_cats = __webpack_require__(156); var get_cat_names = __webpack_require__(157); module.exports = function make_col_cat(cgm) { var params = cgm.params; // make or reuse outer container if (d3.select(params.root + ' .col_cat_outer_container').empty()) { d3.select(params.root + ' .col_container').append('g').attr('class', 'col_cat_outer_container').attr('transform', function () { var inst_offset = params.viz.norm_labels.width.col + 2; return 'translate(0,' + inst_offset + ')'; }).append('g').attr('class', 'col_cat_container'); } else { d3.select(params.root + ' .col_container').select('col_cat_outer_container').attr('transform', function () { var inst_offset = params.viz.norm_labels.width.col + 2; return 'translate(0,' + inst_offset + ')'; }); } // remove old col_cat_tips d3.selectAll(params.viz.root_tips + '_col_cat_tip').remove(); // d3-tooltip var cat_tip = d3_tip_custom().attr('class', function () { var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_col_cat_tip'; return class_string; }).direction('s').offset([5, 0]).style('display', 'none').html(function (d) { return cat_tooltip_text(params, d, this, 'col'); }); // append groups - each will hold classification rects d3.select(params.root + ' .col_cat_container').selectAll('g').data(params.network_data.col_nodes, function (d) { return d.name; }).enter().append('g').attr('class', 'col_cat_group').attr('transform', function (d) { var inst_index = _.indexOf(params.network_data.col_nodes_names, d.name); // return 'translate(' + params.viz.x_scale(d.col_index) + ',0)'; return 'translate(' + params.viz.x_scale(inst_index) + ',0)'; }); d3.select(params.root + ' .col_cat_container').selectAll('.col_cat_group').call(cat_tip); // add category rects d3.selectAll(params.root + ' .col_cat_group').each(function () { var inst_selection = this; var cat_rect; _.each(params.viz.all_cats.col, function (inst_cat) { var inst_num = parseInt(inst_cat.split('-')[1], 10); var cat_rect_class = 'col_cat_rect_' + String(inst_num); if (d3.select(inst_selection).select('.' + cat_rect_class).empty()) { cat_rect = d3.select(inst_selection).append('rect').attr('class', cat_rect_class).attr('cat', inst_cat).attr('transform', function () { var cat_room = params.viz.cat_room.symbol_width + params.viz.cat_room.separation; var inst_shift = inst_num * cat_room; return 'translate(0,' + inst_shift + ')'; }).on('click', function (d) { if (d3.select(this).classed('cat_strings')) { if (d3.event.shiftKey === true) { click_filter_cats_db(cgm, d, this, 'col'); } else { var found_names = get_cat_names(params, d, this, 'col'); $(params.root + ' .dendro_info').modal('toggle'); var group_string = found_names.join(', '); d3.select(params.root + ' .dendro_info input').attr('value', group_string); } } }); } else { cat_rect = d3.select(inst_selection).select('.' + cat_rect_class); } cat_rect.attr('width', params.viz.x_scale.rangeBand()).attr('height', params.viz.cat_room.symbol_width).style('fill', function (d) { var cat_name = d[inst_cat]; var inst_color = params.viz.cat_colors.col[inst_cat][cat_name]; return inst_color; }).on('mouseover', cat_tip.show).on('mouseout', function () { cat_tip.hide(this); reset_cat_opacity(params); d3.select(this).classed('hovering', false); d3.selectAll('.d3-tip').style('display', 'none'); }); ini_cat_opacity(params.viz, 'col', cat_rect, inst_cat); }); }); var click_filter_cats_db = _.debounce(click_filter_cats, 1500); }; /***/ }, /* 153 */ /***/ function(module, exports, __webpack_require__) { var get_cat_title = __webpack_require__(113); module.exports = function cat_tooltip_text(params, inst_data, inst_selection, inst_rc) { d3.selectAll(params.viz.root_tips + '_col_cat_tip').style('display', 'block'); d3.selectAll(params.viz.root_tips + '_row_cat_tip').style('display', 'block'); // category index var inst_cat = d3.select(inst_selection).attr('cat'); var cat_title = get_cat_title(params.viz, inst_cat, inst_rc); var cat_name = inst_data[inst_cat]; if (typeof cat_name === 'string') { if (cat_name.indexOf(': ') >= 0) { cat_name = cat_name.split(': ')[1]; } } var cat_string = cat_title + ': ' + cat_name; d3.select(inst_selection).classed('hovering', true); setTimeout(highlight_categories, 500); return cat_string; function highlight_categories() { var run_highlighting = false; if (d3.select(inst_selection).classed('hovering')) { var node_types = [inst_rc]; if (params.viz.sim_mat) { node_types = ['row', 'col']; } _.each(node_types, function (tmp_rc) { // only highlight string categories that are not 'false' categories if (typeof cat_name === 'string') { if (cat_name.indexOf('Not ') < 0 && cat_name != 'false') { run_highlighting = true; } } if (run_highlighting) { d3.selectAll(params.root + ' .' + tmp_rc + '_cat_group').selectAll('rect').style('opacity', function (d) { var inst_opacity = d3.select(this).style('opacity'); if (d3.select(this).classed('cat_strings') && d3.select(this).classed('filtered_cat') === false) { var tmp_name; var tmp_cat = d3.select(this).attr('cat'); if (d[tmp_cat].indexOf(': ') >= 0) { tmp_name = d[tmp_cat].split(': ')[1]; } else { tmp_name = d[tmp_cat]; } if (tmp_cat === inst_cat && tmp_name === cat_name) { inst_opacity = params.viz.cat_colors.active_opacity; } else { inst_opacity = params.viz.cat_colors.opacity / 4; } } return inst_opacity; }); } }); } } }; /***/ }, /* 154 */ /***/ function(module, exports) { module.exports = function reset_cat_opacity(params) { _.each(['row', 'col'], function (inst_rc) { d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').style('opacity', function () { var inst_opacity = d3.select(this).style('opacity'); if (d3.select(this).classed('cat_strings') && d3.select(this).classed('filtered_cat') === false) { inst_opacity = params.viz.cat_colors.opacity; } return inst_opacity; }); }); }; /***/ }, /* 155 */ /***/ function(module, exports) { module.exports = function ini_cat_opacity(viz, inst_rc, cat_rect, inst_cat, updating = false) { // debugger; var super_string = ': '; var inst_type = viz.cat_info[inst_rc][inst_cat].type; // set opacity based on string or value cats if (inst_type === 'cat_strings') { // optionally have categories transition in if (updating) { cat_rect.classed('cat_strings', true).style('opacity', 0).transition().duration(1000).style('opacity', viz.cat_colors.opacity); } else { // opacity is fixed cat_rect.classed('cat_strings', true).style('opacity', viz.cat_colors.opacity); } } else { // opacity varies based on value cat_rect.classed('cat_values', true).style('opacity', function (d) { var unprocessed_val = d[inst_cat]; var cat_value = get_cat_value(unprocessed_val); return viz.cat_info[inst_rc][inst_cat].cat_scale(Math.abs(cat_value)); }).style('fill', function (d) { var inst_color; var cat_value = get_cat_value(d[inst_cat]); // get positive and negative colors if (cat_value > 0) { inst_color = viz.cat_value_colors[0]; } else { inst_color = viz.cat_value_colors[1]; } return inst_color; }); } function get_cat_value(unprocessed_value) { if (typeof unprocessed_value === 'string') { if (unprocessed_value.indexOf(super_string) > -1) { unprocessed_value = unprocessed_value.split(super_string)[1]; } } var cat_value = parseFloat(unprocessed_value); return cat_value; } }; /***/ }, /* 156 */ /***/ function(module, exports, __webpack_require__) { var get_cat_names = __webpack_require__(157); module.exports = function click_filter_cats(cgm, inst_data, inst_selection, inst_rc) { var params = cgm.params; var inst_cat = d3.select(inst_selection).attr('cat'); var cat_name = inst_data[inst_cat]; var found_names = get_cat_names(params, inst_data, inst_selection, inst_rc); var switch_rc = { 'row': 'col', 'col': 'row' }; var other_rc = switch_rc[inst_rc]; var filter_names = {}; filter_names[inst_rc] = found_names; if (cgm.params.cat_filter[inst_rc] === false) { if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter[other_rc] === false) { var tmp_names = cgm.params.network_data.col_nodes_names; // keep a backup of the inst_view var inst_row_nodes = cgm.params.network_data.row_nodes; var inst_col_nodes = cgm.params.network_data.col_nodes; // run filtering using found names cgm.filter_viz_using_names(filter_names); // overwrite with backup of original nodes cgm.params.inst_nodes.row_nodes = inst_row_nodes; cgm.params.inst_nodes.col_nodes = inst_col_nodes; // must set this after filtering has been run cgm.params.cat_filter[inst_rc] = tmp_names; highlight_filtered_cat(inst_rc, inst_cat, cat_name); } } else { // get backup of names filter_names = cgm.params.cat_filter[inst_rc]; // reset filter cgm.filter_viz_using_names(filter_names); // must set this after filtering has been run cgm.params.cat_filter[inst_rc] = false; // there are no filtered cats d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').classed('filtered_cat', false); } function highlight_filtered_cat(inst_rc, inst_cat, cat_name) { d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').style('opacity', function (d) { var inst_opacity = d3.select(this).style('opacity'); if (d3.select(this).classed('cat_strings')) { var tmp_name; var tmp_cat = d3.select(this).attr('cat'); // no need to filter out title tmp_name = d[tmp_cat]; if (tmp_cat === inst_cat && tmp_name === cat_name) { inst_opacity = 1; d3.select(this).classed('filtered_cat', true); } // else { // inst_opacity = params.viz.cat_colors.opacity/4; // } } return inst_opacity; }); } }; /***/ }, /* 157 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); module.exports = function get_cat_names(params, inst_data, inst_selection, inst_rc) { // category index var inst_cat = d3.select(inst_selection).attr('cat'); var cat_name = inst_data[inst_cat]; var tmp_nodes = params.network_data[inst_rc + '_nodes']; var found_nodes = _.filter(tmp_nodes, function (d) { return d[inst_cat] == cat_name; }); var found_names = utils.pluck(found_nodes, 'name'); return found_names; }; /***/ }, /* 158 */ /***/ function(module, exports, __webpack_require__) { var cat_tooltip_text = __webpack_require__(153); var d3_tip_custom = __webpack_require__(48); var reset_cat_opacity = __webpack_require__(154); var ini_cat_opacity = __webpack_require__(155); var click_filter_cats = __webpack_require__(156); var get_cat_names = __webpack_require__(157); module.exports = function make_row_cat(cgm, updating = false) { // console.log('make_row_cat') var params = cgm.params; // make or reuse outer container if (d3.select(params.root + ' .row_cat_outer_container').empty()) { d3.select(params.root + ' .row_container').append('g').attr('class', 'row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').append('g').attr('class', 'row_cat_container'); } else { d3.select(params.root + ' .row_container').select('row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)'); } // white background if (d3.select(params.root + ' .row_cat_container').select('.white_bars').empty()) { d3.select(params.root + ' .row_cat_container').append('rect').attr('class', 'white_bars').attr('fill', params.viz.background_color).attr('width', params.viz.cat_room.row + 'px').attr('height', function () { var inst_height = params.viz.clust.dim.height; return inst_height; }); } else { d3.select(params.root + ' .row_cat_container').select('.white_bars').attr('fill', params.viz.background_color).attr('width', params.viz.cat_room.row + 'px').attr('height', function () { var inst_height = params.viz.clust.dim.height; return inst_height; }); } // remove old col_cat_tips d3.selectAll(params.viz.root_tips + '_row_cat_tip').remove(); // d3-tooltip var cat_tip = d3_tip_custom().attr('class', function () { var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_cat_tip'; return class_string; }).direction('e').offset([5, 0]).style('display', 'none').html(function (d) { return cat_tooltip_text(params, d, this, 'row'); }); // groups that hold classification triangle and colorbar rect d3.select(params.root + ' .row_cat_container').selectAll('g').data(params.network_data.row_nodes, function (d) { // console.log('-------------') // console.log(d['cat-0']) // console.log('-------------') return d.name; }).enter().append('g').attr('class', 'row_cat_group').attr('transform', function (d) { var inst_index = _.indexOf(params.network_data.row_nodes_names, d.name); return 'translate(0, ' + params.viz.y_scale(inst_index) + ')'; }); d3.select(params.root + ' .row_cat_container').selectAll('.row_cat_group').call(cat_tip); // add row visual-aid triangles (if no downsampling) // if (params.viz.ds_level === -1){ // d3.selectAll(params.root+' .row_cat_group') // .append('path') // .attr('d', function() { // var origin_x = params.viz.cat_room.symbol_width - 1; // var origin_y = 0; // var mid_x = 1; // var mid_y = params.viz.y_scale.rangeBand() / 2; // var final_x = params.viz.cat_room.symbol_width - 1; // var final_y = params.viz.y_scale.rangeBand(); // var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + // mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z'; // return output_string; // }) // .attr('fill', '#eee') // .style('opacity', params.viz.triangle_opacity); // } var cat_rect; var inst_selection; d3.selectAll(params.root + ' .row_cat_group rect').remove(); if (params.viz.show_categories.row) { d3.selectAll(params.root + ' .row_cat_group').each(function () { inst_selection = this; _.each(params.viz.all_cats.row, function (inst_cat) { var inst_num = parseInt(inst_cat.split('-')[1], 10); var cat_rect_class = 'row_cat_rect_' + String(inst_num); if (d3.select(inst_selection).select('.' + cat_rect_class).empty()) { cat_rect = d3.select(inst_selection).append('rect').attr('class', cat_rect_class).attr('cat', inst_cat); } else { cat_rect = d3.select(inst_selection).select('.' + cat_rect_class); } cat_rect.attr('width', params.viz.cat_room.symbol_width).attr('height', params.viz.y_scale.rangeBand()).style('fill', function (d) { var cat_name = d[inst_cat]; // if (cat_name.indexOf(': ') >= 0){ // cat_name = cat_name.split(': ')[1]; // } // console.log(cat_name) var inst_color = params.viz.cat_colors.row[inst_cat][cat_name]; // console.log('inst_color: ' + String(inst_color)); return inst_color; }).attr('x', function () { var inst_offset = params.viz.cat_room.symbol_width + params.viz.uni_margin / 2; return inst_offset + 'px'; }).attr('transform', function () { var cat_room = params.viz.cat_room.symbol_width + params.viz.cat_room.separation; var inst_shift = inst_num * cat_room; return 'translate(' + inst_shift + ',0)'; }).on('click', function (d) { if (d3.select(this).classed('cat_strings')) { if (d3.event.shiftKey === true) { click_filter_cats_db(cgm, d, this, 'row'); } else { var found_names = get_cat_names(params, d, this, 'row'); $(params.root + ' .dendro_info').modal('toggle'); var group_string = found_names.join(', '); d3.select(params.root + ' .dendro_info input').attr('value', group_string); } } }).on('mouseover', cat_tip.show).on('mouseout', function () { cat_tip.hide(this); reset_cat_opacity(params); d3.select(this).classed('hovering', false); d3.selectAll('.d3-tip').style('display', 'none'); }); ini_cat_opacity(params.viz, 'row', cat_rect, inst_cat, updating); }); }); } var click_filter_cats_db = _.debounce(click_filter_cats, 1500); }; /***/ }, /* 159 */ /***/ function(module, exports, __webpack_require__) { var make_dendro_triangles = __webpack_require__(55); module.exports = function make_row_dendro(cgm) { var params = cgm.params; var spillover_width = params.viz.dendro_room.row + params.viz.uni_margin; // position row_dendro_outer_container var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width; var y_offset = params.viz.clust.margin.top; // make or reuse outer container if (d3.select(params.root + ' .row_dendro_outer_container').empty()) { d3.select(params.root + ' .viz_svg').append('g').attr('class', 'row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')'); d3.select(params.root + ' .row_dendro_outer_container').append('rect').classed('row_dendro_spillover', true).attr('fill', params.viz.background_color).attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height); d3.select(params.root + ' .row_dendro_outer_container').append('g').attr('class', 'row_dendro_container').attr('transform', 'translate(' + params.viz.uni_margin / 2 + ',0)'); } else { d3.select(params.root + ' .viz_svg').select('row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')'); d3.select(params.root + ' .row_dendro_outer_container').select('.row_dendro_spillover').attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height); } make_dendro_triangles(cgm, 'row', false); if (params.viz.inst_order.col != 'clust') { d3.selectAll(params.root + ' .row_dendro_group').remove(); } }; /***/ }, /* 160 */ /***/ function(module, exports, __webpack_require__) { var make_dendro_triangles = __webpack_require__(55); module.exports = function make_col_dendro(cgm) { var params = cgm.params; // position col_dendro_outer_container var x_offset = params.viz.clust.margin.left; var y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height; var spillover_height = params.viz.dendro_room.col + params.viz.uni_margin; // make or reuse outer container if (d3.select(params.root + ' .col_dendro_outer_container').empty()) { d3.select(params.root + ' .viz_svg').append('g').attr('class', 'col_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')'); d3.select(params.root + ' .col_dendro_outer_container').append('rect').classed('col_dendro_spillover', true).attr('fill', params.viz.background_color).attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px'); d3.select(params.root + ' .col_dendro_outer_container').append('g').attr('class', 'col_dendro_container').attr('transform', 'translate(0,' + params.viz.uni_margin / 2 + ')'); d3.select(params.root + ' .col_dendro_outer_container').append('rect').classed('col_dendro_spillover_top', true).attr('fill', params.viz.background_color).attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,' + params.viz.dendro_room.col + ')'); } else { d3.select(params.root + ' .viz_svg').select('col_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')'); d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover').attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px'); } make_dendro_triangles(cgm, 'col', false); if (params.viz.inst_order.row != 'clust') { d3.selectAll(params.root + ' .col_dendro_group').remove(); } }; /***/ }, /* 161 */ /***/ function(module, exports, __webpack_require__) { var build_svg_dendro_slider = __webpack_require__(162); module.exports = function make_svg_dendro_sliders(cgm) { build_svg_dendro_slider(cgm, 'row'); build_svg_dendro_slider(cgm, 'col'); }; /***/ }, /* 162 */ /***/ function(module, exports, __webpack_require__) { var change_groups = __webpack_require__(163); var position_svg_dendro_slider = __webpack_require__(150); module.exports = function build_svg_dendro_slider(cgm, inst_rc) { var slider_length = 100; var drag = d3.behavior.drag().on("drag", dragging).on('dragend', function () { cgm.params.is_slider_drag = false; }); var slider_group = d3.select(cgm.params.root + ' .viz_svg').append('g').classed(inst_rc + '_slider_group', true); position_svg_dendro_slider(cgm, inst_rc); var rect_height = slider_length + 20; var rect_width = 30; slider_group.append('rect').classed(inst_rc + '_slider_background', true).attr('height', rect_height + 'px').attr('width', rect_width + 'px').attr('fill', cgm.params.viz.background_color).attr('transform', function () { var translate_string = 'translate(-10, -5)'; return translate_string; }).style('opacity', 0); slider_group.append("line").style('stroke-width', slider_length / 7 + 'px').style('stroke', 'black').style('stroke-linecap', 'round').style('opacity', 0.0).attr("y1", 0).attr("y2", function () { return slider_length - 2; }).on('click', click_dendro_slider); var offset_triangle = -slider_length / 40; slider_group.append('path').style('fill', 'black').attr('transform', 'translate(' + offset_triangle + ', 0)').attr('d', function () { // up triangle var start_x = 0; var start_y = 0; var mid_x = 0; var mid_y = slider_length; var final_x = slider_length / 10; var final_y = 0; var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z'; return output_string; }).style('opacity', 0.35).on('click', click_dendro_slider); var default_opacity = 0.35; var high_opacity = 0.6; slider_group.append('circle').classed(inst_rc + '_group_circle', true).attr('r', slider_length * 0.08).attr('transform', function () { return 'translate(0, ' + slider_length / 2 + ')'; }).style('fill', 'blue').style('opacity', default_opacity).on('mouseover', function () { d3.select(this).style('opacity', high_opacity); }).on('mouseout', function () { d3.select(this).style('opacity', default_opacity); }).call(drag); function dragging() { cgm.params.is_slider_drag = true; // d[0] = d3.event.x; var slider_pos = d3.event.y; if (slider_pos < 0) { slider_pos = 0; } if (slider_pos > slider_length) { slider_pos = slider_length; } if (this.nextSibling) { this.parentNode.appendChild(this); } slider_pos = d3.round(slider_pos, -1); var slider_value = 10 - slider_pos / 10; d3.select(this).attr("transform", "translate(0, " + slider_pos + ")"); change_groups(cgm, inst_rc, slider_value); } function click_dendro_slider() { var clicked_line_position = d3.mouse(this); var rel_pos = d3.round(clicked_line_position[1], -1); d3.select(cgm.params.root + ' .' + inst_rc + '_group_circle').attr('transform', 'translate(0, ' + rel_pos + ')'); var slider_value = 10 - rel_pos / 10; change_groups(cgm, inst_rc, slider_value); } }; /***/ }, /* 163 */ /***/ function(module, exports, __webpack_require__) { // var build_color_groups = require('./build_color_groups'); var make_dendro_triangles = __webpack_require__(55); /* Changes the groupings (x- and y-axis color bars). */ module.exports = function (cgm, inst_rc, inst_index) { var params = cgm.params; if (inst_rc === 'row') { params.group_level.row = inst_index; } else if (inst_rc === 'col') { params.group_level.col = inst_index; } var is_change_group = true; make_dendro_triangles(cgm, inst_rc, is_change_group); }; /***/ }, /* 164 */ /***/ function(module, exports, __webpack_require__) { var make_dendro_crop_buttons = __webpack_require__(60); module.exports = function make_row_dendro_spillover(cgm) { var viz = cgm.params.viz; // hide spillover from right var tmp_left = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin + viz.dendro_room.row; var r_spill_container = d3.select(viz.viz_svg).append('g').classed('right_spillover_container', true).attr('transform', function () { return 'translate(' + tmp_left + ', 0)'; }); var tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col; r_spill_container.append('rect').attr('fill', viz.background_color) //!! prog_colors .attr('width', 10 * viz.clust.dim.width).attr('height', viz.svg_dim.height + 'px').attr('class', 'white_bars').attr('class', 'right_spillover').attr('transform', function () { return 'translate( 0,' + tmp_top + ')'; }); var x_offset = 0; var y_offset = viz.clust.margin.top; r_spill_container.append('g').classed('row_dendro_icons_container', true).attr('transform', 'translate(' + x_offset + ',' + y_offset + ')').append('g').classed('row_dendro_icons_group', true); make_dendro_crop_buttons(cgm, 'row'); // hide spillover from top of row dendrogram x_offset = viz.clust.margin.left + viz.clust.dim.width; y_offset = tmp_top; var tmp_width = viz.dendro_room.row + viz.uni_margin; var tmp_height = viz.cat_room.col + viz.uni_margin; d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () { return 'translate(' + x_offset + ',' + y_offset + ')'; }).classed('white_bars', true).classed('dendro_row_spillover', true); }; /***/ }, /* 165 */ /***/ function(module, exports, __webpack_require__) { /* eslint-disable */ var run_segment = __webpack_require__(166); var play_intro = __webpack_require__(167); var play_zoom = __webpack_require__(169); var play_reset_zoom = __webpack_require__(170); var play_reorder_row = __webpack_require__(172); var play_reorder_buttons = __webpack_require__(173); var play_search = __webpack_require__(175); var play_filter = __webpack_require__(176); var quick_cluster = __webpack_require__(199); var play_groups = __webpack_require__(200); var play_categories = __webpack_require__(201); var play_conclusion = __webpack_require__(202); var toggle_play_button = __webpack_require__(203); var play_menu_button = __webpack_require__(204); module.exports = function play_demo() { var cgm = this; var params = cgm.params; if (d3.select(params.root + ' .running_demo').empty()) { // prevent more than one demo from running at once d3.select(params.root + ' .play_button').classed('running_demo', true); toggle_play_button(params, false); // prevent user interaction while playing $.blockUI({ css: { border: 'none', padding: '15px', backgroundColor: '#000', '-webkit-border-radius': '10px', '-moz-border-radius': '10px', opacity: 0, color: '#fff', cursor: 'default' } }); d3.selectAll('.blockUI').style('opacity', 0); // intro text var inst_time = 750; if (cgm.params.viz.is_expand === false) { inst_time = run_segment(params, inst_time, quick_cluster); inst_time = inst_time - 1500; } // clustergram interaction /////////////////////////////////// inst_time = run_segment(params, inst_time, play_intro); inst_time = run_segment(params, inst_time, play_zoom); inst_time = run_segment(cgm, inst_time, play_reset_zoom); inst_time = run_segment(params, inst_time, play_categories); inst_time = run_segment(params, inst_time, play_reorder_row); // sidebar interaction /////////////////////////////////// inst_time = run_segment(params, inst_time, play_menu_button); inst_time = run_segment(params, inst_time, play_groups); inst_time = run_segment(params, inst_time, play_reorder_buttons); inst_time = run_segment(params, inst_time, play_search); inst_time = run_segment(cgm, inst_time, play_filter); // conclusion /////////////////////////////////// inst_time = run_segment(params, inst_time, quick_cluster); inst_time = run_segment(params, inst_time, play_conclusion); } }; /***/ }, /* 166 */ /***/ function(module, exports) { module.exports = function run_segment(segment_data, inst_time, inst_segment) { /* eslint-disable */ var timer = setTimeout(inst_segment().run, inst_time, segment_data); // set up kill demo that will stop setTimeouts ////////////////////////////////////////////////// // if (clear_timer){ // clearTimeout(timer); // } var inst_duration = inst_segment().get_duration(); inst_time = inst_time + inst_duration; return inst_time; }; /***/ }, /* 167 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); module.exports = function play_intro() { var speed_up = 1; function run(params) { var text_1 = 'Clustergrammer allows users to generate\ninteractive and ' + 'sharable visualizations\nby uploading a matrix'; var text_2 = "This demo will quickly overview some\nof Clustergrammer's " + "interactive features"; setTimeout(demo_text, 0, params, text_1, 4500 / speed_up); setTimeout(demo_text, 4500 / speed_up, params, text_2, 4500 / speed_up); } function get_duration() { return 10000 / speed_up; } return { run: run, get_duration: get_duration }; }; /***/ }, /* 168 */ /***/ function(module, exports) { module.exports = function demo_text(params, text, read_duration) { var split_text = text.split('\n'); if (split_text.length < 3) { split_text.push(''); } d3.select(params.root + ' .demo_group').style('opacity', 0).transition().duration(250).style('opacity', 1).transition().duration(250).delay(read_duration).style('opacity', 0); for (var i = 0; i < split_text.length; i++) { var inst_text_num = i + 1; // make text box ////////////////// var inst_text_obj = d3.select(params.root + ' .demo_group').select('#text_' + inst_text_num).text(split_text[i]); var bbox = inst_text_obj[0][0].getBBox(); var box_opacity = 0.9; var tmp_fs = Number(d3.select('.demo_group').select('text').style('font-size').replace('px', '')); var shift_height = tmp_fs * 1.3; d3.select(params.root + ' .demo_group').select('.rect_' + inst_text_num).style('fill', 'white').attr('width', bbox.width + 20).attr('height', bbox.height).attr('x', -10).attr('y', bbox.y + i * shift_height).style('opacity', box_opacity); } }; /***/ }, /* 169 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var two_translate_zoom = __webpack_require__(116); module.exports = function play_zoom() { function run(cgm) { var params = cgm.params; var text = 'Zoom and pan by\nscrolling and dragging'; demo_text(params, text, 4000); setTimeout(two_translate_zoom, 1500, cgm, 0, 0, 4); } function get_duration() { return 4000; } return { run: run, get_duration: get_duration }; }; /***/ }, /* 170 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var two_translate_zoom = __webpack_require__(116); var sim_click = __webpack_require__(171); module.exports = function play_reset_zoom() { function run(cgm) { var params = cgm.params; var text = 'Reset zoom by double-clicking\n'; demo_text(params, text, 4000); setTimeout(sim_click, 2000, params, 'double', 300, 300); setTimeout(two_translate_zoom, 2400, cgm, 0, 0, 1); } function get_duration() { return 4500; } return { run: run, get_duration: get_duration }; }; /***/ }, /* 171 */ /***/ function(module, exports) { module.exports = function sim_click(params, single_double, pos_x, pos_y) { var click_duration = 200; var click_circle = d3.select(params.root + ' .viz_svg').append('circle').attr('cx', pos_x).attr('cy', pos_y).attr('r', 25).style('stroke', 'black').style('stroke-width', '3px').style('fill', '#007f00').style('opacity', 0.5); if (single_double === 'double') { click_circle.transition().duration(click_duration).style('opacity', 0.0).transition().duration(50).style('opacity', 0.5).transition().duration(click_duration).style('opacity', 0.0).remove(); } else { click_circle.transition().duration(click_duration).style('opacity', 0.0).transition().duration(250).remove(); } }; /***/ }, /* 172 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var sim_click = __webpack_require__(171); module.exports = function play_reorder_row() { /* eslint-disable */ function run(params) { var text = 'Reorder the matrix based on a single\nrow or column by double-clicking a\nlabel'; demo_text(params, text, 7000); var inst_element = get_row_element(params, 'EGFR'); var group_trans = d3.select(inst_element).attr('transform'); var container_trans = d3.select(params.root + ' .clust_container').attr('transform').split(',')[1].replace(')', ''); var x_trans = params.viz.norm_labels.width.row * 0.9; var row_trans = group_trans.split(',')[1].replace(')', ''); var y_trans = String(Number(row_trans) + Number(container_trans) + params.viz.rect_height / 2); var wait_click = 4000; setTimeout(sim_click, wait_click, params, 'double', x_trans, y_trans); var wait_reorder = wait_click + 300; setTimeout(fire_double_click_row, wait_reorder, params, inst_element); } function get_duration() { return 8000; } function get_row_element(params, inst_row) { var inst_element = d3.selectAll(params.root + ' .row_label_group').filter(function () { var inst_data = this.__data__; return inst_data.name == inst_row; })[0][0]; return inst_element; } function fire_double_click_row(params, inst_element) { $(inst_element).d3DblClick(); } // allows doubleclicking on d3 element jQuery.fn.d3DblClick = function () { this.each(function (i, e) { var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); e.dispatchEvent(evt); }); }; return { run: run, get_duration: get_duration }; }; /***/ }, /* 173 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var highlight_sidebar_element = __webpack_require__(174); module.exports = function play_reorder_buttons() { /* eslint-disable */ function run(params) { var text = 'Reorder all rows and columns\nby clicking the reorder\n buttons'; demo_text(params, text, 9000); setTimeout(highlight_sidebar_element, 3000, params, 'toggle_col_order'); setTimeout(click_reorder_button, 3500, params, 'col', 'rank'); setTimeout(highlight_sidebar_element, 7000, params, 'toggle_row_order'); setTimeout(click_reorder_button, 7500, params, 'row', 'rank'); } function get_duration() { return 11000; } function click_reorder_button(params, inst_rc, inst_order) { var inst_button = d3.selectAll('.toggle_' + inst_rc + '_order .btn').filter(function () { return this.__data__ == inst_order; })[0]; $(inst_button).click(); } return { run: run, get_duration: get_duration }; }; /***/ }, /* 174 */ /***/ function(module, exports) { module.exports = function highlight_sidebar_element(params, highlight_class, duration = 4000) { if (highlight_class.indexOf('slider') < 0) { d3.select(params.root + ' .' + highlight_class).style('background', '#007f00').style('box-shadow', '0px 0px 10px 5px #007f00').transition().duration(1).delay(duration).style('background', '#FFFFFF').style('box-shadow', 'none'); } else { d3.select(params.root + ' .' + highlight_class).style('box-shadow', '0px 0px 10px 5px #007f00').transition().duration(1).delay(duration).style('box-shadow', 'none'); } }; /***/ }, /* 175 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var highlight_sidebar_element = __webpack_require__(174); var two_translate_zoom = __webpack_require__(116); module.exports = function play_search() { function run(cgm) { var params = cgm.params; var text = 'Search for rows using\nthe search box'; demo_text(params, text, 5000); var ini_delay = 2500; setTimeout(highlight_sidebar_element, ini_delay, params, 'gene_search_container'); // manually mimic typing and autocomplete setTimeout(type_out_search, ini_delay + 1000, params, 'E'); setTimeout(type_out_search, ini_delay + 1500, params, 'EG'); setTimeout(type_out_search, ini_delay + 2000, params, 'EGF'); setTimeout(type_out_search, ini_delay + 2500, params, 'EGFR'); setTimeout(run_search, 5500, params); setTimeout(two_translate_zoom, 7500, cgm, 0, 0, 1); } function get_duration() { return 10000; } function type_out_search(params, inst_string) { $(params.root + ' .gene_search_box').val(inst_string); $(params.root + ' .gene_search_box').autocomplete("search", inst_string); } function run_search(params) { $(params.root + ' .submit_gene_button').click(); $(params.root + ' .gene_search_box').autocomplete("search", ''); } return { run: run, get_duration: get_duration }; }; /***/ }, /* 176 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var highlight_sidebar_element = __webpack_require__(174); var update_viz_with_view = __webpack_require__(177); module.exports = function play_filter() { function run(cgm) { var params = cgm.params; var text = 'Filter rows based on sum or\nvariance using the sliders'; demo_text(params, text, 4000); var filter_type = 'N_row_sum'; setTimeout(highlight_sidebar_element, 5000, params, 'slider_' + filter_type, 13000); text = 'Filter: Top 20 rows by sum'; setTimeout(demo_text, 5000, params, text, 4000); setTimeout(run_update, 5300, cgm, filter_type, 20, 1); text = 'Filter: Top 10 rows by sum'; setTimeout(demo_text, 10000, params, text, 4000); setTimeout(run_update, 10300, cgm, filter_type, 10, 2); text = 'Filter: All rows'; setTimeout(demo_text, 15000, params, text, 4000); setTimeout(run_update, 15300, cgm, filter_type, 'all', 0); } function get_duration() { return 19500; } function run_update(cgm, filter_type, filter_value, filter_index) { var params = cgm.params; var requested_view = {}; requested_view[filter_type] = filter_value; update_viz_with_view(cgm, requested_view); // quick fix for slider $(params.root + ' .slider_' + filter_type).slider("value", filter_index); var unit_name; if (filter_type === 'N_row_sum') { unit_name = 'sum'; } else { unit_name = 'variance'; } d3.select(params.root + ' .title_' + filter_type).text('Top rows ' + unit_name + ': ' + filter_value); } return { run: run, get_duration: get_duration }; }; /***/ }, /* 177 */ /***/ function(module, exports, __webpack_require__) { var make_network_using_view = __webpack_require__(10); var disable_sidebar = __webpack_require__(178); var update_viz_with_network = __webpack_require__(179); module.exports = function update_viz_with_view(cgm, requested_view) { disable_sidebar(cgm.params); // make new_network_data by filtering the original network data var new_network_data = make_network_using_view(cgm.config, cgm.params, requested_view); // reset crop button d3.select(cgm.params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', true).classed('fa-undo', false).classed('active_cropping', false); // reset dendrogram filtering when updating with a new view // e.g. with the row filter sliders _.each(['row', 'col'], function (inst_rc) { // set class to reflect that no filtering was ran d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').classed('ran_filter', false); // display all crop buttons when cropping has not been done d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_container').style('display', 'block'); }); update_viz_with_network(cgm, new_network_data); }; /***/ }, /* 178 */ /***/ function(module, exports) { module.exports = function disable_sidebar(params) { d3.selectAll(params.root + ' .btn').attr('disabled', true); d3.select(params.viz.viz_svg).style('opacity', 0.70); }; /***/ }, /* 179 */ /***/ function(module, exports, __webpack_require__) { var make_params = __webpack_require__(9); var define_enter_exit_delays = __webpack_require__(180); var enter_exit_update = __webpack_require__(181); var initialize_resizing = __webpack_require__(123); var make_col_cat = __webpack_require__(152); var make_row_cat = __webpack_require__(158); var make_row_dendro = __webpack_require__(159); var make_col_dendro = __webpack_require__(160); var ini_sidebar = __webpack_require__(192); var enable_sidebar = __webpack_require__(194); var ini_doubleclick = __webpack_require__(133); var update_reorder_buttons = __webpack_require__(195); var make_row_cat_super_labels = __webpack_require__(122); var modify_row_node_cats = __webpack_require__(196); var run_zoom = __webpack_require__(125); var ds_enter_exit_update = __webpack_require__(198); var make_cat_params = __webpack_require__(32); module.exports = function update_viz_with_network(cgm, new_network_data) { // console.log('UPDATE VIZ WITH NETWORK') // set runnning_update class, prevents multiple update from running at once d3.select(cgm.params.viz.viz_svg).classed('running_update', true); // remove downsampled rows always d3.selectAll(cgm.params.root + ' .ds' + String(cgm.params.viz.ds_level) + '_row').remove(); // run optional callback function // console.log('before and after matrix_update_callback') // console.log(new_network_data.row_nodes[0]['cat-0']) if (cgm.params.matrix_update_callback != null) { cgm.params.matrix_update_callback(); } // console.log(new_network_data.row_nodes[0]['cat-0']) var inst_group_level = cgm.params.group_level; var inst_crop_fitler = cgm.params.crop_filter_nodes; // make tmp config to make new params var tmp_config = jQuery.extend(true, {}, cgm.config); var new_row_cats = null; // bring in 'new' category data if (cgm.params.new_row_cats != null) { modify_row_node_cats(cgm.params.new_row_cats, new_network_data.row_nodes); new_row_cats = cgm.params.new_row_cats; cgm.params.new_row_cats = new_row_cats; // do not preserve the updated (row) cats var predefined_cat_colors = true; cgm.params.viz = make_cat_params(cgm.params, cgm.params.viz, predefined_cat_colors); } tmp_config.network_data = new_network_data; tmp_config.inst_order = cgm.params.viz.inst_order; tmp_config.input_domain = cgm.params.matrix.opacity_scale.domain()[1]; update_reorder_buttons(tmp_config, cgm.params); // tmp_config.ini_expand = false; tmp_config.ini_view = null; tmp_config.current_col_cat = cgm.params.current_col_cat; // disabled, causing problems when cropping // always preserve category colors when updating tmp_config.cat_colors = cgm.params.viz.cat_colors; var new_params = make_params(tmp_config); // this function is sensitive to further updates, so run here var delays = define_enter_exit_delays(cgm.params, new_params); // pass the newly calcluated params back to the cgm object cgm.params = new_params; // set up zoom cgm.params.zoom_behavior = d3.behavior.zoom().scaleExtent([1, cgm.params.viz.square_zoom * cgm.params.viz.zoom_ratio.x]).on('zoom', function () { run_zoom(cgm); }); // have persistent group levels while updating cgm.params.group_level = inst_group_level; // have persistent crop_filter_nodes while updating cgm.params.crop_filter_nodes = inst_crop_fitler; // only run enter-exit-updates if there is no downsampling if (cgm.params.viz.ds_num_levels === 0) { // new_network_data is necessary enter_exit_update(cgm, new_network_data, delays); } else { ds_enter_exit_update(cgm); } // reduce opacity during update d3.select(cgm.params.viz.viz_svg).style('opacity', 0.70); make_row_cat(cgm); make_row_cat_super_labels(cgm); if (cgm.params.viz.show_categories.col) { make_col_cat(cgm); } if (cgm.params.viz.show_dendrogram) { make_row_dendro(cgm); make_col_dendro(cgm); } initialize_resizing(cgm); d3.select(cgm.params.viz.viz_svg).call(cgm.params.zoom_behavior); ini_doubleclick(cgm); ini_sidebar(cgm); cgm.params.viz.run_trans = true; // d3.selectAll(cgm.params.viz.root_tips) // .style('opacity',0); setTimeout(enable_sidebar, 2500, cgm.params); // remove all dendro shadows setTimeout(remove_shadows, 50); setTimeout(remove_shadows, 100); setTimeout(remove_shadows, 500); setTimeout(remove_shadows, 1000); setTimeout(remove_shadows, 1500); function remove_shadows() { d3.selectAll('.dendro_shadow').remove(); } function finish_update() { d3.select(cgm.params.viz.viz_svg).transition().duration(250).style('opacity', 1.0); setTimeout(finish_update_class, 1000); } setTimeout(finish_update, delays.enter); function finish_update_class() { d3.select(cgm.params.viz.viz_svg).classed('running_update', false); } }; /***/ }, /* 180 */ /***/ function(module, exports) { module.exports = function (old_params, params) { // exit, update, enter // check if exit or enter or both are required var old_row_nodes = old_params.network_data.row_nodes; var old_col_nodes = old_params.network_data.col_nodes; var old_row = _.map(old_row_nodes, function (d) { return d.name; }); var old_col = _.map(old_col_nodes, function (d) { return d.name; }); var all_old_nodes = old_row.concat(old_col); var row_nodes = params.network_data.row_nodes; var col_nodes = params.network_data.col_nodes; var row = _.map(row_nodes, function (d) { return d.name; }); var col = _.map(col_nodes, function (d) { return d.name; }); var all_nodes = row.concat(col); var exit_nodes = _.difference(all_old_nodes, all_nodes).length; var enter_nodes = _.difference(all_nodes, all_old_nodes).length; var delays = {}; if (exit_nodes > 0) { delays.update = 1000; } else { delays.update = 0; } if (enter_nodes > 0) { delays.enter = 1000; } else { delays.enter = 0; } delays.enter = delays.enter + delays.update; delays.run_transition = true; var old_num_links = old_params.network_data.links.length; var new_num_links = params.network_data.links.length; var cutoff_num_links = 0.5 * params.matrix.def_large_matrix; if (old_num_links > cutoff_num_links || new_num_links > cutoff_num_links) { delays.run_transition = false; delays.update = 0; delays.enter = 0; } return delays; }; /***/ }, /* 181 */ /***/ function(module, exports, __webpack_require__) { var reset_size_after_update = __webpack_require__(182); var make_row_label_container = __webpack_require__(49); var make_col_label_container = __webpack_require__(103); var eeu_existing_row = __webpack_require__(183); var exit_components = __webpack_require__(187); var draw_gridlines = __webpack_require__(39); var enter_row_groups = __webpack_require__(188); var resize_containers = __webpack_require__(191); var label_constrain_and_trim = __webpack_require__(117); var d3_tip_custom = __webpack_require__(48); module.exports = function enter_exit_update(cgm, network_data, delays) { var params = cgm.params; // remove old tooltips d3.selectAll(params.viz.root_tips).remove(); // d3-tooltip - for tiles var tip = d3_tip_custom().attr('class', function () { var root_tip_selector = params.viz.root_tips.replace('.', ''); var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_tile_tip'; return class_string; }).direction('nw').offset([0, 0]).style('display', 'none').html(function (d) { var inst_value = String(d.value.toFixed(3)); var tooltip_string; if (params.keep_orig) { var orig_value = String(d.value_orig.toFixed(3)); tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<p> normalized value: ' + inst_value + '</p>' + '<div> original value: ' + orig_value + '</div>'; } else { tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<div> value: ' + inst_value + '</div>'; } return tooltip_string; }); d3.select(params.root + ' .clust_group').call(tip); // necessary for repositioning clust, col and col-cat containers resize_containers(params); var duration = 1000; // make global so that names can be accessed var row_nodes = network_data.row_nodes; var col_nodes = network_data.col_nodes; var links = network_data.links; // var tile_data = links; // add name to links for object constancy for (var i = 0; i < tile_data.length; i++) { var d = tile_data[i]; tile_data[i].name = row_nodes[d.source].name + '_' + col_nodes[d.target].name; } // move rows var move_rows = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) { return d.name; }); if (delays.run_transition) { move_rows.transition().delay(delays.update).duration(duration).attr('transform', function (d) { var tmp_index = d.row_index; return 'translate(0,' + params.viz.y_scale(tmp_index) + ')'; }); } else { move_rows.attr('transform', function (d) { var tmp_index = d.row_index; return 'translate(0,' + params.viz.y_scale(tmp_index) + ')'; }); } // update existing rows - enter, exit, update tiles in existing row d3.select(params.root + ' .clust_group').selectAll('.row').each(function (d) { // TODO add tip back to arguments var inst_selection = this; eeu_existing_row(params, d, delays, duration, inst_selection, tip); }); d3.selectAll(params.root + ' .horz_lines').remove(); d3.selectAll(params.root + ' .vert_lines').remove(); // exit //////////// exit_components(params, delays, duration); // resize clust components using appropriate delays reset_size_after_update(cgm, duration, delays); // enter new elements ////////////////////////// enter_row_groups(params, delays, duration, tip); // update existing rows make_row_label_container(cgm, duration); make_col_label_container(cgm, duration); draw_gridlines(params, delays, duration); setTimeout(label_constrain_and_trim, 2000, params); }; /***/ }, /* 182 */ /***/ function(module, exports, __webpack_require__) { var utils = __webpack_require__(2); var calc_clust_height = __webpack_require__(22); var get_svg_dim = __webpack_require__(19); var calc_clust_width = __webpack_require__(21); var reset_zoom = __webpack_require__(134); var resize_dendro = __webpack_require__(135); var resize_super_labels = __webpack_require__(136); var resize_spillover = __webpack_require__(137); var resize_row_labels = __webpack_require__(139); var resize_row_viz = __webpack_require__(141); var resize_col_labels = __webpack_require__(142); var resize_col_text = __webpack_require__(143); var resize_col_triangle = __webpack_require__(144); var resize_col_hlight = __webpack_require__(145); var resize_label_bars = __webpack_require__(148); var calc_default_fs = __webpack_require__(31); var calc_zoom_switching = __webpack_require__(30); // var show_visible_area = require('../zoom/show_visible_area'); var ini_zoom_info = __webpack_require__(36); module.exports = function reset_size_after_update(cgm, duration = 0, delays = null) { if (delays === null) { delays = {}; delays.enter = 0; delays.update = 0; delays.run_transition = false; } var params = cgm.params; var row_nodes = cgm.params.network_data.row_nodes; params.zoom_info = ini_zoom_info(); // // not sure if this is necessary // //////////////////////////// // show_visible_area(params); // // quick fix for column filtering // setTimeout(show_visible_area, 2200, cgm); var row_nodes_names = params.network_data.row_nodes_names; reset_zoom(params); // Resetting some visualization parameters params = get_svg_dim(params); 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.viz = calc_zoom_switching(params.viz); // redefine x_scale and y_scale rangeBands params.viz.x_scale.rangeBands([0, params.viz.clust.dim.width]); params.viz.y_scale.rangeBands([0, params.viz.clust.dim.height]); // redefine zoom extent params.viz.square_zoom = params.viz.norm_labels.width.col / (params.viz.x_scale.rangeBand() / 2); params.zoom_behavior.scaleExtent([1, params.viz.square_zoom * params.viz.zoom_ratio.x]); // redefine 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; params = calc_default_fs(params); // resize the svg /////////////////////// var svg_group = d3.select(params.viz.viz_wrapper).select('svg'); svg_group.select(params.root + ' .grey_background').transition().delay(delays.update).duration(duration).attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height); resize_row_labels(params, svg_group, delays); // do not delay the font size change since this will break the bounding box calc svg_group.selectAll('.row_label_group').select('text').style('font-size', params.labels.default_fs_row + 'px').text(function (d) { return utils.normal_name(d); }); // change the size of the highlighting rects svg_group.selectAll('.row_label_group').each(function () { var bbox = d3.select(this).select('text')[0][0].getBBox(); d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.y_scale.rangeBand()).style('fill', 'yellow').style('opacity', function (d) { var inst_opacity = 0; // highlight target genes if (d.target === 1) { inst_opacity = 1; } return inst_opacity; }); }); resize_row_viz(params, svg_group, delays); if (delays.run_transition) { // positioning row text after row text size may have been reduced svg_group.selectAll('.row_label_group').select('text').transition().delay(delays.update).duration(duration).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35); svg_group.selectAll('.row_cat_group').data(row_nodes, function (d) { return d.name; }).transition().delay(delays.update).duration(duration).attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0, ' + params.viz.y_scale(inst_index) + ')'; }); svg_group.selectAll('.row_cat_group').select('path').transition().delay(delays.update).duration(duration).attr('d', function () { var origin_x = params.viz.cat_room.symbol_width - 1; var origin_y = 0; var mid_x = 1; var mid_y = params.viz.y_scale.rangeBand() / 2; var final_x = params.viz.cat_room.symbol_width - 1; var final_y = params.viz.y_scale.rangeBand(); var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z'; return output_string; }); svg_group.selectAll('.row_dendro_group').data(row_nodes, function (d) { return d.name; }).transition().delay(delays.update).duration(duration).attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0, ' + params.viz.y_scale(inst_index) + ')'; }); } else { // positioning row text after row text size may have been reduced svg_group.selectAll('.row_label_group').select('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35); svg_group.selectAll('.row_cat_group').data(row_nodes, function (d) { return d.name; }).attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0, ' + params.viz.y_scale(inst_index) + ')'; }); svg_group.selectAll('.row_cat_group').select('path').attr('d', function () { var origin_x = params.viz.cat_room.symbol_width - 1; var origin_y = 0; var mid_x = 1; var mid_y = params.viz.y_scale.rangeBand() / 2; var final_x = params.viz.cat_room.symbol_width - 1; var final_y = params.viz.y_scale.rangeBand(); var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z'; return output_string; }); svg_group.selectAll('.row_dendro_group').data(row_nodes, function (d) { return d.name; }).attr('transform', function (d) { var inst_index = _.indexOf(row_nodes_names, d.name); return 'translate(0, ' + params.viz.y_scale(inst_index) + ')'; }); } if (utils.has(params.network_data.row_nodes[0], 'value')) { resize_label_bars(cgm, svg_group); } // resize col labels /////////////////////// // reduce width of rotated rects resize_col_labels(params, svg_group, delays); resize_col_text(params, svg_group); resize_col_triangle(params, svg_group, delays); resize_col_hlight(params, svg_group, delays); resize_dendro(params, svg_group, delays); resize_super_labels(params, svg_group, delays); resize_spillover(params.viz, svg_group, delays); // reset zoom and translate params.zoom_behavior.scale(1).translate([params.viz.clust.margin.left, params.viz.clust.margin.top]); }; /***/ }, /* 183 */ /***/ function(module, exports, __webpack_require__) { var exit_existing_row = __webpack_require__(184); var enter_existing_row = __webpack_require__(185); var update_split_tiles = __webpack_require__(186); var mouseover_tile = __webpack_require__(45); var mouseout_tile = __webpack_require__(46); var fine_position_tile = __webpack_require__(47); // TODO add tip back to arguments module.exports = function eeu_existing_row(params, ini_inp_row_data, delays, duration, row_selection, tip) { var inp_row_data = ini_inp_row_data.row_data; // remove zero values from var row_values = _.filter(inp_row_data, function (num) { return num.value != 0; }); // bind data to tiles var cur_row_tiles = d3.select(row_selection).selectAll('.tile').data(row_values, function (d) { return d.col_name; }); exit_existing_row(params, delays, cur_row_tiles, inp_row_data, row_selection); /////////////////////////// // Update /////////////////////////// // update tiles in x direction var update_row_tiles = cur_row_tiles.on('mouseover', function (...args) { mouseover_tile(params, this, tip, args); }).on('mouseout', function mouseout() { mouseout_tile(params, this, tip); }); var col_nodes_names = params.network_data.col_nodes_names; if (delays.run_transition) { update_row_tiles.transition().delay(delays.update).duration(duration).attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).attr('transform', function (d) { if (_.contains(col_nodes_names, d.col_name)) { return fine_position_tile(params, d); } else { return 'translate(0,0)'; } }); } else { update_row_tiles.attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).attr('transform', function (d) { if (_.contains(col_nodes_names, d.col_name)) { return fine_position_tile(params, d); } else { return 'translate(0,0)'; } }); } if (params.matrix.tile_type == 'updn') { update_split_tiles(params, inp_row_data, row_selection, delays, duration, cur_row_tiles, tip); } enter_existing_row(params, delays, duration, cur_row_tiles, tip); }; /***/ }, /* 184 */ /***/ function(module, exports) { module.exports = function exit_existing_row(params, delays, cur_row_tiles, inp_row_data, row_selection) { if (delays.run_transition) { cur_row_tiles.exit().transition().duration(300).attr('fill-opacity', 0).remove(); } else { cur_row_tiles.exit().attr('fill-opacity', 0).remove(); } if (params.matrix.tile_type == 'updn') { // value split var row_split_data = _.filter(inp_row_data, function (num) { return num.value_up != 0 || num.value_dn != 0; }); // tile_up var cur_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) { return d.col_name; }); if (delays.run_transition) { cur_tiles_up.exit().transition().duration(300).attr('fill', '0').remove(); } else { cur_tiles_up.exit().attr('fill', 0).remove(); } // tile_dn var cur_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) { return d.col_name; }); if (delays.run_transition) { cur_tiles_dn.exit().transition().duration(300).attr('fill', 0).remove(); } else { cur_tiles_dn.exit().attr('fill', 0).remove(); } } }; /***/ }, /* 185 */ /***/ function(module, exports, __webpack_require__) { var mouseover_tile = __webpack_require__(45); var mouseout_tile = __webpack_require__(46); var fine_position_tile = __webpack_require__(47); module.exports = function enter_existing_row(params, delays, duration, cur_row_tiles, tip) { // enter new tiles var new_tiles = cur_row_tiles.enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).on('mouseover', function (...args) { mouseover_tile(params, this, tip, args); }).on('mouseout', function mouseout() { mouseout_tile(params, this, tip); }).attr('fill-opacity', 0).attr('transform', function (d) { return fine_position_tile(params, d); }); if (delays.run_transition) { new_tiles.transition().delay(delays.enter).duration(duration).style('fill', function (d) { return d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1]; }).attr('fill-opacity', function (d) { var op_val = 0, output_opacity = 0; op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val); output_opacity = params.matrix.opacity_scale(op_val); return output_opacity; }); } else { new_tiles.style('fill', function (d) { return d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1]; }).attr('fill-opacity', function (d) { var op_val = 0, output_opacity = 0; op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val); output_opacity = params.matrix.opacity_scale(Math.abs(op_val)); return output_opacity; }); } // remove new tiles if necessary new_tiles.each(function (d) { if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) { d3.select(this).remove(); } }); }; /***/ }, /* 186 */ /***/ function(module, exports, __webpack_require__) { var draw_up_tile = __webpack_require__(43); var draw_dn_tile = __webpack_require__(44); var mouseover_tile = __webpack_require__(45); var mouseout_tile = __webpack_require__(46); var fine_position_tile = __webpack_require__(47); module.exports = function update_split_tiles(params, inp_row_data, row_selection, delays, duration, cur_row_tiles, tip) { // value split var row_split_data = _.filter(inp_row_data, function (num) { return num.value_up != 0 || num.value_dn != 0; }); // tile_up var cur_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) { return d.col_name; }); // update split tiles_up var update_tiles_up = cur_tiles_up.on('mouseover', function (...args) { mouseover_tile(params, this, tip, args); }).on('mouseout', function mouseout() { mouseout_tile(params, this, tip); }); if (delays.run_transition) { update_tiles_up.transition().delay(delays.update).duration(duration).attr('d', function () { return draw_up_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }); } else { update_tiles_up.attr('d', function () { return draw_up_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }); } // tile_dn var cur_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) { return d.col_name; }); // update split tiles_dn var update_tiles_dn = cur_tiles_dn.on('mouseover', function (...args) { mouseover_tile(params, this, tip, args); }).on('mouseout', function mouseout() { mouseout_tile(params, this, tip); }); if (delays.run_transition) { update_tiles_dn.transition().delay(delays.update).duration(duration).attr('d', function () { return draw_dn_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }); } else { update_tiles_dn.attr('d', function () { return draw_dn_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }); } // remove tiles when splitting is done cur_row_tiles.selectAll('.tile').each(function (d) { if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) { d3.select(this).remove(); } }); }; /***/ }, /* 187 */ /***/ function(module, exports) { module.exports = function exit_components(params, delays, duration) { var row_nodes = params.network_data.row_nodes; var col_nodes = params.network_data.col_nodes; // remove entire rows var exiting_rows = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) { return d.name; }).exit(); if (delays.run_transition) { exiting_rows.transition().duration(duration).style('opacity', 0).remove(); } else { exiting_rows.style('opacity', 0).remove(); } // remove row labels d3.selectAll(params.root + ' .row_label_group').data(row_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); // remove column labels d3.selectAll(params.root + ' .col_label_group').data(col_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); // remove row triangles and colorbars d3.selectAll(params.root + ' .row_cat_group').data(row_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); // remove row triangles and colorbars d3.selectAll(params.root + ' .row_dendro_group').data(row_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); d3.selectAll(params.root + ' .col_label_text').data(col_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); d3.selectAll(params.root + ' .horz_lines').data(row_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); d3.selectAll(params.root + ' .vert_lines').data(col_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); // remove dendrogram d3.selectAll(params.root + ' .col_cat_group').data(col_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); d3.selectAll(params.root + ' .col_dendro_group').data(col_nodes, function (d) { return d.name; }).exit().transition().duration(duration).style('opacity', 0).remove(); }; /***/ }, /* 188 */ /***/ function(module, exports, __webpack_require__) { var enter_new_rows = __webpack_require__(189); module.exports = function enter_row_groups(params, delays, duration, tip) { // enter new rows var new_row_groups = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) { return d.name; }).enter().append('g').classed('row', true).attr('transform', function (d) { return 'translate(0,' + params.viz.y_scale(d.row_index) + ')'; }); new_row_groups.each(function (d) { enter_new_rows(params, d, delays, duration, tip, this); }); }; /***/ }, /* 189 */ /***/ function(module, exports, __webpack_require__) { var enter_split_tiles = __webpack_require__(190); var mouseover_tile = __webpack_require__(45); var mouseout_tile = __webpack_require__(46); var fine_position_tile = __webpack_require__(47); // make each row in the clustergram module.exports = function enter_new_rows(params, ini_inp_row_data, delays, duration, tip, row_selection) { var inp_row_data = ini_inp_row_data.row_data; // remove zero values to make visualization faster var row_data = _.filter(inp_row_data, function (num) { return num.value !== 0; }); // update tiles //////////////////////////////////////////// var tile = d3.select(row_selection).selectAll('rect').data(row_data, function (d) { return d.col_name; }).enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', params.viz.rect_height) // switch the color based on up/dn value .style('fill', function (d) { return d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1]; }).on('mouseover', function (...args) { mouseover_tile(params, this, tip, args); }).on('mouseout', function mouseout() { mouseout_tile(params, this, tip); }); tile.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) { // calculate output opacity using the opacity scale var op_val = 0, output_opacity = 0; op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val); output_opacity = params.matrix.opacity_scale(Math.abs(op_val)); return output_opacity; }); tile.attr('transform', function (d) { return fine_position_tile(params, d); }); if (params.matrix.tile_type == 'updn') { enter_split_tiles(params, inp_row_data, row_selection, tip, delays, duration, tile); } }; /***/ }, /* 190 */ /***/ function(module, exports, __webpack_require__) { var draw_up_tile = __webpack_require__(43); var draw_dn_tile = __webpack_require__(44); var fine_position_tile = __webpack_require__(47); module.exports = function enter_split_tiles(params, inp_row_data, row_selection, tip, delays, duration, tile) { // value split var row_split_data = _.filter(inp_row_data, function (num) { return num.value_up != 0 || num.value_dn != 0; }); // tile_up var new_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) { return d.col_name; }).enter().append('path').attr('class', 'tile_up').attr('d', function () { return draw_up_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }).style('fill', function () { return params.matrix.tile_colors[0]; }).on('mouseover', function (p) { // highlight row - set text to active if d3.selectAll(params.root + ' .row_label_group text').classed('active', function (d) { return p.row_name === d.name; }); d3.selectAll(params.root + ' .col_label_text text').classed('active', function (d) { return p.col_name === d.name; }); if (params.matrix.show_tile_tooltips) { tip.show(p); } }).on('mouseout', function () { d3.selectAll(params.root + ' text').classed('active', false); if (params.matrix.show_tile_tooltips) { tip.hide(); } }); new_tiles_up.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) { var inst_opacity = 0; if (Math.abs(d.value_dn) > 0) { var op_val = params.matrix.mid_val + Math.abs(d.value_up - params.matrix.mid_val); inst_opacity = params.matrix.opacity_scale(op_val); } return inst_opacity; }); // tile_dn var new_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) { return d.col_name; }).enter().append('path').attr('class', 'tile_dn').attr('d', function () { return draw_dn_tile(params); }).attr('transform', function (d) { return fine_position_tile(params, d); }).style('fill', function () { return params.matrix.tile_colors[1]; }).on('mouseover', function (p) { // highlight row - set text to active if d3.selectAll(params.root + ' .row_label_group text').classed('active', function (d) { return p.row_name === d.name; }); d3.selectAll(params.root + ' .col_label_text text').classed('active', function (d) { return p.col_name === d.name; }); if (params.matrix.show_tile_tooltips) { tip.show(p); } }).on('mouseout', function () { d3.selectAll(params.root + ' text').classed('active', false); if (params.matrix.show_tile_tooltips) { tip.hide(); } }); new_tiles_dn.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) { var inst_opacity = 0; if (Math.abs(d.value_up) > 0) { var op_val = params.matrix.mid_val + Math.abs(d.value_dn - params.matrix.mid_val); inst_opacity = params.matrix.opacity_scale(op_val); } return inst_opacity; }); // remove tiles when splitting is done tile.each(function (d) { if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) { d3.select(this).remove(); } }); }; /***/ }, /* 191 */ /***/ function(module, exports) { module.exports = function resize_containers(params) { // reposition matrix d3.select(params.root + ' .clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')'); // reposition col container d3.select(params.root + ' .col_label_outer_container').attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')'); // reposition col_viz container d3.select(params.root + ' .col_cat_outer_container').attr('transform', function () { var inst_offset = params.viz.norm_labels.width.col + 2; return 'translate(0,' + inst_offset + ')'; }); }; /***/ }, /* 192 */ /***/ function(module, exports, __webpack_require__) { /* eslint-disable */ var change_groups = __webpack_require__(163); var all_reorder = __webpack_require__(115); var ini_cat_reorder = __webpack_require__(114); var run_row_search = __webpack_require__(193); module.exports = function ini_sidebar(cgm) { var params = cgm.params; var input = d3.select(params.root + ' .gene_search_box')[0][0]; var awesomplete = new Awesomplete(input, { minChars: 1, maxItems: 15 }); var entities = cgm.params.network_data.row_nodes_names; awesomplete.list = entities; // position awesomplete list elements above other elements in the page d3.selectAll('.awesomplete ul').style('z-index', 99); // submit genes button $(params.root + ' .gene_search_box').keyup(function (e) { if (e.keyCode === 13) { var search_gene = $(params.root + ' .gene_search_box').val(); run_row_search(cgm, search_gene, entities); } }); $(params.root + ' .submit_gene_button').off().click(function () { var search_gene = $(params.root + ' .gene_search_box').val(); run_row_search(cgm, search_gene, entities); }); var reorder_types; if (params.sim_mat) { reorder_types = ['both']; } else { reorder_types = ['row', 'col']; } _.each(reorder_types, function (inst_rc) { // reorder buttons $(params.root + ' .toggle_' + inst_rc + '_order .btn').off().click(function (evt) { var order_id = $(evt.target).attr('name').replace('_row', '').replace('_col', ''); d3.selectAll(params.root + ' .toggle_' + inst_rc + '_order .btn').classed('active', false); d3.select(this).classed('active', true); if (inst_rc != 'both') { all_reorder(cgm, order_id, inst_rc); } else { all_reorder(cgm, order_id, 'row'); all_reorder(cgm, order_id, 'col'); } }); }); ini_cat_reorder(cgm); // Opacity Slider ////////////////////////////////////////////////////////////////////// if (d3.select(cgm.params.root + ' .opacity_slider').select('#handle-one').empty()) { var slider_fun = d3.slider().snap(true).value(1).min(0.1).max(1.9).step(0.1).on('slide', function (evt, value) { run_on_opacity_slide(evt, value); }); d3.select(cgm.params.root + ' .opacity_slider').call(slider_fun); } function run_on_dendro_slide(evt, value, inst_rc) { $("#amount").val("$" + value); var inst_index = value * 10; // var inst_rc; if (inst_rc != 'both') { change_groups(cgm, inst_rc, inst_index); } else { change_groups(cgm, 'row', inst_index); change_groups(cgm, 'col', inst_index); } } function run_on_opacity_slide(evt, value) { var inst_index = 2 - value; var scaled_max = cgm.params.matrix.abs_max_val * inst_index; cgm.params.matrix.opacity_scale.domain([0, scaled_max]); d3.selectAll(cgm.params.root + ' .tile').style('fill-opacity', function (d) { // calculate output opacity using the opacity scale var op_val = 0, output_opacity = 0; op_val = cgm.params.matrix.mid_val + Math.abs(d.value - cgm.params.matrix.mid_val); var output_opacity = cgm.params.matrix.opacity_scale(op_val); return output_opacity; }); } }; /***/ }, /* 193 */ /***/ function(module, exports, __webpack_require__) { var two_translate_zoom = __webpack_require__(116); module.exports = function run_row_search(cgm, search_term, entities) { var prop = 'name'; if (entities.indexOf(search_term) !== -1) { // unhighlight d3.selectAll(cgm.params.root + ' .row_label_group').select('rect').style('opacity', 0); // calc pan_dy var idx = _.indexOf(entities, search_term); var inst_y_pos = cgm.params.viz.y_scale(idx); var pan_dy = cgm.params.viz.clust.dim.height / 2 - inst_y_pos; var inst_zoom = cgm.params.viz.zoom_ratio.x; // working on improving zoom behavior /////////////////////////////////////////////////// /////////////////////////////////////////////////// // // increase zoom // inst_zoom = 3 * inst_zoom; // // move visualization down less // pan_dy = pan_dy - 5; two_translate_zoom(cgm, 0, pan_dy, inst_zoom); // set y zoom to zoom_switch cgm.params.zoom_info.zoom_y = inst_zoom; // highlight d3.selectAll(cgm.params.root + ' .row_label_group').filter(function (d) { return d[prop] === search_term; }).select('rect').style('opacity', 1); } }; /***/ }, /* 194 */ /***/ function(module, exports) { module.exports = function enable_sidebar(params) { /* only enable dendrogram sliders if there has been no dendro_filtering */ // only enable reordering if params.dendro_filter.row === false if (params.dendro_filter.row === false) { // orders are switched! if (params.viz.inst_order.col === 'clust') { d3.select(params.root + ' .row_slider_group').style('opacity', 1).style('pointer-events', 'all'); } } d3.selectAll(params.root + ' .toggle_row_order .btn').attr('disabled', null); if (params.dendro_filter.col === false) { // orders are switched! if (params.viz.inst_order.row === 'clust') { d3.select(params.root + ' .col_slider_group').style('opacity', 1).style('pointer-events', 'all'); } } d3.selectAll(params.root + ' .toggle_col_order .btn').attr('disabled', null); d3.selectAll(params.root + ' .gene_search_button .btn').attr('disabled', null); params.viz.run_trans = false; }; /***/ }, /* 195 */ /***/ function(module, exports) { module.exports = function update_reorder_buttons(tmp_config, params) { _.each(['row', 'col'], function (inst_rc) { var other_rc; if (inst_rc === 'row') { other_rc = 'col'; } else { other_rc = 'row'; } d3.selectAll(params.root + ' .toggle_' + other_rc + '_order .btn').filter(function () { return d3.select(this).attr('name') === tmp_config.inst_order[inst_rc]; }).classed('active', true); }); }; /***/ }, /* 196 */ /***/ function(module, exports, __webpack_require__) { var remove_node_cats = __webpack_require__(197); var utils = __webpack_require__(2); module.exports = function modify_row_node_cats(cat_data, inst_nodes, strip_names = false) { // console.log('MODIFY ROW NODE CATS') // console.log('CAT_DATA') // console.log(cat_data) var cat_type_num = 0; var inst_index = 0; var inst_cat_title; var inst_cats; var inst_members; var inst_name; var inst_category; var inst_cat_name; var inst_full_cat; var inst_cat_num; // loop through row nodes ////////////////////////// _.each(inst_nodes, function (inst_node) { inst_name = inst_node.name; // not sure if this is needed // inst_name = inst_name.toUpperCase(); if (strip_names === true) { // only consider first part of inst_name //////////////////////////////////////////// // may improve this if (inst_name.indexOf(' ')) { inst_name = inst_name.split(' ')[0]; } else if (inst_name.indexOf('_')) { inst_name = inst_name.split('_')[0]; } } cat_type_num = 0; remove_node_cats(inst_node); // loop through each category type _.each(cat_data, function (inst_cat_data) { inst_cat_title = inst_cat_data.cat_title; inst_cats = inst_cat_data.cats; // initialize with no category inst_category = 'false'; inst_index = -1; inst_cat_num = 0; // loop through each category in the category-type _.each(inst_cats, function (inst_cat) { inst_cat_name = inst_cat.cat_name; inst_members = inst_cat.members; // add category if node is a member if (_.contains(inst_members, inst_name)) { inst_category = inst_cat_name; inst_index = inst_cat_num; } inst_cat_num = inst_cat_num + 1; }); if (utils.has(inst_cat_data, 'pval')) { var inst_pval = inst_cat_data.pval.toExponential(); inst_full_cat = inst_cat_title + ': ' + inst_category + '<p> Pval ' + String(inst_pval) + '</p>'; } else { if (inst_cat_title.indexOf('cat-') === -1) { inst_full_cat = inst_cat_title + ': ' + inst_category; } else { inst_full_cat = inst_category; } } inst_node['cat-' + String(cat_type_num)] = inst_full_cat; inst_node['cat_' + String(cat_type_num) + '_index'] = inst_index; cat_type_num = cat_type_num + 1; }); }); }; /***/ }, /* 197 */ /***/ function(module, exports) { module.exports = function remove_node_cats(inst_node) { var all_props = _.keys(inst_node); _.each(all_props, function (inst_prop) { if (inst_prop.indexOf('cat-') > -1) { delete inst_node[inst_prop]; } if (inst_prop.indexOf('cat_') > -1) { delete inst_node[inst_prop]; } }); }; /***/ }, /* 198 */ /***/ function(module, exports, __webpack_require__) { var reset_size_after_update = __webpack_require__(182); var make_col_label_container = __webpack_require__(103); var show_visible_area = __webpack_require__(106); var resize_containers = __webpack_require__(191); module.exports = function ds_enter_exit_update(cgm) { // console.log('======== ds_enter_exit_update ==============='); // remove row labels, remove non-downsampled rows, and add downsampled rows d3.selectAll(cgm.params.root + ' .row_cat_group').remove(); d3.selectAll(cgm.params.root + ' .row_label_group').remove(); d3.selectAll(cgm.params.root + ' .row').remove(); // no need to re-calculate the downsampled layers // calc_downsampled_levels(params); var zooming_stopped = true; var zooming_out = true; var make_all_rows = true; // show_visible_area is also run with two_translate_zoom, but at that point // the parameters were not updated and two_translate_zoom if only run // if needed to reset zoom show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows); make_col_label_container(cgm); var col_nodes = cgm.params.network_data.col_nodes; // remove column labels d3.selectAll(cgm.params.root + ' .col_label_group').data(col_nodes, function (d) { return d.name; }).exit().style('opacity', 0).remove(); d3.selectAll(cgm.params.root + ' .col_label_text').data(col_nodes, function (d) { return d.name; }).exit().style('opacity', 0).remove(); d3.selectAll(cgm.params.root + ' .col_cat_group').data(col_nodes, function (d) { return d.name; }).exit().style('opacity', 0).remove(); d3.selectAll(cgm.params.root + ' .col_dendro_group').data(col_nodes, function (d) { return d.name; }).exit().style('opacity', 0).remove(); // necessary for repositioning clust, col and col-cat containers resize_containers(cgm.params); // seeing if this fixes resizing issue var delays = {}; delays.enter = 0; delays.update = 0; delays.run_transition = false; var duration = 0; reset_size_after_update(cgm, duration, delays); }; /***/ }, /* 199 */ /***/ function(module, exports, __webpack_require__) { var sim_click = __webpack_require__(171); module.exports = function quick_cluster() { /* eslint-disable */ function run(params) { var x_trans = Number(d3.select(params.root + ' .expand_button').attr('x').replace('px', '')); var y_trans = Number(d3.select(params.root + ' .expand_button').attr('y').replace('px', '')); var wait_click = 0; var wait_real_click = 400; setTimeout(sim_click, wait_click, params, 'single', x_trans, y_trans); setTimeout(click_menu_button, wait_real_click, params); setTimeout(reset_cluster_order, 1500, params); } function get_duration() { return 3500; } function click_menu_button(params) { $(params.root + ' .expand_button').d3Click(); }; function reset_cluster_order(params) { click_reorder_button(params, 'row', 'clust'); click_reorder_button(params, 'col', 'clust'); } function click_reorder_button(params, inst_rc, inst_order) { var inst_button = d3.selectAll('.toggle_' + inst_rc + '_order .btn').filter(function () { return this.__data__ == inst_order; })[0]; $(inst_button).click(); } // allows doubleclicking on d3 element jQuery.fn.d3Click = function () { this.each(function (i, e) { var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); e.dispatchEvent(evt); }); }; return { run: run, get_duration: get_duration }; }; /***/ }, /* 200 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var highlight_sidebar_element = __webpack_require__(174); var change_groups = __webpack_require__(163); module.exports = function play_groups() { /* eslint-disable */ function run(params) { var text = 'Identify row and column groups\nof varying sizes using ' + ' the\nsliders and dendrogram'; demo_text(params, text, 10000); setTimeout(highlight_sidebar_element, 3000, params, 'slider_col', 7000); setTimeout(change_group_slider, 4000, params, 'row', 3); setTimeout(change_group_slider, 5000, params, 'row', 4); setTimeout(change_group_slider, 6000, params, 'row', 5); setTimeout(change_group_slider, 7000, params, 'row', 6); setTimeout(change_group_slider, 8000, params, 'row', 7); setTimeout(change_group_slider, 9000, params, 'row', 5); } function get_duration() { return 11000; } function change_group_slider(params, inst_rc, inst_value) { $(cgm.params.root + ' .slider_col').slider("value", inst_value / 10); change_groups(cgm, inst_rc, inst_value); } return { run: run, get_duration: get_duration }; }; /***/ }, /* 201 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var sim_click = __webpack_require__(171); module.exports = function play_category() { /* eslint-disable */ function run(params) { var text = 'Row and column categories\ncan be use to reorder\nby double-clicking'; demo_text(params, text, 7000); var inst_element = d3.selectAll(params.root + ' .col_cat_super').filter(function () { return this.__data__ === 'cat-1'; })[0]; var tmp_pos = d3.select('.col_cat_super').attr('transform'); var x_trans = Number(tmp_pos.split('(')[1].split(',')[0].replace(')', '')) + 20; var y_trans = Number(tmp_pos.split(',')[1].replace(')', '')); var wait_click = 4000; setTimeout(sim_click, wait_click, params, 'double', x_trans, y_trans); var wait_reorder = wait_click + 300; setTimeout(fire_double_click_row, wait_reorder, params, inst_element); } function get_duration() { return 8000; } function fire_double_click_row(params, inst_element) { $(inst_element).d3DblClick(); } // allows doubleclicking on d3 element jQuery.fn.d3DblClick = function () { this.each(function (i, e) { var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); e.dispatchEvent(evt); }); }; return { run: run, get_duration: get_duration }; }; /***/ }, /* 202 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var toggle_play_button = __webpack_require__(203); module.exports = function play_conclusion() { function run(params) { var text_1 = "Clustergrammer is built with gene\nexpression data in mind" + " and interfaces\nwith several Ma'ayan lab web tools"; var text_2 = "The example data being visualized is\ngene expression data" + " obtained from the\nCancer Cell Line Encyclopedia"; var text_3 = "For more information please view\nthe help documentation"; setTimeout(demo_text, 0, params, text_1, 4500); setTimeout(demo_text, 4500, params, text_2, 4500); setTimeout(demo_text, 9000, params, text_3, 4500); setTimeout(reset_demo, 14000, params); } function reset_demo(params) { // prevent more than one demo from running at once d3.select(params.root + ' .play_button').classed('running_demo', false); toggle_play_button(params, true); } function get_duration() { return 12000; } return { run: run, get_duration: get_duration }; }; /***/ }, /* 203 */ /***/ function(module, exports) { module.exports = function toggle_play_button(params, show) { if (show === false) { d3.select(params.root + ' .play_button').transition().duration(500).style('opacity', 0); } else { d3.select(params.root + ' .play_button').transition().duration(500).style('opacity', 1); $.unblockUI(); } }; /***/ }, /* 204 */ /***/ function(module, exports, __webpack_require__) { var demo_text = __webpack_require__(168); var sim_click = __webpack_require__(171); module.exports = function play_menu_button() { /* eslint-disable */ function run(params) { var text = 'View additional controls\nby clicking the menu button'; demo_text(params, text, 4000); // var inst_element = get_row_element(params, 'EGFR'); // var group_trans = d3.select(inst_element).attr('transform'); // var container_trans = d3.select(params.root+' .clust_container') // .attr('transform') // .split(',')[1].replace(')',''); // var x_trans = params.viz.norm_labels.width.row * 0.9; // var row_trans = group_trans.split(',')[1].replace(')',''); // var y_trans = String(Number(row_trans) + Number(container_trans) + // params.viz.rect_height/2); var x_trans = Number(d3.select(params.root + ' .expand_button').attr('x').replace('px', '')); var y_trans = Number(d3.select(params.root + ' .expand_button').attr('y').replace('px', '')); var wait_click = 3000; var wait_real_click = 3400; setTimeout(sim_click, wait_click, params, 'single', x_trans, y_trans); setTimeout(click_menu_button, wait_real_click, params); } function get_duration() { return 5000; } function click_menu_button(params) { $(params.root + ' .expand_button').d3Click(); }; function get_row_element(params, inst_row) { var inst_element = d3.selectAll(params.root + ' .row_label_group').filter(function () { var inst_data = this.__data__; return inst_data.name == inst_row; })[0][0]; return inst_element; } // allows doubleclicking on d3 element jQuery.fn.d3Click = function () { this.each(function (i, e) { var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); e.dispatchEvent(evt); }); }; // allows doubleclicking on d3 element jQuery.fn.d3DblClick = function () { this.each(function (i, e) { var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); e.dispatchEvent(evt); }); }; return { run: run, get_duration: get_duration }; }; /***/ }, /* 205 */ /***/ function(module, exports, __webpack_require__) { var make_play_button = __webpack_require__(206); var make_demo_text_containers = __webpack_require__(207); module.exports = function ini_demo() { var cgm = this; var params = cgm.params; make_play_button(cgm); var demo_text_size = 30; make_demo_text_containers(params, demo_text_size); }; /***/ }, /* 206 */ /***/ function(module, exports, __webpack_require__) { var position_play_button = __webpack_require__(149); module.exports = function make_play_button(cgm) { var params = cgm.params; if (d3.select(params.root + ' .play_button').empty()) { var play_button = d3.select(params.root + ' .viz_svg').append('g').classed('play_button', true).classed('running_demo', false); position_play_button(params); play_button.append('circle').style('r', 45).style('fill', 'white').style('stroke', 'black').style('stroke-width', '3px').style('opacity', 0.5); play_button.append('path').attr('d', function () { var tri_w = 40; var tri_h = 22; var tri_offset = 15; return 'M-' + tri_offset + ',-' + tri_h + ' l ' + tri_w + ',' + tri_h + ' l -' + tri_w + ',' + tri_h + ' z '; }).style('fill', 'black').style('opacity', 0.5); // mouseover behavior play_button.on('mouseover', function () { d3.select(this).select('path').style('fill', 'red').style('opacity', 1); d3.select(this).select('circle').style('opacity', 1); }).on('mouseout', function () { d3.select(this).select('path').style('fill', 'black').style('opacity', 0.5); d3.select(this).select('circle').style('opacity', 0.5); }).on('click', function () { // running from anonymous function to keep this defined correctly cgm.play_demo(); }); } }; /***/ }, /* 207 */ /***/ function(module, exports) { module.exports = function make_demo_text_containers(params, demo_text_size) { if (d3.select(params.root + ' .demo_group').empty()) { var clust_transform = d3.select(params.root + ' .clust_container').attr('transform'); var clust_x = Number(clust_transform.split('(')[1].split(',')[0]); var clust_y = Number(clust_transform.split(',')[1].replace(')', '')); // demo text container var demo_group = d3.select(params.root + ' .viz_svg').append('g').classed('demo_group', true).attr('transform', function () { var pos_x = clust_x + 20; var pos_y = clust_y + 40; return 'translate(' + pos_x + ',' + pos_y + ')'; }); demo_group.append('rect').classed('rect_1', true); demo_group.append('rect').classed('rect_2', true); demo_group.append('rect').classed('rect_3', true); var shift_height = 1.3 * demo_text_size; demo_group.append('text').attr('id', 'text_1').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif'); demo_group.append('text').attr('id', 'text_2').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('transform', function () { return 'translate(0,' + String(shift_height) + ')'; }); demo_group.append('text').attr('id', 'text_3').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('transform', function () { return 'translate(0,' + String(2 * shift_height) + ')'; }); } }; /***/ }, /* 208 */ /***/ function(module, exports, __webpack_require__) { var filter_network_using_new_nodes = __webpack_require__(11); var update_viz_with_network = __webpack_require__(179); module.exports = function filter_viz_using_nodes(new_nodes) { var new_network_data = filter_network_using_new_nodes(this.config, new_nodes); update_viz_with_network(this, new_network_data); }; /***/ }, /* 209 */ /***/ function(module, exports, __webpack_require__) { var filter_network_using_new_nodes = __webpack_require__(11); var update_viz_with_network = __webpack_require__(179); module.exports = function filter_viz_using_names(names, external_cgm = false) { // names is an object with row and column names that will be used to filter // the matrix var cgm; if (external_cgm === false) { cgm = this; } else { cgm = external_cgm; } var params = cgm.params; var new_nodes = {}; var found_nodes; _.each(['row', 'col'], function (inst_rc) { var orig_nodes = params.inst_nodes[inst_rc + '_nodes']; if (_.has(names, inst_rc)) { if (names[inst_rc].length > 0) { var inst_names = names[inst_rc]; found_nodes = $.grep(orig_nodes, function (d) { return $.inArray(d.name, inst_names) > -1; }); } else { found_nodes = orig_nodes; } } else { found_nodes = orig_nodes; } new_nodes[inst_rc + '_nodes'] = found_nodes; }); // keep backup of the nodes for resetting filtering var inst_row_nodes = cgm.params.network_data.row_nodes; var inst_col_nodes = cgm.params.network_data.col_nodes; var new_network_data = filter_network_using_new_nodes(cgm.config, new_nodes); // takes entire cgm object // last argument tells it to not preserve categoty colors update_viz_with_network(cgm, new_network_data); // only keep backup if previous number of nodes were larger than current number // of nodes if (inst_row_nodes.length > cgm.params.inst_nodes.row_nodes.length) { cgm.params.inst_nodes.row_nodes = inst_row_nodes; } if (inst_col_nodes.length > cgm.params.inst_nodes.col_nodes.length) { cgm.params.inst_nodes.col_nodes = inst_col_nodes; } }; /***/ }, /* 210 */ /***/ function(module, exports, __webpack_require__) { var make_row_cat = __webpack_require__(158); var calc_viz_params = __webpack_require__(15); var resize_viz = __webpack_require__(124); var modify_row_node_cats = __webpack_require__(196); module.exports = function update_cats(cgm, cat_data) { // Only accessible from the cgm API, cat_data is provided by externally /////////////////////////////////////////////////////////////////////////// if (cgm.params.cat_update_callback != null) { cgm.params.cat_update_callback(this); } // do not change column category info var col_cat_colors = cgm.params.viz.cat_colors.col; modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes, true); // modify the current inst copy of nodes modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes, true); // recalculate the visualization parameters using the updated network_data cgm.params = calc_viz_params(cgm.params, false); make_row_cat(cgm, true); resize_viz(cgm); cgm.params.new_row_cats = cat_data; cgm.params.viz.cat_colors.col = col_cat_colors; }; /***/ }, /* 211 */ /***/ function(module, exports, __webpack_require__) { var make_row_cat = __webpack_require__(158); var calc_viz_params = __webpack_require__(15); var resize_viz = __webpack_require__(124); var modify_row_node_cats = __webpack_require__(196); var generate_cat_data = __webpack_require__(212); module.exports = function reset_cats(run_resize_viz = true) { // console.log('RESET CATS') var cgm = this; var cat_data = generate_cat_data(cgm); // do not change column category info var col_cat_colors = cgm.params.viz.cat_colors.col; modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes); // modify the current inst copy of nodes modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes); cgm.params.new_row_cats = cat_data; cgm.params.viz.cat_colors.col = col_cat_colors; if (run_resize_viz) { // resize visualizatino //////////////////////////// // recalculate the visualization parameters using the updated network_data var predefine_cat_colors = true; cgm.params = calc_viz_params(cgm.params, predefine_cat_colors); make_row_cat(cgm, true); resize_viz(cgm); } }; /***/ }, /* 212 */ /***/ function(module, exports) { module.exports = function generate_cat_data(cgm) { // only row category resetting is supported currently // get row_nodes from config, since this is has the original network var row_nodes = cgm.config.network_data.row_nodes; var title_sep = ': '; // contains all the category information stored as an array of // cat_type var cat_data = []; var cat_type; var cat_info; var found_cat_title; var found_cat_name; var cat_name; // console.log('generate_cat_data') // console.log(cgm.params.viz.cat_names.row) // get current list of cateories var check_node = row_nodes[0]; var node_keys = _.keys(check_node); var current_cats = {}; var tmp_cat; var tmp_title; var cat_index; _.each(node_keys, function (inst_prop) { if (inst_prop.indexOf('cat-') >= 0) { // generate titles from cat info tmp_cat = check_node[inst_prop]; cat_index = parseInt(inst_prop.split('cat-')[1], 10); // use given title if (tmp_cat.indexOf(title_sep) >= 0) { tmp_title = tmp_cat.split(title_sep)[0]; } else { tmp_title = inst_prop; } // current_cats.push(tmp_title); current_cats[cat_index] = tmp_title; } }); // console.log('current_cats') // console.log(current_cats) // initialize cat_data with categories in the correct order var all_index = _.keys(current_cats).sort(); var inst_data; _.each(all_index, function (inst_index) { inst_data = {}; inst_data.cat_title = current_cats[inst_index]; inst_data.cats = []; cat_data.push(inst_data); }); // // initialize cat_data (keep original order) // var found_title; // _.each(cgm.params.viz.cat_names.row, function(inst_title){ // found_title = false; // console.log('inst_title -> ' + String(inst_title)) // if (current_cats.indexOf(inst_title) >= 0){ // found_title = true; // } // // only track cats that are found in the incoming nodes // if (found_title){ // var inst_data = {}; // inst_data.cat_title = inst_title; // inst_data.cats = []; // cat_data.push(inst_data); // } // }); // console.log('cat_data after cross checking with current cats') // console.log(cat_data) // console.log('-------------------------\n') _.each(row_nodes, function (inst_node) { var all_props = _.keys(inst_node); _.each(all_props, function (inst_prop) { if (inst_prop.indexOf('cat-') > -1) { cat_name = inst_node[inst_prop]; cat_index = parseInt(inst_prop.split('cat-')[1], 10); // default title and name var cat_title = inst_prop; cat_name = inst_node[inst_prop]; var cat_string = inst_node[inst_prop]; var cat_row_name = inst_node.name; // console.log('cat_string: '+String(cat_string)) // found actual title if (cat_string.indexOf(title_sep) > -1) { cat_title = cat_string.split(title_sep)[0]; cat_name = cat_string.split(title_sep)[1]; } else { // cat_title = 'Category-'+String(parseInt(inst_prop.split('-')[1]) + 1) cat_title = inst_prop; cat_name = cat_string; } // console.log('cat_index -> ' + String(cat_index)) // console.log('cat_name '+cat_name) // console.log('cat_title ' + cat_title) // console.log('--------') // cat_data is empty if (cat_data.length === 0) { add_new_cat_type(cat_title, cat_name, cat_row_name); // cat_data is not empty } else { // look for cat_title in cat_data found_cat_title = false; _.each(cat_data, function (inst_cat_type) { // console.log('inst_cat_data title ' + inst_cat_type.cat_title) // check each cat_type object for a matching title if (cat_title === inst_cat_type.cat_title) { found_cat_title = true; // check if cat_name is in cats found_cat_name = false; _.each(inst_cat_type.cats, function (inst_cat_obj) { // found category name, add cat_row_name to members if (cat_name === inst_cat_obj.cat_name) { found_cat_name = true; // add cat_row_name to members inst_cat_obj.members.push(cat_row_name); } }); // did not find cat name in cat_type - add cat_info for new // category if (found_cat_name === false) { cat_info = {}; cat_info.cat_name = cat_name; cat_info.members = []; cat_info.members.push(cat_row_name); inst_cat_type.cats.push(cat_info); } } }); // did not find category type, initialize category type object if (found_cat_title === false) { // console.log('did not find cat_title: ' + String(cat_title)) // add_new_cat_type(cat_title, cat_name, cat_row_name); } } } }); }); function add_new_cat_type(cat_title, cat_name, cat_row_name) { // initialize cat_type object to push to cat_data cat_type = {}; cat_type.cat_title = cat_title; cat_type.cats = []; // initialize cat_info (e.g. 'true' category has members [...]) cat_info = {}; cat_info.cat_name = cat_name; cat_info.members = []; cat_info.members.push(cat_row_name); cat_type.cats.push(cat_info); cat_data.push(cat_type); } // console.log('RETURNING CAT DATA') // console.log(cat_data) return cat_data; }; /***/ }, /* 213 */ /***/ function(module, exports, __webpack_require__) { var update_viz_with_view = __webpack_require__(177); var reset_other_filter_sliders = __webpack_require__(214); module.exports = function external_update_view(filter_type, inst_state) { // add something to control slider position ///////////////////////////////////////////// var cgm = this; var requested_view = {}; requested_view[filter_type] = inst_state; update_viz_with_view(this, requested_view); reset_other_filter_sliders(cgm, filter_type, inst_state); }; /***/ }, /* 214 */ /***/ function(module, exports, __webpack_require__) { var make_filter_title = __webpack_require__(215); module.exports = function reset_other_filter_sliders(cgm, filter_type, inst_state) { var params = cgm.params; var inst_rc; var reset_rc; d3.select(params.root + ' .slider_' + filter_type).attr('current_state', inst_state); _.each(_.keys(params.viz.possible_filters), function (reset_filter) { if (filter_type.indexOf('row') > -1) { inst_rc = 'row'; } else if (filter_type.indexOf('col') > -1) { inst_rc = 'col'; } else { inst_rc = 'neither'; } if (reset_filter.indexOf('row') > -1) { reset_rc = 'row'; } else if (reset_filter.indexOf('col') > -1) { reset_rc = 'col'; } else { reset_rc = 'neither'; } if (filter_type != reset_filter && inst_rc != 'neither') { if (inst_rc == reset_rc) { var tmp_title = make_filter_title(params, reset_filter); cgm.slider_functions[reset_filter].value(0); d3.select(params.root + ' .title_' + reset_filter).text(tmp_title.text + tmp_title.state); d3.select(params.root + ' .slider_' + reset_filter).attr('current_state', tmp_title.state); } } }); var filter_title = make_filter_title(params, filter_type); d3.select(params.root + ' .title_' + filter_type).text(filter_title.text + inst_state + filter_title.suffix); }; /***/ }, /* 215 */ /***/ function(module, exports, __webpack_require__) { var get_filter_default_state = __webpack_require__(5); module.exports = function make_filter_title(params, filter_type) { var filter_title = {}; var title = {}; var type = {}; filter_title.state = get_filter_default_state(params.viz.filter_data, filter_type); type.top = filter_type.split('_')[0]; type.node = filter_type.split('_')[1]; type.measure = filter_type.split('_')[2]; if (type.node === 'row') { title.node = 'rows'; } else { title.node = 'columns'; } if (type.top === 'N') { // filter_title.suffix = ' '+title.node; filter_title.suffix = ''; } if (type.top === 'pct') { filter_title.suffix = '%'; } if (type.measure == 'sum') { title.measure = 'sum'; } else if (type.measure == 'var') { title.measure = 'variance'; } if (type.measure === 'sum') { filter_title.text = 'Top ' + title.node + ' ' + title.measure + ': '; } if (type.measure === 'var') { filter_title.text = 'Top ' + title.node + ' ' + title.measure + ': '; } // Enrichr specific rules if (_.keys(params.viz.possible_filters).indexOf('enr_score_type') > -1) { if (type.node === 'col') { filter_title.text = 'Top Enriched Terms: '; filter_title.suffix = ''; } } return filter_title; }; /***/ }, /* 216 */ /***/ function(module, exports, __webpack_require__) { var file_saver = __webpack_require__(217); var make_matrix_string = __webpack_require__(218); module.exports = function save_matrix() { var saveAs = file_saver(); var params = this.params; var matrix_string = make_matrix_string(params); var blob = new Blob([matrix_string], { type: 'text/plain;charset=utf-8' }); saveAs(blob, 'clustergrammer.txt'); }; /***/ }, /* 217 */ /***/ function(module, exports) { module.exports = function file_saver() { /* eslint-disable */ /* FileSaver.js * A saveAs() FileSaver implementation. * 2013-01-23 * * By Eli Grey, http://eligrey.com * License: X11/MIT * See LICENSE.md */ /*global self */ /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, plusplus: true */ /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ var saveAs = saveAs || navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator) || function (view) { "use strict"; var doc = view.document // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet , get_URL = function () { return view.URL || view.webkitURL || view; }, URL = view.URL || view.webkitURL || view, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"), can_use_save_link = "download" in save_link, click = function (node) { var event = doc.createEvent("MouseEvents"); event.initMouseEvent("click", true, false, view, 0, 0, 0, 0, 0, false, false, false, false, 0, null); node.dispatchEvent(event); }, webkit_req_fs = view.webkitRequestFileSystem, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem, throw_outside = function (ex) { (view.setImmediate || view.setTimeout)(function () { throw ex; }, 0); }, force_saveable_type = "application/octet-stream", fs_min_size = 0, deletion_queue = [], process_deletion_queue = function () { var i = deletion_queue.length; while (i--) { var file = deletion_queue[i]; if (typeof file === "string") { // file is an object URL URL.revokeObjectURL(file); } else { // file is a File file.remove(); } } deletion_queue.length = 0; // clear queue }, dispatch = function (filesaver, event_types, event) { event_types = [].concat(event_types); var i = event_types.length; while (i--) { var listener = filesaver["on" + event_types[i]]; if (typeof listener === "function") { try { listener.call(filesaver, event || filesaver); } catch (ex) { throw_outside(ex); } } } }, FileSaver = function (blob, name) { // First try a.download, then web filesystem, then object URLs var filesaver = this, type = blob.type, blob_changed = false, object_url, target_view, get_object_url = function () { var object_url = get_URL().createObjectURL(blob); deletion_queue.push(object_url); return object_url; }, dispatch_all = function () { dispatch(filesaver, "writestart progress write writeend".split(" ")); } // on any filesys errors revert to saving with object URLs , fs_error = function () { // don't create more object URLs than needed if (blob_changed || !object_url) { object_url = get_object_url(blob); } if (target_view) { target_view.location.href = object_url; } filesaver.readyState = filesaver.DONE; dispatch_all(); }, abortable = function (func) { return function () { if (filesaver.readyState !== filesaver.DONE) { return func.apply(this, arguments); } }; }, create_if_not_found = { create: true, exclusive: false }, slice; filesaver.readyState = filesaver.INIT; if (!name) { name = "download"; } if (can_use_save_link) { object_url = get_object_url(blob); save_link.href = object_url; save_link.download = name; click(save_link); filesaver.readyState = filesaver.DONE; dispatch_all(); return; } // Object and web filesystem URLs have a problem saving in Google Chrome when // viewed in a tab, so I force save with application/octet-stream // http://code.google.com/p/chromium/issues/detail?id=91158 if (view.chrome && type && type !== force_saveable_type) { slice = blob.slice || blob.webkitSlice; blob = slice.call(blob, 0, blob.size, force_saveable_type); blob_changed = true; } // Since I can't be sure that the guessed media type will trigger a download // in WebKit, I append .download to the filename. // https://bugs.webkit.org/show_bug.cgi?id=65440 if (webkit_req_fs && name !== "download") { name += ".download"; } if (type === force_saveable_type || webkit_req_fs) { target_view = view; } else { target_view = view.open(); } if (!req_fs) { fs_error(); return; } fs_min_size += blob.size; req_fs(view.TEMPORARY, fs_min_size, abortable(function (fs) { fs.root.getDirectory("saved", create_if_not_found, abortable(function (dir) { var save = function () { dir.getFile(name, create_if_not_found, abortable(function (file) { file.createWriter(abortable(function (writer) { writer.onwriteend = function (event) { target_view.location.href = file.toURL(); deletion_queue.push(file); filesaver.readyState = filesaver.DONE; dispatch(filesaver, "writeend", event); }; writer.onerror = function () { var error = writer.error; if (error.code !== error.ABORT_ERR) { fs_error(); } }; "writestart progress write abort".split(" ").forEach(function (event) { writer["on" + event] = filesaver["on" + event]; }); writer.write(blob); filesaver.abort = function () { writer.abort(); filesaver.readyState = filesaver.DONE; }; filesaver.readyState = filesaver.WRITING; }), fs_error); }), fs_error); }; dir.getFile(name, { create: false }, abortable(function (file) { // delete file if it already exists file.remove(); save(); }), abortable(function (ex) { if (ex.code === ex.NOT_FOUND_ERR) { save(); } else { fs_error(); } })); }), fs_error); }), fs_error); }, FS_proto = FileSaver.prototype, saveAs = function (blob, name) { return new FileSaver(blob, name); }; FS_proto.abort = function () { var filesaver = this; filesaver.readyState = filesaver.DONE; dispatch(filesaver, "abort"); }; FS_proto.readyState = FS_proto.INIT = 0; FS_proto.WRITING = 1; FS_proto.DONE = 2; FS_proto.error = FS_proto.onwritestart = FS_proto.onprogress = FS_proto.onwrite = FS_proto.onabort = FS_proto.onerror = FS_proto.onwriteend = null; view.addEventListener("unload", process_deletion_queue, false); return saveAs; }(self); return saveAs; }; /***/ }, /* 218 */ /***/ function(module, exports, __webpack_require__) { var make_full_name = __webpack_require__(219); module.exports = function make_matrix_string(params) { var inst_matrix = params.matrix; // get order indexes var order_indexes = {}; var inst_name; _.each(['row', 'col'], function (tmp_rc) { var inst_rc; // row/col names are reversed in saved orders if (tmp_rc === 'row') { inst_rc = 'col'; } else { inst_rc = 'row'; } // use tmp_rc inst_name = params.inst_order[tmp_rc]; // use tmp_rc order_indexes[inst_rc] = inst_matrix.orders[inst_name + '_' + tmp_rc]; }); var matrix_string = '\t'; var row_nodes = params.network_data.row_nodes; var col_nodes = params.network_data.col_nodes; // alternate column entry for (var c_i = 0; c_i < order_indexes.col.length; c_i++) { var inst_index = order_indexes.col[c_i]; var inst_col = col_nodes[inst_index]; var col_name = make_full_name(params, inst_col, 'col'); if (c_i < order_indexes.col.length - 1) { matrix_string = matrix_string + col_name + '\t'; } else { matrix_string = matrix_string + col_name; } } var row_data; matrix_string = matrix_string + '\n'; _.each(order_indexes.row, function (inst_index) { // row names row_data = inst_matrix.matrix[inst_index].row_data; // var row_name = inst_matrix.matrix[inst_index].name; var inst_row = row_nodes[inst_index]; // var row_name = inst_row.name; var row_name = make_full_name(params, inst_row, 'row'); matrix_string = matrix_string + row_name + '\t'; // alternate data entry for (var r_i = 0; r_i < order_indexes.col.length; r_i++) { // get the order var col_index = order_indexes.col[r_i]; if (r_i < order_indexes.col.length - 1) { matrix_string = matrix_string + String(row_data[col_index].value) + '\t'; } else { matrix_string = matrix_string + String(row_data[col_index].value); } } matrix_string = matrix_string + '\n'; }); return matrix_string; }; /***/ }, /* 219 */ /***/ function(module, exports) { module.exports = function make_full_name(params, inst_node, inst_rc) { var cat_name; var inst_name = inst_node.name; var num_cats = params.viz.all_cats[inst_rc].length; // make tuple if necessary if (num_cats > 0) { inst_name = "('" + inst_name + "'"; for (var cat_index = 0; cat_index < num_cats; cat_index++) { cat_name = 'cat-' + String(cat_index); inst_name = inst_name + ", '" + String(inst_node[cat_name]) + "'"; } inst_name = inst_name + ')'; } else { // always make names strings inst_name = String(inst_name); } return inst_name; }; /***/ }, /* 220 */ /***/ function(module, exports, __webpack_require__) { var deactivate_cropping = __webpack_require__(221); module.exports = function brush_crop_matrix() { // get rows/cols from brush-extent // works for differnt brushing directions (e.g. start end sites) var cgm = this; var params = cgm.params; var clust_width = params.viz.clust.dim.width; var clust_height = params.viz.clust.dim.height; var x = d3.scale.linear().domain([0, clust_width]).range([0, clust_width]); var y = d3.scale.linear().domain([0, clust_height]).range([0, clust_height]); // make brush group d3.select(params.root + ' .clust_container').append('g').classed('brush_group', true); cgm.params.is_cropping = true; var brush = d3.svg.brush().x(x).y(y).on("brushend", brushend); d3.select(params.root + ' .brush_group').call(brush); function brushend() { // do not display dendro crop buttons when cropping with brushing d3.select(cgm.params.root + ' .col_dendro_icons_container').style('display', 'none'); d3.select(cgm.params.root + ' .row_dendro_icons_container').style('display', 'none'); var brushing_extent = brush.extent(); var brush_start = brushing_extent[0]; var brush_end = brushing_extent[1]; var x_start = brush_start[0]; var x_end = brush_end[0]; var y_start = brush_start[1]; var y_end = brush_end[1]; if (x_start != x_end && y_start != y_end) { setTimeout(deactivate_cropping, 500, cgm); // find cropped nodes var found_nodes = find_cropped_nodes(x_start, x_end, y_start, y_end, brush_start, brush_end); cgm.filter_viz_using_names(found_nodes); d3.select(params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', false).classed('fa-undo', true); } } function find_cropped_nodes(x_start, x_end, y_start, y_end, brush_start, brush_end) { // reverse if necessary (depending on how brushing was done) if (x_start > x_end) { x_start = brush_end[0]; x_end = brush_start[0]; } if (y_start > y_end) { y_start = brush_end[1]; y_end = brush_start[1]; } // add room to brushing y_start = y_start - params.viz.rect_height; x_start = x_start - params.viz.rect_width; var found_nodes = {}; found_nodes.row = []; found_nodes.col = []; // d3.selectAll(params.root+' .row_label_group') // .each(function(inst_row){ // // there is already bound data on the rows // var inst_trans = d3.select(this) // .attr('transform'); // var y_trans = Number(inst_trans.split(',')[1].split(')')[0]); // if (y_trans > y_start && y_trans < y_end){ // found_nodes.row.push(inst_row.name); // } // }); _.each(params.matrix.matrix, function (row_data) { var y_trans = params.viz.y_scale(row_data.row_index); if (y_trans > y_start && y_trans < y_end) { found_nodes.row.push(row_data.name); } }); d3.selectAll(params.root + ' .col_label_text').each(function (inst_col) { // there is already bound data on the cols var inst_trans = d3.select(this).attr('transform'); var x_trans = Number(inst_trans.split(',')[0].split('(')[1]); if (x_trans > x_start && x_trans < x_end) { found_nodes.col.push(inst_col.name); } }); return found_nodes; } d3.selectAll(params.root + ' .extent').style('opacity', 0.2).style('fill', 'black'); }; /***/ }, /* 221 */ /***/ function(module, exports) { module.exports = function deactivate_cropping(cgm) { d3.select(cgm.params.root + ' .brush_group').transition().style('opacity', 0).remove(); cgm.params.is_cropping = false; }; /***/ }, /* 222 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* D3.js Slider Inspired by jQuery UI Slider Copyright (c) 2013, Bjorn Sandvik - http://blog.thematicmapping.org BSD license: http://opensource.org/licenses/BSD-3-Clause */ (function (root, factory) { if (true) { // AMD. Register as an anonymous module. !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(223)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if (typeof exports === 'object') { if (process.browser) { // Browserify. Import css too using cssify. require('./d3.slider.css'); } // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(require('d3')); } else { // Browser globals (root is window) root.d3.slider = factory(root.d3); } })(this, function (d3) { return function module() { "use strict"; // Public variables width default settings var min = 0, max = 100, step = 0.01, animate = false, orientation = "horizontal", axis = false, margin = 50, value, active = 1, snap = false, scale; // Private variables var axisScale, dispatch = d3.dispatch("slide", "slideend"), formatPercent = d3.format(".2%"), tickFormat = d3.format(".0"), handle1, handle2 = null, divRange, sliderLength; function slider(selection) { selection.each(function () { // Create scale if not defined by user if (!scale) { scale = d3.scale.linear().domain([min, max]); } // Start value value = value || scale.domain()[0]; // DIV container var div = d3.select(this).classed("d3-slider d3-slider-" + orientation, true); var drag = d3.behavior.drag(); drag.on('dragend', function () { dispatch.slideend(d3.event, value); }); // Slider handle //if range slider, create two // var divRange; if (toType(value) == "array" && value.length == 2) { handle1 = div.append("a").classed("d3-slider-handle", true).attr("xlink:href", "#").attr('id', "handle-one").on("click", stopPropagation).call(drag); handle2 = div.append("a").classed("d3-slider-handle", true).attr('id', "handle-two").attr("xlink:href", "#").on("click", stopPropagation).call(drag); } else { handle1 = div.append("a").classed("d3-slider-handle", true).attr("xlink:href", "#").attr('id', "handle-one").on("click", stopPropagation).call(drag); } // Horizontal slider if (orientation === "horizontal") { div.on("click", onClickHorizontal); if (toType(value) == "array" && value.length == 2) { divRange = d3.select(this).append('div').classed("d3-slider-range", true); handle1.style("left", formatPercent(scale(value[0]))); divRange.style("left", formatPercent(scale(value[0]))); drag.on("drag", onDragHorizontal); var width = 100 - parseFloat(formatPercent(scale(value[1]))); handle2.style("left", formatPercent(scale(value[1]))); divRange.style("right", width + "%"); drag.on("drag", onDragHorizontal); } else { handle1.style("left", formatPercent(scale(value))); drag.on("drag", onDragHorizontal); } sliderLength = parseInt(div.style("width"), 10); } else { // Vertical div.on("click", onClickVertical); drag.on("drag", onDragVertical); if (toType(value) == "array" && value.length == 2) { divRange = d3.select(this).append('div').classed("d3-slider-range-vertical", true); handle1.style("bottom", formatPercent(scale(value[0]))); divRange.style("bottom", formatPercent(scale(value[0]))); drag.on("drag", onDragVertical); var top = 100 - parseFloat(formatPercent(scale(value[1]))); handle2.style("bottom", formatPercent(scale(value[1]))); divRange.style("top", top + "%"); drag.on("drag", onDragVertical); } else { handle1.style("bottom", formatPercent(scale(value))); drag.on("drag", onDragVertical); } sliderLength = parseInt(div.style("height"), 10); } if (axis) { createAxis(div); } function createAxis(dom) { // Create axis if not defined by user if (typeof axis === "boolean") { axis = d3.svg.axis().ticks(Math.round(sliderLength / 100)).tickFormat(tickFormat).orient(orientation === "horizontal" ? "bottom" : "right"); } // Copy slider scale to move from percentages to pixels axisScale = scale.ticks ? scale.copy().range([0, sliderLength]) : scale.copy().rangePoints([0, sliderLength], 0.5); axis.scale(axisScale); // Create SVG axis container var svg = dom.append("svg").classed("d3-slider-axis d3-slider-axis-" + axis.orient(), true).on("click", stopPropagation); var g = svg.append("g"); // Horizontal axis if (orientation === "horizontal") { svg.style("margin-left", -margin + "px"); svg.attr({ width: sliderLength + margin * 2, height: margin }); if (axis.orient() === "top") { svg.style("top", -margin + "px"); g.attr("transform", "translate(" + margin + "," + margin + ")"); } else { // bottom g.attr("transform", "translate(" + margin + ",0)"); } } else { // Vertical svg.style("top", -margin + "px"); svg.attr({ width: margin, height: sliderLength + margin * 2 }); if (axis.orient() === "left") { svg.style("left", -margin + "px"); g.attr("transform", "translate(" + margin + "," + margin + ")"); } else { // right g.attr("transform", "translate(" + 0 + "," + margin + ")"); } } g.call(axis); } function onClickHorizontal() { if (toType(value) != "array") { var pos = Math.max(0, Math.min(sliderLength, d3.event.offsetX || d3.event.layerX)); moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength)); } } function onClickVertical() { if (toType(value) != "array") { var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.offsetY || d3.event.layerY)); moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength)); } } function onDragHorizontal() { if (d3.event.sourceEvent.target.id === "handle-one") { active = 1; } else if (d3.event.sourceEvent.target.id == "handle-two") { active = 2; } var pos = Math.max(0, Math.min(sliderLength, d3.event.x)); moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength)); } function onDragVertical() { if (d3.event.sourceEvent.target.id === "handle-one") { active = 1; } else if (d3.event.sourceEvent.target.id == "handle-two") { active = 2; } var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.y)); moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength)); } function stopPropagation() { d3.event.stopPropagation(); } }); } // Move slider handle on click/drag function moveHandle(newValue) { var currentValue = toType(value) == "array" && value.length == 2 ? value[active - 1] : value, oldPos = formatPercent(scale(stepValue(currentValue))), newPos = formatPercent(scale(stepValue(newValue))), position = orientation === "horizontal" ? "left" : "bottom"; if (oldPos !== newPos) { if (toType(value) == "array" && value.length == 2) { value[active - 1] = newValue; if (d3.event) { dispatch.slide(d3.event, value); }; } else { if (d3.event) { dispatch.slide(d3.event.sourceEvent || d3.event, value = newValue); }; } if (value[0] >= value[1]) return; if (active === 1) { if (toType(value) == "array" && value.length == 2) { position === "left" ? divRange.style("left", newPos) : divRange.style("bottom", newPos); } if (animate) { handle1.transition().styleTween(position, function () { return d3.interpolate(oldPos, newPos); }).duration(typeof animate === "number" ? animate : 250); } else { handle1.style(position, newPos); } } else { var width = 100 - parseFloat(newPos); var top = 100 - parseFloat(newPos); position === "left" ? divRange.style("right", width + "%") : divRange.style("top", top + "%"); if (animate) { handle2.transition().styleTween(position, function () { return d3.interpolate(oldPos, newPos); }).duration(typeof animate === "number" ? animate : 250); } else { handle2.style(position, newPos); } } } } // Calculate nearest step value function stepValue(val) { if (val === scale.domain()[0] || val === scale.domain()[1]) { return val; } var alignValue = val; if (snap) { alignValue = nearestTick(scale(val)); } else { var valModStep = (val - scale.domain()[0]) % step; alignValue = val - valModStep; if (Math.abs(valModStep) * 2 >= step) { alignValue += valModStep > 0 ? step : -step; } }; return alignValue; } // Find the nearest tick function nearestTick(pos) { var ticks = scale.ticks ? scale.ticks() : scale.domain(); var dist = ticks.map(function (d) { return pos - scale(d); }); var i = -1, index = 0, r = scale.ticks ? scale.range()[1] : scale.rangeExtent()[1]; do { i++; if (Math.abs(dist[i]) < r) { r = Math.abs(dist[i]); index = i; }; } while (dist[i] > 0 && i < dist.length - 1); return ticks[index]; }; // Return the type of an object function toType(v) { return {}.toString.call(v).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); }; // Getter/setter functions slider.min = function (_) { if (!arguments.length) return min; min = _; return slider; }; slider.max = function (_) { if (!arguments.length) return max; max = _; return slider; }; slider.step = function (_) { if (!arguments.length) return step; step = _; return slider; }; slider.animate = function (_) { if (!arguments.length) return animate; animate = _; return slider; }; slider.orientation = function (_) { if (!arguments.length) return orientation; orientation = _; return slider; }; slider.axis = function (_) { if (!arguments.length) return axis; axis = _; return slider; }; slider.margin = function (_) { if (!arguments.length) return margin; margin = _; return slider; }; slider.value = function (_) { if (!arguments.length) return value; if (value) { moveHandle(stepValue(_)); }; value = _; return slider; }; slider.snap = function (_) { if (!arguments.length) return snap; snap = _; return slider; }; slider.scale = function (_) { if (!arguments.length) return scale; scale = _; return slider; }; d3.rebind(slider, dispatch, "on"); return slider; }; }); /***/ }, /* 223 */ /***/ function(module, exports) { module.exports = d3; /***/ }, /* 224 */ /***/ function(module, exports) { /** * Simple, lightweight, usable local autocomplete library for modern browsers * Because there weren’t enough autocomplete scripts in the world? Because I’m completely insane and have NIH syndrome? Probably both. :P * @author Lea Verou http://leaverou.github.io/awesomplete * MIT license */ (function () { var _ = function (input, o) { var me = this; // Setup this.input = $(input); this.input.setAttribute("autocomplete", "off"); this.input.setAttribute("aria-autocomplete", "list"); o = o || {}; configure(this, { minChars: 2, maxItems: 10, autoFirst: false, data: _.DATA, filter: _.FILTER_CONTAINS, sort: _.SORT_BYLENGTH, item: _.ITEM, replace: _.REPLACE }, o); this.index = -1; // Create necessary elements this.container = $.create("div", { className: "awesomplete", around: input }); this.ul = $.create("ul", { hidden: "hidden", inside: this.container }); this.status = $.create("span", { className: "visually-hidden", role: "status", "aria-live": "assertive", "aria-relevant": "additions", inside: this.container }); // Bind events $.bind(this.input, { "input": this.evaluate.bind(this), "blur": this.close.bind(this, { reason: "blur" }), "keydown": function (evt) { var c = evt.keyCode; // If the dropdown `ul` is in view, then act on keydown for the following keys: // Enter / Esc / Up / Down if (me.opened) { if (c === 13 && me.selected) { // Enter evt.preventDefault(); me.select(); } else if (c === 27) { // Esc me.close({ reason: "esc" }); } else if (c === 38 || c === 40) { // Down/Up arrow evt.preventDefault(); me[c === 38 ? "previous" : "next"](); } } } }); $.bind(this.input.form, { "submit": this.close.bind(this, { reason: "submit" }) }); $.bind(this.ul, { "mousedown": function (evt) { var li = evt.target; if (li !== this) { while (li && !/li/i.test(li.nodeName)) { li = li.parentNode; } if (li && evt.button === 0) { // Only select on left click evt.preventDefault(); me.select(li, evt.target); } } } }); if (this.input.hasAttribute("list")) { this.list = "#" + this.input.getAttribute("list"); this.input.removeAttribute("list"); } else { this.list = this.input.getAttribute("data-list") || o.list || []; } _.all.push(this); }; _.prototype = { set list(list) { if (Array.isArray(list)) { this._list = list; } else if (typeof list === "string" && list.indexOf(",") > -1) { this._list = list.split(/\s*,\s*/); } else { // Element or CSS selector list = $(list); if (list && list.children) { var items = []; slice.apply(list.children).forEach(function (el) { if (!el.disabled) { var text = el.textContent.trim(); var value = el.value || text; var label = el.label || text; if (value !== "") { items.push({ label: label, value: value }); } } }); this._list = items; } } if (document.activeElement === this.input) { this.evaluate(); } }, get selected() { return this.index > -1; }, get opened() { return !this.ul.hasAttribute("hidden"); }, close: function (o) { if (!this.opened) { return; } this.ul.setAttribute("hidden", ""); this.index = -1; $.fire(this.input, "awesomplete-close", o || {}); }, open: function () { this.ul.removeAttribute("hidden"); if (this.autoFirst && this.index === -1) { this.goto(0); } $.fire(this.input, "awesomplete-open"); }, next: function () { var count = this.ul.children.length; this.goto(this.index < count - 1 ? this.index + 1 : -1); }, previous: function () { var count = this.ul.children.length; this.goto(this.selected ? this.index - 1 : count - 1); }, // Should not be used, highlights specific item without any checks! goto: function (i) { var lis = this.ul.children; if (this.selected) { lis[this.index].setAttribute("aria-selected", "false"); } this.index = i; if (i > -1 && lis.length > 0) { lis[i].setAttribute("aria-selected", "true"); this.status.textContent = lis[i].textContent; $.fire(this.input, "awesomplete-highlight", { text: this.suggestions[this.index] }); } }, select: function (selected, origin) { if (selected) { this.index = $.siblingIndex(selected); } else { selected = this.ul.children[this.index]; } if (selected) { var suggestion = this.suggestions[this.index]; var allowed = $.fire(this.input, "awesomplete-select", { text: suggestion, origin: origin || selected }); if (allowed) { this.replace(suggestion); this.close({ reason: "select" }); $.fire(this.input, "awesomplete-selectcomplete", { text: suggestion }); } } }, evaluate: function () { var me = this; var value = this.input.value; if (value.length >= this.minChars && this._list.length > 0) { this.index = -1; // Populate list with options that match this.ul.innerHTML = ""; this.suggestions = this._list.map(function (item) { return new Suggestion(me.data(item, value)); }).filter(function (item) { return me.filter(item, value); }).sort(this.sort).slice(0, this.maxItems); this.suggestions.forEach(function (text) { me.ul.appendChild(me.item(text, value)); }); if (this.ul.children.length === 0) { this.close({ reason: "nomatches" }); } else { this.open(); } } else { this.close({ reason: "nomatches" }); } } }; // Static methods/properties _.all = []; _.FILTER_CONTAINS = function (text, input) { return RegExp($.regExpEscape(input.trim()), "i").test(text); }; _.FILTER_STARTSWITH = function (text, input) { return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text); }; _.SORT_BYLENGTH = function (a, b) { if (a.length !== b.length) { return a.length - b.length; } return a < b ? -1 : 1; }; _.ITEM = function (text, input) { var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>"); return $.create("li", { innerHTML: html, "aria-selected": "false" }); }; _.REPLACE = function (text) { this.input.value = text.value; }; _.DATA = function (item /*, input*/) { return item; }; // Private functions function Suggestion(data) { var o = Array.isArray(data) ? { label: data[0], value: data[1] } : typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data }; this.label = o.label || o.value; this.value = o.value; } Object.defineProperty(Suggestion.prototype = Object.create(String.prototype), "length", { get: function () { return this.label.length; } }); Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () { return "" + this.label; }; function configure(instance, properties, o) { for (var i in properties) { var initial = properties[i], attrValue = instance.input.getAttribute("data-" + i.toLowerCase()); if (typeof initial === "number") { instance[i] = parseInt(attrValue); } else if (initial === false) { // Boolean options must be false by default anyway instance[i] = attrValue !== null; } else if (initial instanceof Function) { instance[i] = null; } else { instance[i] = attrValue; } if (!instance[i] && instance[i] !== 0) { instance[i] = i in o ? o[i] : initial; } } } // Helpers var slice = Array.prototype.slice; function $(expr, con) { return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null; } function $$(expr, con) { return slice.call((con || document).querySelectorAll(expr)); } $.create = function (tag, o) { var element = document.createElement(tag); for (var i in o) { var val = o[i]; if (i === "inside") { $(val).appendChild(element); } else if (i === "around") { var ref = $(val); ref.parentNode.insertBefore(element, ref); element.appendChild(ref); } else if (i in element) { element[i] = val; } else { element.setAttribute(i, val); } } return element; }; $.bind = function (element, o) { if (element) { for (var event in o) { var callback = o[event]; event.split(/\s+/).forEach(function (event) { element.addEventListener(event, callback); }); } } }; $.fire = function (target, type, properties) { var evt = document.createEvent("HTMLEvents"); evt.initEvent(type, true, true); for (var j in properties) { evt[j] = properties[j]; } return target.dispatchEvent(evt); }; $.regExpEscape = function (s) { return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); }; $.siblingIndex = function (el) { /* eslint-disable no-cond-assign */ for (var i = 0; el = el.previousElementSibling; i++); return i; }; // Initialization function init() { $$("input.awesomplete").forEach(function (input) { new _(input); }); } // Are we in a browser? Check for Document constructor if (typeof Document !== "undefined") { // DOM already loaded? if (document.readyState !== "loading") { init(); } else { // Wait for it document.addEventListener("DOMContentLoaded", init); } } _.$ = $; _.$$ = $$; // Make sure to export Awesomplete on self when in a browser if (typeof self !== "undefined") { self.Awesomplete = _; } // Expose Awesomplete as a CJS module if (typeof module === "object" && module.exports) { module.exports = _; } return _; })(); /***/ }, /* 225 */ /***/ function(module, exports, __webpack_require__) { // style-loader: Adds some css to the DOM by adding a <style> tag // load the styles var content = __webpack_require__(226); if(typeof content === 'string') content = [[module.id, content, '']]; // add the styles to the DOM var update = __webpack_require__(228)(content, {}); if(content.locals) module.exports = content.locals; // Hot Module Replacement if(false) { // When the styles change, update the <style> tags if(!content.locals) { module.hot.accept("!!./../../node_modules/css-loader/index.js!./d3.slider.css", function() { var newContent = require("!!./../../node_modules/css-loader/index.js!./d3.slider.css"); if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; update(newContent); }); } // When the module is disposed, remove the <style> tags module.hot.dispose(function() { update(); }); } /***/ }, /* 226 */ /***/ function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(227)(); // imports // module exports.push([module.id, ".d3-slider {\n position: relative;\n font-family: Verdana,Arial,sans-serif;\n font-size: 1.1em;\n border: 1px solid #aaaaaa;\n z-index: 2;\n}\n\n.d3-slider-horizontal {\n height: .8em;\n} \n\n.d3-slider-range {\n background:#2980b9;\n left:0px;\n right:0px;\n height: 0.8em;\n position: absolute;\n}\n\n.d3-slider-range-vertical {\n background:#2980b9;\n left:0px;\n right:0px;\n position: absolute;\n top:0;\n}\n\n.d3-slider-vertical {\n width: .8em;\n height: 100px;\n} \n\n.d3-slider-handle {\n position: absolute;\n width: 1.2em;\n height: 1.2em;\n border: 1px solid #d3d3d3;\n border-radius: 4px;\n background: #eee;\n background: linear-gradient(to bottom, #eee 0%, #ddd 100%);\n z-index: 3;\n}\n\n.d3-slider-handle:hover {\n border: 1px solid #999999;\n}\n\n.d3-slider-horizontal .d3-slider-handle {\n top: -.3em;\n margin-left: -.6em;\n}\n\n.d3-slider-axis {\n position: relative;\n z-index: 1; \n}\n\n.d3-slider-axis-bottom {\n top: .8em;\n}\n\n.d3-slider-axis-right {\n left: .8em;\n}\n\n.d3-slider-axis path {\n stroke-width: 0;\n fill: none;\n}\n\n.d3-slider-axis line {\n fill: none;\n stroke: #aaa;\n shape-rendering: crispEdges;\n}\n\n.d3-slider-axis text {\n font-size: 11px;\n}\n\n.d3-slider-vertical .d3-slider-handle {\n left: -.25em;\n margin-left: 0;\n margin-bottom: -.6em; \n}", ""]); // exports /***/ }, /* 227 */ /***/ function(module, exports) { /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ // css base code, injected by the css-loader module.exports = function () { var list = []; // return the list of modules as css string list.toString = function toString() { var result = []; for (var i = 0; i < this.length; i++) { var item = this[i]; if (item[2]) { result.push("@media " + item[2] + "{" + item[1] + "}"); } else { result.push(item[1]); } } return result.join(""); }; // import a list of modules into the list list.i = function (modules, mediaQuery) { if (typeof modules === "string") modules = [[null, modules, ""]]; var alreadyImportedModules = {}; for (var i = 0; i < this.length; i++) { var id = this[i][0]; if (typeof id === "number") alreadyImportedModules[id] = true; } for (i = 0; i < modules.length; i++) { var item = modules[i]; // skip already imported module // this implementation is not 100% perfect for weird media query combinations // when a module is imported multiple times with different media queries. // I hope this will never occur (Hey this way we have smaller bundles) if (typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { if (mediaQuery && !item[2]) { item[2] = mediaQuery; } else if (mediaQuery) { item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; } list.push(item); } } }; return list; }; /***/ }, /* 228 */ /***/ function(module, exports, __webpack_require__) { /* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ var stylesInDom = {}, memoize = function(fn) { var memo; return function () { if (typeof memo === "undefined") memo = fn.apply(this, arguments); return memo; }; }, isOldIE = memoize(function() { return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase()); }), getHeadElement = memoize(function () { return document.head || document.getElementsByTagName("head")[0]; }), singletonElement = null, singletonCounter = 0, styleElementsInsertedAtTop = []; module.exports = function(list, options) { if(false) { if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); } options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style> // tags it will allow on a page if (typeof options.singleton === "undefined") options.singleton = isOldIE(); // By default, add <style> tags to the bottom of <head>. if (typeof options.insertAt === "undefined") options.insertAt = "bottom"; var styles = listToStyles(list); addStylesToDom(styles, options); return function update(newList) { var mayRemove = []; for(var i = 0; i < styles.length; i++) { var item = styles[i]; var domStyle = stylesInDom[item.id]; domStyle.refs--; mayRemove.push(domStyle); } if(newList) { var newStyles = listToStyles(newList); addStylesToDom(newStyles, options); } for(var i = 0; i < mayRemove.length; i++) { var domStyle = mayRemove[i]; if(domStyle.refs === 0) { for(var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j](); delete stylesInDom[domStyle.id]; } } }; } function addStylesToDom(styles, options) { for(var i = 0; i < styles.length; i++) { var item = styles[i]; var domStyle = stylesInDom[item.id]; if(domStyle) { domStyle.refs++; for(var j = 0; j < domStyle.parts.length; j++) { domStyle.parts[j](item.parts[j]); } for(; j < item.parts.length; j++) { domStyle.parts.push(addStyle(item.parts[j], options)); } } else { var parts = []; for(var j = 0; j < item.parts.length; j++) { parts.push(addStyle(item.parts[j], options)); } stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts}; } } } function listToStyles(list) { var styles = []; var newStyles = {}; for(var i = 0; i < list.length; i++) { var item = list[i]; var id = item[0]; var css = item[1]; var media = item[2]; var sourceMap = item[3]; var part = {css: css, media: media, sourceMap: sourceMap}; if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]}); else newStyles[id].parts.push(part); } return styles; } function insertStyleElement(options, styleElement) { var head = getHeadElement(); var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1]; if (options.insertAt === "top") { if(!lastStyleElementInsertedAtTop) { head.insertBefore(styleElement, head.firstChild); } else if(lastStyleElementInsertedAtTop.nextSibling) { head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling); } else { head.appendChild(styleElement); } styleElementsInsertedAtTop.push(styleElement); } else if (options.insertAt === "bottom") { head.appendChild(styleElement); } else { throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'."); } } function removeStyleElement(styleElement) { styleElement.parentNode.removeChild(styleElement); var idx = styleElementsInsertedAtTop.indexOf(styleElement); if(idx >= 0) { styleElementsInsertedAtTop.splice(idx, 1); } } function createStyleElement(options) { var styleElement = document.createElement("style"); styleElement.type = "text/css"; insertStyleElement(options, styleElement); return styleElement; } function createLinkElement(options) { var linkElement = document.createElement("link"); linkElement.rel = "stylesheet"; insertStyleElement(options, linkElement); return linkElement; } function addStyle(obj, options) { var styleElement, update, remove; if (options.singleton) { var styleIndex = singletonCounter++; styleElement = singletonElement || (singletonElement = createStyleElement(options)); update = applyToSingletonTag.bind(null, styleElement, styleIndex, false); remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true); } else if(obj.sourceMap && typeof URL === "function" && typeof URL.createObjectURL === "function" && typeof URL.revokeObjectURL === "function" && typeof Blob === "function" && typeof btoa === "function") { styleElement = createLinkElement(options); update = updateLink.bind(null, styleElement); remove = function() { removeStyleElement(styleElement); if(styleElement.href) URL.revokeObjectURL(styleElement.href); }; } else { styleElement = createStyleElement(options); update = applyToTag.bind(null, styleElement); remove = function() { removeStyleElement(styleElement); }; } update(obj); return function updateStyle(newObj) { if(newObj) { if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) return; update(obj = newObj); } else { remove(); } }; } var replaceText = (function () { var textStore = []; return function (index, replacement) { textStore[index] = replacement; return textStore.filter(Boolean).join('\n'); }; })(); function applyToSingletonTag(styleElement, index, remove, obj) { var css = remove ? "" : obj.css; if (styleElement.styleSheet) { styleElement.styleSheet.cssText = replaceText(index, css); } else { var cssNode = document.createTextNode(css); var childNodes = styleElement.childNodes; if (childNodes[index]) styleElement.removeChild(childNodes[index]); if (childNodes.length) { styleElement.insertBefore(cssNode, childNodes[index]); } else { styleElement.appendChild(cssNode); } } } function applyToTag(styleElement, obj) { var css = obj.css; var media = obj.media; if(media) { styleElement.setAttribute("media", media) } if(styleElement.styleSheet) { styleElement.styleSheet.cssText = css; } else { while(styleElement.firstChild) { styleElement.removeChild(styleElement.firstChild); } styleElement.appendChild(document.createTextNode(css)); } } function updateLink(linkElement, obj) { var css = obj.css; var sourceMap = obj.sourceMap; if(sourceMap) { // http://stackoverflow.com/a/26603875 css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */"; } var blob = new Blob([css], { type: "text/css" }); var oldSrc = linkElement.href; linkElement.href = URL.createObjectURL(blob); if(oldSrc) URL.revokeObjectURL(oldSrc); } /***/ }, /* 229 */ /***/ function(module, exports, __webpack_require__) { // style-loader: Adds some css to the DOM by adding a <style> tag // load the styles var content = __webpack_require__(230); if(typeof content === 'string') content = [[module.id, content, '']]; // add the styles to the DOM var update = __webpack_require__(228)(content, {}); if(content.locals) module.exports = content.locals; // Hot Module Replacement if(false) { // When the styles change, update the <style> tags if(!content.locals) { module.hot.accept("!!./../css-loader/index.js!./awesomplete.css", function() { var newContent = require("!!./../css-loader/index.js!./awesomplete.css"); if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; update(newContent); }); } // When the module is disposed, remove the <style> tags module.hot.dispose(function() { update(); }); } /***/ }, /* 230 */ /***/ function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(227)(); // imports // module exports.push([module.id, "[hidden] { display: none; }\n\n.visually-hidden {\n\tposition: absolute;\n\tclip: rect(0, 0, 0, 0);\n}\n\ndiv.awesomplete {\n\tdisplay: inline-block;\n\tposition: relative;\n}\n\ndiv.awesomplete > input {\n\tdisplay: block;\n}\n\ndiv.awesomplete > ul {\n\tposition: absolute;\n\tleft: 0;\n\tz-index: 1;\n\tmin-width: 100%;\n\tbox-sizing: border-box;\n\tlist-style: none;\n\tpadding: 0;\n\tborder-radius: .3em;\n\tmargin: .2em 0 0;\n\tbackground: hsla(0,0%,100%,.9);\n\tbackground: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));\n\tborder: 1px solid rgba(0,0,0,.3);\n\tbox-shadow: .05em .2em .6em rgba(0,0,0,.2);\n\ttext-shadow: none;\n}\n\ndiv.awesomplete > ul[hidden],\ndiv.awesomplete > ul:empty {\n\tdisplay: none;\n}\n\n@supports (transform: scale(0)) {\n\tdiv.awesomplete > ul {\n\t\ttransition: .3s cubic-bezier(.4,.2,.5,1.4);\n\t\ttransform-origin: 1.43em -.43em;\n\t}\n\t\n\tdiv.awesomplete > ul[hidden],\n\tdiv.awesomplete > ul:empty {\n\t\topacity: 0;\n\t\ttransform: scale(0);\n\t\tdisplay: block;\n\t\ttransition-timing-function: ease;\n\t}\n}\n\n\t/* Pointer */\n\tdiv.awesomplete > ul:before {\n\t\tcontent: \"\";\n\t\tposition: absolute;\n\t\ttop: -.43em;\n\t\tleft: 1em;\n\t\twidth: 0; height: 0;\n\t\tpadding: .4em;\n\t\tbackground: white;\n\t\tborder: inherit;\n\t\tborder-right: 0;\n\t\tborder-bottom: 0;\n\t\t-webkit-transform: rotate(45deg);\n\t\ttransform: rotate(45deg);\n\t}\n\n\tdiv.awesomplete > ul > li {\n\t\tposition: relative;\n\t\tpadding: .2em .5em;\n\t\tcursor: pointer;\n\t}\n\t\n\tdiv.awesomplete > ul > li:hover {\n\t\tbackground: hsl(200, 40%, 80%);\n\t\tcolor: black;\n\t}\n\t\n\tdiv.awesomplete > ul > li[aria-selected=\"true\"] {\n\t\tbackground: hsl(205, 40%, 40%);\n\t\tcolor: white;\n\t}\n\t\n\t\tdiv.awesomplete mark {\n\t\t\tbackground: hsl(65, 100%, 50%);\n\t\t}\n\t\t\n\t\tdiv.awesomplete li:hover mark {\n\t\t\tbackground: hsl(68, 100%, 41%);\n\t\t}\n\t\t\n\t\tdiv.awesomplete li[aria-selected=\"true\"] mark {\n\t\t\tbackground: hsl(86, 100%, 21%);\n\t\t\tcolor: inherit;\n\t\t}", ""]); // exports /***/ }, /* 231 */ /***/ function(module, exports, __webpack_require__) { var ini_sidebar = __webpack_require__(192); var set_up_filters = __webpack_require__(232); var set_up_search = __webpack_require__(237); var set_up_reorder = __webpack_require__(238); var set_sidebar_ini_view = __webpack_require__(239); var make_icons = __webpack_require__(240); var make_modals = __webpack_require__(242); var set_up_opacity_slider = __webpack_require__(244); var make_colorbar = __webpack_require__(245); /* Represents sidebar with controls. */ module.exports = function sidebar(cgm) { var params = cgm.params; var sidebar = d3.select(params.root + ' .sidebar_wrapper'); // console.log('is_expand ',params.viz.is_expand) if (params.viz.is_expand) { sidebar.style('display', 'none'); } sidebar.append('div').classed('title_section', true); if (params.sidebar.title != null) { sidebar.select('.title_section').append('h4') // .style('margin-left', params.sidebar.title_margin_left+'px') .style('margin-left', '20px').style('margin-top', '5px').style('margin-bottom', '0px').text(params.sidebar.title); } sidebar.append('div').style('padding-right', '2px').classed('about_section', true); if (params.sidebar.about != null) { sidebar.select('.about_section').append('h5').classed('sidebar_text', true).style('margin-left', '7px').style('margin-top', '5px').style('margin-bottom', '2px').style('text-align', 'justify').html(params.sidebar.about); } sidebar.append('div').classed('icons_section', true).style('text-align', 'center'); if (cgm.params.make_modals) { make_modals(params); } if (params.sidebar.icons) { make_icons(cgm, sidebar); } set_up_reorder(params, sidebar); set_up_search(sidebar, params); set_up_opacity_slider(sidebar); var possible_filter_names = _.keys(params.viz.possible_filters); if (possible_filter_names.indexOf('enr_score_type') > -1) { possible_filter_names.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }); } cgm.slider_functions = {}; _.each(possible_filter_names, function (inst_filter) { set_up_filters(cgm, inst_filter); }); ini_sidebar(cgm); // when initializing the visualization using a view if (params.ini_view !== null) { set_sidebar_ini_view(params); params.ini_view = null; } make_colorbar(cgm); }; /***/ }, /* 232 */ /***/ function(module, exports, __webpack_require__) { var make_slider_filter = __webpack_require__(233); var make_button_filter = __webpack_require__(236); module.exports = function set_up_filters(cgm, filter_type) { var params = cgm.params; var div_filters = d3.select(params.root + ' .sidebar_wrapper').append('div').classed('div_filters', true).style('padding-left', '10px').style('padding-right', '10px'); if (params.viz.possible_filters[filter_type] == 'numerical') { make_slider_filter(cgm, filter_type, div_filters); } else if (params.viz.possible_filters[filter_type] == 'categorical') { make_button_filter(cgm, filter_type, div_filters); } }; /***/ }, /* 233 */ /***/ function(module, exports, __webpack_require__) { var make_filter_title = __webpack_require__(215); var run_filter_slider = __webpack_require__(234); var get_filter_default_state = __webpack_require__(5); var get_subset_views = __webpack_require__(12); d3.slider = __webpack_require__(222); module.exports = function make_slider_filter(cgm, filter_type, div_filters) { var params = cgm.params; var inst_view = {}; var possible_filters = _.keys(params.viz.possible_filters); _.each(possible_filters, function (tmp_filter) { if (tmp_filter != filter_type) { var default_state = get_filter_default_state(params.viz.filter_data, tmp_filter); inst_view[tmp_filter] = default_state; } }); var filter_title = make_filter_title(params, filter_type); div_filters.append('div').classed('title_' + filter_type, true).classed('sidebar_text', true).classed('slider_description', true).style('margin-top', '5px').style('margin-bottom', '3px').text(filter_title.text + filter_title.state + filter_title.suffix); div_filters.append('div').classed('slider_' + filter_type, true).classed('slider', true).attr('current_state', filter_title.state); var views = params.network_data.views; var available_views = get_subset_views(params, views, inst_view); // sort available views by filter_type value available_views = available_views.sort(function (a, b) { return b[filter_type] - a[filter_type]; }); var inst_max = available_views.length - 1; var ini_value = 0; // change the starting position of the slider if necessary if (params.requested_view !== null && filter_type in params.requested_view) { var inst_filter_value = params.requested_view[filter_type]; if (inst_filter_value != 'all') { var found_value = available_views.map(function (e) { return e[filter_type]; }).indexOf(inst_filter_value); if (found_value > 0) { ini_value = found_value; } } } // Filter Slider ////////////////////////////////////////////////////////////////////// var slide_filter_fun = d3.slider().value(ini_value).min(0).max(inst_max).step(1).on('slide', function (evt, value) { run_filter_slider_db(cgm, filter_type, available_views, value); }).on('slideend', function (evt, value) { run_filter_slider_db(cgm, filter_type, available_views, value); }); // save slider function in order to reset value later cgm.slider_functions[filter_type] = slide_filter_fun; d3.select(cgm.params.root + ' .slider_' + filter_type).call(slide_filter_fun); ////////////////////////////////////////////////////////////////////// var run_filter_slider_db = _.debounce(run_filter_slider, 800); }; /***/ }, /* 234 */ /***/ function(module, exports, __webpack_require__) { var update_viz_with_view = __webpack_require__(177); var reset_other_filter_sliders = __webpack_require__(214); var get_current_orders = __webpack_require__(235); var make_requested_view = __webpack_require__(14); module.exports = function run_filter_slider(cgm, filter_type, available_views, inst_index) { // only update if not running update if (d3.select(cgm.params.viz.viz_svg).classed('running_update') === false) { var params = cgm.params; // get value var inst_state = available_views[inst_index][filter_type]; reset_other_filter_sliders(cgm, filter_type, inst_state); params = get_current_orders(params); var requested_view = {}; requested_view[filter_type] = inst_state; requested_view = make_requested_view(params, requested_view); if (_.has(available_views[0], 'enr_score_type')) { var enr_state = d3.select(params.root + ' .toggle_enr_score_type').attr('current_state'); requested_view.enr_score_type = enr_state; } update_viz_with_view(cgm, requested_view); } }; /***/ }, /* 235 */ /***/ function(module, exports) { module.exports = function get_current_orders(params) { // get current orders var other_rc; _.each(['row', 'col'], function (inst_rc) { if (inst_rc === 'row') { other_rc = 'col'; } else { other_rc = 'row'; } if (d3.select(params.root + ' .toggle_' + other_rc + '_order .active').empty() === false) { params.viz.inst_order[inst_rc] = d3.select(params.root + ' .toggle_' + other_rc + '_order').select('.active').attr('name'); } else { // default to cluster ordering params.viz.inst_order[inst_rc] = 'clust'; } }); return params; }; /***/ }, /* 236 */ /***/ function(module, exports, __webpack_require__) { // var update_network = require('../network/update_network'); var make_requested_view = __webpack_require__(14); module.exports = function make_button_filter(config, params, filter_type, div_filters) { /* Enrichr specific code */ var buttons = div_filters.append('div').classed('categorical_filter', true).classed('toggle_' + filter_type, true).classed('btn-group-vertical', true).style('width', '100%').style('margin-top', '10px').attr('current_state', 'combined_score'); var filter_options = params.viz.filter_data[filter_type]; var button_dict = { 'combined_score': 'Combined Score', 'pval': 'P-Value', 'zscore': 'Z-score' }; buttons.selectAll('button').data(filter_options).enter().append('button').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('.filter_button', true).classed('active', function (d) { var is_active = false; if (d == 'combined_score') { is_active = true; } return is_active; }).attr('name', function (d) { return d; }).html(function (d) { return button_dict[d]; }); $(params.root + ' .categorical_filter .btn').off().click(function () { d3.selectAll(params.root + ' .categorical_filter .btn').classed('active', false); d3.select(this).classed('active', true); var inst_state = d3.select(this).attr('name'); var requested_view = { 'enr_score_type': inst_state }; make_requested_view(params, requested_view); d3.select(params.root + ' .toggle_enr_score_type').attr('current_state', inst_state); }); }; /***/ }, /* 237 */ /***/ function(module, exports) { module.exports = function set_up_search(sidebar, params) { var search_container = sidebar.append('div') // .classed('row',true) .classed('gene_search_container', true).style('padding-left', '10px').style('padding-right', '10px').style('margin-top', '10px'); search_container.append('input').classed('form-control', true).classed('gene_search_box', true).classed('sidebar_text', true).attr('type', 'text').attr('placeholder', params.sidebar.row_search.placeholder).style('height', params.sidebar.row_search.box.height + 'px').style('margin-top', '10px'); search_container.append('div').classed('gene_search_button', true).style('margin-top', '5px').attr('data-toggle', 'buttons').append('button').classed('sidebar_text', true).html('Search').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('submit_gene_button', true).style('width', '100%').style('font-size', '14px'); }; /***/ }, /* 238 */ /***/ function(module, exports) { // var get_cat_title = require('../categories/get_cat_title'); module.exports = function set_up_reorder(params, sidebar) { var button_dict; var tmp_orders; var rc_dict = { 'row': 'Row', 'col': 'Column', 'both': '' }; var is_active; var inst_reorder; // var all_cats; // var inst_order_label; var reorder_section = sidebar.append('div').style('padding-left', '10px').style('padding-right', '10px').classed('reorder_section', true); var reorder_types; if (params.sim_mat) { reorder_types = ['both']; } else { reorder_types = ['row', 'col']; } _.each(reorder_types, function (inst_rc) { button_dict = { 'clust': 'Cluster', 'rank': 'Rank by Sum', 'rankvar': 'Rank by Variance', 'ini': 'Initial Order', 'alpha': 'Alphabetically' }; var other_rc; if (inst_rc === 'row') { other_rc = 'col'; } else { other_rc = 'row'; } tmp_orders = Object.keys(params.matrix.orders); var possible_orders = []; _.each(tmp_orders, function (inst_name) { if (inst_name.indexOf(other_rc) > -1) { inst_name = inst_name.replace('_row', '').replace('_col', ''); if (inst_name.indexOf('cat_') < 0) { possible_orders.push(inst_name); } } }); // specific to Enrichr if (_.keys(params.viz.filter_data).indexOf('enr_score_type') > -1) { possible_orders = ['clust', 'rank']; } possible_orders = _.uniq(possible_orders); possible_orders = possible_orders.sort(); var reorder_text; if (inst_rc != 'both') { reorder_text = ' Order'; } else { reorder_text = 'Reorder Matrix'; } reorder_section.append('div').classed('sidebar_button_text', true).style('clear', 'both').style('margin-top', '10px').html(rc_dict[inst_rc] + reorder_text); inst_reorder = reorder_section.append('div').classed('btn-group-vertical', true).style('width', '100%').classed('toggle_' + inst_rc + '_order', true).attr('role', 'group'); inst_reorder.selectAll('.button').data(possible_orders).enter().append('button').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('sidebar_button_text', true).classed('active', function (d) { is_active = false; if (d == params.viz.inst_order[other_rc]) { is_active = true; } return is_active; }).attr('name', function (d) { return d; }).html(function (d) { return button_dict[d]; }); }); }; /***/ }, /* 239 */ /***/ function(module, exports, __webpack_require__) { var make_filter_title = __webpack_require__(215); module.exports = function set_sidebar_ini_view(params) { _.each(_.keys(params.ini_view), function (inst_filter) { // initialize filter slider using ini_view var inst_value = params.ini_view[inst_filter]; var filter_type = params.viz.possible_filters[inst_filter]; if (filter_type === 'numerical') { if (inst_value != 'all') { inst_value = parseInt(inst_value, 10); } if (params.viz.filter_data[inst_filter].indexOf(inst_value) <= -1) { inst_value = 'all'; } var filter_title = make_filter_title(params, inst_filter); d3.select(params.root + ' .title_' + inst_filter).text(filter_title.text + inst_value + filter_title.suffix); d3.select(params.root + ' .slider_' + inst_filter).attr('current_state', inst_value); } else { // set up button initialization } }); }; /***/ }, /* 240 */ /***/ function(module, exports, __webpack_require__) { var file_saver = __webpack_require__(217); var two_translate_zoom = __webpack_require__(116); var deactivate_cropping = __webpack_require__(221); var save_svg_png = __webpack_require__(241); module.exports = function make_icons(cgm, sidebar) { var params = cgm.params; // var saveSvgAsPng = save_svg_png(); var saveAs = file_saver(); var row = sidebar.select('.icons_section').style('margin-top', '7px').style('margin-left', '5%'); var width_pct = '22%'; var padding_left = '0px'; var padding_right = '0px'; row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa-share-alt', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () { $(params.root + ' .share_info').modal('toggle'); $('.share_url').val(window.location.href); }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Share').style('left', '0%'); row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa-camera', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () { $(params.root + ' .picture_info').modal('toggle'); }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Take snapshot').style('left', '-100%'); row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa fa-cloud-download', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () { cgm.save_matrix(); }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Download matrix').style('left', '-200%'); row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', '-5px').append('i').classed('fa', true).classed('fa-crop', true).classed('crop_button', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () { // do nothing if dendro filtering has been done if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false) { var is_crop = d3.select(this).classed('fa-crop'); var is_undo = d3.select(this).classed('fa-undo'); // press crop button (can be active/incative) if (is_crop) { // keep list of names to return to state cgm.params.crop_filter_nodes = {}; cgm.params.crop_filter_nodes.row_nodes = cgm.params.network_data.row_nodes; cgm.params.crop_filter_nodes.col_nodes = cgm.params.network_data.col_nodes; cgm.brush_crop_matrix(); if (d3.select(this).classed('active_cropping') === false) { // set active_cropping (button turns red) d3.select(this).classed('active_cropping', true).style('color', 'red'); } else { // deactivate cropping (button turns blue) d3.select(this).classed('active_cropping', false).style('color', '#337ab7'); deactivate_cropping(cgm); } } // press undo button if (is_undo) { d3.select(params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', true).classed('fa-undo', false); // cgm.filter_viz_using_names(cgm.params.crop_filter_nodes); cgm.filter_viz_using_nodes(cgm.params.crop_filter_nodes); // show dendro crop buttons after brush-cropping has been undone d3.select(cgm.params.root + ' .col_dendro_icons_container').style('display', 'block'); d3.select(cgm.params.root + ' .row_dendro_icons_container').style('display', 'block'); } two_translate_zoom(cgm, 0, 0, 1); } }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Crop matrix').style('left', '-400%'); // save svg: example from: http://bl.ocks.org/pgiraud/8955139#profile.json //////////////////////////////////////////////////////////////////////////// function save_clust_svg() { d3.select(params.root + ' .expand_button').style('opacity', 0); var html = d3.select(params.root + " .viz_svg").attr("title", "test2").attr("version", 1.1).attr("xmlns", "http://www.w3.org/2000/svg").node().parentNode.innerHTML; var blob = new Blob([html], { type: "image/svg+xml" }); saveAs(blob, "clustergrammer.svg"); d3.select(params.root + ' .expand_button').style('opacity', 0.4); } d3.select(params.root + ' .download_buttons').append('p').append('a').html('Download SVG').on('click', function () { save_clust_svg(); }); var svg_id = 'svg_' + params.root.replace('#', ''); // save as PNG ///////////////////////////////////////// d3.select(params.root + ' .download_buttons').append('p').append('a').html('Download PNG').on('click', function () { d3.select(params.root + ' .expand_button').style('opacity', 0); // saveSvgAsPng(document.getElementById(svg_id), "clustergrammer.png"); save_svg_png.saveSvgAsPng(document.getElementById(svg_id), "clustergrammer.png"); d3.select(params.root + ' .expand_button').style('opacity', 0.4); }); }; /***/ }, /* 241 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;(function () { var out$ = typeof exports != 'undefined' && exports || "function" != 'undefined' && {} || this; var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [<!ENTITY nbsp " ">]>'; function isElement(obj) { return obj instanceof HTMLElement || obj instanceof SVGElement; } function requireDomNode(el) { if (!isElement(el)) { throw new Error('an HTMLElement or SVGElement is required; got ' + el); } } function isExternal(url) { return url && url.lastIndexOf('http', 0) == 0 && url.lastIndexOf(window.location.host) == -1; } function inlineImages(el, callback) { requireDomNode(el); var images = el.querySelectorAll('image'), left = images.length, checkDone = function () { if (left === 0) { callback(); } }; checkDone(); for (var i = 0; i < images.length; i++) { (function (image) { var href = image.getAttributeNS("http://www.w3.org/1999/xlink", "href"); if (href) { if (isExternal(href.value)) { console.warn("Cannot render embedded images linking to external hosts: " + href.value); return; } } var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var img = new Image(); img.crossOrigin = "anonymous"; href = href || image.getAttribute('href'); if (href) { img.src = href; img.onload = function () { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); image.setAttributeNS("http://www.w3.org/1999/xlink", "href", canvas.toDataURL('image/png')); left--; checkDone(); }; img.onerror = function () { console.log("Could not load " + href); left--; checkDone(); }; } else { left--; checkDone(); } })(images[i]); } } function styles(el, options, cssLoadedCallback) { var selectorRemap = options.selectorRemap; var modifyStyle = options.modifyStyle; var css = ""; // each font that has extranl link is saved into queue, and processed // asynchronously var fontsQueue = []; var sheets = document.styleSheets; for (var i = 0; i < sheets.length; i++) { try { var rules = sheets[i].cssRules; } catch (e) { console.warn("Stylesheet could not be loaded: " + sheets[i].href); continue; } if (rules != null) { for (var j = 0, match; j < rules.length; j++, match = null) { var rule = rules[j]; if (typeof rule.style != "undefined") { var selectorText; try { selectorText = rule.selectorText; } catch (err) { console.warn('The following CSS rule has an invalid selector: "' + rule + '"', err); } try { if (selectorText) { match = el.querySelector(selectorText); } } catch (err) { console.warn('Invalid CSS selector "' + selectorText + '"', err); } if (match) { var selector = selectorRemap ? selectorRemap(rule.selectorText) : rule.selectorText; var cssText = modifyStyle ? modifyStyle(rule.style.cssText) : rule.style.cssText; css += selector + " { " + cssText + " }\n"; } else if (rule.cssText.match(/^@font-face/)) { // below we are trying to find matches to external link. E.g. // @font-face { // // ... // src: local('Abel'), url(https://fonts.gstatic.com/s/abel/v6/UzN-iejR1VoXU2Oc-7LsbvesZW2xOQ-xsNqO47m55DA.woff2); // } // // This regex will save extrnal link into first capture group var fontUrlRegexp = /url\(["']?(.+?)["']?\)/; // TODO: This needs to be changed to support multiple url declarations per font. var fontUrlMatch = rule.cssText.match(fontUrlRegexp); var externalFontUrl = fontUrlMatch && fontUrlMatch[1] || ''; var fontUrlIsDataURI = externalFontUrl.match(/^data:/); if (fontUrlIsDataURI) { // We should ignore data uri - they are already embedded externalFontUrl = ''; } if (externalFontUrl) { // okay, we are lucky. We can fetch this font later fontsQueue.push({ text: rule.cssText, // Pass url regex, so that once font is downladed, we can run `replace()` on it fontUrlRegexp: fontUrlRegexp, format: getFontMimeTypeFromUrl(externalFontUrl), url: externalFontUrl }); } else { // otherwise, use previous logic css += rule.cssText + '\n'; } } } } } } // Now all css is processed, it's time to handle scheduled fonts processFontQueue(fontsQueue); function getFontMimeTypeFromUrl(fontUrl) { var supportedFormats = { 'woff2': 'font/woff2', 'woff': 'font/woff', 'otf': 'application/x-font-opentype', 'ttf': 'application/x-font-ttf', 'eot': 'application/vnd.ms-fontobject', 'sfnt': 'application/font-sfnt', 'svg': 'image/svg+xml' }; var extensions = Object.keys(supportedFormats); for (var i = 0; i < extensions.length; ++i) { var extension = extensions[i]; // TODO: This is not bullet proof, it needs to handle edge cases... if (fontUrl.indexOf('.' + extension) > 0) { return supportedFormats[extension]; } } // If you see this error message, you probably need to update code above. console.error('Unknown font format for ' + fontUrl + '; Fonts may not be working correctly'); return 'application/octet-stream'; } function processFontQueue(queue) { if (queue.length > 0) { // load fonts one by one until we have anything in the queue: var font = queue.pop(); processNext(font); } else { // no more fonts to load. cssLoadedCallback(css); } function processNext(font) { // TODO: This could benefit from caching. var oReq = new XMLHttpRequest(); oReq.addEventListener('load', fontLoaded); oReq.addEventListener('error', transferFailed); oReq.addEventListener('abort', transferFailed); oReq.open('GET', font.url); oReq.responseType = 'arraybuffer'; oReq.send(); function fontLoaded() { // TODO: it may be also worth to wait until fonts are fully loaded before // attempting to rasterize them. (e.g. use https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet ) var fontBits = oReq.response; var fontInBase64 = arrayBufferToBase64(fontBits); updateFontStyle(font, fontInBase64); } function transferFailed(e) { console.warn('Failed to load font from: ' + font.url); console.warn(e); css += font.text + '\n'; processFontQueue(); } function updateFontStyle(font, fontInBase64) { var dataUrl = 'url("data:' + font.format + ';base64,' + fontInBase64 + '")'; css += font.text.replace(font.fontUrlRegexp, dataUrl) + '\n'; // schedule next font download on next tick. setTimeout(function () { processFontQueue(queue); }, 0); } } } function arrayBufferToBase64(buffer) { var binary = ''; var bytes = new Uint8Array(buffer); var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return window.btoa(binary); } } function getDimension(el, clone, dim) { var v = el.viewBox && el.viewBox.baseVal && el.viewBox.baseVal[dim] || clone.getAttribute(dim) !== null && !clone.getAttribute(dim).match(/%$/) && parseInt(clone.getAttribute(dim)) || el.getBoundingClientRect()[dim] || parseInt(clone.style[dim]) || parseInt(window.getComputedStyle(el).getPropertyValue(dim)); return typeof v === 'undefined' || v === null || isNaN(parseFloat(v)) ? 0 : v; } function reEncode(data) { data = encodeURIComponent(data); data = data.replace(/%([0-9A-F]{2})/g, function (match, p1) { var c = String.fromCharCode('0x' + p1); return c === '%' ? '%25' : c; }); return decodeURIComponent(data); } out$.prepareSvg = function (el, options, cb) { requireDomNode(el); options = options || {}; options.scale = options.scale || 1; options.responsive = options.responsive || false; var xmlns = "http://www.w3.org/2000/xmlns/"; inlineImages(el, function () { var outer = document.createElement("div"); var clone = el.cloneNode(true); var width, height; if (el.tagName == 'svg') { width = options.width || getDimension(el, clone, 'width'); height = options.height || getDimension(el, clone, 'height'); } else if (el.getBBox) { var box = el.getBBox(); width = box.x + box.width; height = box.y + box.height; clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\(.*?\)/, '')); var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.appendChild(clone); clone = svg; } else { console.error('Attempted to render non-SVG element', el); return; } clone.setAttribute("version", "1.1"); if (!clone.getAttribute('xmlns')) { clone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg"); } if (!clone.getAttribute('xmlns:xlink')) { clone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink"); } if (options.responsive) { clone.removeAttribute('width'); clone.removeAttribute('height'); clone.setAttribute('preserveAspectRatio', 'xMinYMin meet'); } else { clone.setAttribute("width", width * options.scale); clone.setAttribute("height", height * options.scale); } clone.setAttribute("viewBox", [options.left || 0, options.top || 0, width, height].join(" ")); var fos = clone.querySelectorAll('foreignObject > *'); for (var i = 0; i < fos.length; i++) { if (!fos[i].getAttribute('xmlns')) { fos[i].setAttributeNS(xmlns, "xmlns", "http://www.w3.org/1999/xhtml"); } } outer.appendChild(clone); // In case of custom fonts we need to fetch font first, and then inline // its url into data-uri format (encode as base64). That's why style // processing is done asynchonously. Once all inlining is finshed // cssLoadedCallback() is called. styles(el, options, cssLoadedCallback); function cssLoadedCallback(css) { // here all fonts are inlined, so that we can render them properly. var s = document.createElement('style'); s.setAttribute('type', 'text/css'); s.innerHTML = "<![CDATA[\n" + css + "\n]]>"; var defs = document.createElement('defs'); defs.appendChild(s); clone.insertBefore(defs, clone.firstChild); if (cb) { var outHtml = outer.innerHTML; outHtml = outHtml.replace(/NS\d+:href/gi, 'xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href'); cb(outHtml, width, height); } } }); }; out$.svgAsDataUri = function (el, options, cb) { out$.prepareSvg(el, options, function (svg) { var uri = 'data:image/svg+xml;base64,' + window.btoa(reEncode(doctype + svg)); if (cb) { cb(uri); } }); }; out$.svgAsPngUri = function (el, options, cb) { requireDomNode(el); options = options || {}; options.encoderType = options.encoderType || 'image/png'; options.encoderOptions = options.encoderOptions || 0.8; var convertToPng = function (src, w, h) { var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); canvas.width = w; canvas.height = h; if (options.canvg) { options.canvg(canvas, src); } else { context.drawImage(src, 0, 0); } if (options.backgroundColor) { context.globalCompositeOperation = 'destination-over'; context.fillStyle = options.backgroundColor; context.fillRect(0, 0, canvas.width, canvas.height); } var png; try { png = canvas.toDataURL(options.encoderType, options.encoderOptions); } catch (e) { if (typeof SecurityError !== 'undefined' && e instanceof SecurityError || e.name == "SecurityError") { console.error("Rendered SVG images cannot be downloaded in this browser."); return; } else { throw e; } } cb(png); }; if (options.canvg) { out$.prepareSvg(el, options, convertToPng); } else { out$.svgAsDataUri(el, options, function (uri) { var image = new Image(); image.onload = function () { convertToPng(image, image.width, image.height); }; image.onerror = function () { console.error('There was an error loading the data URI as an image on the following SVG\n', window.atob(uri.slice(26)), '\n', "Open the following link to see browser's diagnosis\n", uri); }; image.src = uri; }); } }; out$.download = function (name, uri) { if (navigator.msSaveOrOpenBlob) { navigator.msSaveOrOpenBlob(uriToBlob(uri), name); } else { var saveLink = document.createElement('a'); var downloadSupported = 'download' in saveLink; if (downloadSupported) { saveLink.download = name; saveLink.href = uri; saveLink.style.display = 'none'; document.body.appendChild(saveLink); saveLink.click(); document.body.removeChild(saveLink); } else { window.open(uri, '_temp', 'menubar=no,toolbar=no,status=no'); } } }; function uriToBlob(uri) { var byteString = window.atob(uri.split(',')[1]); var mimeString = uri.split(',')[0].split(':')[1].split(';')[0]; var buffer = new ArrayBuffer(byteString.length); var intArray = new Uint8Array(buffer); for (var i = 0; i < byteString.length; i++) { intArray[i] = byteString.charCodeAt(i); } return new Blob([buffer], { type: mimeString }); } out$.saveSvg = function (el, name, options) { requireDomNode(el); options = options || {}; out$.svgAsDataUri(el, options, function (uri) { out$.download(name, uri); }); }; out$.saveSvgAsPng = function (el, name, options) { requireDomNode(el); options = options || {}; out$.svgAsPngUri(el, options, function (uri) { out$.download(name, uri); }); }; // if define is defined create as an AMD module if (true) { !(__WEBPACK_AMD_DEFINE_RESULT__ = function () { return out$; }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } })(); /***/ }, /* 242 */ /***/ function(module, exports, __webpack_require__) { var make_modal_skeleton = __webpack_require__(243); module.exports = function ini_modals(params) { // share modal /////////////////////////////////////// var share_modal = make_modal_skeleton(params, 'share_info'); share_modal.header.append('a').attr('target', '_blank').attr('href', '/clustergrammer/'); share_modal.header.append('h4').classed('modal-title', true).html('Share the visualization using the current URL:'); share_modal.body.append('input').classed('bootstrap_highlight', true).classed('share_url', true); // picture modal /////////////////////////////////////// var screenshot_modal = make_modal_skeleton(params, 'picture_info'); screenshot_modal.header.append('h4').classed('modal-title', true).html('Save a snapshot of the visualization'); screenshot_modal.body.append('div').classed('download_buttons', true); // dendro modal /////////////////////////////////////// var dendro_modal = make_modal_skeleton(params, 'dendro_info'); dendro_modal.header.append('h4').classed('modal-title', true).html('Cluster Information'); dendro_modal.body.append('g').classed('cluster_info_container', true); dendro_modal.body.append('div').classed('dendro_text', true).append('input').classed('bootstrap_highlight', true).classed('current_names', true).style('width', '100%'); }; /***/ }, /* 243 */ /***/ function(module, exports) { module.exports = function make_modal_skeleton(params, modal_class) { var modal_skeleton = {}; var modal = d3.select(params.root).append('div').classed('modal', true).classed('fade', true).classed(modal_class, true).attr('role', 'dialog'); var modal_dialog = modal.append('div').classed('modal-dialog', true); var modal_content = modal_dialog.append('div').classed('modal-content', true); modal_skeleton.header = modal_content.append('div').classed('modal-header', true); modal_skeleton.header.append('button').attr('type', 'button').classed('close', true).attr('data-dismiss', 'modal').html('×'); modal_skeleton.body = modal_content.append('div').classed('modal-body', true); return modal_skeleton; }; /***/ }, /* 244 */ /***/ function(module, exports) { module.exports = function set_up_opacity_slider(sidebar) { var slider_container = sidebar.append('div').classed('opacity_slider_container', true).style('margin-top', '5px').style('padding-left', '10px').style('padding-right', '10px'); slider_container.append('div').classed('sidebar_text', true).classed('opacity_slider_text', true).style('margin-bottom', '3px').text('Opacity Slider'); slider_container.append('div').classed('slider', true).classed('opacity_slider', true); }; /***/ }, /* 245 */ /***/ function(module, exports) { module.exports = function make_colorbar(cgm) { var params = cgm.params; d3.select(params.root + ' .sidebar_wrapper').append('div').classed('sidebar_text', true).style('padding-left', '10px').style('padding-top', '5px').text('Matrix Values'); var colorbar_width = params.sidebar.width - 20; var colorbar_height = 13; var svg_height = 3 * colorbar_height; var svg_width = 1.2 * colorbar_width; var low_left_margin = 10; var top_margin = 33; var high_left_margin = colorbar_width + 10; var bar_margin_left = 10; var bar_margin_top = 3; var network_data = params.network_data; /* var max_link = _.max(network_data.links, function (d) { return d.value; }).value; var min_link = _.min(network_data.links, function (d) { return d.value; }).value; */ var main_svg = d3.select(params.root + ' .sidebar_wrapper').append('svg').attr('height', svg_height + 'px').attr('width', svg_width + 'px'); //Append a defs (for definition) element to your SVG var defs = main_svg.append("defs"); //Append a linearGradient element to the defs and give it a unique id var linearGradient = defs.append("linearGradient").attr("id", "linear-gradient"); var special_case = 'none'; /* // no negative numbers if (min_link >= 0) { //Set the color for the start (0%) linearGradient.append("stop").attr("offset", "0%").attr("stop-color", "white"); //Set the color for the end (100%) linearGradient.append("stop").attr("offset", "100%").attr("stop-color", params.tile_colors[0]); special_case = 'all_postiive'; // no positive numbers } else if (max_link <= 0) { //Set the color for the start (0%) linearGradient.append("stop").attr("offset", "0%").attr("stop-color", params.tile_colors[1]); //Set the color for the end (100%) linearGradient.append("stop").attr("offset", "100%").attr("stop-color", "white"); special_case = 'all_negative'; } // both postive and negative numbers else {*/ //Set the color for the start (0%) linearGradient.append("stop").attr("offset", "0%").attr("stop-color", params.tile_colors[1]); //Set the color for the end (100%) linearGradient.append("stop").attr("offset", "50%").attr("stop-color", "white"); //Set the color for the end (100%) linearGradient.append("stop").attr("offset", "100%").attr("stop-color", params.tile_colors[0]); // } // make colorbar main_svg.append('rect').classed('background', true).attr('height', colorbar_height + 'px').attr('width', colorbar_width + 'px').attr('fill', 'url(#linear-gradient)').attr('transform', 'translate(' + bar_margin_left + ', ' + bar_margin_top + ')').attr('stroke', 'grey').attr('stroke-width', '0.25px'); // make title /////////////// var max_abs_val = Math.abs(Math.round(params.matrix.true_max * 10) / 10); var min_abs_val = Math.abs(Math.round(params.matrix.true_min * 10) / 10); var font_size = 13; main_svg.append('text').text(function () { var inst_string; if (params.matrix.true_min < 0) { inst_string = '-' + min_abs_val.toLocaleString(); } else { inst_string = min_abs_val.toLocaleString(); } return inst_string; }).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 300).style('font-size', font_size).attr('transform', 'translate(' + low_left_margin + ',' + top_margin + ')').attr('text-anchor', 'start'); main_svg.append('text').text(max_abs_val.toLocaleString()).text(function () { return max_abs_val.toLocaleString(); }).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 300).style('font-size', font_size).attr('transform', 'translate(' + high_left_margin + ',' + top_margin + ')').attr('text-anchor', 'end'); }; /***/ } /******/ ]); //# sourceMappingURL=clustergrammer.js.map