├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── LICENSES
├── LICENSE
├── LICENSE_D3_tip
├── LICENSE_FileSaver
├── LICENSE_saveSVGasPng
└── LICSNSE_D3
├── README.md
├── clustergrammer.js
├── clustergrammer.min.js
├── clustergrammer.node.js
├── clustergrammer.node.min.js
├── css
└── custom.css
├── img
├── cat_tsv.png
├── clustergrammer_logo.png
├── demo_high-fr.gif
├── demo_screenshot.png
└── demo_screenshot_full_screen.png
├── index.html
├── js
├── Enrichrgram.js
├── hzome_functions.js
├── load_clustergram.js
├── load_multiple_clustergrams.js
├── load_scrolling_tour.js
├── scroll_section_functions.js
└── send_to_Enrichr.js
├── json
├── mult_view.json
├── mult_view_sim_col.json
├── mult_view_sim_row.json
└── tutorial_info.json
├── lib
├── css
│ ├── bootstrap.css
│ ├── custom_scrolling.css
│ └── font-awesome.min.css
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
└── js
│ ├── bootstrap.min.js
│ ├── d3.js
│ ├── graph-scroll.js
│ ├── jquery-1.11.2.min.js
│ └── underscore-min.js
├── make_clustergrammer.py
├── multiple_clustergrams.html
├── package-lock.json
├── package.json
├── row_dist_mat_py_cos.txt
├── scrolling_tour.html
├── src
├── Colors.js
├── Utils_clust.js
├── categories
│ ├── binom_prop_pval_lookup.js
│ ├── binom_test.js
│ ├── calc_cat_cluster_breakdown.js
│ ├── cat_breakdown_bars.js
│ ├── cat_breakdown_values.js
│ ├── cat_tooltip_text.js
│ ├── click_filter_cats.js
│ ├── get_cat_names.js
│ ├── get_cat_title.js
│ ├── ini_cat_opacity.js
│ ├── make_cat_breakdown_graph.js
│ ├── make_col_cat.js
│ ├── make_row_cat.js
│ └── reset_cat_opacity.js
├── clusterfck_local
│ ├── clusterfck.js
│ ├── distance.js
│ ├── hcluster.js
│ └── kmeans.js
├── config
│ ├── check_nodes_for_categories.js
│ ├── check_sim_mat.js
│ └── set_defaults.js
├── d3.slider
│ ├── .npmignore
│ ├── LICENSE
│ ├── README.md
│ ├── d3.slider.css
│ ├── d3.slider.js
│ ├── index.html
│ └── package.json
├── demo
│ ├── demo_text.js
│ ├── highlight_sidebar_element.js
│ ├── ini_demo.js
│ ├── make_demo_text_containers.js
│ ├── make_play_button.js
│ ├── play_categories.js
│ ├── play_conclusion.js
│ ├── play_demo.js
│ ├── play_filter.js
│ ├── play_groups.js
│ ├── play_intro.js
│ ├── play_menu_button.js
│ ├── play_reorder_buttons.js
│ ├── play_reorder_row.js
│ ├── play_reset_zoom.js
│ ├── play_search.js
│ ├── play_zoom.js
│ ├── position_play_button.js
│ ├── quick_cluster.js
│ ├── run_segment.js
│ ├── sim_click.js
│ └── toggle_play_button.js
├── dendrogram
│ ├── build_dendro_sliders.js
│ ├── build_single_dendro_slider.js
│ ├── calc_col_dendro_triangles.js
│ ├── calc_row_dendro_triangles.js
│ ├── change_groups.js
│ ├── dendro_group_highlight.js
│ ├── dendro_shade_bars.js
│ ├── get_inst_group.js
│ ├── make_col_dendro.js
│ ├── make_dendro_crop_buttons.js
│ ├── make_dendro_triangles.js
│ ├── make_row_dendro.js
│ ├── position_dendro_slider.js
│ ├── run_dendro_filter.js
│ └── toggle_dendro_view.js
├── enter
│ ├── draw_dn_tile.js
│ ├── draw_up_tile.js
│ ├── ds_enter_exit_update.js
│ ├── eeu_existing_row.js
│ ├── enter_existing_row.js
│ ├── enter_exit_update.js
│ ├── enter_new_rows.js
│ ├── enter_row_groups.js
│ └── enter_split_tiles.js
├── exit
│ ├── exit_components.js
│ └── exit_existing_row.js
├── filters
│ ├── get_current_orders.js
│ ├── get_filter_default_state.js
│ ├── get_subset_views.js
│ ├── make_button_filter.js
│ ├── make_filter_title.js
│ ├── make_requested_view.js
│ ├── make_slider_filter.js
│ ├── reset_other_filter_sliders.js
│ ├── run_filter_slider.js
│ └── set_up_filters.js
├── initialize_matrix.js
├── initialize_resizing.js
├── labels
│ ├── add_col_click_hlight.js
│ ├── add_row_click_hlight.js
│ ├── col_viz_aid_triangle.js
│ ├── label_constrain_and_trim.js
│ ├── make_col_label_container.js
│ ├── make_col_tooltips.js
│ ├── make_row_cat_super_labels.js
│ ├── make_row_label_container.js
│ ├── make_row_labels.js
│ ├── make_row_tooltips.js
│ ├── make_row_visual_aid_triangles.js
│ └── super_labels.js
├── main.js
├── make_config.js
├── make_viz.js
├── matrix
│ ├── add_click_hlight.js
│ ├── brush_crop_matrix.js
│ ├── calc_downsampled_levels.js
│ ├── calc_downsampled_matrix.js
│ ├── deactivate_cropping.js
│ ├── draw_gridlines.js
│ ├── fine_position_tile.js
│ ├── grid_lines_viz.js
│ ├── index.js
│ ├── make_full_name.js
│ ├── make_matrix_rows.js
│ ├── make_matrix_string.js
│ ├── make_simple_rows.js
│ ├── mouseout_tile.js
│ ├── mouseover_tile.js
│ ├── save_matrix.js
│ ├── sum_rows_mat.js
│ └── toggle_grid_lines.js
├── menus
│ ├── build_filter_icon.js
│ ├── build_tree_icon.js
│ ├── make_filter_menu.js
│ ├── make_menu_button_section.js
│ ├── make_menu_update_button.js
│ ├── make_tree_menu.js
│ ├── position_filter_icon.js
│ ├── position_filter_menu.js
│ ├── position_tree_icon.js
│ ├── position_tree_menu.js
│ └── toggle_menu.js
├── modal
│ └── make_modal_skeleton.js
├── network
│ ├── change_category.js
│ ├── define_enter_exit_delays.js
│ ├── filter_network_using_new_nodes.js
│ ├── filter_viz_using_names.js
│ ├── filter_viz_using_nodes.js
│ ├── make_network_using_view.js
│ ├── transpose_network.js
│ └── update_viz_with_view.js
├── params
│ ├── calc_cat_params.js
│ ├── calc_clust_height.js
│ ├── calc_clust_width.js
│ ├── calc_default_fs.js
│ ├── calc_label_params.js
│ ├── calc_matrix_params.js
│ ├── calc_val_max.js
│ ├── calc_viz_dimensions.js
│ ├── calc_viz_params.js
│ ├── check_if_value_cats.js
│ ├── get_available_filters.js
│ ├── get_svg_dim.js
│ ├── ini_label_params.js
│ ├── ini_matrix_params.js
│ ├── ini_sidebar_params.js
│ ├── make_cat_params.js
│ ├── make_params.js
│ └── set_zoom_params.js
├── recluster
│ ├── distance_functions.js
│ ├── get_max_distance_in_dm.js
│ ├── get_order_and_groups_clusterfck_tree.js
│ └── recluster.js
├── reorder
│ ├── all_reorder.js
│ ├── col_reorder.js
│ ├── ini_cat_reorder.js
│ ├── reposition_tile_highlight.js
│ ├── row_reorder.js
│ └── update_reorder_buttons.js
├── reset_size
│ ├── recalc_params_for_resize.js
│ ├── reset_size_after_update.js
│ ├── resize_borders.js
│ ├── resize_col_hlight.js
│ ├── resize_col_labels.js
│ ├── resize_col_text.js
│ ├── resize_col_triangle.js
│ ├── resize_containers.js
│ ├── resize_dendro.js
│ ├── resize_highlights.js
│ ├── resize_label_bars.js
│ ├── resize_row_labels.js
│ ├── resize_row_tiles.js
│ ├── resize_row_viz.js
│ ├── resize_spillover.js
│ ├── resize_super_labels.js
│ └── resize_viz.js
├── screenshot
│ └── file_saver.js
├── search
│ └── run_row_search.js
├── set_viz_wrapper_size.js
├── sidebar
│ ├── disable_sidebar.js
│ ├── enable_sidebar.js
│ ├── index.js
│ ├── ini_sidebar.js
│ ├── make_colorbar.js
│ ├── make_icons.js
│ ├── make_modals.js
│ ├── set_sidebar_ini_view.js
│ ├── set_up_opacity_slider.js
│ ├── set_up_reorder.js
│ └── set_up_search.js
├── spillover
│ ├── main_spillover.js
│ └── make_row_dendro_spillover.js
├── tooltip
│ └── d3_tip_custom.js
├── update
│ ├── generate_cat_data.js
│ ├── modify_row_node_cats.js
│ ├── remove_node_cats.js
│ ├── reset_cats.js
│ ├── update_cats.js
│ ├── update_split_tiles.js
│ ├── update_view.js
│ └── update_viz_with_network.js
└── zoom
│ ├── calc_real_font_size.js
│ ├── calc_zoom_switching.js
│ ├── check_zoom_stop_status.js
│ ├── constrain_font_size.js
│ ├── find_viz_rows.js
│ ├── get_previous_zoom.js
│ ├── ini_doubleclick.js
│ ├── ini_zoom_info.js
│ ├── num_visible_labels.js
│ ├── reset_zoom.js
│ ├── resize_label_val_bars.js
│ ├── run_transformation.js
│ ├── run_when_zoom_stopped.js
│ ├── run_zoom.js
│ ├── show_visible_area.js
│ ├── trim_text.js
│ ├── two_translate_zoom.js
│ ├── zoom_crop_triangles.js
│ ├── zoom_rules_x.js
│ └── zoom_rules_y.js
├── tests
├── Compare_Front_and_Back_End_Clustering.ipynb
└── output_1.13819231887
├── txt
├── GO_Biological_Process_2015.txt
├── KEA_matrix.txt
├── ccle_example.txt
├── example_tsv.txt
├── mat_1mb.txt
├── missing_values.txt
├── mnist.txt
├── number_labels.txt
├── rc_two_cats.txt
├── rc_val_cats.txt
└── tuple_cats.txt
└── webpack.config.js
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 | node_modules
23 |
24 | # Logs and databases #
25 | ######################
26 | *.log
27 | *.sql
28 | *.sqlite
29 |
30 | # OS generated files #
31 | ######################
32 | .DS_Store
33 | .DS_Store?
34 | ._*
35 | .Spotlight-V100
36 | .Trashes
37 | ehthumbs.db
38 | Thumbs.db
39 |
40 | # cache files for sublime text
41 | *.tmlanguage.cache
42 | *.tmPreferences.cache
43 | *.stTheme.cache
44 |
45 | # workspace files are user-specific
46 | *.sublime-workspace
47 | *.sublime-project
48 | *.idea
49 | *.swo
50 | *.swp
51 |
52 | # sftp configuration file
53 | sftp-config.json
54 |
55 | #TernJS
56 | .tern-port
57 |
58 | # webpack
59 | *.js.map
60 | .eslint*
61 |
62 | # python
63 | *.ipynb_checkpoints
64 | *.pyc
65 | clustergrammer
66 |
67 | # # eslint
68 | # .eslint*
69 |
70 | # how to retroactively use
71 | ############################
72 | # git rm -r --cached .
73 | # git add .
74 | # git commit -m "fixing .gitignore"
75 |
76 | # Word temporary
77 | ~$*.doc*
78 |
79 | # Excel temporary
80 | ~$*.xls*
81 |
82 | # Excel Backup File
83 | *.xlk
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Ma'ayan Lab
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSES/LICENSE_D3_tip:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2013 Justin Palmer
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/LICENSES/LICENSE_FileSaver:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright © 2016 Eli Grey.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/LICENSES/LICENSE_saveSVGasPng:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Eric Shull
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSES/LICSNSE_D3:
--------------------------------------------------------------------------------
1 | Copyright 2010-2016 Mike Bostock
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of the author nor the names of contributors may be used to
15 | endorse or promote products derived from this software without specific prior
16 | written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/img/cat_tsv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/img/cat_tsv.png
--------------------------------------------------------------------------------
/img/clustergrammer_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/img/clustergrammer_logo.png
--------------------------------------------------------------------------------
/img/demo_high-fr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/img/demo_high-fr.gif
--------------------------------------------------------------------------------
/img/demo_screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/img/demo_screenshot.png
--------------------------------------------------------------------------------
/img/demo_screenshot_full_screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/img/demo_screenshot_full_screen.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Clustergrammer.js
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Please wait ...
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/js/hzome_functions.js:
--------------------------------------------------------------------------------
1 | function ini_hzome(root_id){
2 |
3 | // save gene data to global variable
4 | gene_data = {};
5 |
6 | function get_mouseover(root_tip, gene_symbol){
7 |
8 | // not sure if this is necessary
9 | if ( d3.select(root_tip + '_row_tip').classed(gene_symbol) ){
10 | get_request(root_tip, gene_symbol);
11 | }
12 |
13 | }
14 |
15 | function get_request(root_tip, ini_gene_symbol){
16 |
17 | var gene_symbol;
18 | if (ini_gene_symbol.indexOf(' ') > 0){
19 | gene_symbol = ini_gene_symbol.split(' ')[0];
20 | } else if (ini_gene_symbol.indexOf('_') > 0){
21 | gene_symbol = ini_gene_symbol.split('_')[0];
22 | }
23 | else {
24 | gene_symbol = ini_gene_symbol;
25 | }
26 |
27 | var base_url = 'https://amp.pharm.mssm.edu/Harmonizome/api/1.0/gene/';
28 | var url = base_url + gene_symbol;
29 |
30 | $.get(url, function(data) {
31 |
32 | data = JSON.parse(data);
33 |
34 | // save data for repeated use
35 | gene_data[gene_symbol] = {}
36 | gene_data[gene_symbol].name = data.name;
37 | gene_data[gene_symbol].description = data.description;
38 |
39 | set_tooltip(data, root_tip, ini_gene_symbol);
40 |
41 | return data;
42 |
43 | });
44 | }
45 |
46 | function set_tooltip(data, root_tip, gene_symbol){
47 |
48 | if (data.name != undefined){
49 |
50 | d3.selectAll(root_tip + '_row_tip')
51 | .html(function(){
52 | var sym_name = gene_symbol + ': ' + data.name;
53 | var full_html = '' + sym_name + '
' + '' +
54 | data.description + '
';
55 | return full_html;
56 | });
57 | }
58 | }
59 |
60 |
61 | function gene_info(root_tip, gene_info){
62 |
63 | var gene_symbol = gene_info.name;
64 |
65 | if (_.has(gene_data, gene_symbol)){
66 | var inst_data = gene_data[gene_symbol];
67 | set_tooltip(inst_data, root_tip, gene_symbol);
68 | } else{
69 | setTimeout(get_mouseover, 250, root_tip, gene_symbol);
70 | }
71 |
72 | }
73 |
74 | hzome = {}
75 |
76 | hzome.gene_info = gene_info;
77 | hzome.gene_data = gene_data;
78 | hzome.get_mouseover = get_mouseover;
79 | hzome.get_request = get_request;
80 |
81 | return hzome;
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/js/send_to_Enrichr.js:
--------------------------------------------------------------------------------
1 | function send_to_Enrichr(options) { // http://amp.pharm.mssm.edu/Enrichr/#help
2 | var defaultOptions = {
3 | description: "",
4 | popup: false
5 | };
6 |
7 | if (typeof options.description == 'undefined')
8 | options.description = defaultOptions.description;
9 | if (typeof options.popup == 'undefined')
10 | options.popup = defaultOptions.popup;
11 | if (typeof options.list == 'undefined')
12 | alert('No genes defined.');
13 |
14 | var form = document.createElement('form');
15 | form.setAttribute('method', 'post');
16 | form.setAttribute('action', 'https://amp.pharm.mssm.edu/Enrichr/enrich');
17 | if (options.popup)
18 | form.setAttribute('target', '_blank');
19 | form.setAttribute('enctype', 'multipart/form-data');
20 |
21 | var listField = document.createElement('input');
22 | listField.setAttribute('type', 'hidden');
23 | listField.setAttribute('name', 'list');
24 | listField.setAttribute('value', options.list);
25 | form.appendChild(listField);
26 |
27 | var descField = document.createElement('input');
28 | descField.setAttribute('type', 'hidden');
29 | descField.setAttribute('name', 'description');
30 | descField.setAttribute('value', options.description);
31 | form.appendChild(descField);
32 |
33 | document.body.appendChild(form);
34 | form.submit();
35 | document.body.removeChild(form);
36 | }
--------------------------------------------------------------------------------
/lib/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/lib/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/lib/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/lib/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/lib/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/lib/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/lib/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/lib/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/lib/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaayanLab/clustergrammer/12a8f1caac6e9707475fe005a00bd60935ea4161/lib/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/make_clustergrammer.py:
--------------------------------------------------------------------------------
1 | '''
2 | Python 2.7
3 | The clustergrammer python module can be installed using pip:
4 | pip install clustergrammer
5 |
6 | or by getting the code from the repo:
7 | https://github.com/MaayanLab/clustergrammer-py
8 | '''
9 |
10 | from clustergrammer import Network
11 | net = Network()
12 |
13 | # load matrix tsv file
14 | net.load_file('txt/rc_two_cats.txt')
15 | # net.load_file('txt/ccle_example.txt')
16 | # net.load_file('txt/rc_val_cats.txt')
17 | # net.load_file('txt/number_labels.txt')
18 | # net.load_file('txt/mnist.txt')
19 | # net.load_file('txt/tuple_cats.txt')
20 | # net.load_file('txt/example_tsv.txt')
21 |
22 | # net.enrichrgram('KEA_2015')
23 |
24 | # optional filtering and normalization
25 | ##########################################
26 | # net.filter_sum('row', threshold=20)
27 | # net.normalize(axis='col', norm_type='zscore', keep_orig=True)
28 | # net.filter_N_top('row', 250, rank_type='sum')
29 | # net.filter_threshold('row', threshold=3.0, num_occur=4)
30 | # net.swap_nan_for_zero()
31 | # net.set_cat_color('col', 1, 'Category: one', 'blue')
32 |
33 | # net.make_clust()
34 | # net.dendro_cats('row', 5)
35 |
36 | net.cluster(dist_type='cos',views=['N_row_sum', 'N_row_var'] , dendro=True,
37 | sim_mat=True, filter_sim=0.1, calc_cat_pval=False, enrichrgram=
38 | False, run_clustering=True)
39 |
40 | # write jsons for front-end visualizations
41 | net.write_json_to_file('viz', 'json/mult_view.json', 'indent')
42 | net.write_json_to_file('sim_row', 'json/mult_view_sim_row.json', 'no-indent')
43 | net.write_json_to_file('sim_col', 'json/mult_view_sim_col.json', 'no-indent')
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clustergrammer",
3 | "version": "v1.19.5",
4 | "description": "This is a clustergram implemented in D3.js. I started from the example http://bost.ocks.org/mike/miserables/ and added the following features",
5 | "main": "clustergrammer.node.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/MaayanLab/clustergrammer.git"
12 | },
13 | "author": "Nicolas Fernandez",
14 | "license": "MIT",
15 | "bugs": {
16 | "url": "https://github.com/MaayanLab/clustergrammer/issues"
17 | },
18 | "homepage": "https://github.com/MaayanLab/clustergrammer#readme",
19 | "devDependencies": {
20 | "babel-core": "^6.14.0",
21 | "babel-eslint": "^4.1.8",
22 | "babel-loader": "^6.2.5",
23 | "babel-preset-es2015": "^6.14.0",
24 | "browser-sync": "^2.18.13",
25 | "browser-sync-webpack-plugin": "^1.2.0",
26 | "css-loader": "^0.23.1",
27 | "eslint": "^2.1.0",
28 | "expose-loader": "^0.7.1",
29 | "less-loader": "^2.2.3",
30 | "object-assign": "^4.1.0",
31 | "webpack": "^1.13.2"
32 | },
33 | "dependencies": {
34 | "awesomplete": "1.1.1",
35 | "d3": "^3.5.15",
36 | "jquery": "1.11.0",
37 | "mathjs": "3.17.0",
38 | "save-svg-as-png": "^1.1.0",
39 | "style-loader": "^0.13.1",
40 | "underscore": "1.8.3"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/scrolling_tour.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/Colors.js:
--------------------------------------------------------------------------------
1 | // colors from http://graphicdesign.stackexchange.com/revisions/3815/8
2 | var all_colors;
3 |
4 | all_colors = [ "#393b79", "#aec7e8", "#ff7f0e", "#ffbb78", "#98df8a", "#bcbd22",
5 | "#404040", "#ff9896", "#c5b0d5", "#8c564b", "#1f77b4", "#5254a3", "#FFDB58",
6 | "#c49c94", "#e377c2", "#7f7f7f", "#2ca02c", "#9467bd", "#dbdb8d", "#17becf",
7 | "#637939", "#6b6ecf", "#9c9ede", "#d62728", "#8ca252", "#8c6d31", "#bd9e39",
8 | "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#7b4173", "#a55194", "#ce6dbd",
9 | "#de9ed6"];
10 |
11 | // too light colors
12 | // "#e7969c",
13 | // "#c7c7c7",
14 | // "#f7b6d2",
15 | // "#cedb9c",
16 | // "#9edae5",
17 |
18 | function get_default_color() {
19 | return '#EEE';
20 | }
21 |
22 | function get_random_color(i) {
23 | return all_colors[i % get_num_colors()];
24 | }
25 |
26 | function get_num_colors() {
27 | return all_colors.length;
28 | }
29 |
30 | module.exports = {
31 | get_default_color: get_default_color,
32 | get_random_color: get_random_color,
33 | get_num_colors: get_num_colors
34 | };
35 |
--------------------------------------------------------------------------------
/src/Utils_clust.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | /* Utility functions
4 | * ----------------------------------------------------------------------- */
5 | module.exports = {
6 | normal_name: function(d) {
7 | var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
8 | return inst_name;
9 | },
10 | is_supported_order: function(order) {
11 | return order === 'ini' || order === 'clust' || order === 'rank_var' || order === 'rank' || order === 'class' || order == 'alpha';
12 | },
13 |
14 | /* Returns whether or not an object has a certain property.
15 | */
16 | has: function(obj, key) {
17 | return obj != null && hasOwnProperty.call(obj, key);
18 | },
19 |
20 | property: function(key) {
21 | return function(obj) {
22 | return obj == null ? void 0 : obj[key];
23 | };
24 | },
25 |
26 | // Convenience version of a common use case of `map`: fetching a property.
27 | pluck: function(arr, key) {
28 | var self = this;
29 | // Double check that we have lodash or underscore available
30 | if (window._) {
31 | // Underscore provides a pluck function. Use that.
32 | if (typeof underscore.pluck === 'function') {
33 | return underscore.pluck(arr, key);
34 | } else if (typeof underscore.map === 'function') {
35 | // Lodash does not have a pluck function.
36 | // Use underscore.map with the property function defined above.
37 | return underscore.map(arr, self.property(key));
38 | }
39 | } else if (arr.map && typeof arr.map === 'function') {
40 | // If lodash or underscore not available, check to see if the native arr.map is available.
41 | // If so, use it with the property function defined above.
42 | return arr.map(self.property(key));
43 | }
44 | },
45 |
46 | /* Returns true if the object is undefined.
47 | */
48 | is_undefined: function(obj) {
49 | return obj === void 0;
50 | },
51 |
52 | /* Mixes two objects in together, overwriting a target with a source.
53 | */
54 | extend: function(target, source) {
55 | target = target || {};
56 | for (var prop in source) {
57 | if (typeof source[prop] === 'object') {
58 | target[prop] = this.extend(target[prop], source[prop]);
59 | } else {
60 | target[prop] = source[prop];
61 | }
62 | }
63 | return target;
64 | }
65 | };
66 |
--------------------------------------------------------------------------------
/src/categories/binom_test.js:
--------------------------------------------------------------------------------
1 |
2 | // Load the math.js core
3 | // Create a new, empty math.js instance
4 | // It will only contain methods `import` and `config`
5 | // math.import(require('mathjs/lib/type/fraction'));
6 | var p_dict = require('./binom_prop_pval_lookup');
7 | var core = require('mathjs/core');
8 | var math = core.create();
9 |
10 | math.import(require('mathjs/lib/function/probability/factorial'));
11 |
12 | module.exports = function binom_test(actual_k, n, p){
13 |
14 | var fact = math.factorial;
15 | var pval;
16 |
17 | function binom_dist(k, n, p){
18 | var bin_coeff = (fact(n))/( fact(k) * fact(n-k) );
19 | p = bin_coeff * (Math.pow(p, k) * Math.pow((1 - p), (n-k)) );
20 | return p;
21 | }
22 |
23 | function my_binom_test_2(actual_k, n, p){
24 | var cp = 0;
25 | var k;
26 | var dp;
27 | for (var inst_k=actual_k; inst_k < n+1; inst_k++ ){
28 | k = inst_k;
29 | dp = binom_dist(k, n, p);
30 | cp = cp + dp;
31 | }
32 |
33 | return cp;
34 |
35 | }
36 |
37 | // look up p-value from z-score using table
38 | function binom_prop_table(actual_k, n, p){
39 |
40 | // expected average number of successes
41 | var mu = n * p;
42 |
43 | // standard deviation
44 | var sigma = Math.sqrt(n * p * (1 - p));
45 |
46 | // how many standard deviations is the actual_k away
47 | // from the expected value
48 | var z = (actual_k - mu)/sigma;
49 |
50 | var z_vals = p_dict.z;
51 | var p_vals = p_dict.p;
52 |
53 | var found_index = -1;
54 | var found = false;
55 |
56 | for (var index=0; index < z_vals.length; index++){
57 | var inst_z = z_vals[index];
58 |
59 | // increasing inst_z until z is less than inst_z
60 | if (z < inst_z && found === false){
61 | found_index = index;
62 | found = true;
63 | }
64 | }
65 |
66 | // give it the smallest p-val if the z-score was larger than
67 | // any in the table
68 | if (found_index === -1){
69 | found_index = z_vals.length - 1;
70 | }
71 | pval = p_vals[found_index];
72 |
73 | return pval;
74 |
75 | }
76 |
77 | // calculate pval
78 | pval = my_binom_test_2(actual_k, n, p);
79 | if ( isNaN(pval) ){
80 | pval = binom_prop_table(actual_k, n, p);
81 | }
82 |
83 | return pval;
84 |
85 | };
--------------------------------------------------------------------------------
/src/categories/get_cat_names.js:
--------------------------------------------------------------------------------
1 | var utils = require('../Utils_clust');
2 | var underscore = require('underscore');
3 |
4 | module.exports = function get_cat_names(params, inst_data, inst_selection, inst_rc){
5 |
6 | // category index
7 | var inst_cat = d3.select(inst_selection).attr('cat');
8 | var cat_name = inst_data[inst_cat];
9 | var tmp_nodes = params.network_data[inst_rc+'_nodes'];
10 |
11 | var found_nodes = underscore.filter(tmp_nodes, function(d){
12 | return d[inst_cat] == cat_name;
13 | });
14 |
15 | var found_names = utils.pluck(found_nodes, 'name');
16 |
17 | return found_names;
18 | };
--------------------------------------------------------------------------------
/src/categories/get_cat_title.js:
--------------------------------------------------------------------------------
1 | module.exports = function get_cat_title(viz, inst_cat, inst_rc){
2 | var cat_title;
3 |
4 | // make default title if none is given
5 | if(viz.cat_names[inst_rc][inst_cat] === inst_cat){
6 | var inst_num = parseInt( inst_cat.split('-')[1], 10) + 1;
7 | // generate placeholder title
8 | cat_title = 'Category ' + inst_num;
9 | } else {
10 | // make real title
11 | cat_title = viz.cat_names[inst_rc][inst_cat];
12 | }
13 |
14 | return cat_title;
15 |
16 | };
--------------------------------------------------------------------------------
/src/categories/ini_cat_opacity.js:
--------------------------------------------------------------------------------
1 | module.exports = function ini_cat_opacity(viz, inst_rc, cat_rect, inst_cat, updating=false){
2 |
3 | // debugger;
4 |
5 | var super_string = ': ';
6 | var inst_type = viz.cat_info[inst_rc][inst_cat].type;
7 |
8 | // set opacity based on string or value cats
9 | if (inst_type === 'cat_strings'){
10 |
11 | // optionally have categories transition in
12 | if (updating){
13 | cat_rect
14 | .classed('cat_strings', true)
15 | .style('opacity', 0)
16 | .transition()
17 | .duration(1000)
18 | .style('opacity', viz.cat_colors.opacity);
19 |
20 | } else {
21 | // opacity is fixed
22 | cat_rect
23 | .classed('cat_strings', true)
24 | .style('opacity', viz.cat_colors.opacity);
25 |
26 | }
27 |
28 |
29 |
30 | } else {
31 |
32 | // opacity varies based on value
33 | cat_rect
34 | .classed('cat_values', true)
35 | .style('opacity', function(d){
36 |
37 | var unprocessed_val = d[inst_cat];
38 |
39 | var cat_value = get_cat_value(unprocessed_val);
40 |
41 | return viz.cat_info[inst_rc][inst_cat].cat_scale(Math.abs(cat_value));
42 | })
43 | .style('fill', function(d){
44 | var inst_color;
45 |
46 | var cat_value = get_cat_value(d[inst_cat]);
47 |
48 | // get positive and negative colors
49 | if (cat_value > 0){
50 | inst_color = viz.cat_value_colors[0];
51 | } else {
52 | inst_color = viz.cat_value_colors[1];
53 | }
54 |
55 | return inst_color;
56 | });
57 | }
58 |
59 | function get_cat_value(unprocessed_value){
60 | if (typeof unprocessed_value === 'string'){
61 |
62 | if ( unprocessed_value.indexOf(super_string) > -1 ){
63 | unprocessed_value = unprocessed_value.split(super_string)[1];
64 | }
65 | }
66 |
67 | var cat_value = parseFloat(unprocessed_value);
68 |
69 | return cat_value;
70 | }
71 |
72 | };
--------------------------------------------------------------------------------
/src/categories/reset_cat_opacity.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function reset_cat_opacity(params){
4 |
5 | underscore.each(['row','col'], function(inst_rc){
6 |
7 | d3.selectAll(params.root+' .'+inst_rc+'_cat_group')
8 | .selectAll('rect')
9 | .style('opacity', function(){
10 |
11 | var inst_opacity = d3.select(this).style('opacity');
12 |
13 | if (d3.select(this).classed('cat_strings') && d3.select(this).classed('filtered_cat') === false){
14 | inst_opacity = params.viz.cat_colors.opacity;
15 | }
16 |
17 | return inst_opacity;
18 | });
19 |
20 | });
21 |
22 | };
23 |
--------------------------------------------------------------------------------
/src/clusterfck_local/clusterfck.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2011 Heather Arthur
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | */
25 |
26 | /* eslint-disable */
27 |
28 | module.exports = {
29 | hcluster: require("./hcluster"),
30 | Kmeans: require("./kmeans"),
31 | kmeans: require("./kmeans").kmeans
32 | };
--------------------------------------------------------------------------------
/src/clusterfck_local/distance.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | euclidean: function(v1, v2) {
3 | var total = 0;
4 | for (var i = 0; i < v1.length; i++) {
5 | total = total + Math.pow(v2[i] - v1[i], 2);
6 | }
7 | return Math.sqrt(total);
8 | },
9 | manhattan: function(v1, v2) {
10 | var total = 0;
11 | for (var i = 0; i < v1.length ; i++) {
12 | total = total + Math.abs(v2[i] - v1[i]);
13 | }
14 | return total;
15 | },
16 | max: function(v1, v2) {
17 | var max = 0;
18 | for (var i = 0; i < v1.length; i++) {
19 | max = Math.max(max , Math.abs(v2[i] - v1[i]));
20 | }
21 | return max;
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/src/config/check_nodes_for_categories.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function check_nodes_for_categories(nodes){
4 |
5 | var super_string = ': ';
6 | var has_cat = true;
7 |
8 | underscore.each(nodes, function(inst_node){
9 | var inst_name = String(inst_node.name);
10 | if (inst_name.indexOf(super_string) < 0){
11 | has_cat = false;
12 | }
13 | });
14 |
15 | return has_cat;
16 |
17 | };
--------------------------------------------------------------------------------
/src/config/check_sim_mat.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function check_sim_mat(config){
4 |
5 | var sim_mat = false;
6 |
7 | var num_rows = config.network_data.row_nodes_names.length;
8 | var num_cols = config.network_data.col_nodes_names.length;
9 |
10 | if (num_rows == num_cols){
11 |
12 | // the sort here was causing errors
13 | var rows = config.network_data.row_nodes_names;
14 | var cols = config.network_data.col_nodes_names;
15 | sim_mat = true;
16 |
17 | underscore.each(rows, function(inst_row){
18 | var inst_index = rows.indexOf(inst_row);
19 | if (inst_row !== cols[inst_index]){
20 | sim_mat = false;
21 | }
22 | });
23 |
24 | }
25 |
26 | if (sim_mat){
27 | config.expand_button = false;
28 | }
29 |
30 | return sim_mat;
31 | };
--------------------------------------------------------------------------------
/src/config/set_defaults.js:
--------------------------------------------------------------------------------
1 | module.exports = function set_defaults(){
2 |
3 | var defaults = {
4 | // Label options
5 | row_label_scale: 1,
6 | col_label_scale: 1,
7 | super_labels: false,
8 | super: {},
9 | show_label_tooltips: true,
10 | show_tile_tooltips: true,
11 | // matrix options
12 | transpose: false,
13 | tile_colors: ['#FF0000', '#1C86EE'],
14 | bar_colors: ['#FF0000', '#1C86EE'],
15 | // value-cat colors
16 | // cat_value_colors: ['#2F4F4F', '#8A2BE2'],
17 | cat_value_colors: ['#2F4F4F', '#9370DB'],
18 | outline_colors: ['orange','black'],
19 | highlight_color: '#FFFF00',
20 | tile_title: false,
21 | // Default domain is set to 0: the domain will be set automatically
22 | input_domain: 0,
23 | opacity_scale: 'linear',
24 | do_zoom: true,
25 | is_zoom:0,
26 | is_slider_drag:false,
27 | is_cropping:false,
28 | background_color: '#FFFFFF',
29 | super_border_color: '#F5F5F5',
30 | outer_margins: {
31 | top: 0,
32 | bottom: 0,
33 | left: 0,
34 | right: 0
35 | },
36 | ini_expand: false,
37 | grey_border_width: 2,
38 | tile_click_hlight: false,
39 | super_label_scale: 1,
40 | make_tile_tooltip: function(d) { return d.info; },
41 | // initialize view, e.g. initialize with row filtering
42 | ini_view: null,
43 | // record of requested views
44 | requested_view: null,
45 | use_sidebar: true,
46 | title:null,
47 | about:null,
48 | sidebar_width:160,
49 | sidebar_icons:true,
50 | row_search_placeholder:'Row',
51 | buffer_width:10,
52 | show_sim_mat:false,
53 | cat_colors:null,
54 | resize:true,
55 | clamp_opacity:0.85,
56 | expand_button:true,
57 | max_allow_fs: 20,
58 | dendro_filter:{'row':false, 'col':false},
59 | cat_filter:{'row':false, 'col':false},
60 | crop_filter_nodes:{'row':false, 'col':false},
61 | row_tip_callback:null,
62 | col_tip_callback:null,
63 | tile_tip_callback:null,
64 | matrix_update_callback:null,
65 | cat_update_callback: null,
66 | dendro_callback:null,
67 | dendro_click_callback:null,
68 | new_row_cats:null,
69 | make_modals:true,
70 | show_viz_border:false,
71 | };
72 |
73 | return defaults;
74 | };
--------------------------------------------------------------------------------
/src/d3.slider/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
--------------------------------------------------------------------------------
/src/d3.slider/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Bjorn Sandvik
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | Redistributions in binary form must reproduce the above copyright notice, this
11 | list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | Neither the name of the {organization} nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/src/d3.slider/README.md:
--------------------------------------------------------------------------------
1 | D3.js Slider
2 | ============
3 |
4 | This is a pure D3.js slider inspired by the jQuery UI Slider. Supports D3’s axis component. Feel free to contribute!
5 |
6 | Examples
7 |
--------------------------------------------------------------------------------
/src/d3.slider/d3.slider.css:
--------------------------------------------------------------------------------
1 | .d3-slider {
2 | position: relative;
3 | font-family: Verdana,Arial,sans-serif;
4 | font-size: 1.1em;
5 | border: 1px solid #aaaaaa;
6 | z-index: 2;
7 | }
8 |
9 | .d3-slider-horizontal {
10 | height: .8em;
11 | }
12 |
13 | .d3-slider-range {
14 | background:#2980b9;
15 | left:0px;
16 | right:0px;
17 | height: 0.8em;
18 | position: absolute;
19 | }
20 |
21 | .d3-slider-range-vertical {
22 | background:#2980b9;
23 | left:0px;
24 | right:0px;
25 | position: absolute;
26 | top:0;
27 | }
28 |
29 | .d3-slider-vertical {
30 | width: .8em;
31 | height: 100px;
32 | }
33 |
34 | .d3-slider-handle {
35 | position: absolute;
36 | width: 1.2em;
37 | height: 1.2em;
38 | border: 1px solid #d3d3d3;
39 | border-radius: 4px;
40 | background: #eee;
41 | background: linear-gradient(to bottom, #eee 0%, #ddd 100%);
42 | z-index: 3;
43 | }
44 |
45 | .d3-slider-handle:hover {
46 | border: 1px solid #999999;
47 | }
48 |
49 | .d3-slider-horizontal .d3-slider-handle {
50 | top: -.3em;
51 | margin-left: -.6em;
52 | }
53 |
54 | .d3-slider-axis {
55 | position: relative;
56 | z-index: 1;
57 | }
58 |
59 | .d3-slider-axis-bottom {
60 | top: .8em;
61 | }
62 |
63 | .d3-slider-axis-right {
64 | left: .8em;
65 | }
66 |
67 | .d3-slider-axis path {
68 | stroke-width: 0;
69 | fill: none;
70 | }
71 |
72 | .d3-slider-axis line {
73 | fill: none;
74 | stroke: #aaa;
75 | shape-rendering: crispEdges;
76 | }
77 |
78 | .d3-slider-axis text {
79 | font-size: 11px;
80 | }
81 |
82 | .d3-slider-vertical .d3-slider-handle {
83 | left: -.25em;
84 | margin-left: 0;
85 | margin-bottom: -.6em;
86 | }
--------------------------------------------------------------------------------
/src/demo/demo_text.js:
--------------------------------------------------------------------------------
1 | module.exports = function demo_text(params, text, read_duration){
2 |
3 | var split_text = text.split('\n');
4 |
5 | if (split_text.length < 3){
6 | split_text.push('');
7 | }
8 |
9 | d3.select(params.root+' .demo_group')
10 | .style('opacity',0)
11 | .transition().duration(250)
12 | .style('opacity',1)
13 | .transition().duration(250).delay(read_duration)
14 | .style('opacity',0);
15 |
16 | for (var i=0; i triangle_info[tmp_group].pos_bot){
38 | triangle_info[tmp_group].name_bot = d.name;
39 | triangle_info[tmp_group].pos_bot = inst_bot;
40 | triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot)/2;
41 | }
42 |
43 | });
44 |
45 | var group_info = [];
46 |
47 | underscore.each(triangle_info, function(d){
48 | group_info.push(d);
49 | });
50 |
51 | return group_info;
52 |
53 | };
--------------------------------------------------------------------------------
/src/dendrogram/calc_row_dendro_triangles.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function calc_row_dendro_triangles(params){
4 |
5 | var triangle_info = {};
6 | var inst_level = params.group_level.row;
7 | var row_nodes = params.network_data.row_nodes;
8 | var row_nodes_names = params.network_data.row_nodes_names;
9 |
10 | underscore.each(row_nodes, function(d){
11 |
12 | // console.log('row_node '+d.name)
13 |
14 | var tmp_group = d.group[inst_level];
15 | var inst_index = underscore.indexOf(row_nodes_names, d.name);
16 | var inst_top = params.viz.y_scale(inst_index);
17 | var inst_bot = inst_top + params.viz.y_scale.rangeBand();
18 |
19 | if ( underscore.has(triangle_info, tmp_group) === false ){
20 | triangle_info[tmp_group] = {};
21 | triangle_info[tmp_group].name_top = d.name;
22 | triangle_info[tmp_group].name_bot = d.name;
23 | triangle_info[tmp_group].pos_top = inst_top;
24 | triangle_info[tmp_group].pos_bot = inst_bot;
25 | triangle_info[tmp_group].pos_mid = (inst_top + inst_bot)/2;
26 | triangle_info[tmp_group].name = tmp_group;
27 | triangle_info[tmp_group].all_names = [];
28 | triangle_info[tmp_group].inst_rc = 'row';
29 | }
30 |
31 | triangle_info[tmp_group].all_names.push(d.name);
32 |
33 | if (inst_top < triangle_info[tmp_group].pos_top){
34 | triangle_info[tmp_group].name_top = d.name;
35 | triangle_info[tmp_group].pos_top = inst_top;
36 | triangle_info[tmp_group].pos_mid = (inst_top + triangle_info[tmp_group].pos_bot)/2;
37 | }
38 |
39 | if (inst_bot > triangle_info[tmp_group].pos_bot){
40 | triangle_info[tmp_group].name_bot = d.name;
41 | triangle_info[tmp_group].pos_bot = inst_bot;
42 | triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot)/2;
43 | }
44 |
45 | });
46 |
47 | var group_info = [];
48 |
49 | underscore.each(triangle_info, function(d){
50 | group_info.push(d);
51 | });
52 |
53 | return group_info;
54 | };
--------------------------------------------------------------------------------
/src/dendrogram/change_groups.js:
--------------------------------------------------------------------------------
1 | var make_dendro_triangles = require('./make_dendro_triangles');
2 |
3 | /* Changes the groupings (x- and y-axis color bars).
4 | */
5 | module.exports = function (cgm, inst_rc, inst_index) {
6 |
7 | var params = cgm.params;
8 |
9 | if (inst_rc==='row'){
10 | params.group_level.row = inst_index;
11 | } else if (inst_rc==='col'){
12 | params.group_level.col = inst_index;
13 | }
14 |
15 | var is_change_group = true;
16 |
17 | make_dendro_triangles(cgm, inst_rc, is_change_group);
18 |
19 | };
20 |
--------------------------------------------------------------------------------
/src/dendrogram/dendro_group_highlight.js:
--------------------------------------------------------------------------------
1 | var dendro_shade_bars = require('./dendro_shade_bars');
2 |
3 | module.exports = function dendro_group_highlight(params, inst_selection, inst_data, inst_rc){
4 |
5 | // only make shadows if there is more than one crop button
6 | if (d3.selectAll(params.root+' .'+ inst_rc +'_dendro_crop_buttons')[0].length > 1){
7 | setTimeout(still_hovering, 500);
8 | } else {
9 | d3.selectAll(params.root+' .dendro_shadow')
10 | .remove();
11 | }
12 |
13 | function still_hovering(){
14 |
15 | // check that user is still hovering over dendrogram group
16 | if (d3.select(inst_selection).classed('hovering')){
17 |
18 | // check that user is not using dendrogram slider
19 | if (params.is_slider_drag === false){
20 |
21 | d3.select(inst_selection)
22 | .style('opacity', 0.7);
23 |
24 | if (d3.select(params.viz.viz_svg).classed('running_update') === false){
25 | make_shadow_bars();
26 | }
27 |
28 | }
29 |
30 | }
31 | }
32 |
33 | function make_shadow_bars(){
34 |
35 | if (inst_rc === 'row'){
36 |
37 | // row and col labling are reversed
38 | if (params.viz.inst_order.col === 'clust'){
39 | dendro_shade_bars(params, inst_selection, inst_rc, inst_data);
40 | }
41 |
42 | } else if (inst_rc === 'col') {
43 |
44 | // row and col labeling are reversed
45 | if (params.viz.inst_order.row === 'clust'){
46 | dendro_shade_bars(params, inst_selection, inst_rc, inst_data);
47 | }
48 |
49 | } else if (inst_rc === 'both'){
50 |
51 | if (params.viz.inst_order.col === 'clust'){
52 | dendro_shade_bars(params, inst_selection, 'row', inst_data);
53 | }
54 | if (params.viz.inst_order.row === 'clust'){
55 | dendro_shade_bars(params, inst_selection, 'col', inst_data);
56 | }
57 |
58 | }
59 |
60 |
61 |
62 | }
63 | };
--------------------------------------------------------------------------------
/src/dendrogram/dendro_shade_bars.js:
--------------------------------------------------------------------------------
1 | module.exports = function dendro_shade_bars(params, inst_selection, inst_rc, inst_data){
2 |
3 | var inst_opacity = 0.2;
4 | var bot_height;
5 |
6 | d3.selectAll(params.root+' .dendro_shadow')
7 | .remove();
8 |
9 | if (inst_rc == 'row'){
10 |
11 | // top shade
12 | d3.select(params.root+' .clust_group')
13 | .append('rect')
14 | .attr('width', params.viz.clust.dim.width+'px')
15 | .attr('height', inst_data.pos_top+'px')
16 | .attr('fill','black')
17 | .classed('dendro_shadow',true)
18 | .attr('opacity', inst_opacity);
19 |
20 | bot_height = params.viz.clust.dim.height - inst_data.pos_bot;
21 | // bottom shade
22 | d3.select(params.root+' .clust_group')
23 | .append('rect')
24 | .attr('width', params.viz.clust.dim.width+'px')
25 | .attr('height', bot_height+'px')
26 | .attr('transform','translate(0,'+inst_data.pos_bot+')')
27 | .attr('fill','black')
28 | .classed('dendro_shadow',true)
29 | .attr('opacity', inst_opacity);
30 |
31 | } else if (inst_rc === 'col'){
32 |
33 | // top shade
34 | d3.select(params.root+' .clust_group')
35 | .append('rect')
36 | .attr('width', inst_data.pos_top+'px')
37 | .attr('height', params.viz.clust.dim.height+'px')
38 | .attr('fill','black')
39 | .classed('dendro_shadow',true)
40 | .attr('opacity', inst_opacity);
41 |
42 | // bottom shade
43 | bot_height = params.viz.clust.dim.width - inst_data.pos_bot;
44 | d3.select(params.root+' .clust_group')
45 | .append('rect')
46 | .attr('width', bot_height+'px')
47 | .attr('height', params.viz.clust.dim.height+'px')
48 | .attr('transform','translate('+inst_data.pos_bot+',0)')
49 | .attr('fill','black')
50 | .classed('dendro_shadow',true)
51 | .attr('opacity',inst_opacity);
52 |
53 | }
54 |
55 | };
--------------------------------------------------------------------------------
/src/dendrogram/get_inst_group.js:
--------------------------------------------------------------------------------
1 | module.exports = function(params, inst_rc, d) {
2 | var inst_level;
3 | var inst_nodes;
4 |
5 | if (inst_rc === 'col') {
6 | inst_level = params.group_level.col;
7 | inst_nodes = params.network_data.col_nodes;
8 | } else if (inst_rc === 'row') {
9 | inst_level = params.group_level.row;
10 | inst_nodes = params.network_data.row_nodes;
11 | }
12 |
13 | var inst_group = d.group[inst_level];
14 | var group_nodes_list = [];
15 |
16 | inst_nodes.forEach(function(node) {
17 | if (node.group[inst_level] === inst_group){
18 | group_nodes_list.push(node.name);
19 | }
20 | });
21 |
22 | return group_nodes_list;
23 | };
24 |
--------------------------------------------------------------------------------
/src/dendrogram/make_col_dendro.js:
--------------------------------------------------------------------------------
1 | var make_dendro_triangles = require('./make_dendro_triangles');
2 |
3 | module.exports = function make_col_dendro(cgm) {
4 |
5 | var params = cgm.params;
6 |
7 | // position col_dendro_outer_container
8 | var x_offset = params.viz.clust.margin.left;
9 | var y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;
10 | var spillover_height = params.viz.dendro_room.col + params.viz.uni_margin;
11 |
12 | // make or reuse outer container
13 | if (d3.select(params.root+' .col_dendro_outer_container').empty()){
14 |
15 | d3.select(params.root+' .viz_svg')
16 | .append('g')
17 | .attr('class', 'col_dendro_outer_container')
18 | .attr('transform', 'translate('+x_offset+','+y_offset+')');
19 |
20 | d3.select(params.root+' .col_dendro_outer_container')
21 | .append('rect')
22 | .classed('col_dendro_spillover',true)
23 | .attr('fill', params.viz.background_color)
24 | .attr('width', params.viz.svg_dim.width)
25 | .attr('height', spillover_height+'px');
26 |
27 | d3.select(params.root+' .col_dendro_outer_container')
28 | .append('g')
29 | .attr('class', 'col_dendro_container')
30 | .attr('transform', 'translate(0,'+params.viz.uni_margin/2+')');
31 |
32 | d3.select(params.root+' .col_dendro_outer_container')
33 | .append('rect')
34 | .classed('col_dendro_spillover_top',true)
35 | .attr('fill', params.viz.background_color)
36 | .attr('width', params.viz.svg_dim.width)
37 | .attr('height', params.viz.svg_dim.height)
38 | .attr('transform', 'translate(0,'+params.viz.dendro_room.col+')');
39 |
40 | } else {
41 |
42 | d3.select(params.root+' .viz_svg')
43 | .select('col_dendro_outer_container')
44 | .attr('transform', 'translate('+x_offset+','+y_offset+')');
45 |
46 | d3.select(params.root+' .col_dendro_outer_container')
47 | .select('.col_dendro_spillover')
48 | .attr('width', params.viz.svg_dim.width)
49 | .attr('height', spillover_height+'px');
50 |
51 | }
52 |
53 | make_dendro_triangles(cgm, 'col', false);
54 |
55 | if (params.viz.inst_order.row != 'clust'){
56 | d3.selectAll(params.root+' .col_dendro_group').remove();
57 | }
58 |
59 | };
60 |
--------------------------------------------------------------------------------
/src/dendrogram/make_row_dendro.js:
--------------------------------------------------------------------------------
1 | var make_dendro_triangles = require('./make_dendro_triangles');
2 |
3 | module.exports = function make_row_dendro(cgm){
4 |
5 | var params = cgm.params;
6 |
7 | var spillover_width = params.viz.dendro_room.row + params.viz.uni_margin;
8 |
9 | // position row_dendro_outer_container
10 | var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width;
11 | var y_offset = params.viz.clust.margin.top;
12 |
13 | // make or reuse outer container
14 | if (d3.select(params.root+' .row_dendro_outer_container').empty()){
15 |
16 | d3.select(params.root+' .viz_svg')
17 | .append('g')
18 | .attr('class','row_dendro_outer_container')
19 | .attr('transform', 'translate(' + x_offset + ','+ y_offset +')');
20 |
21 | d3.select(params.root+' .row_dendro_outer_container')
22 | .append('rect')
23 | .classed('row_dendro_spillover',true)
24 | .attr('fill', params.viz.background_color)
25 | .attr('width', spillover_width + 'px')
26 | .attr('height', params.viz.svg_dim.height);
27 |
28 | d3.select(params.root+' .row_dendro_outer_container')
29 | .append('g')
30 | .attr('class', 'row_dendro_container')
31 | .attr('transform', 'translate('+params.viz.uni_margin/2+',0)');
32 |
33 | } else {
34 | d3.select(params.root+' .viz_svg')
35 | .select('row_dendro_outer_container')
36 | .attr('transform', 'translate(' + x_offset + ','+y_offset+')');
37 |
38 | d3.select(params.root+' .row_dendro_outer_container')
39 | .select('.row_dendro_spillover')
40 | .attr('width', spillover_width + 'px')
41 | .attr('height', params.viz.svg_dim.height);
42 | }
43 |
44 | make_dendro_triangles(cgm, 'row', false);
45 |
46 | if (params.viz.inst_order.col != 'clust'){
47 | d3.selectAll(params.root+' .row_dendro_group').remove();
48 | }
49 |
50 | };
51 |
--------------------------------------------------------------------------------
/src/dendrogram/position_dendro_slider.js:
--------------------------------------------------------------------------------
1 | module.exports = function position_dendro_slider(cgm, inst_rc='row'){
2 |
3 | var viz = cgm.params.viz;
4 | var tmp_left;
5 | var tmp_top;
6 | if (inst_rc === 'row'){
7 |
8 | // row dendrogram
9 | ///////////////////////
10 |
11 | // keep slider near clustergram
12 | var max_room = viz.svg_dim.width - 3 * viz.uni_margin;
13 |
14 | // position close to row dendrogram trapezoids
15 | tmp_left = viz.clust.margin.left + viz.clust.dim.width + 5.25 * viz.dendro_room.row + 2;
16 |
17 | if (tmp_left > max_room){
18 | tmp_left = max_room;
19 | }
20 |
21 | // tmp_top = viz.clust.margin.top + 3 * viz.uni_margin - 50;
22 | // 135 is a magic number that moves the slider down to make room for the
23 | // reordering tree (use 75 when enabling reclustering icon)
24 | tmp_top = viz.clust.margin.top + 3 * viz.uni_margin + 30;
25 |
26 | } else {
27 |
28 | // column dendrogram
29 | ///////////////////////
30 | tmp_left = 2 * viz.uni_margin;
31 | // tmp_top = viz.svg_dim.height - 2.5 * viz.uni_margin;
32 | tmp_top = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2*viz.uni_margin;
33 |
34 | }
35 |
36 | // reposiiton slider
37 | d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group')
38 | .attr('transform', function() {
39 | var inst_translation;
40 | if (inst_rc === 'row'){
41 | tmp_left = tmp_left + 0.8 * viz.dendro_room.row;
42 | inst_translation = 'translate(' + tmp_left + ',' + tmp_top + ')';
43 | } else {
44 | inst_translation = 'translate(' + tmp_left + ',' + tmp_top +
45 | '), rotate(-90)';
46 | }
47 | return inst_translation;
48 | })
49 | .style('opacity', 1);
50 |
51 | };
--------------------------------------------------------------------------------
/src/dendrogram/run_dendro_filter.js:
--------------------------------------------------------------------------------
1 | module.exports = function run_dendro_filter(cgm, d, inst_rc){
2 |
3 | var names = {};
4 |
5 | if (cgm.params.dendro_filter.row === false &&
6 | cgm.params.dendro_filter.col === false &&
7 | cgm.params.cat_filter.row === false &&
8 | cgm.params.cat_filter.col === false
9 | ){
10 |
11 | d3.select(cgm.params.root+' .'+inst_rc+'_slider_group')
12 | .style('opacity', 0.35)
13 | .style('pointer-events','none');
14 |
15 | names[inst_rc] = d.all_names;
16 |
17 | var tmp_names = cgm.params.network_data[inst_rc+'_nodes_names'];
18 |
19 | // keep a backup of the inst_view
20 | var inst_row_nodes = cgm.params.network_data.row_nodes;
21 | var inst_col_nodes = cgm.params.network_data.col_nodes;
22 |
23 | cgm.filter_viz_using_names(names);
24 |
25 | // overwrite with backup of original nodes
26 | cgm.params.inst_nodes.row_nodes = inst_row_nodes;
27 | cgm.params.inst_nodes.col_nodes = inst_col_nodes;
28 |
29 | d3.selectAll(cgm.params.root+' .dendro_shadow')
30 | .transition()
31 | .duration(1000)
32 | .style('opacity',0)
33 | .remove();
34 |
35 | // keep the names of all the nodes
36 | cgm.params.dendro_filter[inst_rc] = tmp_names;
37 |
38 | /* reset filter */
39 | } else {
40 |
41 | names[inst_rc] = cgm.params.dendro_filter[inst_rc];
42 |
43 | cgm.filter_viz_using_names(names);
44 | cgm.params.dendro_filter[inst_rc] = false;
45 |
46 | }
47 |
48 | };
--------------------------------------------------------------------------------
/src/dendrogram/toggle_dendro_view.js:
--------------------------------------------------------------------------------
1 | var make_dendro_triangles = require('../dendrogram/make_dendro_triangles');
2 |
3 | module.exports = function toggle_dendro_view(cgm, inst_rc, wait_time = 1500){
4 |
5 | var params = cgm.params;
6 |
7 | // row and col are reversed
8 | if (inst_rc === 'row'){
9 | if (params.viz.inst_order.col === 'clust'){
10 | // the last true tells the viz that I'm chaning group size and not to
11 | // delay the change in dendro
12 | setTimeout( make_dendro_triangles, wait_time, cgm, 'row', true);
13 | }
14 | }
15 |
16 | if (inst_rc === 'col'){
17 | if (params.viz.inst_order.row === 'clust'){
18 | setTimeout( make_dendro_triangles, wait_time, cgm, 'col', true);
19 | }
20 | }
21 |
22 | if (params.viz.inst_order.row != 'clust' && params.viz.dendro_filter.col === false){
23 | d3.selectAll(params.root+' .col_dendro_group')
24 | .style('opacity',0)
25 | .on('mouseover',null)
26 | .on('mouseout',null);
27 |
28 | d3.select(params.root+' .col_slider_group')
29 | .style('opacity', 0);
30 |
31 | // toggle crop buttons
32 | d3.selectAll(params.root+' .col_dendro_crop_buttons')
33 | .style('opacity',0)
34 | .on('mouseover', null)
35 | .on('mouseout', null);
36 |
37 | }
38 |
39 | if (params.viz.inst_order.col != 'clust' && params.viz.dendro_filter.row === false){
40 |
41 | d3.selectAll(params.root+' .row_dendro_group')
42 | .style('opacity',0)
43 | .on('mouseover',null)
44 | .on('mouseout',null)
45 | .on('click', null);
46 |
47 | d3.select(params.root+' .row_slider_group')
48 | .style('opacity', 0);
49 |
50 | // toggle crop buttons
51 | d3.selectAll(params.root+' .row_dendro_crop_buttons')
52 | .style('opacity',0)
53 | .on('mouseover', null)
54 | .on('mouseout', null);
55 |
56 | }
57 | };
--------------------------------------------------------------------------------
/src/enter/draw_dn_tile.js:
--------------------------------------------------------------------------------
1 | module.exports = function draw_dn_tile(params){
2 |
3 | var start_x = 0;
4 | var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
5 | var start_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
6 | var final_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
7 |
8 | var output_string = 'M' + start_x + ', ' + start_y + ' L' +
9 | final_x + ', ' + final_y + ' L' + final_x + ',0 Z';
10 |
11 | return output_string;
12 | };
--------------------------------------------------------------------------------
/src/enter/draw_up_tile.js:
--------------------------------------------------------------------------------
1 | module.exports = function draw_up_tile(params){
2 |
3 | var start_x = 0;
4 | var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
5 | var start_y = 0;
6 | var final_y = params.viz.y_scale.rangeBand()- params.viz.border_width.y;
7 |
8 | var output_string = 'M' + start_x + ',' + start_y + ' L' +
9 | start_x + ', ' + final_y + ' L' + final_x + ',0 Z';
10 |
11 | return output_string;
12 | };
--------------------------------------------------------------------------------
/src/enter/ds_enter_exit_update.js:
--------------------------------------------------------------------------------
1 | var reset_size_after_update = require('../reset_size/reset_size_after_update');
2 | var make_col_label_container = require('../labels/make_col_label_container');
3 | var show_visible_area = require('../zoom/show_visible_area');
4 | var resize_containers = require('../reset_size/resize_containers');
5 |
6 | module.exports = function ds_enter_exit_update(cgm){
7 |
8 | // console.log('======== ds_enter_exit_update ===============');
9 |
10 | // remove row labels, remove non-downsampled rows, and add downsampled rows
11 | d3.selectAll(cgm.params.root+' .row_cat_group')
12 | .remove();
13 | d3.selectAll(cgm.params.root+' .row_label_group')
14 | .remove();
15 | d3.selectAll(cgm.params.root+' .row')
16 | .remove();
17 |
18 | // no need to re-calculate the downsampled layers
19 | // calc_downsampled_levels(params);
20 | var zooming_stopped = true;
21 | var zooming_out = true;
22 | var make_all_rows = true;
23 |
24 | // show_visible_area is also run with two_translate_zoom, but at that point
25 | // the parameters were not updated and two_translate_zoom if only run
26 | // if needed to reset zoom
27 | show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
28 |
29 | make_col_label_container(cgm);
30 |
31 | var col_nodes = cgm.params.network_data.col_nodes;
32 |
33 | // remove column labels
34 | d3.selectAll(cgm.params.root+' .col_label_group')
35 | .data(col_nodes, function(d){return d.name;})
36 | .exit()
37 | .style('opacity',0)
38 | .remove();
39 |
40 | d3.selectAll(cgm.params.root+' .col_label_text')
41 | .data(col_nodes, function(d){return d.name;})
42 | .exit()
43 | .style('opacity',0)
44 | .remove();
45 |
46 | d3.selectAll(cgm.params.root+' .col_cat_group')
47 | .data(col_nodes, function(d){return d.name;})
48 | .exit()
49 | .style('opacity',0)
50 | .remove();
51 |
52 | d3.selectAll(cgm.params.root+' .col_dendro_group')
53 | .data(col_nodes, function(d){return d.name;})
54 | .exit()
55 | .style('opacity',0)
56 | .remove();
57 |
58 | // necessary for repositioning clust, col and col-cat containers
59 | resize_containers(cgm.params);
60 |
61 | // seeing if this fixes resizing issue
62 | var delays = {};
63 | delays.enter = 0;
64 | delays.update = 0;
65 | delays.run_transition = false;
66 | var duration = 0;
67 | reset_size_after_update(cgm, duration, delays);
68 |
69 | };
--------------------------------------------------------------------------------
/src/enter/enter_existing_row.js:
--------------------------------------------------------------------------------
1 | var mouseover_tile = require('../matrix/mouseover_tile');
2 | var mouseout_tile = require('../matrix/mouseout_tile');
3 | var fine_position_tile = require('../matrix/fine_position_tile');
4 |
5 | module.exports = function enter_existing_row(params, delays, duration, cur_row_tiles, tip){
6 |
7 | // enter new tiles
8 | var new_tiles = cur_row_tiles
9 | .enter()
10 | .append('rect')
11 | .attr('class', 'tile row_tile')
12 | .attr('width', params.viz.rect_width)
13 | .attr('height', params.viz.rect_height)
14 | .on('mouseover', function(...args) {
15 | mouseover_tile(params, this, tip, args);
16 | })
17 | .on('mouseout', function mouseout() {
18 | mouseout_tile(params, this, tip);
19 | })
20 | .attr('fill-opacity',0)
21 | .attr('transform', function(d){
22 | return fine_position_tile(params, d);
23 | });
24 |
25 |
26 | if (delays.run_transition){
27 | new_tiles
28 | .transition().delay(delays.enter).duration(duration)
29 | .style('fill', function(d) {
30 | return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
31 | })
32 | .attr('fill-opacity',function(d){
33 | var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
34 | return output_opacity;
35 | });
36 | } else {
37 | new_tiles
38 | .style('fill', function(d) {
39 | return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
40 | })
41 | .attr('fill-opacity',function(d){
42 | var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
43 | return output_opacity;
44 | });
45 | }
46 |
47 | // remove new tiles if necessary
48 | new_tiles
49 | .each(function(d){
50 | if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
51 | d3.select(this)
52 | .remove();
53 | }
54 | });
55 | };
--------------------------------------------------------------------------------
/src/enter/enter_new_rows.js:
--------------------------------------------------------------------------------
1 | var enter_split_tiles = require('./enter_split_tiles');
2 | var mouseover_tile = require('../matrix/mouseover_tile');
3 | var mouseout_tile = require('../matrix/mouseout_tile');
4 | var fine_position_tile = require('../matrix/fine_position_tile');
5 | var underscore = require('underscore');
6 |
7 | // make each row in the clustergram
8 | module.exports = function enter_new_rows(params, ini_inp_row_data, delays, duration, tip, row_selection) {
9 |
10 | var inp_row_data = ini_inp_row_data.row_data;
11 |
12 | // remove zero values to make visualization faster
13 | var row_data = underscore.filter(inp_row_data, function(num) {
14 | return num.value !== 0;
15 | });
16 |
17 | // update tiles
18 | ////////////////////////////////////////////
19 | var tile = d3.select(row_selection)
20 | .selectAll('rect')
21 | .data(row_data, function(d){ return d.col_name; })
22 | .enter()
23 | .append('rect')
24 | .attr('class', 'tile row_tile')
25 | .attr('width', params.viz.rect_width)
26 | .attr('height', params.viz.rect_height)
27 | // switch the color based on up/dn value
28 | .style('fill', function(d) {
29 | return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
30 | })
31 | .on('mouseover', function(...args) {
32 | mouseover_tile(params, this, tip, args);
33 | })
34 | .on('mouseout', function mouseout() {
35 | mouseout_tile(params, this, tip);
36 | });
37 |
38 | tile
39 | .style('fill-opacity',0)
40 | .transition().delay(delays.enter)
41 | .duration(duration)
42 | .style('fill-opacity', function(d) {
43 | // calculate output opacity using the opacity scale
44 | var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
45 | return output_opacity;
46 | });
47 |
48 | tile
49 | .attr('transform', function(d) {
50 | return fine_position_tile(params, d);
51 | });
52 |
53 | if (params.matrix.tile_type == 'updn'){
54 | enter_split_tiles(params, inp_row_data, row_selection, tip, delays, duration, tile);
55 | }
56 |
57 | };
--------------------------------------------------------------------------------
/src/enter/enter_row_groups.js:
--------------------------------------------------------------------------------
1 | var enter_new_rows = require('./enter_new_rows');
2 |
3 | module.exports = function enter_row_groups(params, delays, duration, tip){
4 |
5 | // enter new rows
6 | var new_row_groups = d3.select(params.root+' .clust_group')
7 | .selectAll('.row')
8 | .data(params.matrix.matrix, function(d){return d.name;})
9 | .enter()
10 | .append('g')
11 | .classed('row', true)
12 | .attr('transform', function(d) {
13 | return 'translate(0,' + params.viz.y_scale(d.row_index) + ')';
14 | }) ;
15 |
16 | new_row_groups
17 | .each( function(d){
18 | enter_new_rows(params, d, delays, duration, tip, this);
19 | } );
20 |
21 | };
--------------------------------------------------------------------------------
/src/exit/exit_existing_row.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function exit_existing_row(params, delays, cur_row_tiles, inp_row_data, row_selection){
4 |
5 | if (delays.run_transition){
6 | cur_row_tiles
7 | .exit()
8 | .transition().duration(300)
9 | .attr('fill-opacity',0)
10 | .remove();
11 | } else {
12 | cur_row_tiles
13 | .exit()
14 | .attr('fill-opacity',0)
15 | .remove();
16 | }
17 |
18 | if (params.matrix.tile_type == 'updn'){
19 |
20 | // value split
21 | var row_split_data = underscore.filter(inp_row_data, function(num){
22 | return num.value_up != 0 || num.value_dn !=0 ;
23 | });
24 |
25 | // tile_up
26 | var cur_tiles_up = d3.select(row_selection)
27 | .selectAll('.tile_up')
28 | .data(row_split_data, function(d){return d.col_name;});
29 |
30 | if (delays.run_transition){
31 | cur_tiles_up
32 | .exit()
33 | .transition().duration(300)
34 | .attr('fill','0')
35 | .remove();
36 | } else {
37 | cur_tiles_up
38 | .exit()
39 | .attr('fill',0)
40 | .remove();
41 | }
42 |
43 | // tile_dn
44 | var cur_tiles_dn = d3.select(row_selection)
45 | .selectAll('.tile_dn')
46 | .data(row_split_data, function(d){return d.col_name;});
47 |
48 | if (delays.run_transition){
49 | cur_tiles_dn
50 | .exit()
51 | .transition().duration(300)
52 | .attr('fill',0)
53 | .remove();
54 | } else {
55 | cur_tiles_dn
56 | .exit()
57 | .attr('fill',0)
58 | .remove();
59 | }
60 |
61 | }
62 |
63 |
64 |
65 | };
--------------------------------------------------------------------------------
/src/filters/get_current_orders.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function get_current_orders(params){
4 |
5 | // get current orders
6 | var other_rc;
7 | underscore.each(['row','col'], function(inst_rc){
8 |
9 | if (inst_rc === 'row'){
10 | other_rc = 'col';
11 | } else {
12 | other_rc = 'row';
13 | }
14 |
15 | if (d3.select(params.root+' .toggle_'+other_rc+'_order .active').empty() === false){
16 |
17 | params.viz.inst_order[inst_rc] = d3.select(params.root+' .toggle_'+other_rc+'_order')
18 | .select('.active').attr('name');
19 |
20 | } else {
21 |
22 | // default to cluster ordering
23 | params.viz.inst_order[inst_rc] = 'clust';
24 |
25 | }
26 |
27 | });
28 |
29 | return params;
30 | };
--------------------------------------------------------------------------------
/src/filters/get_filter_default_state.js:
--------------------------------------------------------------------------------
1 | module.exports = function get_filter_default_state(filter_data, filter_type){
2 |
3 | var default_state = filter_data[filter_type]
4 | .sort(function(a, b){return b-a;})[0];
5 |
6 | default_state = String(default_state);
7 |
8 | return default_state;
9 | };
--------------------------------------------------------------------------------
/src/filters/make_button_filter.js:
--------------------------------------------------------------------------------
1 | // var update_network = require('../network/update_network');
2 | var make_requested_view = require('./make_requested_view');
3 |
4 | module.exports = function make_button_filter(config, params, filter_type, div_filters){
5 |
6 | /*
7 | Enrichr specific code
8 | */
9 |
10 | var buttons = div_filters
11 | .append('div')
12 | .classed('categorical_filter',true)
13 | .classed('toggle_'+filter_type,true)
14 | .classed('btn-group-vertical',true)
15 | .style('width', '100%')
16 | .style('margin-top','10px')
17 | .attr('current_state','combined_score');
18 |
19 | var filter_options = params.viz.filter_data[filter_type];
20 |
21 | var button_dict = {
22 | 'combined_score':'Combined Score',
23 | 'pval':'P-Value',
24 | 'zscore':'Z-score'
25 | };
26 |
27 | buttons
28 | .selectAll('button')
29 | .data(filter_options)
30 | .enter()
31 | .append('button')
32 | .attr('type','button')
33 | .classed('btn',true)
34 | .classed('btn-primary',true)
35 | .classed('.filter_button',true)
36 | .classed('active', function(d){
37 | var is_active = false;
38 | if (d == 'combined_score'){
39 | is_active = true;
40 | }
41 | return is_active;
42 | })
43 | .attr('name', function(d){
44 | return d;
45 | })
46 | .html(function(d){
47 | return button_dict[d];
48 | });
49 |
50 | $(params.root+ ' .categorical_filter .btn')
51 | .off()
52 | .click(function(){
53 |
54 | d3.selectAll(params.root+' .categorical_filter .btn')
55 | .classed('active',false);
56 |
57 | d3.select(this)
58 | .classed('active',true);
59 |
60 | var inst_state = d3.select(this)
61 | .attr('name');
62 |
63 | var requested_view = {'enr_score_type':inst_state};
64 |
65 | make_requested_view(params, requested_view);
66 |
67 | d3.select(params.root+' .toggle_enr_score_type')
68 | .attr('current_state', inst_state);
69 |
70 | });
71 |
72 | };
73 |
--------------------------------------------------------------------------------
/src/filters/make_filter_title.js:
--------------------------------------------------------------------------------
1 | var get_filter_default_state = require('./get_filter_default_state');
2 | var underscore = require('underscore');
3 |
4 | module.exports = function make_filter_title(params, filter_type){
5 |
6 | var filter_title = {};
7 | var title = {};
8 | var type = {};
9 |
10 | filter_title.state = get_filter_default_state(params.viz.filter_data, filter_type);
11 |
12 | type.top = filter_type.split('_')[0];
13 | type.node = filter_type.split('_')[1];
14 | type.measure = filter_type.split('_')[2];
15 |
16 | if (type.node === 'row'){
17 | title.node = 'rows';
18 | } else {
19 | title.node = 'columns';
20 | }
21 |
22 | if (type.top === 'N'){
23 | // filter_title.suffix = ' '+title.node;
24 | filter_title.suffix = '';
25 | }
26 |
27 | if (type.top === 'pct'){
28 | filter_title.suffix = '%';
29 | }
30 |
31 | if (type.measure == 'sum'){
32 | title.measure = 'sum';
33 | } else if (type.measure == 'var'){
34 | title.measure = 'variance';
35 | }
36 |
37 | if (type.measure === 'sum'){
38 | filter_title.text = 'Top '+ title.node + ' ' + title.measure+': ';
39 | }
40 |
41 | if (type.measure === 'var'){
42 | filter_title.text = 'Top '+ title.node + ' ' + title.measure+': ';
43 | }
44 |
45 | // Enrichr specific rules
46 | if ( underscore.keys(params.viz.possible_filters).indexOf('enr_score_type') > -1 ){
47 | if (type.node === 'col'){
48 | filter_title.text = 'Top Enriched Terms: ';
49 | filter_title.suffix = '';
50 | }
51 | }
52 |
53 | return filter_title;
54 | };
--------------------------------------------------------------------------------
/src/filters/make_requested_view.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function make_view_request(params, requested_view){
4 |
5 | // this will add all necessary information to a view request
6 | // it will grab necessary view information from the sliders
7 |
8 | // only one component will be changed at a time
9 | var changed_component = underscore.keys(requested_view)[0];
10 |
11 | // add additional filter information from othe possible filters
12 | underscore.each( underscore.keys(params.viz.possible_filters), function(inst_filter){
13 |
14 | if (inst_filter != changed_component){
15 |
16 | if (!d3.select(params.root+' .slider_'+inst_filter).empty()){
17 |
18 | var inst_state = d3.select(params.root+' .slider_'+inst_filter)
19 | .attr('current_state');
20 |
21 | requested_view[inst_filter] = inst_state;
22 | }
23 |
24 | }
25 |
26 | });
27 |
28 | return requested_view;
29 |
30 | };
--------------------------------------------------------------------------------
/src/filters/reset_other_filter_sliders.js:
--------------------------------------------------------------------------------
1 | var make_filter_title = require('./make_filter_title');
2 | var underscore = require('underscore');
3 |
4 | module.exports = function reset_other_filter_sliders(cgm, filter_type, inst_state){
5 |
6 | var params = cgm.params;
7 | var inst_rc;
8 | var reset_rc;
9 |
10 | d3.select(params.root+' .slider_'+filter_type)
11 | .attr('current_state', inst_state);
12 |
13 | underscore.each( underscore.keys(params.viz.possible_filters), function(reset_filter){
14 |
15 | if ( filter_type.indexOf('row') > -1 ){
16 | inst_rc = 'row';
17 | } else if ( filter_type.indexOf('col') > -1 ){
18 | inst_rc = 'col';
19 | } else {
20 | inst_rc = 'neither';
21 | }
22 |
23 | if ( reset_filter.indexOf('row') > -1 ){
24 | reset_rc = 'row';
25 | } else if ( reset_filter.indexOf('col') > -1 ){
26 | reset_rc = 'col';
27 | } else {
28 | reset_rc = 'neither';
29 | }
30 |
31 | if (filter_type != reset_filter && inst_rc != 'neither'){
32 |
33 | if (inst_rc == reset_rc){
34 |
35 | var tmp_title = make_filter_title(params, reset_filter);
36 |
37 | cgm.slider_functions[reset_filter].value(0);
38 |
39 | d3.select(params.root+' .title_'+reset_filter)
40 | .text(tmp_title.text + tmp_title.state);
41 |
42 | d3.select(params.root+' .slider_'+reset_filter)
43 | .attr('current_state', tmp_title.state);
44 |
45 | }
46 |
47 | }
48 |
49 |
50 | });
51 |
52 | var filter_title = make_filter_title(params, filter_type);
53 |
54 | d3.select(params.root+' .title_'+filter_type)
55 | .text(filter_title.text + inst_state + filter_title.suffix);
56 |
57 | };
--------------------------------------------------------------------------------
/src/filters/run_filter_slider.js:
--------------------------------------------------------------------------------
1 | var update_viz_with_view = require('../network/update_viz_with_view');
2 | var reset_other_filter_sliders = require('./reset_other_filter_sliders');
3 | var get_current_orders = require('./get_current_orders');
4 | var make_requested_view = require('./make_requested_view');
5 | var underscore = require('underscore');
6 |
7 | module.exports = function run_filter_slider(cgm, filter_type, available_views, inst_index){
8 |
9 | // only update if not running update
10 | if (d3.select(cgm.params.viz.viz_svg).classed('running_update') === false){
11 |
12 | var params = cgm.params;
13 |
14 | // get value
15 | var inst_state = available_views[inst_index][filter_type];
16 |
17 | reset_other_filter_sliders(cgm, filter_type, inst_state);
18 |
19 | params = get_current_orders(params);
20 |
21 | var requested_view = {};
22 | requested_view[filter_type] = inst_state;
23 |
24 | requested_view = make_requested_view(params, requested_view);
25 |
26 | if ( underscore.has(available_views[0],'enr_score_type') ){
27 | var enr_state = d3.select(params.root+' .toggle_enr_score_type')
28 | .attr('current_state');
29 |
30 | requested_view.enr_score_type = enr_state;
31 | }
32 |
33 | update_viz_with_view(cgm, requested_view);
34 |
35 | }
36 |
37 | };
--------------------------------------------------------------------------------
/src/filters/set_up_filters.js:
--------------------------------------------------------------------------------
1 | var make_slider_filter = require('./make_slider_filter');
2 | var make_button_filter = require('./make_button_filter');
3 |
4 | module.exports = function set_up_filters(cgm, filter_type) {
5 |
6 | var params = cgm.params;
7 |
8 | var div_filters = d3.select(params.root+' .sidebar_wrapper')
9 | .append('div')
10 | .classed('div_filters',true)
11 | .style('padding-left', '10px')
12 | .style('padding-right', '10px');
13 |
14 | if (params.viz.possible_filters[filter_type] == 'numerical'){
15 | make_slider_filter(cgm, filter_type, div_filters);
16 | } else if (params.viz.possible_filters[filter_type] == 'categorical'){
17 | make_button_filter(cgm, filter_type, div_filters);
18 | }
19 |
20 | };
21 |
--------------------------------------------------------------------------------
/src/initialize_matrix.js:
--------------------------------------------------------------------------------
1 | var utils = require('./Utils_clust');
2 |
3 | module.exports = function(network_data) {
4 | var matrix = [];
5 | var ini_object;
6 |
7 | var keep_orig;
8 | if (utils.has(network_data.links[0], 'value_orig')){
9 | keep_orig = true;
10 | } else {
11 | keep_orig = false;
12 | }
13 |
14 | network_data.row_nodes.forEach(function (tmp, row_index) {
15 |
16 | matrix[row_index] = {};
17 | matrix[row_index].name = network_data.row_nodes[row_index].name;
18 | matrix[row_index].row_index = row_index;
19 |
20 | matrix[row_index].row_data = d3.range(network_data.col_nodes.length).map(
21 | function (col_index) {
22 |
23 | if (utils.has(network_data.links[0], 'value_up') || utils.has(network_data.links[0], 'value_dn')) {
24 |
25 | ini_object = {
26 | pos_x: col_index,
27 | pos_y: row_index,
28 | value: 0,
29 | value_up: 0,
30 | value_dn: 0,
31 | highlight: 0
32 | };
33 |
34 | } else {
35 |
36 | ini_object = {
37 | pos_x: col_index,
38 | pos_y: row_index,
39 | value: 0,
40 | highlight: 0
41 | };
42 |
43 | }
44 |
45 | if (keep_orig){
46 | ini_object.value_orig = 0;
47 | }
48 |
49 | return ini_object;
50 | });
51 |
52 | });
53 |
54 | network_data.links.forEach(function (link) {
55 |
56 | // transfer additional link information is necessary
57 | matrix[link.source].row_data[link.target].value = link.value;
58 | matrix[link.source].row_data[link.target].row_name = link.row_name;
59 | matrix[link.source].row_data[link.target].col_name = link.col_name;
60 |
61 | if (utils.has(link, 'value_up') || utils.has(link, 'value_dn')) {
62 | matrix[link.source].row_data[link.target].value_up = link.value_up;
63 | matrix[link.source].row_data[link.target].value_dn = link.value_dn;
64 | }
65 |
66 | if (keep_orig){
67 | matrix[link.source].row_data[link.target].value_orig = link.value_orig;
68 | }
69 |
70 | if (link.highlight) {
71 | matrix[link.source].row_data[link.target].highlight = link.highlight;
72 | }
73 | if (link.info) {
74 | matrix[link.source].row_data[link.target].info = link.info;
75 | }
76 | });
77 |
78 | return matrix;
79 | };
80 |
--------------------------------------------------------------------------------
/src/labels/add_col_click_hlight.js:
--------------------------------------------------------------------------------
1 | module.exports = function(params, clicked_col, id_clicked_col) {
2 |
3 | if (id_clicked_col != params.click_hlight_col){
4 |
5 | params.click_hlight_col = id_clicked_col;
6 |
7 | var rel_width_hlight = 6;
8 | var opacity_hlight = 0.85;
9 | var hlight_width = rel_width_hlight * params.viz.border_width.x;
10 |
11 | d3.selectAll(params.root+' .click_hlight')
12 | .remove();
13 |
14 | // // highlight selected column
15 | // ///////////////////////////////
16 | // // unhilight and unbold all columns (already unbolded earlier)
17 | // d3.selectAll('.col_label_text')
18 | // .select('rect')
19 | // .style('opacity', 0);
20 | // // highlight column name
21 | // d3.select(clicked_col)
22 | // .select('rect')
23 | // .style('opacity', 1);
24 |
25 | d3.select(clicked_col)
26 | .append('rect')
27 | .classed('click_hlight',true)
28 | .classed('col_top_hlight',true)
29 | .attr('width',params.viz.clust.dim.height)
30 | .attr('height',hlight_width)
31 | .attr('fill',params.matrix.hlight_color)
32 | .attr('opacity',opacity_hlight)
33 | .attr('transform',function(){
34 | var tmp_translate_y = 0;
35 | var tmp_translate_x = -(params.viz.clust.dim.height+
36 | params.viz.cat_room.col+params.viz.uni_margin);
37 | return 'translate('+tmp_translate_x+','+tmp_translate_y+')';
38 | });
39 |
40 | d3.select(clicked_col)
41 | .append('rect')
42 | .classed('click_hlight',true)
43 | .classed('col_bottom_hlight',true)
44 | .attr('width',params.viz.clust.dim.height)
45 | .attr('height',hlight_width)
46 | .attr('fill',params.matrix.hlight_color)
47 | .attr('opacity',opacity_hlight)
48 | .attr('transform', function(){
49 | // reverse x and y since rotated
50 | var tmp_translate_y = params.viz.x_scale.rangeBand() - hlight_width;
51 | var tmp_translate_x = -(params.viz.clust.dim.height +
52 | params.viz.cat_room.col+params.viz.uni_margin);
53 | return 'translate('+tmp_translate_x+','+tmp_translate_y+')';
54 | });
55 | } else {
56 | d3.selectAll(params.root+' .click_hlight')
57 | .remove();
58 | params.click_hlight_col = -666;
59 | }
60 |
61 | };
62 |
--------------------------------------------------------------------------------
/src/labels/add_row_click_hlight.js:
--------------------------------------------------------------------------------
1 | module.exports = function(params, clicked_row, id_clicked_row) {
2 | if (id_clicked_row != params.click_hlight_row){
3 |
4 | var rel_width_hlight = 6;
5 | var opacity_hlight = 0.85;
6 | var hlight_height = rel_width_hlight * params.viz.border_width.x;
7 |
8 | d3.selectAll(params.root+' .click_hlight')
9 | .remove();
10 |
11 | // // highlight selected row
12 | // d3.selectAll(params.root+' .row_label_group')
13 | // .select('rect')
14 | // d3.select(this)
15 | // .select('rect')
16 | // .style('opacity', 1);
17 |
18 | d3.select(clicked_row)
19 | .append('rect')
20 | .classed('click_hlight',true)
21 | .classed('row_top_hlight',true)
22 | .attr('width',params.viz.svg_dim.width)
23 | .attr('height',hlight_height)
24 | .attr('fill',params.matrix.hlight_color)
25 | .attr('opacity',opacity_hlight);
26 |
27 | d3.select(clicked_row)
28 | .append('rect')
29 | .classed('click_hlight',true)
30 | .classed('row_bottom_hlight',true)
31 | .attr('width',params.viz.svg_dim.width)
32 | .attr('height',hlight_height)
33 | .attr('fill',params.matrix.hlight_color)
34 | .attr('opacity',opacity_hlight)
35 | .attr('transform', function(){
36 | var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
37 | return 'translate(0,'+tmp_translate_y+')';
38 | });
39 | } else{
40 | d3.selectAll(params.root+' .click_hlight')
41 | .remove();
42 | params.click_hlight_row = -666;
43 | }
44 |
45 | };
46 |
--------------------------------------------------------------------------------
/src/labels/col_viz_aid_triangle.js:
--------------------------------------------------------------------------------
1 | module.exports = function col_viz_aid_triangle(params){
2 |
3 | // x and y are flipped since its rotated
4 | var reduce_rect_width = params.viz.x_scale.rangeBand() * 0.36;
5 | var origin_y = -params.viz.border_width.x;
6 | var start_x = 0;
7 | var final_x = params.viz.x_scale.rangeBand() - reduce_rect_width;
8 | var start_y = -(params.viz.x_scale.rangeBand() - reduce_rect_width +
9 | params.viz.border_width.x);
10 | var final_y = -params.viz.border_width.x;
11 | var output_string = 'M ' + origin_y + ',0 L ' + start_y + ',' +
12 | start_x + ' L ' + final_y + ',' + final_x + ' Z';
13 | return output_string;
14 | };
--------------------------------------------------------------------------------
/src/labels/label_constrain_and_trim.js:
--------------------------------------------------------------------------------
1 | var utils = require('../Utils_clust');
2 | var trim_text = require('../zoom/trim_text');
3 | var constrain_font_size = require('../zoom/constrain_font_size');
4 |
5 | module.exports = function label_constrain_and_trim(params){
6 |
7 | // console.log('label_constrain_and_trim');
8 |
9 | // reset text in rows and columns
10 | d3.selectAll(params.root+' .row_label_group')
11 | .select('text')
12 | .text(function(d){ return utils.normal_name(d); });
13 |
14 | d3.selectAll(params.root+' .col_label_text')
15 | .select('text')
16 | .text(function(d){ return utils.normal_name(d); });
17 |
18 | constrain_font_size(params);
19 |
20 | d3.selectAll(params.root+' .row_label_group' )
21 | .each(function() { trim_text(params, this, 'row'); });
22 |
23 | d3.selectAll(params.root+' .col_label_group')
24 | .each(function() { trim_text(params, this, 'col'); });
25 |
26 | };
--------------------------------------------------------------------------------
/src/labels/make_col_tooltips.js:
--------------------------------------------------------------------------------
1 | var d3_tip_custom = require('../tooltip/d3_tip_custom');
2 |
3 | module.exports = function make_col_tooltips(params){
4 |
5 | if (params.labels.show_label_tooltips){
6 |
7 | // remove old col tooltips
8 | d3.selectAll(params.viz.root_tips + '_col_tip').remove();
9 |
10 | // d3-tooltip
11 | var col_tip = d3_tip_custom()
12 | .attr('class', function(){
13 | var root_tip_selector = params.viz.root_tips.replace('.','');
14 | var class_string = root_tip_selector + ' d3-tip '+
15 | root_tip_selector + '_col_tip';
16 | return class_string;
17 | })
18 | .direction('w')
19 | .offset([20, 0])
20 | .style('display','none')
21 | .html(function(d) {
22 | var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
23 | return "" + inst_name + "";
24 | });
25 |
26 | d3.select(params.viz.viz_wrapper)
27 | .select('svg')
28 | .select(params.root+' .col_zoom_container')
29 | .selectAll('.col_label_group')
30 | .select('text')
31 | .call(col_tip);
32 |
33 | d3.select(params.root+' .col_zoom_container')
34 | .selectAll('.col_label_group')
35 | .on('mouseover', function(d){
36 |
37 | d3.selectAll(params.viz.root_tips+'_col_tip')
38 | .style('display', 'block');
39 |
40 | col_tip.show(d);
41 | if (params.col_tip_callback != null){
42 | params.col_tip_callback(d);
43 | }
44 | })
45 | .on('mouseout', function(){
46 | col_tip.hide(this);
47 |
48 | d3.selectAll(params.viz.root_tips+'_col_tip')
49 | .style('display', 'none');
50 |
51 | });
52 |
53 | }
54 |
55 | };
--------------------------------------------------------------------------------
/src/labels/make_row_label_container.js:
--------------------------------------------------------------------------------
1 | var make_row_labels = require('./make_row_labels');
2 |
3 | module.exports = function make_row_label_container(cgm, text_delay) {
4 |
5 | var params = cgm.params;
6 |
7 | var row_container;
8 |
9 | // row container holds all row text and row visualizations (triangles rects)
10 | ////////////////////////////////////////////////////////////////////////////
11 | if ( d3.select(params.viz.viz_svg + ' .row_container').empty() ){
12 | row_container = d3.select(params.viz.viz_svg)
13 | .append('g')
14 | .classed('row_container', true)
15 | .attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' +
16 | params.viz.clust.margin.top + ')');
17 | } else {
18 | row_container = d3.select(params.viz.viz_svg)
19 | .select('.row_container')
20 | .attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' +
21 | params.viz.clust.margin.top + ')');
22 | }
23 |
24 | if (d3.select(params.root+' .row_white_background').empty()){
25 | row_container
26 | .append('rect')
27 | .classed('row_white_background',true)
28 | .classed('white_bars',true)
29 | .attr('fill', params.viz.background_color)
30 | .attr('width', params.viz.label_background.row)
31 | .attr('height', 30*params.viz.clust.dim.height + 'px');
32 | }
33 |
34 | // add container to hold text row labels if not already there
35 | if ( d3.select(params.root +' .row_label_container').empty() ){
36 | row_container
37 | .append('g')
38 | .classed('row_label_container', true)
39 | .attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)')
40 | .append('g')
41 | .classed('row_label_zoom_container', true);
42 | } else {
43 | row_container
44 | .select(params.root+' .row_label_container')
45 | .attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
46 | }
47 |
48 | // make row labels in the container
49 | ///////////////////////////////////////
50 | if (params.viz.ds_level === -1){
51 | make_row_labels(cgm, 'all', text_delay);
52 | }
53 |
54 | };
55 |
--------------------------------------------------------------------------------
/src/labels/make_row_tooltips.js:
--------------------------------------------------------------------------------
1 | var d3_tip_custom = require('../tooltip/d3_tip_custom');
2 |
3 | module.exports = function make_row_tooltips(params){
4 |
5 | if (params.labels.show_label_tooltips){
6 |
7 | // remove old tooltips
8 | d3.selectAll(params.viz.root_tips + '_row_tip').remove();
9 |
10 | var root_tip_selector = params.viz.root_tips.replace('.','');
11 |
12 | // d3-tooltip
13 | var row_tip = d3_tip_custom()
14 | .attr('class', function(){
15 | var class_string = root_tip_selector + ' d3-tip '+
16 | root_tip_selector + '_row_tip';
17 | return class_string;
18 | })
19 | .direction('e')
20 | .offset([0, 10])
21 | .style('display','none')
22 | .html(function(d) {
23 | var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
24 | return "" + inst_name + "";
25 | });
26 |
27 | d3.select(params.viz.viz_wrapper)
28 | .select(params.root+' .row_container')
29 | .call(row_tip);
30 |
31 | d3.select(params.root+' .row_label_zoom_container')
32 | .selectAll('g')
33 | .on('mouseover', function(d) {
34 |
35 | d3.select(params.viz.root_tips+'_row_tip')
36 | .classed(d.name, true);
37 |
38 | d3.selectAll(params.viz.root_tips+'_row_tip')
39 | .style('display', 'block');
40 |
41 | d3.select(this)
42 | .select('text')
43 | .classed('active', true);
44 |
45 | row_tip.show(d);
46 |
47 | if (params.row_tip_callback != null){
48 | params.row_tip_callback(params.viz.root_tips, d);
49 | }
50 |
51 | })
52 | .on('mouseout', function mouseout(d) {
53 |
54 | d3.selectAll(params.viz.root_tips+'_row_tip')
55 | .style('display', 'none')
56 | .classed(d.name, false);
57 |
58 | d3.select(this)
59 | .select('text')
60 | .classed('active',false);
61 |
62 | row_tip.hide(d);
63 | });
64 |
65 |
66 | } else{
67 |
68 | d3.select(params.root+' .row_label_zoom_container')
69 | .selectAll('g')
70 | .on('mouseover', function() {
71 | d3.select(this)
72 | .select('text')
73 | .classed('active',true);
74 | })
75 | .on('mouseout', function mouseout() {
76 | d3.select(this)
77 | .select('text')
78 | .classed('active',false);
79 | });
80 | }
81 |
82 | };
--------------------------------------------------------------------------------
/src/labels/make_row_visual_aid_triangles.js:
--------------------------------------------------------------------------------
1 | module.exports = function make_row_visual_aid_triangles(params){
2 |
3 | if (d3.select(params.root+' .row_cat_group path').empty() === true){
4 | d3.selectAll(params.root+' .row_cat_group')
5 | .append('path')
6 | .attr('d', function() {
7 | var origin_x = params.viz.cat_room.symbol_width - 1;
8 | var origin_y = 0;
9 | var mid_x = 1;
10 | var mid_y = params.viz.y_scale.rangeBand() / 2;
11 | var final_x = params.viz.cat_room.symbol_width - 1;
12 | var final_y = params.viz.y_scale.rangeBand();
13 | var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' +
14 | mid_x + ',' + mid_y + ' L ' + final_x + ',' + final_y + ' Z';
15 | return output_string;
16 | })
17 | .attr('fill', '#eee')
18 | .style('opacity', params.viz.triangle_opacity);
19 | }
20 |
21 | };
--------------------------------------------------------------------------------
/src/matrix/calc_downsampled_matrix.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function calc_downsampled_matrix(params, mat, ds_level){
4 |
5 | var inst_num_rows = params.viz.ds[ds_level].num_rows;
6 |
7 | var num_compressed_rows = params.network_data.row_nodes.length / inst_num_rows;
8 |
9 | // increase ds opacity, as more rows are compressed into a single downsampled
10 | // row, increase the opacity of the downsampled row.
11 | var opacity_factor = params.viz.ds_opacity_scale(num_compressed_rows);
12 |
13 | var mod_val = params.viz.clust.dim.height / inst_num_rows;
14 |
15 | var ds_mat = [];
16 | var inst_obj;
17 |
18 | var len_ds_array = inst_num_rows + 1;
19 |
20 | var i;
21 | var x;
22 |
23 | // initialize array of objects
24 | for (i=0; i < len_ds_array; i++){
25 |
26 | inst_obj = {};
27 | inst_obj.row_index = i;
28 | inst_obj.name = String(i);
29 | inst_obj.all_names = [];
30 |
31 | ds_mat.push(inst_obj);
32 | }
33 |
34 | underscore.each(mat, function(inst_row){
35 |
36 | // row ordering information is contained in y_scale
37 | var inst_y = params.viz.y_scale(inst_row.row_index);
38 |
39 | var ds_index = Math.round(inst_y/mod_val);
40 |
41 | var inst_row_data = inst_row.row_data;
42 |
43 | // gather names
44 | ds_mat[ds_index].all_names.push(inst_row.name);
45 |
46 | // gather row_data
47 | if (_.has(ds_mat[ds_index], 'row_data')){
48 |
49 | for (x=0; x < inst_row_data.length; x++){
50 | ds_mat[ds_index].row_data[x].value = ds_mat[ds_index].row_data[x].value + inst_row_data[x].value;
51 | }
52 |
53 | } else {
54 |
55 | var new_data = [];
56 | for (x=0; x < inst_row_data.length; x++){
57 | new_data[x] = inst_row_data[x];
58 | }
59 |
60 | ds_mat[ds_index].row_data = new_data;
61 |
62 | }
63 |
64 | });
65 |
66 | // average the values
67 | underscore.each(ds_mat, function(tmp_ds){
68 |
69 | var tmp_row_data = tmp_ds.row_data;
70 |
71 | var num_names = tmp_ds.all_names.length;
72 |
73 | underscore.each(tmp_row_data, function(tmp_obj){
74 | tmp_obj.value = (tmp_obj.value / num_names)*opacity_factor;
75 | });
76 |
77 | });
78 |
79 | // all names were found
80 | var all_names = [];
81 |
82 | underscore.each(ds_mat, function(inst_row){
83 | all_names = all_names.concat(inst_row.all_names);
84 | });
85 |
86 | return ds_mat;
87 |
88 | };
--------------------------------------------------------------------------------
/src/matrix/deactivate_cropping.js:
--------------------------------------------------------------------------------
1 | module.exports = function deactivate_cropping(cgm){
2 |
3 | d3.select(cgm.params.root+' .brush_group')
4 | .transition()
5 | .style('opacity', 0)
6 | .remove();
7 |
8 | cgm.params.is_cropping = false;
9 |
10 | };
--------------------------------------------------------------------------------
/src/matrix/draw_gridlines.js:
--------------------------------------------------------------------------------
1 | // var grid_lines_viz = require('./grid_lines_viz');
2 | // var toggle_grid_lines = require('./toggle_grid_lines');
3 |
4 | /* eslint-disable */
5 | module.exports = function draw_gridlines(params, delays, duration){
6 |
7 | // var row_nodes = params.network_data.row_nodes;
8 | // var col_nodes = params.network_data.col_nodes;
9 |
10 | // // Fade in new gridlines
11 | // ///////////////////////////
12 |
13 | // // append horizontal line groups
14 | // var horz_lines = d3.select(params.root+' .clust_group')
15 | // .selectAll('.horz_lines')
16 | // .data(row_nodes, function(d){return d.name;})
17 | // .enter()
18 | // .append('g')
19 | // .attr('class','horz_lines');
20 |
21 | // // append vertical line groups
22 | // var vert_lines = d3.select(params.root+' .clust_group')
23 | // .selectAll('.vert_lines')
24 | // .data(col_nodes)
25 | // .enter()
26 | // .append('g')
27 | // .attr('class', 'vert_lines');
28 |
29 | // grid_lines_viz(params, duration);
30 |
31 | // horz_lines
32 | // .select('line')
33 | // .attr('opacity',0)
34 | // .attr('stroke','white')
35 | // .attr('opacity', 1);
36 |
37 | // vert_lines
38 | // .select('line')
39 | // .style('stroke', 'white')
40 | // .attr('opacity',0)
41 | // .transition().delay(delays.enter).duration(2*duration)
42 | // .attr('opacity', 1);
43 |
44 | // toggle_grid_lines(params);
45 |
46 | };
47 |
--------------------------------------------------------------------------------
/src/matrix/fine_position_tile.js:
--------------------------------------------------------------------------------
1 | module.exports = function fine_position_tile(params, d){
2 |
3 | var offset_x;
4 |
5 | // prevent rows not in x_scale domain from causing errors
6 | if (d.pos_x in params.viz.x_scale.domain()){
7 | offset_x = params.viz.x_scale(d.pos_x);
8 | } else {
9 | offset_x = 0;
10 | }
11 |
12 | var x_pos = offset_x + 0.5 * params.viz.border_width.x;
13 | var y_pos = 0.5 * params.viz.border_width.y;
14 | return 'translate(' + x_pos + ',' + y_pos + ')';
15 | };
--------------------------------------------------------------------------------
/src/matrix/grid_lines_viz.js:
--------------------------------------------------------------------------------
1 | module.exports = function grid_lines_viz(params, duration=0){
2 |
3 | var delay = 0;
4 | if (duration > 0){
5 | delay = 2000;
6 | }
7 |
8 | var horz_lines = d3.selectAll(params.root+' .horz_lines');
9 | var vert_lines = d3.selectAll(params.root+' .vert_lines');
10 |
11 | horz_lines
12 | .style('opacity', 0)
13 | .attr('transform', function(d) {
14 | var inst_index = d.row_index;
15 | var inst_trans = params.viz.y_scale(inst_index);
16 | return 'translate( 0,' + inst_trans + ') rotate(0)';
17 | })
18 | .transition()
19 | .duration(duration)
20 | .delay(delay)
21 | .style('opacity', 1);
22 |
23 | horz_lines
24 | .append('line')
25 | .attr('x1',0)
26 | .attr('x2',params.viz.clust.dim.width)
27 | .style('stroke-width', function(){
28 | var inst_width = params.viz.border_width.y;
29 | return inst_width+'px';
30 | });
31 |
32 | vert_lines
33 | .style('opacity', 0)
34 | .attr('transform', function(d) {
35 | var inst_index = d.col_index;
36 | var inst_trans = params.viz.x_scale(inst_index);
37 | return 'translate(' + inst_trans + ') rotate(-90)';
38 | })
39 | .transition()
40 | .duration(duration)
41 | .delay(delay)
42 | .style('opacity', 1);
43 |
44 | vert_lines
45 | .append('line')
46 | .attr('x1', 0)
47 | .attr('x2', -params.viz.clust.dim.height)
48 | .style('stroke-width', function(){
49 | var inst_width = params.viz.border_width.x;
50 | return inst_width + 'px';
51 | });
52 |
53 | };
--------------------------------------------------------------------------------
/src/matrix/make_full_name.js:
--------------------------------------------------------------------------------
1 | module.exports = function make_full_name(params, inst_node, inst_rc){
2 |
3 | var cat_name;
4 | var inst_name = inst_node.name;
5 | var num_cats = params.viz.all_cats[inst_rc].length;
6 |
7 | // make tuple if necessary
8 | if (num_cats>0){
9 |
10 | inst_name = "('" + inst_name + "'";
11 |
12 | for (var cat_index= 0; cat_index < num_cats; cat_index++) {
13 | cat_name = 'cat-'+ String(cat_index);
14 |
15 | inst_name = inst_name + ", '" + String(inst_node[cat_name]) + "'";
16 |
17 | }
18 |
19 | inst_name = inst_name + ')';
20 |
21 | } else {
22 |
23 | // always make names strings
24 | inst_name = String(inst_name);
25 |
26 | }
27 |
28 |
29 | return inst_name;
30 | };
--------------------------------------------------------------------------------
/src/matrix/make_matrix_string.js:
--------------------------------------------------------------------------------
1 | var make_full_name = require('./make_full_name');
2 | var underscore = require('underscore');
3 |
4 | module.exports = function make_matrix_string(params){
5 |
6 | var inst_matrix = params.matrix;
7 |
8 | // get order indexes
9 | var order_indexes = {};
10 | var inst_name;
11 | underscore.each(['row', 'col'], function(tmp_rc){
12 |
13 | var inst_rc;
14 | // row/col names are reversed in saved orders
15 | if (tmp_rc === 'row'){
16 | inst_rc = 'col';
17 | } else {
18 | inst_rc = 'row';
19 | }
20 |
21 | // use tmp_rc
22 | inst_name = params.inst_order[tmp_rc];
23 |
24 | // use tmp_rc
25 | order_indexes[inst_rc] = inst_matrix.orders[ inst_name+ '_' + tmp_rc ];
26 |
27 | });
28 |
29 | var matrix_string = '\t';
30 | var row_nodes = params.network_data.row_nodes;
31 | var col_nodes = params.network_data.col_nodes;
32 |
33 | // alternate column entry
34 | for (var c_i=0; c_i 1){
4 | d3.selectAll(params.root+' .vert_lines').select('line')
5 | .style('display','block')
6 | .style('opacity', 0)
7 | .transition()
8 | .style('opacity', 1);
9 | } else {
10 | d3.selectAll(params.root+' .vert_lines').select('line').style('display','none');
11 | }
12 |
13 | if (params.zoom_info.zoom_y * params.viz.border_width.y > 1){
14 | d3.selectAll(params.root+' .horz_lines').select('line')
15 | .style('display','block')
16 | .style('opacity', 0)
17 | .transition()
18 | .style('opacity', 1);
19 | } else {
20 | d3.selectAll(params.root+' .horz_lines').select('line').style('display','none');
21 | }
22 | };
--------------------------------------------------------------------------------
/src/menus/make_menu_update_button.js:
--------------------------------------------------------------------------------
1 | module.exports = function make_menu_update_button(cgm, button_info, update_callback){
2 |
3 |
4 | var update_button_width = cgm.params.viz.update_button_width;
5 |
6 | // var menu_width = button_info.menu_width;
7 | // var button_x = menu_width/2 + button_info.default_x_offset;
8 |
9 | var default_opacity = 0.35;
10 | var high_opacity = 0.5;
11 |
12 | var update_button = button_info.selection
13 | .append('g')
14 | .classed('update_button', true)
15 | .attr('transform', 'translate('+ button_info.update_x +', ' + button_info.update_y + ')')
16 | .on('click', update_callback)
17 | .on('mouseover', function(){
18 | d3.select(this)
19 | .select('rect')
20 | .attr('opacity', high_opacity);
21 | })
22 | .on('mouseout', function(){
23 | d3.select(this)
24 | .select('rect')
25 | .attr('opacity', default_opacity);
26 | });
27 |
28 | update_button
29 | .append('rect')
30 | .attr('width', update_button_width + 'px')
31 | .attr('height', '35px')
32 | .attr('fill', 'blue')
33 | .attr('transform', 'translate(0, -23)')
34 | .attr('stroke', '#A3A3A3')
35 | .attr('stroke-width', '1px')
36 | .attr('opacity', default_opacity);
37 |
38 | update_button
39 | .append('text')
40 | .attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif')
41 | .attr('font-size','18px')
42 | .attr('font-weight', 500)
43 | .attr('cursor', 'default')
44 | .text('Update')
45 | .attr('transform', 'translate(18, 0)');
46 |
47 | };
--------------------------------------------------------------------------------
/src/menus/position_filter_icon.js:
--------------------------------------------------------------------------------
1 | module.exports = function position_filter_icon(cgm){
2 |
3 | var viz = cgm.params.viz;
4 | var tmp_left;
5 | var tmp_top;
6 |
7 | // keep slider near clustergram
8 | var max_room = viz.svg_dim.width - 3 * viz.uni_margin;
9 |
10 | // position close to row dendrogram trapezoids
11 | tmp_left = viz.clust.margin.left + viz.clust.dim.width + 4 * viz.dendro_room.row + 7;
12 |
13 | if (tmp_left > max_room){
14 | tmp_left = max_room;
15 | }
16 |
17 | // tmp_top = viz.clust.margin.top + 3 * viz.uni_margin - 50;
18 | tmp_top = viz.clust.margin.top + 3 * viz.uni_margin + 152;
19 |
20 | // reposition tree icon
21 | d3.select(cgm.params.root + ' .' + 'filter_icon')
22 | .attr('transform', function() {
23 | var inst_translation;
24 | tmp_top = tmp_top - 75;
25 | inst_translation = 'translate(' + tmp_left + ',' + tmp_top + ')';
26 | return inst_translation;
27 | })
28 | .style('opacity', 1);
29 | };
--------------------------------------------------------------------------------
/src/menus/position_filter_menu.js:
--------------------------------------------------------------------------------
1 | module.exports = function position_filter_menu(cgm){
2 |
3 | var params = cgm.params;
4 |
5 | if (d3.select(params.root+' .filter_menu').empty() === false){
6 |
7 | var menu_width = cgm.params.viz.filter_menu_width;
8 |
9 | d3.select(params.root+' .filter_menu')
10 | .attr('transform', function(){
11 | var shift = {};
12 | shift.x = params.viz.clust.dim.width + params.viz.clust.margin.left - menu_width + 30;
13 | shift.y = params.viz.clust.margin.top + 80;
14 | return 'translate(' + shift.x + ', ' + shift.y + ')';
15 | });
16 |
17 | }
18 | };
--------------------------------------------------------------------------------
/src/menus/position_tree_icon.js:
--------------------------------------------------------------------------------
1 | module.exports = function position_tree_icon(cgm){
2 |
3 | var viz = cgm.params.viz;
4 | var tmp_left;
5 | var tmp_top;
6 |
7 | // keep slider near clustergram
8 | var max_room = viz.svg_dim.width - 3 * viz.uni_margin;
9 |
10 | // position close to row dendrogram trapezoids
11 | tmp_left = viz.clust.margin.left + viz.clust.dim.width + 5.25 * viz.dendro_room.row;
12 |
13 | if (tmp_left > max_room){
14 | tmp_left = max_room;
15 | }
16 |
17 | // tmp_top = viz.clust.margin.top + 3 * viz.uni_margin - 50;
18 | tmp_top = viz.clust.margin.top + 3 * viz.uni_margin + 90;
19 |
20 | // reposition tree icon
21 | d3.select(cgm.params.root + ' .' + 'tree_icon')
22 | .attr('transform', function() {
23 | var inst_translation;
24 | tmp_top = tmp_top - 75;
25 | inst_translation = 'translate(' + tmp_left + ',' + tmp_top + ')';
26 | return inst_translation;
27 | })
28 | .style('opacity', 1);
29 | };
--------------------------------------------------------------------------------
/src/menus/position_tree_menu.js:
--------------------------------------------------------------------------------
1 | module.exports = function position_tree_menu(cgm){
2 |
3 | var params = cgm.params;
4 |
5 | if (d3.select(params.root+' .tree_menu').empty() === false){
6 |
7 | var menu_width = cgm.params.viz.tree_menu_width;
8 |
9 | d3.select(params.root+' .tree_menu')
10 | .attr('transform', function(){
11 | var shift = {};
12 | shift.x = params.viz.clust.dim.width + params.viz.clust.margin.left - menu_width + 30;
13 | shift.y = params.viz.clust.margin.top + 15;
14 | return 'translate(' + shift.x + ', ' + shift.y + ')';
15 | });
16 |
17 | }
18 | };
--------------------------------------------------------------------------------
/src/menus/toggle_menu.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = function toggle_menu(cgm, menu_type, toggle, make_menu=null){
3 |
4 | var params = cgm.params;
5 |
6 | if (toggle === 'open'){
7 |
8 | d3.selectAll(cgm.params.root + ' .svg_menus')
9 | .remove();
10 |
11 | if (make_menu != null){
12 | make_menu(cgm);
13 | }
14 |
15 |
16 | } else if (toggle === 'close'){
17 |
18 | d3.select(params.root + ' .' + menu_type)
19 | .transition(700)
20 | .attr('opacity', 0);
21 |
22 | setTimeout(function(){
23 | d3.select(params.root + ' .' + menu_type)
24 | .remove();
25 | }, 700);
26 | }
27 |
28 | };
--------------------------------------------------------------------------------
/src/modal/make_modal_skeleton.js:
--------------------------------------------------------------------------------
1 | module.exports = function make_modal_skeleton(params, modal_class){
2 |
3 | var modal_skeleton = {};
4 |
5 | var modal = d3.select(params.root)
6 | .append('div')
7 | .classed('modal', true)
8 | .classed('fade', true)
9 | .classed(modal_class, true)
10 | .attr('role','dialog');
11 |
12 | var modal_dialog = modal
13 | .append('div')
14 | .classed('modal-dialog', true);
15 |
16 | var modal_content = modal_dialog
17 | .append('div')
18 | .classed('modal-content', true);
19 |
20 | modal_skeleton.header = modal_content
21 | .append('div')
22 | .classed('modal-header', true);
23 |
24 | modal_skeleton.header
25 | .append('button')
26 | .attr('type','button')
27 | .classed('close', true)
28 | .attr('data-dismiss','modal')
29 | .html('×');
30 |
31 | modal_skeleton.body = modal_content
32 | .append('div')
33 | .classed('modal-body', true);
34 |
35 | return modal_skeleton;
36 |
37 | };
--------------------------------------------------------------------------------
/src/network/change_category.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = function(params, inst_cat) {
3 | // change the category
4 | params.current_col_cat = inst_cat;
5 | };
6 |
--------------------------------------------------------------------------------
/src/network/define_enter_exit_delays.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function(old_params, params) {
4 |
5 | // exit, update, enter
6 |
7 | // check if exit or enter or both are required
8 | var old_row_nodes = old_params.network_data.row_nodes;
9 | var old_col_nodes = old_params.network_data.col_nodes;
10 | var old_row = underscore.map(old_row_nodes, function(d){return d.name;});
11 | var old_col = underscore.map(old_col_nodes, function(d){return d.name;});
12 | var all_old_nodes = old_row.concat(old_col);
13 |
14 | var row_nodes = params.network_data.row_nodes;
15 | var col_nodes = params.network_data.col_nodes;
16 | var row = underscore.map(row_nodes, function(d){return d.name;});
17 | var col = underscore.map(col_nodes, function(d){return d.name;});
18 | var all_nodes = row.concat(col);
19 |
20 | var exit_nodes = underscore.difference( all_old_nodes, all_nodes ).length;
21 | var enter_nodes = underscore.difference( all_nodes, all_old_nodes ).length;
22 |
23 | var delays = {};
24 |
25 | if (exit_nodes > 0){
26 | delays.update = 1000;
27 | } else {
28 | delays.update = 0;
29 | }
30 |
31 | if (enter_nodes > 0){
32 | delays.enter = 1000;
33 | } else {
34 | delays.enter = 0;
35 | }
36 |
37 | delays.enter = delays.enter + delays.update ;
38 |
39 | delays.run_transition = true;
40 |
41 | var old_num_links = old_params.network_data.links.length;
42 | var new_num_links = params.network_data.links.length;
43 | var cutoff_num_links = 0.5*params.matrix.def_large_matrix;
44 |
45 | if ( old_num_links > cutoff_num_links || new_num_links > cutoff_num_links ){
46 | delays.run_transition = false;
47 | delays.update = 0;
48 | delays.enter = 0;
49 | }
50 |
51 | return delays;
52 | };
53 |
--------------------------------------------------------------------------------
/src/network/filter_network_using_new_nodes.js:
--------------------------------------------------------------------------------
1 | var utils = require('../Utils_clust');
2 | var core = require('mathjs/core');
3 | var underscore = require('underscore');
4 | var math = core.create();
5 | math.import(require('mathjs/lib/type/matrix'));
6 | math.import(require('mathjs/lib/function/matrix/zeros'));
7 |
8 | module.exports = function filter_network_using_new_nodes(config, new_nodes) {
9 |
10 |
11 | var links = config.network_data.links;
12 |
13 | // // make new mat from links
14 | // var new_mat = config.network_data.mat;
15 |
16 | // get new names of rows and cols
17 | var row_names = utils.pluck(new_nodes.row_nodes, 'name');
18 | var col_names = utils.pluck(new_nodes.col_nodes, 'name');
19 |
20 | var new_mat = math.matrix(math.zeros([new_nodes.row_nodes.length, new_nodes.col_nodes.length]));
21 | new_mat = new_mat.toArray();
22 |
23 | var new_links = underscore.filter(links, function(inst_link){
24 |
25 | var inst_row = inst_link.name.split('_')[0];
26 | var inst_col = inst_link.name.split('_')[1];
27 |
28 | var row_index = underscore.indexOf(row_names, inst_row);
29 | var col_index = underscore.indexOf(col_names, inst_col);
30 |
31 | // only keep links that have not been filtered out
32 | if ( row_index >-1 & col_index >-1 ){
33 |
34 | // redefine source and target
35 | inst_link.source = row_index;
36 | inst_link.target = col_index;
37 |
38 | new_mat[row_index][col_index] = inst_link.value;
39 |
40 | return inst_link;
41 | }
42 | });
43 |
44 | // set up new_network_data
45 | var new_network_data = {};
46 |
47 | // rows
48 | new_network_data.row_nodes = new_nodes.row_nodes;
49 | new_network_data.row_nodes_names = row_names;
50 |
51 | // cols
52 | new_network_data.col_nodes = new_nodes.col_nodes;
53 | new_network_data.col_nodes_names = col_names;
54 |
55 | // save all links
56 | new_network_data.links = new_links;
57 | new_network_data.all_links = links;
58 |
59 | // mat
60 | new_network_data.mat = new_mat;
61 |
62 | // add back all views
63 | new_network_data.views = config.network_data.views;
64 |
65 | // add cat_colors if necessary
66 | if (_.has(config.network_data, 'cat_colors')){
67 | new_network_data.cat_colors = config.network_data.cat_colors;
68 | }
69 |
70 | return new_network_data;
71 | };
72 |
--------------------------------------------------------------------------------
/src/network/filter_viz_using_names.js:
--------------------------------------------------------------------------------
1 | var filter_network_using_new_nodes = require('./filter_network_using_new_nodes');
2 | var update_viz_with_network = require('../update/update_viz_with_network');
3 | var underscore = require('underscore');
4 |
5 | module.exports = function filter_viz_using_names(names, external_cgm = false){
6 |
7 | // names is an object with row and column names that will be used to filter
8 | // the matrix
9 |
10 | var cgm;
11 | if (external_cgm === false){
12 | cgm = this;
13 | } else {
14 | cgm = external_cgm;
15 | }
16 |
17 | var params = cgm.params;
18 | var new_nodes = {};
19 | var found_nodes;
20 |
21 | underscore.each(['row', 'col'], function(inst_rc){
22 |
23 | var orig_nodes = params.inst_nodes[inst_rc+'_nodes'];
24 |
25 | if (_.has(names, inst_rc)){
26 |
27 | if (names[inst_rc].length > 0){
28 | var inst_names = names[inst_rc];
29 | found_nodes = $.grep(orig_nodes, function(d){
30 | return $.inArray(d.name, inst_names) > -1 ;
31 | });
32 |
33 | } else {
34 |
35 | found_nodes = orig_nodes;
36 |
37 | }
38 |
39 | } else {
40 |
41 | found_nodes = orig_nodes;
42 | }
43 |
44 | new_nodes[inst_rc+'_nodes'] = found_nodes;
45 |
46 | });
47 |
48 | // keep backup of the nodes for resetting filtering
49 | var inst_row_nodes = cgm.params.network_data.row_nodes;
50 | var inst_col_nodes = cgm.params.network_data.col_nodes;
51 |
52 | var new_network_data = filter_network_using_new_nodes(cgm.config, new_nodes);
53 |
54 | // takes entire cgm object
55 | // last argument tells it to not preserve categoty colors
56 | update_viz_with_network(cgm, new_network_data);
57 |
58 | // only keep backup if previous number of nodes were larger than current number
59 | // of nodes
60 | if (inst_row_nodes.length > cgm.params.inst_nodes.row_nodes.length){
61 | cgm.params.inst_nodes.row_nodes = inst_row_nodes;
62 | }
63 |
64 | if (inst_col_nodes.length > cgm.params.inst_nodes.col_nodes.length){
65 | cgm.params.inst_nodes.col_nodes = inst_col_nodes;
66 | }
67 |
68 | };
--------------------------------------------------------------------------------
/src/network/filter_viz_using_nodes.js:
--------------------------------------------------------------------------------
1 | var filter_network_using_new_nodes = require('./filter_network_using_new_nodes');
2 | var update_viz_with_network = require('../update/update_viz_with_network');
3 |
4 | module.exports = function filter_viz_using_nodes(new_nodes){
5 |
6 | var new_network_data = filter_network_using_new_nodes(this.config, new_nodes);
7 | update_viz_with_network(this, new_network_data);
8 |
9 | };
--------------------------------------------------------------------------------
/src/network/make_network_using_view.js:
--------------------------------------------------------------------------------
1 | var filter_network_using_new_nodes = require('./filter_network_using_new_nodes');
2 | var get_subset_views = require('../filters/get_subset_views');
3 |
4 | module.exports = function make_network_using_view(config, params, requested_view) {
5 |
6 | var orig_views = config.network_data.views;
7 |
8 | var is_enr = false;
9 | if (_.has(orig_views[0], 'enr_score_type')){
10 | is_enr = true;
11 | }
12 |
13 | var sub_views = get_subset_views(params, orig_views, requested_view);
14 |
15 | //////////////////////////////
16 | // Enrichr specific rules
17 | //////////////////////////////
18 | if (is_enr && sub_views.length == 0){
19 | requested_view = {'N_row_sum':'all', 'N_col_sum':'10'};
20 | sub_views = get_subset_views(params, orig_views, requested_view);
21 | }
22 |
23 | var inst_view = sub_views[0];
24 |
25 | var new_network_data;
26 |
27 | // get new_network_data or default back to old_network_data
28 | if (typeof inst_view !== 'undefined'){
29 | var new_nodes = inst_view.nodes;
30 | new_network_data = filter_network_using_new_nodes(config, new_nodes);
31 | } else {
32 | new_network_data = config.network_data;
33 | }
34 |
35 | return new_network_data;
36 | };
37 |
--------------------------------------------------------------------------------
/src/network/transpose_network.js:
--------------------------------------------------------------------------------
1 | var utils = require('../Utils_clust');
2 | /* Transpose network.
3 | */
4 | module.exports = function (net) {
5 | var tnet = {},
6 | inst_link,
7 | i;
8 |
9 | tnet.row_nodes = net.col_nodes;
10 | tnet.col_nodes = net.row_nodes;
11 | tnet.links = [];
12 |
13 | for (i = 0; i < net.links.length; i++) {
14 | inst_link = {};
15 | inst_link.source = net.links[i].target;
16 | inst_link.target = net.links[i].source;
17 | inst_link.value = net.links[i].value;
18 |
19 | // Optional highlight.
20 | if (utils.has(net.links[i], 'highlight')) {
21 | inst_link.highlight = net.links[i].highlight;
22 | }
23 | if (utils.has(net.links[i], 'value_up')) {
24 | inst_link.value_up = net.links[i].value_up;
25 | }
26 | if (utils.has(net.links[i], 'value_dn')) {
27 | inst_link.value_dn = net.links[i].value_dn;
28 | }
29 | if (utils.has(net.links[i], 'info')) {
30 | inst_link.info = net.links[i].info;
31 | }
32 | tnet.links.push(inst_link);
33 | }
34 |
35 | return tnet;
36 | };
37 |
--------------------------------------------------------------------------------
/src/network/update_viz_with_view.js:
--------------------------------------------------------------------------------
1 | var make_network_using_view = require('./make_network_using_view');
2 | var disable_sidebar = require('../sidebar/disable_sidebar');
3 | var update_viz_with_network = require('../update/update_viz_with_network');
4 | var underscore = require('underscore');
5 |
6 | module.exports = function update_viz_with_view(cgm, requested_view) {
7 |
8 | disable_sidebar(cgm.params);
9 |
10 | // make new_network_data by filtering the original network data
11 | var new_network_data = make_network_using_view(cgm.config, cgm.params,
12 | requested_view);
13 |
14 | // reset crop button
15 | d3.select(cgm.params.root+' .crop_button')
16 | .style('color', '#337ab7')
17 | .classed('fa-crop', true)
18 | .classed('fa-undo', false)
19 | .classed('active_cropping', false);
20 |
21 | // reset dendrogram filtering when updating with a new view
22 | // e.g. with the row filter sliders
23 | underscore.each(['row', 'col'], function(inst_rc){
24 |
25 | // set class to reflect that no filtering was ran
26 | d3.select(cgm.params.root+' .'+inst_rc+'_dendro_icons_group')
27 | .classed('ran_filter', false);
28 |
29 | // display all crop buttons when cropping has not been done
30 | d3.select(cgm.params.root+' .'+ inst_rc +'_dendro_icons_container')
31 | .style('display', 'block');
32 | });
33 |
34 | update_viz_with_network(cgm, new_network_data);
35 |
36 | };
37 |
--------------------------------------------------------------------------------
/src/params/calc_cat_params.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function calc_cat_params(params, viz){
4 |
5 | var separtion_room;
6 |
7 | // increase the width of the label container based on the label length
8 | var label_scale = d3.scale.linear()
9 | .domain([5, 15])
10 | .range([ 85, 120]).clamp('true');
11 |
12 | viz.cat_room = {};
13 | viz.cat_room.symbol_width = 12;
14 | viz.cat_room.separation = 3;
15 |
16 | underscore.each(['row','col'], function(inst_rc){
17 |
18 | viz.norm_labels.width[inst_rc] = label_scale(params.labels[inst_rc+'_max_char'])
19 | * params[inst_rc+'_label_scale'];
20 |
21 | viz['num_'+inst_rc+'_nodes'] = params.network_data[inst_rc+'_nodes'].length;
22 |
23 | // if (_.has(config, 'group_level')){
24 | // config.group_level[inst_rc] = 5;
25 | // }
26 |
27 | if(inst_rc === 'row'){
28 | viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width;
29 | } else {
30 | viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width + 3*viz.uni_margin;
31 | }
32 |
33 | var num_cats = viz.all_cats[inst_rc].length;
34 |
35 | if (viz.show_categories[inst_rc]){
36 |
37 | separtion_room = (num_cats-1)*viz.cat_room.separation;
38 |
39 | var adjusted_cats;
40 | if (inst_rc === 'row'){
41 | adjusted_cats = num_cats + 1;
42 | } else {
43 | adjusted_cats = num_cats;
44 | }
45 |
46 | viz.cat_room[inst_rc] = adjusted_cats * viz.cat_room.symbol_width + separtion_room;
47 |
48 | } else {
49 | // no categories
50 | if (inst_rc == 'row'){
51 | viz.cat_room[inst_rc] = viz.cat_room.symbol_width;
52 | } else {
53 | viz.cat_room[inst_rc] = 0;
54 | }
55 | }
56 |
57 | });
58 |
59 | return viz;
60 |
61 | };
--------------------------------------------------------------------------------
/src/params/calc_clust_height.js:
--------------------------------------------------------------------------------
1 | module.exports = function calc_clust_height(viz){
2 |
3 | // the clustergram/matrix height is the svg width minus:
4 | // the margin of the clustergram on the top
5 | // the dendrogram
6 | // the bottom_space
7 | var ini_clust_height = viz.svg_dim.height
8 | - viz.clust.margin.top
9 | - viz.dendro_room.col
10 | - viz.bottom_space;
11 |
12 | viz.clust.dim.height = ini_clust_height;
13 |
14 | return viz;
15 | };
--------------------------------------------------------------------------------
/src/params/calc_clust_width.js:
--------------------------------------------------------------------------------
1 | module.exports = function calc_clust_width(viz){
2 |
3 | viz.clust = {};
4 | viz.clust.margin = {};
5 |
6 | // margin on left/top of the clustergram/matrix
7 | // 1) norm_label margin and width
8 | // 2) cat_room and uni_margin
9 | viz.clust.margin.left = viz.norm_labels.margin.left +
10 | viz.norm_labels.width.row + viz.cat_room.row + viz.uni_margin;
11 |
12 | viz.clust.margin.top = viz.norm_labels.margin.top +
13 | viz.norm_labels.width.col + viz.cat_room.col + viz.uni_margin;
14 |
15 | // the clustergram/matrix width is the svg width minus:
16 | // the margin of the clustergram on the left
17 | // the room for the spillover on the right
18 | // ** the dendro will fit in the spillover room on the right
19 | var ini_clust_width = viz.svg_dim.width
20 | - viz.clust.margin.left
21 | - viz.spillover_col_slant;
22 |
23 | // make tmp scale to calc height of triangle col labels
24 | var tmp_x_scale = d3.scale
25 | .ordinal()
26 | .rangeBands([0, ini_clust_width])
27 | .domain(_.range( viz.num_col_nodes ));
28 |
29 | var triangle_height = tmp_x_scale.rangeBand()/2;
30 |
31 | // prevent the visualization from being unnecessarily wide
32 | if (triangle_height > viz.norm_labels.width.col) {
33 | var reduce_width = viz.norm_labels.width.col / triangle_height;
34 | ini_clust_width = ini_clust_width * reduce_width;
35 | }
36 |
37 | viz.clust.dim = {};
38 | viz.clust.dim.width = ini_clust_width;
39 |
40 | return viz;
41 | };
--------------------------------------------------------------------------------
/src/params/calc_default_fs.js:
--------------------------------------------------------------------------------
1 | module.exports = function calc_default_fs(params){
2 |
3 | params.labels.default_fs_row = params.viz.y_scale.rangeBand() * 1.01;
4 | params.labels.default_fs_col = params.viz.x_scale.rangeBand() * 0.87;
5 |
6 | if ( params.labels.default_fs_row > params.labels.max_allow_fs){
7 | params.labels.default_fs_row = params.labels.max_allow_fs;
8 | }
9 |
10 | if ( params.labels.default_fs_col > params.labels.max_allow_fs){
11 | params.labels.default_fs_col = params.labels.max_allow_fs;
12 | }
13 |
14 | return params;
15 |
16 | };
--------------------------------------------------------------------------------
/src/params/calc_label_params.js:
--------------------------------------------------------------------------------
1 | module.exports = function calc_label_params(viz){
2 |
3 | viz.norm_labels.margin = {};
4 |
5 | viz.norm_labels.margin.left = viz.super_labels.margin.left
6 | + viz.super_labels.dim.width;
7 |
8 | viz.norm_labels.margin.top = viz.super_labels.margin.top
9 | + viz.super_labels.dim.width;
10 |
11 | viz.label_background = {};
12 |
13 | viz.label_background.row = viz.norm_labels.width.row +
14 | viz.cat_room.row + viz.uni_margin;
15 |
16 | viz.label_background.col = viz.norm_labels.width.col +
17 | viz.cat_room.col + viz.uni_margin;
18 |
19 | return viz;
20 | };
--------------------------------------------------------------------------------
/src/params/calc_matrix_params.js:
--------------------------------------------------------------------------------
1 | var ini_matrix_params = require('./ini_matrix_params');
2 | var calc_downsampled_levels = require('../matrix/calc_downsampled_levels');
3 | var underscore = require('underscore');
4 |
5 | module.exports = function calc_matrix_params(params){
6 |
7 | params.matrix = ini_matrix_params(params);
8 |
9 | // X and Y scales: set domains and ranges
10 | //////////////////////////////////////////////
11 | params.viz.x_scale = d3.scale.ordinal()
12 | .rangeBands([0, params.viz.clust.dim.width]);
13 |
14 | params.viz.y_scale = d3.scale.ordinal()
15 | .rangeBands([0, params.viz.clust.dim.height]);
16 |
17 | var inst_order;
18 |
19 | underscore.each(['row','col'], function(inst_rc){
20 |
21 | inst_order = params.viz.inst_order[inst_rc];
22 |
23 | if (inst_order === 'custom'){
24 | inst_order = 'clust';
25 | }
26 |
27 | if (inst_rc === 'row'){
28 | params.viz.x_scale
29 | .domain( params.matrix.orders[ inst_order + '_' + inst_rc ] );
30 | } else{
31 | params.viz.y_scale
32 | .domain( params.matrix.orders[ inst_order + '_' + inst_rc ] );
33 | }
34 |
35 | });
36 |
37 | // border width
38 | params.viz.border_width = {};
39 | params.viz.border_width.x = params.viz.x_scale.rangeBand() /
40 | params.viz.border_fraction;
41 | params.viz.border_width.y = params.viz.y_scale.rangeBand() /
42 | params.viz.border_fraction;
43 |
44 | // rect width needs matrix and zoom parameters
45 | params.viz.rect_width = params.viz.x_scale.rangeBand() -
46 | params.viz.border_width.x;
47 |
48 | // moved calculateion to calc_matrix_params
49 | params.viz.rect_height = params.viz.y_scale.rangeBand() -
50 | params.viz.border_width.y;
51 |
52 | calc_downsampled_levels(params);
53 |
54 | return params;
55 |
56 | };
--------------------------------------------------------------------------------
/src/params/calc_val_max.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function calc_val_max(params){
4 |
5 | var val_max = Math.abs(underscore.max(params.network_data.col_nodes, function (d) {
6 | return Math.abs(d.value);
7 | }).value);
8 |
9 | params.labels.bar_scale_col = d3.scale
10 | .linear()
11 | .domain([0, val_max])
12 | .range([0, 0.75 * params.viz.norm_labels.width.col]);
13 |
14 | val_max = Math.abs(underscore.max(params.network_data.row_nodes, function (d) {
15 | return Math.abs(d.value);
16 | }).value);
17 |
18 | params.labels.bar_scale_row = d3.scale
19 | .linear()
20 | .domain([0, val_max])
21 | .range([0, params.viz.norm_labels.width.row]);
22 |
23 | return params;
24 | };
--------------------------------------------------------------------------------
/src/params/calc_viz_dimensions.js:
--------------------------------------------------------------------------------
1 | module.exports = function calc_viz_dimensions(params){
2 |
3 | var cont_dim = {};
4 | var extra_space = params.buffer_width;
5 |
6 | // var screen_width = window.innerWidth;
7 | // var screen_height = window.innerHeight;
8 |
9 | // // resize container, then resize visualization within container
10 | // d3.select(params.root)
11 | // .style('width', screen_width+'px')
12 | // .style('height', screen_height+'px');
13 |
14 | var container_width = d3.select(params.root).style('width').replace('px','');
15 | var container_height = d3.select(params.root).style('height').replace('px','');
16 |
17 | // get outer_margins
18 | var outer_margins;
19 | if (params.viz.is_expand === false) {
20 | outer_margins = params.viz.outer_margins;
21 | cont_dim.width = container_width - params.sidebar_width - extra_space;
22 | } else {
23 | outer_margins = params.viz.outer_margins;
24 | cont_dim.width = container_width - extra_space;
25 | }
26 |
27 | cont_dim.top = outer_margins.top;
28 | cont_dim.left = outer_margins.left;
29 |
30 | if (params.viz.resize) {
31 |
32 | cont_dim.height = container_height;
33 |
34 | } else {
35 |
36 | if (params.viz.is_expand){
37 | cont_dim.width = params.viz.fixed_size.width;
38 | } else {
39 | cont_dim.width = params.viz.fixed_size.width - params.sidebar_width;
40 | }
41 |
42 | cont_dim.height = params.viz.fixed_size.height;
43 |
44 | }
45 |
46 | return cont_dim;
47 |
48 | };
49 |
--------------------------------------------------------------------------------
/src/params/check_if_value_cats.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function check_if_value_cats(cat_states){
4 |
5 | var tmp_cat = cat_states[0];
6 |
7 | var has_title = false;
8 | var might_have_values = false;
9 | var cat_types = 'cat_strings';
10 | var max_abs_val = NaN;
11 | var all_values = [];
12 | var cat_scale = null;
13 |
14 | var super_string = ': ';
15 |
16 | if (typeof tmp_cat === 'string'){
17 | if ( tmp_cat.indexOf(super_string) > -1 ){
18 | has_title = true;
19 | tmp_cat = tmp_cat.split(super_string)[1];
20 | }
21 | }
22 |
23 | if ( isNaN(tmp_cat) == false ){
24 | might_have_values = true;
25 | }
26 |
27 | // check each value for number
28 | if (might_have_values){
29 |
30 | // the default state is that all are now values, check each one
31 | cat_types = 'cat_values';
32 |
33 | underscore.each(cat_states, function(inst_cat){
34 |
35 | if (has_title){
36 | inst_cat = inst_cat.split(super_string)[1];
37 | }
38 |
39 | // checking whether inst_cat is 'not a number'
40 | if ( isNaN(inst_cat) === true ){
41 | cat_types = 'cat_strings';
42 | } else {
43 | inst_cat = parseFloat(inst_cat);
44 | all_values.push(inst_cat);
45 | }
46 |
47 | });
48 |
49 | }
50 |
51 | if (cat_types === 'cat_values'){
52 |
53 | // get absolute value
54 | var max_value = underscore.max(all_values, function (d) {
55 | return Math.abs(d);
56 | });
57 |
58 | max_abs_val = Math.abs(max_value);
59 |
60 | cat_scale = d3.scale.linear().domain([0, max_abs_val]).range([0,1]);
61 | }
62 |
63 | var inst_info = {};
64 | inst_info.type = cat_types;
65 | inst_info.max_abs_val = max_abs_val;
66 | inst_info.cat_scale = cat_scale;
67 |
68 | return inst_info;
69 |
70 | };
--------------------------------------------------------------------------------
/src/params/get_available_filters.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function get_available_filters(views){
4 |
5 | var possible_filters = {};
6 | var filter_data = {};
7 |
8 | underscore.each(views, function(inst_view){
9 | var inst_keys = underscore.keys(inst_view);
10 |
11 | underscore.each(inst_keys, function(inst_key){
12 |
13 | if (inst_key != 'nodes'){
14 |
15 | if (!_.has(filter_data, inst_key)){
16 | filter_data[inst_key] = [];
17 | }
18 |
19 | filter_data[inst_key].push(inst_view[inst_key]);
20 |
21 | filter_data[inst_key] = underscore.uniq( filter_data[inst_key] );
22 |
23 | }
24 |
25 | });
26 |
27 | });
28 |
29 | var tmp_filters = underscore.keys(filter_data);
30 |
31 | underscore.each( tmp_filters, function(inst_filter){
32 |
33 | var options = filter_data[inst_filter];
34 | var num_options = options.length;
35 |
36 | var filter_type = 'categorical';
37 | underscore.each(options, function(inst_option){
38 | if (typeof inst_option === 'number'){
39 | filter_type = 'numerical';
40 | }
41 | });
42 |
43 | if (num_options > 1){
44 | possible_filters[inst_filter] = filter_type;
45 | }
46 |
47 | });
48 |
49 | var filters = {};
50 | filters.possible_filters = possible_filters;
51 | filters.filter_data = filter_data;
52 |
53 | return filters;
54 |
55 | };
--------------------------------------------------------------------------------
/src/params/get_svg_dim.js:
--------------------------------------------------------------------------------
1 | module.exports = function get_svg_dim(params){
2 |
3 | params.viz.svg_dim = {};
4 | params.viz.svg_dim.width = Number(
5 | d3.select(params.viz.viz_wrapper)
6 | .style('width').replace('px', '')
7 | );
8 |
9 | params.viz.svg_dim.height = Number(
10 | d3.select(params.viz.viz_wrapper)
11 | .style('height').replace('px', '')
12 | );
13 |
14 | return params;
15 | };
--------------------------------------------------------------------------------
/src/params/ini_label_params.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function ini_label_params(params){
4 |
5 | var labels = {};
6 | labels.super_label_scale = params.super_label_scale;
7 | labels.super_labels = params.super_labels;
8 | labels.super_label_fs = 13.8;
9 |
10 | if (labels.super_labels) {
11 | labels.super = {};
12 | labels.super.row = params.super.row;
13 | labels.super.col = params.super.col;
14 | }
15 |
16 | labels.show_label_tooltips = params.show_label_tooltips;
17 |
18 | labels.row_max_char = underscore.max(params.network_data.row_nodes,
19 | function (inst) {
20 | return inst.name.length;
21 | }).name.length;
22 |
23 | labels.col_max_char = underscore.max(params.network_data.col_nodes,
24 | function (inst) {
25 | return inst.name.length;
26 | }).name.length;
27 |
28 | labels.max_allow_fs = params.max_allow_fs;
29 |
30 | return labels;
31 | };
--------------------------------------------------------------------------------
/src/params/ini_sidebar_params.js:
--------------------------------------------------------------------------------
1 | module.exports = function ini_sidebar_params(params){
2 | var sidebar = {};
3 |
4 | sidebar.wrapper = {};
5 | // sidebar.wrapper.width = 170;
6 |
7 | sidebar.row_search = {};
8 | sidebar.row_search.box = {};
9 | sidebar.row_search.box.height = 34;
10 | sidebar.row_search.box.width = 95;
11 | sidebar.row_search.placeholder = params.row_search_placeholder;
12 | sidebar.row_search.margin_left = 7;
13 |
14 | sidebar.slider = {};
15 | sidebar.slider.width = params.sidebar_width - 30;
16 | sidebar.slider.margin_left = 15;
17 |
18 |
19 | sidebar.key_cat = {};
20 | sidebar.key_cat.width = params.sidebar_width - 15;
21 | sidebar.key_cat.margin_left = 5;
22 | sidebar.key_cat.max_height = 100;
23 |
24 | sidebar.title = params.title;
25 | sidebar.title_margin_left = 7;
26 | sidebar.about = params.about;
27 | sidebar.width = params.sidebar_width;
28 |
29 | sidebar.buttons = {};
30 | sidebar.buttons.width = params.sidebar_width - 15;
31 |
32 | sidebar.text = {};
33 |
34 | sidebar.icons = params.sidebar_icons;
35 | sidebar.icon_margin_left = -5;
36 |
37 | return sidebar;
38 | };
--------------------------------------------------------------------------------
/src/params/make_params.js:
--------------------------------------------------------------------------------
1 | var make_network_using_view = require('../network/make_network_using_view');
2 | var ini_sidebar_params = require('./ini_sidebar_params');
3 | var make_requested_view = require('../filters/make_requested_view');
4 | var get_available_filters = require('./get_available_filters');
5 | var calc_viz_params = require('./calc_viz_params');
6 | var ini_zoom_info = require('../zoom/ini_zoom_info');
7 |
8 | /*
9 | Params: calculates the size of all the visualization elements in the
10 | clustergram.
11 | */
12 |
13 | module.exports = function make_params(input_config) {
14 |
15 | var config = $.extend(true, {}, input_config);
16 | var params = config;
17 |
18 | // keep a copy of inst_view
19 | params.inst_nodes = {};
20 | params.inst_nodes.row_nodes = params.network_data.row_nodes;
21 | params.inst_nodes.col_nodes = params.network_data.col_nodes;
22 |
23 | // when pre-loading the visualization using a view
24 | if (params.ini_view !== null) {
25 |
26 | var requested_view = params.ini_view;
27 |
28 | var filters = get_available_filters(params.network_data.views);
29 |
30 | params.viz = {};
31 | params.viz.possible_filters = filters.possible_filters;
32 | params.viz.filter_data = filters.filter_data;
33 |
34 | requested_view = make_requested_view(params, requested_view);
35 | params.network_data = make_network_using_view(config, params, requested_view);
36 |
37 | // save ini_view as requested_view
38 | params.requested_view = requested_view;
39 |
40 | }
41 |
42 | params = calc_viz_params(params);
43 |
44 | if (params.use_sidebar){
45 | params.sidebar = ini_sidebar_params(params);
46 | }
47 |
48 | params.zoom_info = ini_zoom_info();
49 |
50 | return params;
51 | };
52 |
--------------------------------------------------------------------------------
/src/params/set_zoom_params.js:
--------------------------------------------------------------------------------
1 | var calc_zoom_switching = require('../zoom/calc_zoom_switching');
2 |
3 | module.exports = function set_zoom_params(params){
4 |
5 | params.viz.zoom_scale_font = {};
6 | params.viz.zoom_scale_font.row = 1;
7 | params.viz.zoom_scale_font.col = 1;
8 |
9 | var max_zoom_limit = 0.75;
10 | var half_col_height = (params.viz.x_scale.rangeBand() / 2);
11 | params.viz.square_zoom = (params.viz.norm_labels.width.col / half_col_height )*max_zoom_limit;
12 |
13 | params.viz = calc_zoom_switching(params.viz);
14 |
15 | return params;
16 | };
--------------------------------------------------------------------------------
/src/recluster/distance_functions.js:
--------------------------------------------------------------------------------
1 | function vec_dot_product(vecA, vecB) {
2 | var product = 0;
3 | for (var i = 0; i < vecA.length; i++) {
4 | product = product + vecA[i] * vecB[i];
5 | }
6 | return product;
7 | }
8 |
9 | function vec_magnitude(vec) {
10 | var sum = 0;
11 | for (var i = 0; i < vec.length; i++) {
12 | sum = sum + vec[i] * vec[i];
13 | }
14 | return Math.sqrt(sum);
15 | }
16 |
17 | function vec_diff_value(vec, val){
18 | var vec_sub = [];
19 | for (var i = 0; i < vec.length; i++){
20 | vec_sub.push( vec[i] - val );
21 | }
22 | return vec_sub;
23 | }
24 |
25 | function vec_mean(vec){
26 | var sum = 0;
27 | var mean;
28 | for (var i = 0; i < vec.length; i++){
29 | sum = sum + vec[i];
30 | }
31 |
32 | mean = sum / vec.length;
33 |
34 | return mean;
35 | }
36 |
37 | module.exports = {
38 |
39 | 'euclidean': function(v1, v2) {
40 | var total = 0;
41 | for (var i = 0; i < v1.length; i++) {
42 | total = total + Math.pow(v2[i] - v1[i], 2);
43 | }
44 | return Math.sqrt(total);
45 | },
46 | 'cosine': function(vecA, vecB) {
47 |
48 | var cos_sim = vec_dot_product(vecA, vecB) / (vec_magnitude(vecA) * vec_magnitude(vecB));
49 |
50 | var cos_dist = 1 - cos_sim;
51 |
52 | return cos_dist;
53 | },
54 | 'correlation': function(vecA, vecB){
55 |
56 | var vecA_mean = vec_mean(vecA);
57 | var vecB_mean = vec_mean(vecB);
58 |
59 | var vecA_diff_mean = vec_diff_value(vecA, vecA_mean);
60 | var vecB_diff_mean = vec_diff_value(vecB, vecB_mean);
61 |
62 | var cor_sim = vec_dot_product(vecA_diff_mean, vecB_diff_mean) / ( vec_magnitude(vecA_diff_mean) * vec_magnitude(vecB_diff_mean) );
63 | var cor_diff = 1 - cor_sim;
64 |
65 | return cor_diff;
66 | }
67 | };
--------------------------------------------------------------------------------
/src/recluster/get_max_distance_in_dm.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function get_max_tree_distance(dm){
4 |
5 | var max_distance_in_dm = 0;
6 |
7 | underscore.each(dm, function(row){
8 | underscore.each(row, function(inst_val){
9 | if (isFinite(inst_val)){
10 | if (inst_val > max_distance_in_dm){
11 | max_distance_in_dm = inst_val;
12 | }
13 | }
14 | });
15 |
16 | });
17 |
18 | return max_distance_in_dm;
19 |
20 | };
--------------------------------------------------------------------------------
/src/reorder/ini_cat_reorder.js:
--------------------------------------------------------------------------------
1 | var all_reorder = require('./all_reorder');
2 | var underscore = require('underscore');
3 |
4 | module.exports = function ini_cat_reorder(cgm){
5 | /* eslint-disable */
6 |
7 | var params = cgm.params;
8 |
9 | underscore.each(['row','col'], function(inst_rc){
10 |
11 | if (params.viz.show_categories[inst_rc]){
12 | d3.selectAll(params.root+' .'+inst_rc+'_cat_super')
13 | .on('dblclick',function(){
14 |
15 | if (params.sim_mat){
16 | inst_rc = 'both';
17 | }
18 |
19 | d3.selectAll(params.root+' .toggle_'+inst_rc+'_order .btn')
20 | .classed('active',false);
21 |
22 | var order_id = this.__data__.replace('-','_') + '_index';
23 | if (params.viz.sim_mat){
24 | all_reorder( cgm, order_id, 'row');
25 | all_reorder( cgm, order_id, 'col');
26 | }
27 | else {
28 | all_reorder( cgm, order_id, inst_rc);
29 | }
30 | });
31 | }
32 |
33 | });
34 | };
--------------------------------------------------------------------------------
/src/reorder/reposition_tile_highlight.js:
--------------------------------------------------------------------------------
1 | module.exports = function(params) {
2 |
3 | // resize click hlight
4 | var rel_width_hlight = 6;
5 | // var opacity_hlight = 0.85;
6 |
7 | var hlight_width = rel_width_hlight*params.viz.border_width.x;
8 | var hlight_height = rel_width_hlight*params.viz.border_width.y;
9 |
10 | // reposition tile highlight
11 | ////////////////////////////////
12 | // top highlight
13 | d3.select(params.root+' .top_hlight')
14 | .attr('width', params.viz.x_scale.rangeBand())
15 | .attr('height', hlight_height)
16 | .transition().duration(2500)
17 | .attr('transform', function() {
18 | return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',0)';
19 | });
20 |
21 | // left highlight
22 | d3.select(params.root+' .left_hlight')
23 | .attr('width', hlight_width)
24 | .attr('height', params.viz.y_scale.rangeBand() - hlight_height*0.99 )
25 | .transition().duration(2500)
26 | .attr('transform', function() {
27 | return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ','+
28 | hlight_height*0.99+')';
29 | });
30 |
31 | // right highlight
32 | d3.select(params.root+' .right_hlight')
33 | .attr('width', hlight_width)
34 | .attr('height', params.viz.y_scale.rangeBand() - hlight_height*0.99 )
35 | .transition().duration(2500)
36 | .attr('transform', function() {
37 | var tmp_translate = params.viz.x_scale(params.matrix.click_hlight_x) + params.viz.x_scale.rangeBand() - hlight_width;
38 | return 'translate(' + tmp_translate + ','+
39 | hlight_height*0.99+')';
40 | });
41 |
42 | // bottom highlight
43 | d3.select(params.root+' .bottom_hlight')
44 | .attr('width', function(){
45 | return params.viz.x_scale.rangeBand() - 1.98*hlight_width;})
46 | .attr('height', hlight_height)
47 | .transition().duration(2500)
48 | .attr('transform', function() {
49 | var tmp_translate_x = params.viz.x_scale(params.matrix.click_hlight_x) + hlight_width*0.99;
50 | var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
51 | return 'translate(' + tmp_translate_x + ','+
52 | tmp_translate_y+')';
53 | });
54 |
55 | };
56 |
--------------------------------------------------------------------------------
/src/reorder/update_reorder_buttons.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function update_reorder_buttons(tmp_config, params){
4 | underscore.each(['row','col'], function(inst_rc){
5 |
6 | var other_rc;
7 | if (inst_rc === 'row'){
8 | other_rc = 'col';
9 | } else {
10 | other_rc = 'row';
11 | }
12 |
13 | d3.selectAll(params.root+' .toggle_'+other_rc+'_order .btn')
14 | .filter(function(){
15 | return d3.select(this).attr('name') === tmp_config.inst_order[inst_rc];
16 | })
17 | .classed('active',true);
18 |
19 | });
20 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_borders.js:
--------------------------------------------------------------------------------
1 | module.exports = function resize_borders(params, svg_group){
2 |
3 | // left border
4 | svg_group.select('.left_border')
5 | .attr('width', params.viz.grey_border_width)
6 | .attr('height', params.viz.svg_dim.height)
7 | .attr('transform', 'translate(0,0)');
8 |
9 | // right border
10 | svg_group.select('.right_border')
11 | .attr('width', params.viz.grey_border_width)
12 | .attr('height', params.viz.svg_dim.height)
13 | .attr('transform', function() {
14 | var inst_offset = params.viz.svg_dim.width - params.viz.grey_border_width;
15 | return 'translate(' + inst_offset + ',0)';
16 | });
17 |
18 | // top border
19 | svg_group.select('.top_border')
20 | .attr('width', params.viz.svg_dim.width)
21 | .attr('height', params.viz.grey_border_width)
22 | .attr('transform', function() {
23 | var inst_offset = 0;
24 | return 'translate(' + inst_offset + ',0)';
25 | });
26 |
27 | // bottom border
28 | svg_group.select('.bottom_border')
29 | .attr('width', params.viz.svg_dim.width)
30 | .attr('height', params.viz.grey_border_width)
31 | .attr('transform', function() {
32 | var inst_offset = params.viz.svg_dim.height - params.viz.grey_border_width;
33 | return 'translate(0,' + inst_offset + ')';
34 | });
35 |
36 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_col_hlight.js:
--------------------------------------------------------------------------------
1 | var utils = require('../Utils_clust');
2 |
3 | module.exports = function resize_col_hlight(params, svg_group, delay_info=false){
4 |
5 | var delays = {};
6 | // var duration = params.viz.duration;
7 |
8 | if(delay_info === false){
9 | delays.run_transition = false;
10 | } else {
11 | delays = delay_info;
12 | }
13 |
14 | if (utils.has( params.network_data.col_nodes[0], 'value')) {
15 |
16 | svg_group
17 | .selectAll('.col_bars')
18 | .data(params.network_data.col_nodes, function(d){return d.name;})
19 | .attr('width', function(d) {
20 |
21 | var inst_value = 0;
22 |
23 | if (d.value > 0){
24 | inst_value = params.labels.bar_scale_col(d.value);
25 | }
26 | return inst_value;
27 | })
28 | // rotate labels - reduce width if rotating
29 | .attr('height', params.viz.rect_width * 0.66);
30 |
31 | }
32 |
33 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_col_text.js:
--------------------------------------------------------------------------------
1 | var utils = require('../Utils_clust');
2 |
3 | module.exports = function resize_col_text(params, svg_group){
4 | svg_group
5 | .selectAll('.col_label_group')
6 | .select('text')
7 | .style('font-size', params.labels.default_fs_col + 'px')
8 | .text(function(d){ return utils.normal_name(d);});
9 |
10 | svg_group
11 | .selectAll('.col_label_group')
12 | .each(function() {
13 | d3.select(this)
14 | .select('text')[0][0]
15 | .getBBox();
16 | });
17 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_col_triangle.js:
--------------------------------------------------------------------------------
1 | var col_viz_aid_triangle = require('../labels/col_viz_aid_triangle');
2 |
3 | module.exports = function resize_col_triangle(params, ini_svg_group, delay_info=false){
4 |
5 | // resize column triangle
6 | var ini_triangle_group = ini_svg_group
7 | .selectAll('.col_label_group')
8 | .select('path');
9 |
10 | var delays = {};
11 | var duration = params.viz.duration;
12 |
13 | if(delay_info === false){
14 | delays.run_transition = false;
15 | } else {
16 | delays = delay_info;
17 | }
18 |
19 | var triangle_group;
20 | if (delays.run_transition){
21 | triangle_group = ini_triangle_group
22 | .transition().delay(delays.update).duration(duration);
23 | } else {
24 | triangle_group = ini_triangle_group;
25 | }
26 |
27 |
28 | triangle_group
29 | .attr('d', function() {
30 | return col_viz_aid_triangle(params);
31 | })
32 | .attr('fill', '#eee');
33 |
34 |
35 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_containers.js:
--------------------------------------------------------------------------------
1 | module.exports = function resize_containers(params){
2 |
3 | // reposition matrix
4 | d3.select(params.root+' .clust_container')
5 | .attr('transform', 'translate(' +
6 | params.viz.clust.margin.left + ',' +
7 | params.viz.clust.margin.top + ')');
8 |
9 | // reposition col container
10 | d3.select(params.root+' .col_label_outer_container')
11 | .attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')');
12 |
13 | // reposition col_viz container
14 | d3.select(params.root+' .col_cat_outer_container')
15 | .attr('transform', function() {
16 | var inst_offset = params.viz.norm_labels.width.col + 2;
17 | return 'translate(0,' + inst_offset + ')';
18 | });
19 |
20 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_label_bars.js:
--------------------------------------------------------------------------------
1 | var calc_val_max = require('../params/calc_val_max');
2 | // var underscore = require('underscore');
3 |
4 | module.exports = function resize_label_bars(cgm, svg_group){
5 | var params = cgm.params;
6 |
7 | // // set bar scale
8 | // var val_max = Math.abs(underscore.max( params.network_data.row_nodes, function(d) {
9 | // return Math.abs(d.value);
10 | // } ).value) ;
11 |
12 | // params.labels.bar_scale_row = d3.scale
13 | // .linear()
14 | // .domain([0, val_max])
15 | // .range([0, params.viz.norm_labels.width.row ]);
16 |
17 | params = calc_val_max(params);
18 |
19 | svg_group.selectAll('.row_bars')
20 | // .transition().delay(delays.update).duration(duration)
21 | .attr('width', function(d) {
22 | var inst_value = 0;
23 | inst_value = params.labels.bar_scale_row( Math.abs(d.value) );
24 | return inst_value;
25 | })
26 | .attr('x', function(d) {
27 | var inst_value = 0;
28 | inst_value = -params.labels.bar_scale_row( Math.abs(d.value) );
29 | return inst_value;
30 | })
31 | .attr('height', params.viz.y_scale.rangeBand() );
32 |
33 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_row_labels.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function resize_row_labels(params, ini_svg_group, delay_info=false){
4 |
5 | var delays = {};
6 | var duration = params.viz.duration;
7 | var svg_group;
8 |
9 | var row_nodes = params.network_data.row_nodes;
10 | var row_nodes_names = params.network_data.row_nodes_names;
11 |
12 | if(delay_info === false){
13 | delays.run_transition = false;
14 | } else {
15 | delays = delay_info;
16 | }
17 |
18 | if (delays.run_transition){
19 |
20 | ini_svg_group.selectAll('.row_label_group')
21 | // data bind necessary for loss/gain of rows
22 | .data(row_nodes, function(d){return d.name;})
23 | .transition().delay(delays.update).duration(duration)
24 | .attr('transform', function(d) {
25 | var inst_index = underscore.indexOf(row_nodes_names, d.name);
26 | return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
27 | })
28 | .attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row*0.35 );
29 |
30 | svg_group = ini_svg_group
31 | .transition().delay(delays.update).duration(duration);
32 |
33 | } else {
34 |
35 | ini_svg_group.selectAll('.row_label_group')
36 | // data bind necessary for loss/gain of rows
37 | .data(row_nodes, function(d){return d.name;})
38 | .attr('transform', function(d) {
39 | var inst_index = underscore.indexOf(row_nodes_names, d.name);
40 | return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
41 | })
42 | .attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row*0.35 );
43 |
44 | svg_group = ini_svg_group;
45 | }
46 |
47 | svg_group.select(params.root+' .row_container')
48 | .attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' +
49 | params.viz.clust.margin.top + ')');
50 |
51 | svg_group.select(params.root+' .row_container')
52 | .select('.white_bars')
53 | .attr('width', params.viz.label_background.row)
54 | .attr('height', 30*params.viz.clust.dim.height + 'px');
55 |
56 | svg_group.select(params.root + ' .row_container')
57 | .select('.row_label_container')
58 | .attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
59 |
60 | };
61 |
62 |
--------------------------------------------------------------------------------
/src/reset_size/resize_row_viz.js:
--------------------------------------------------------------------------------
1 | module.exports = function resize_row_viz(params, ini_svg_group, delay_info=false){
2 |
3 | var delays = {};
4 | var duration = params.viz.duration;
5 | var svg_group;
6 |
7 | if (delay_info === false){
8 | delays.run_transition = false;
9 | } else {
10 | delays = delay_info;
11 | }
12 |
13 | if (delays.run_transition){
14 | svg_group = ini_svg_group
15 | .transition().delay(delays.update).duration(duration);
16 |
17 | } else {
18 | svg_group = ini_svg_group;
19 | }
20 |
21 | svg_group.select('.row_cat_outer_container')
22 | .attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)')
23 | .select('white_bars')
24 | .attr('width', params.viz.cat_room.row + 'px')
25 | .attr('height', function() {
26 | var inst_height = params.viz.clust.dim.height;
27 | return inst_height;
28 | });
29 |
30 | var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width ;
31 | var y_offset = params.viz.clust.margin.top;
32 | svg_group.select('.row_dendro_outer_container')
33 | .attr('transform','translate('+ x_offset + ','+y_offset+')');
34 |
35 | // !! tmp resize col dendro
36 | x_offset = params.viz.clust.margin.left;
37 | y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;
38 |
39 | svg_group
40 | .select(' .col_dendro_outer_container')
41 | .attr('transform', function() {
42 | return 'translate('+x_offset+',' + y_offset + ')';
43 | });
44 |
45 | };
--------------------------------------------------------------------------------
/src/reset_size/resize_super_labels.js:
--------------------------------------------------------------------------------
1 | module.exports = function resize_super_labels(params, ini_svg_group, delay_info=false){
2 |
3 | var delays = {};
4 | var duration = params.viz.duration;
5 | var svg_group;
6 |
7 | if(delay_info === false){
8 | delays.run_transition = false;
9 | } else {
10 | delays = delay_info;
11 | }
12 |
13 | if (delays.run_transition){
14 | svg_group = ini_svg_group
15 | .transition().delay(delays.update).duration(duration);
16 | } else {
17 | svg_group = ini_svg_group;
18 | }
19 |
20 | svg_group.select('.super_col_bkg')
21 | .attr('height', params.viz.super_labels.dim.width + 'px')
22 | .attr('transform', 'translate('+params.viz.clust.margin.left+',' + params.viz.grey_border_width + ')');
23 |
24 | // super col title
25 | svg_group.select('.super_col')
26 | .attr('transform', function() {
27 | var inst_x = params.viz.clust.dim.width / 2 + params.viz.norm_labels.width
28 | .row;
29 | var inst_y = params.viz.super_labels.dim.width ;
30 | return 'translate(' + inst_x + ',' + inst_y + ')';
31 | });
32 |
33 | svg_group.select('.super_row_bkg')
34 | .attr('width', params.viz.super_labels.dim.width + 'px')
35 | .attr('transform', 'translate(' + params.viz.grey_border_width + ',0)');
36 |
37 | svg_group.select('.super_row')
38 | .attr('transform', function() {
39 | var inst_x = params.viz.super_labels.dim.width;
40 | var inst_y = params.viz.clust.dim.height / 2 + params.viz.norm_labels.width
41 | .col;
42 | return 'translate(' + inst_x + ',' + inst_y + ')';
43 | });
44 |
45 | };
--------------------------------------------------------------------------------
/src/search/run_row_search.js:
--------------------------------------------------------------------------------
1 | var two_translate_zoom = require('../zoom/two_translate_zoom');
2 | var underscore = require('underscore');
3 |
4 | module.exports = function run_row_search(cgm, search_term, entities){
5 |
6 | var prop = 'name';
7 |
8 | if (entities.indexOf(search_term) !== -1) {
9 |
10 | // unhighlight
11 | d3.selectAll(cgm.params.root+' .row_label_group')
12 | .select('rect').style('opacity', 0);
13 |
14 | // calc pan_dy
15 | var idx = underscore.indexOf(entities, search_term);
16 | var inst_y_pos = cgm.params.viz.y_scale(idx);
17 | var pan_dy = cgm.params.viz.clust.dim.height / 2 - inst_y_pos;
18 |
19 | var inst_zoom = cgm.params.viz.zoom_ratio.x;
20 |
21 | // working on improving zoom behavior
22 | ///////////////////////////////////////////////////
23 | ///////////////////////////////////////////////////
24 |
25 | // // increase zoom
26 | // inst_zoom = 3 * inst_zoom;
27 |
28 | // // move visualization down less
29 | // pan_dy = pan_dy - 5;
30 |
31 | two_translate_zoom(cgm, 0, pan_dy, inst_zoom);
32 |
33 | // set y zoom to zoom_switch
34 | cgm.params.zoom_info.zoom_y = inst_zoom;
35 |
36 | // highlight
37 | d3.selectAll(cgm.params.root+' .row_label_group')
38 | .filter(function(d) {
39 | return d[prop] === search_term;
40 | })
41 | .select('rect')
42 | .style('opacity', 1);
43 | }
44 |
45 | };
--------------------------------------------------------------------------------
/src/set_viz_wrapper_size.js:
--------------------------------------------------------------------------------
1 | var calc_viz_dimensions = require('./params/calc_viz_dimensions');
2 |
3 | module.exports = function set_viz_wrapper_size(params) {
4 |
5 | // Create wrapper around SVG visualization
6 | if (d3.select(params.root+' .viz_wrapper').empty()){
7 |
8 | d3.select(params.root)
9 | .append('div')
10 | .classed('sidebar_wrapper', true);
11 |
12 | d3.select(params.root)
13 | .append('div')
14 | .classed('viz_wrapper', true);
15 |
16 | }
17 |
18 | var cont_dim = calc_viz_dimensions(params);
19 |
20 | d3.select(params.root+' .sidebar_wrapper')
21 | .style('float', 'left')
22 | .style('width', params.sidebar_width+'px')
23 | .style('height', cont_dim.height+'px')
24 | .style('overflow','hidden');
25 |
26 | d3.select(params.viz.viz_wrapper)
27 | .style('float', 'left')
28 | .style('width', cont_dim.width + 'px')
29 | .style('height', cont_dim.height + 'px');
30 | };
31 |
--------------------------------------------------------------------------------
/src/sidebar/disable_sidebar.js:
--------------------------------------------------------------------------------
1 | module.exports = function disable_sidebar(params){
2 |
3 | d3.selectAll(params.root+' .btn').attr('disabled',true);
4 | d3.select( params.viz.viz_svg ).style('opacity',0.70);
5 |
6 | };
7 |
--------------------------------------------------------------------------------
/src/sidebar/enable_sidebar.js:
--------------------------------------------------------------------------------
1 | module.exports = function enable_sidebar(params) {
2 |
3 | /* only enable dendrogram sliders if there has been no dendro_filtering */
4 |
5 | // only enable reordering if params.dendro_filter.row === false
6 | if (params.dendro_filter.row === false){
7 |
8 | // orders are switched!
9 | if (params.viz.inst_order.col === 'clust'){
10 | d3.select(params.root+' .row_slider_group')
11 | .style('opacity',1)
12 | .style('pointer-events','all');
13 | }
14 |
15 | }
16 |
17 | d3.selectAll(params.root+' .toggle_row_order .btn')
18 | .attr('disabled',null);
19 |
20 | if (params.dendro_filter.col === false){
21 |
22 | // orders are switched!
23 | if (params.viz.inst_order.row === 'clust'){
24 | d3.select(params.root+' .col_slider_group')
25 | .style('opacity',1)
26 | .style('pointer-events','all');
27 | }
28 |
29 | }
30 |
31 | d3.selectAll(params.root+' .toggle_col_order .btn')
32 | .attr('disabled',null);
33 |
34 | d3.selectAll(params.root+' .gene_search_button .btn')
35 | .attr('disabled',null);
36 |
37 |
38 | params.viz.run_trans = false;
39 |
40 | };
41 |
--------------------------------------------------------------------------------
/src/sidebar/make_modals.js:
--------------------------------------------------------------------------------
1 | var make_modal_skeleton = require('../modal/make_modal_skeleton');
2 |
3 | module.exports = function ini_modals(params){
4 |
5 | // share modal
6 | ///////////////////////////////////////
7 | var share_modal = make_modal_skeleton(params, 'share_info');
8 |
9 | share_modal.header
10 | .append('a')
11 | .attr('target','_blank')
12 | .attr('href', '/clustergrammer/');
13 |
14 | share_modal.header
15 | .append('h4')
16 | .classed('modal-title', true)
17 | .html('Share the visualization using the current URL:');
18 |
19 | share_modal.body
20 | .append('input')
21 | .classed('bootstrap_highlight', true)
22 | .classed('share_url', true);
23 |
24 | // picture modal
25 | ///////////////////////////////////////
26 | var screenshot_modal = make_modal_skeleton(params, 'picture_info');
27 |
28 | screenshot_modal.header
29 | .append('h4')
30 | .classed('modal-title', true)
31 | .html('Save a snapshot of the visualization');
32 |
33 | screenshot_modal.body
34 | .append('div')
35 | .classed('download_buttons', true);
36 |
37 | // dendro modal
38 | ///////////////////////////////////////
39 | var dendro_modal = make_modal_skeleton(params, 'dendro_info');
40 |
41 | dendro_modal.header
42 | .append('h4')
43 | .classed('modal-title', true)
44 | .html('Cluster Information');
45 |
46 | dendro_modal.body
47 | .append('g')
48 | .classed('cluster_info_container', true);
49 |
50 | dendro_modal.body
51 | .append('div')
52 | .classed('dendro_text', true)
53 | .append('input')
54 | .classed('bootstrap_highlight', true)
55 | .classed('current_names', true)
56 | .style('width', '100%');
57 |
58 | };
--------------------------------------------------------------------------------
/src/sidebar/set_sidebar_ini_view.js:
--------------------------------------------------------------------------------
1 | var make_filter_title = require('../filters/make_filter_title');
2 | var underscore = require('underscore');
3 |
4 | module.exports = function set_sidebar_ini_view(params){
5 |
6 | underscore.each( underscore.keys(params.ini_view), function(inst_filter){
7 |
8 | // initialize filter slider using ini_view
9 | var inst_value = params.ini_view[inst_filter];
10 |
11 | var filter_type = params.viz.possible_filters[inst_filter];
12 |
13 | if (filter_type === 'numerical'){
14 |
15 | if (inst_value != 'all'){
16 | inst_value = parseInt(inst_value,10);
17 | }
18 |
19 | if (params.viz.filter_data[inst_filter].indexOf(inst_value) <= -1){
20 | inst_value = 'all';
21 | }
22 |
23 | var filter_title = make_filter_title(params, inst_filter);
24 |
25 | d3.select(params.root+' .title_'+inst_filter)
26 | .text(filter_title.text + inst_value + filter_title.suffix);
27 |
28 | d3.select(params.root+' .slider_'+inst_filter)
29 | .attr('current_state', inst_value);
30 |
31 | } else {
32 |
33 | // set up button initialization
34 |
35 | }
36 |
37 | });
38 |
39 | };
40 |
--------------------------------------------------------------------------------
/src/sidebar/set_up_opacity_slider.js:
--------------------------------------------------------------------------------
1 | module.exports = function set_up_opacity_slider(sidebar){
2 |
3 | var slider_container = sidebar
4 | .append('div')
5 | .classed('opacity_slider_container', true)
6 | .style('margin-top', '5px')
7 | .style('padding-left', '10px')
8 | .style('padding-right', '10px');
9 |
10 | slider_container
11 | .append('div')
12 | .classed('sidebar_text', true)
13 | .classed('opacity_slider_text', true)
14 | .style('margin-bottom', '3px')
15 | .text('Opacity Slider');
16 |
17 | slider_container
18 | .append('div')
19 | .classed('slider', true)
20 | .classed('opacity_slider', true);
21 |
22 | };
23 |
--------------------------------------------------------------------------------
/src/sidebar/set_up_search.js:
--------------------------------------------------------------------------------
1 | module.exports = function set_up_search(sidebar, params ){
2 |
3 | var search_container = sidebar
4 | .append('div')
5 | // .classed('row',true)
6 | .classed('gene_search_container',true)
7 | .style('padding-left','10px')
8 | .style('padding-right','10px')
9 | .style('margin-top','10px');
10 |
11 | search_container
12 | .append('input')
13 | .classed('form-control',true)
14 | .classed('gene_search_box',true)
15 | .classed('sidebar_text', true)
16 | .attr('type','text')
17 | .attr('placeholder', params.sidebar.row_search.placeholder)
18 | .style('height', params.sidebar.row_search.box.height+'px')
19 | .style('margin-top', '10px');
20 |
21 | search_container
22 | .append('div')
23 | .classed('gene_search_button',true)
24 | .style('margin-top', '5px')
25 | .attr('data-toggle','buttons')
26 | .append('button')
27 | .classed('sidebar_text', true)
28 | .html('Search')
29 | .attr('type','button')
30 | .classed('btn',true)
31 | .classed('btn-primary',true)
32 | .classed('submit_gene_button',true)
33 | .style('width', '100%')
34 | .style('font-size', '14px');
35 |
36 | };
37 |
--------------------------------------------------------------------------------
/src/spillover/make_row_dendro_spillover.js:
--------------------------------------------------------------------------------
1 | var make_dendro_crop_buttons = require('../dendrogram/make_dendro_crop_buttons');
2 |
3 | module.exports = function make_row_dendro_spillover(cgm){
4 |
5 | var viz = cgm.params.viz;
6 |
7 | // hide spillover from right
8 | var tmp_left = viz.clust.margin.left +
9 | viz.clust.dim.width +
10 | viz.uni_margin +
11 | viz.dendro_room.row;
12 |
13 | var r_spill_container = d3.select(viz.viz_svg)
14 | .append('g')
15 | .classed('right_spillover_container', true)
16 | .attr('transform', function() {
17 | return 'translate(' + tmp_left + ', 0)';
18 | });
19 |
20 | var tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col;
21 |
22 | r_spill_container
23 | .append('rect')
24 | .attr('fill', viz.background_color) //!! prog_colors
25 | .attr('width', 10*viz.clust.dim.width)
26 | .attr('height', viz.svg_dim.height+'px')
27 | .attr('class', 'white_bars')
28 | .attr('class','right_spillover')
29 | .attr('transform', function() {
30 | return 'translate( 0,' + tmp_top + ')';
31 | });
32 |
33 | var x_offset = 0;
34 | var y_offset = viz.clust.margin.top;
35 | r_spill_container
36 | .append('g')
37 | .classed('row_dendro_icons_container', true)
38 | .attr('transform', 'translate(' + x_offset + ','+ y_offset +')')
39 | .append('g')
40 | .classed('row_dendro_icons_group', true);
41 |
42 | make_dendro_crop_buttons(cgm, 'row');
43 |
44 | // hide spillover from top of row dendrogram
45 | x_offset = viz.clust.margin.left + viz.clust.dim.width;
46 | y_offset = tmp_top;
47 |
48 | var tmp_width = viz.dendro_room.row + viz.uni_margin;
49 | var tmp_height = viz.cat_room.col + viz.uni_margin;
50 | d3.select(viz.viz_svg)
51 | .append('rect')
52 | .attr('fill', viz.background_color)
53 | .attr('width',tmp_width)
54 | .attr('height',tmp_height)
55 | .attr('transform', function(){
56 | return 'translate('+x_offset+','+y_offset+')';
57 | })
58 | .classed('white_bars',true)
59 | .classed('dendro_row_spillover',true);
60 |
61 | };
--------------------------------------------------------------------------------
/src/update/remove_node_cats.js:
--------------------------------------------------------------------------------
1 | var underscore = require('underscore');
2 |
3 | module.exports = function remove_node_cats(inst_node){
4 |
5 | var all_props = underscore.keys(inst_node);
6 |
7 | underscore.each(all_props, function(inst_prop){
8 |
9 | if (inst_prop.indexOf('cat-') > -1){
10 | delete inst_node[inst_prop];
11 | }
12 |
13 | if (inst_prop.indexOf('cat_') > -1){
14 | delete inst_node[inst_prop];
15 | }
16 |
17 | });
18 |
19 | };
--------------------------------------------------------------------------------
/src/update/reset_cats.js:
--------------------------------------------------------------------------------
1 | var make_row_cat = require('../categories/make_row_cat');
2 | var calc_viz_params = require('../params/calc_viz_params');
3 | var resize_viz = require('../reset_size/resize_viz');
4 | var modify_row_node_cats = require('./modify_row_node_cats');
5 | var generate_cat_data = require('./generate_cat_data');
6 |
7 | module.exports = function reset_cats(run_resize_viz = true){
8 |
9 | // console.log('RESET CATS')
10 |
11 | var cgm = this;
12 |
13 | var cat_data = generate_cat_data(cgm);
14 |
15 | // do not change column category info
16 | var col_cat_colors = cgm.params.viz.cat_colors.col;
17 |
18 | modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes);
19 | // modify the current inst copy of nodes
20 | modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes);
21 |
22 | cgm.params.new_row_cats = cat_data;
23 | cgm.params.viz.cat_colors.col = col_cat_colors;
24 |
25 | if (run_resize_viz){
26 |
27 | // resize visualizatino
28 | ////////////////////////////
29 | // recalculate the visualization parameters using the updated network_data
30 | var predefine_cat_colors = true;
31 | cgm.params = calc_viz_params(cgm.params, predefine_cat_colors);
32 |
33 | make_row_cat(cgm, true);
34 | resize_viz(cgm);
35 |
36 | }
37 |
38 | };
--------------------------------------------------------------------------------
/src/update/update_cats.js:
--------------------------------------------------------------------------------
1 | var make_row_cat = require('../categories/make_row_cat');
2 | var calc_viz_params = require('../params/calc_viz_params');
3 | var resize_viz = require('../reset_size/resize_viz');
4 | var modify_row_node_cats = require('./modify_row_node_cats');
5 |
6 | module.exports = function update_cats(cgm, cat_data){
7 |
8 | // Only accessible from the cgm API, cat_data is provided by externally
9 | ///////////////////////////////////////////////////////////////////////////
10 |
11 | if (cgm.params.cat_update_callback != null){
12 | cgm.params.cat_update_callback(this);
13 | }
14 |
15 | // do not change column category info
16 | var col_cat_colors = cgm.params.viz.cat_colors.col;
17 |
18 | modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes, true);
19 | // modify the current inst copy of nodes
20 | modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes, true);
21 |
22 | // recalculate the visualization parameters using the updated network_data
23 | cgm.params = calc_viz_params(cgm.params, false);
24 |
25 | make_row_cat(cgm, true);
26 | resize_viz(cgm);
27 |
28 | cgm.params.new_row_cats = cat_data;
29 |
30 | cgm.params.viz.cat_colors.col = col_cat_colors;
31 |
32 | };
--------------------------------------------------------------------------------
/src/update/update_view.js:
--------------------------------------------------------------------------------
1 | var update_viz_with_view = require('../network/update_viz_with_view');
2 | var reset_other_filter_sliders = require('../filters/reset_other_filter_sliders');
3 |
4 | module.exports = function update_view(cgm, filter_type, inst_state){
5 |
6 | // add something to control slider position
7 | /////////////////////////////////////////////
8 |
9 | var requested_view = {};
10 | requested_view[filter_type] = inst_state;
11 | update_viz_with_view(cgm, requested_view);
12 |
13 | reset_other_filter_sliders(cgm, filter_type, inst_state);
14 | };
--------------------------------------------------------------------------------
/src/zoom/calc_real_font_size.js:
--------------------------------------------------------------------------------
1 | module.exports = function calc_real_font_size(params){
2 |
3 | var real_font_size = {};
4 | // zoom_switch behavior has to change with zoom_ratio.y
5 | if (params.viz.zoom_ratio.x > 1){
6 | real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale();
7 | real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale();
8 | } else {
9 | real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale()/params.viz.zoom_ratio.y;
10 | real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale();
11 | }
12 |
13 | return real_font_size;
14 |
15 | };
--------------------------------------------------------------------------------
/src/zoom/calc_zoom_switching.js:
--------------------------------------------------------------------------------
1 | module.exports = function calc_zoom_switching(viz){
2 |
3 | var width_by_col = viz.clust.dim.width / viz.num_col_nodes;
4 | var height_by_row = viz.clust.dim.height / viz.num_row_nodes;
5 |
6 | viz.zoom_ratio = {};
7 | viz.zoom_ratio.x = width_by_col / height_by_row;
8 | viz.zoom_ratio.y = 1;
9 |
10 | if (viz.zoom_ratio.x < 1) {
11 | viz.zoom_ratio.y = 1/viz.zoom_ratio.x;
12 | viz.zoom_ratio.x = 1;
13 | }
14 |
15 | return viz;
16 | };
--------------------------------------------------------------------------------
/src/zoom/check_zoom_stop_status.js:
--------------------------------------------------------------------------------
1 | module.exports = function check_zoom_stop_status(params){
2 |
3 | var inst_zoom = Number(d3.select(params.root+' .viz_svg').attr('is_zoom'));
4 |
5 | var check_stop = Number(d3.select(params.root+' .viz_svg')
6 | .attr('stopped_zoom'));
7 |
8 | var stop_attributes = false;
9 | if (inst_zoom === 0 && check_stop != 0){
10 | stop_attributes = true;
11 | }
12 |
13 | return stop_attributes;
14 | };
--------------------------------------------------------------------------------
/src/zoom/find_viz_rows.js:
--------------------------------------------------------------------------------
1 | module.exports = function find_viz_rows(params, viz_area){
2 |
3 | var should_be_rows = [];
4 | var curr_rows = [];
5 |
6 | // find rows that should be visible
7 | var y_trans;
8 |
9 | // default y_scale (no downsampling)
10 | var y_scale = params.viz.y_scale;
11 | var ds_level = params.viz.ds_level;
12 | var row_names = params.network_data.row_nodes_names;
13 | var row_class = '.row';
14 |
15 | // if downsampling redefine variables
16 | if (ds_level >=0){
17 | y_scale = params.viz.ds[ds_level].y_scale;
18 | row_names = d3.range(params.matrix.ds_matrix[ds_level].length).map(String);
19 | row_class = '.ds'+String(ds_level)+'_row';
20 | }
21 |
22 | // find rows that should be visible
23 | for (var i=0; i < row_names.length; i++){
24 | y_trans = y_scale(i);
25 | if (y_trans < viz_area.max_y && y_trans > viz_area.min_y){
26 | should_be_rows.push(row_names[i]);
27 | }
28 | }
29 |
30 | // find currently visible rows
31 | d3.selectAll(params.root+' '+row_class)
32 | .each(function(d){
33 | curr_rows.push(d.name);
34 | });
35 |
36 | // nodes that should be visible
37 | params.viz.viz_nodes.row = should_be_rows;
38 | // nodes that are visible
39 | params.viz.viz_nodes.curr_row = curr_rows;
40 |
41 | };
--------------------------------------------------------------------------------
/src/zoom/get_previous_zoom.js:
--------------------------------------------------------------------------------
1 | module.exports = function get_previous_zoom(params){
2 | var prev_zoom = {};
3 |
4 | var inst_trans = d3.select(params.root+' .clust_group')
5 | .attr('transform');
6 |
7 | if (inst_trans != null){
8 |
9 | // prevent from crashing if no scaling was done
10 | if (inst_trans.indexOf('scale') > 0){
11 | prev_zoom.zoom_x = parseFloat(inst_trans.split('scale')[1].replace('(','')
12 | .replace(')','').split(',')[0]);
13 |
14 | prev_zoom.zoom_y = parseFloat(inst_trans.split('scale')[1].replace('(','')
15 | .replace(')','').split(',')[1]);
16 | } else {
17 | prev_zoom.zoom_x = 1;
18 | prev_zoom.zoom_y = 1;
19 | }
20 |
21 | } else {
22 | prev_zoom.zoom_x = 1;
23 | prev_zoom.zoom_y = 1;
24 | }
25 |
26 | return prev_zoom;
27 |
28 | };
--------------------------------------------------------------------------------
/src/zoom/ini_doubleclick.js:
--------------------------------------------------------------------------------
1 | var two_translate_zoom = require('./two_translate_zoom');
2 |
3 | module.exports = function ini_doubleclick(cgm) {
4 |
5 | var params = cgm.params;
6 | // disable double-click zoom
7 | d3.selectAll(params.viz.zoom_element)
8 | .on('dblclick.zoom', null);
9 |
10 | d3.select(params.viz.zoom_element)
11 | .on('dblclick', function() {
12 | two_translate_zoom(cgm, 0, 0, 1);
13 | });
14 | };
15 |
--------------------------------------------------------------------------------
/src/zoom/ini_zoom_info.js:
--------------------------------------------------------------------------------
1 | module.exports = function ini_zoom_info(){
2 |
3 | var zoom_info = {};
4 | zoom_info.zoom_x = 1;
5 | zoom_info.zoom_y = 1;
6 | zoom_info.trans_x = 0;
7 | zoom_info.trans_y = 0;
8 |
9 | return zoom_info;
10 |
11 | };
--------------------------------------------------------------------------------
/src/zoom/num_visible_labels.js:
--------------------------------------------------------------------------------
1 | module.exports = function num_visible_labels(params, inst_rc){
2 |
3 | // counting the number of visible labels, probably not necessary
4 |
5 | var num_visible;
6 | if (inst_rc === 'row'){
7 |
8 | // initialize at high number
9 | num_visible = 10000;
10 |
11 | // only count visible rows if no downsampling
12 | if (params.viz.ds_level === -1){
13 | num_visible = d3.selectAll(params.root+' .row')[0].length;
14 | }
15 |
16 | } else if (inst_rc === 'col') {
17 |
18 | num_visible = d3.selectAll(params.root+' .'+inst_rc+'_label_text')
19 | .filter(function(){
20 | return d3.select(this).style('display')!='none';
21 | })[0].length;
22 |
23 | }
24 |
25 | return num_visible;
26 | };
--------------------------------------------------------------------------------
/src/zoom/reset_zoom.js:
--------------------------------------------------------------------------------
1 | module.exports = function(params){
2 |
3 | // reset zoom
4 | //////////////////////////////
5 | var zoom_y = 1;
6 | // var zoom_x = 1;
7 | var pan_dx = 0;
8 | var pan_dy = 0;
9 |
10 | var half_height = params.viz.clust.dim.height / 2;
11 | var center_y = -(zoom_y - 1) * half_height;
12 |
13 | d3.select(params.root + ' .clust_group')
14 | .attr('transform', 'translate(' + [0, 0 + center_y] + ')' +
15 | ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [pan_dx,pan_dy] + ')');
16 |
17 | d3.select(params.root+' .row_label_zoom_container')
18 | .attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' +
19 | zoom_y + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');
20 |
21 | d3.select(params.root+' .row_cat_container')
22 | .attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' +
23 | 1 + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');
24 |
25 | d3.select(params.root+' .row_dendro_container')
26 | .attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' +
27 | zoom_y + ',' + zoom_y + ')' + 'translate(' + [params.viz.uni_margin/2, pan_dy] + ')');
28 |
29 | d3.select(params.root+' .col_zoom_container')
30 | .attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');
31 |
32 | d3.select(params.root+' .col_cat_container')
33 | .attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');
34 |
35 | d3.select(params.root+' .col_dendro_container')
36 | .attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, params.viz.uni_margin/2] + ')');
37 |
38 | // reset crop button zooming
39 | d3.select(params.root+' .row_dendro_icons_group')
40 | .attr('transform', function(){
41 | return 'translate(0,0) scale(1)';
42 | });
43 |
44 | d3.select(params.root+' .row_dendro_icons_group')
45 | .selectAll('path')
46 | .attr('transform', function(d){
47 | var inst_x = 7;
48 | var inst_y = d.pos_mid;
49 | return 'translate('+ inst_x +',' + inst_y + ') ' + 'scale(1, 1)';
50 | });
51 |
52 | };
--------------------------------------------------------------------------------
/src/zoom/resize_label_val_bars.js:
--------------------------------------------------------------------------------
1 | var utils = require('../Utils_clust');
2 |
3 | module.exports = function resize_label_val_bars(params){
4 |
5 | var zoom_info = params.zoom_info;
6 |
7 | // resize label bars if necessary
8 | if (utils.has(params.network_data.row_nodes[0], 'value')) {
9 | d3.selectAll(params.root+' .row_bars')
10 | .attr('width', function(d) {
11 | var inst_value = 0;
12 | inst_value = params.labels.bar_scale_row(Math.abs(d.value))/zoom_info.zoom_y;
13 | return inst_value;
14 | })
15 | .attr('x', function(d) {
16 | var inst_value = 0;
17 | inst_value = -params.labels.bar_scale_row(Math.abs(d.value))/zoom_info.zoom_y;
18 | return inst_value;
19 | });
20 | }
21 |
22 | if (utils.has(params.network_data.col_nodes[0], 'value')) {
23 | d3.selectAll(params.root+' .col_bars')
24 | .attr('width', function(d) {
25 | var inst_value = 0;
26 | if (d.value > 0){
27 | inst_value = params.labels.bar_scale_col(d.value)/zoom_info.zoom_x;
28 | }
29 | return inst_value;
30 | });
31 | }
32 |
33 | };
--------------------------------------------------------------------------------
/src/zoom/run_zoom.js:
--------------------------------------------------------------------------------
1 | var run_transformation = require('./run_transformation');
2 | var zoom_rules_y = require('./zoom_rules_y');
3 | var zoom_rules_x = require('./zoom_rules_x');
4 |
5 | module.exports = function zoomed(cgm) {
6 |
7 | var params = cgm.params;
8 |
9 | var zoom_info = {};
10 | zoom_info.zoom_x = d3.event.scale;
11 | zoom_info.zoom_y = d3.event.scale;
12 |
13 | // subtract away the margin to easily calculate pan_room etc.
14 | zoom_info.trans_x = params.zoom_behavior.translate()[0] - params.viz.clust.margin.left;
15 | zoom_info.trans_y = params.zoom_behavior.translate()[1] - params.viz.clust.margin.top;
16 |
17 | d3.selectAll(params.viz.root_tips)
18 | .style('display','none');
19 |
20 | // transfer zoom_info to params
21 | params.zoom_info = zoom_rules_y(params, zoom_info);
22 | params.zoom_info = zoom_rules_x(params, zoom_info);
23 |
24 | // do not run transformation if moving slider
25 | if (params.is_slider_drag === false && params.is_cropping === false){
26 |
27 | // reset translate vector - add back margins to trans_x and trans_y
28 | var new_x = params.zoom_info.trans_x + params.viz.clust.margin.left;
29 | var new_y = params.zoom_info.trans_y + params.viz.clust.margin.top;
30 |
31 | params.zoom_behavior.translate([new_x, new_y]);
32 | cgm.params = params;
33 |
34 | run_transformation(cgm);
35 |
36 | }
37 |
38 | };
39 |
--------------------------------------------------------------------------------
/src/zoom/zoom_crop_triangles.js:
--------------------------------------------------------------------------------
1 | module.exports = function zoom_crop_triangles(params, zoom_info, inst_rc){
2 |
3 | if (inst_rc === 'row'){
4 |
5 | // transform icons (undo zoom on triangles)
6 | d3.select(params.root+' .row_dendro_icons_group')
7 | .selectAll('path')
8 | .attr('transform', function(d){
9 | var inst_x = params.viz.uni_margin;
10 | var inst_y = d.pos_mid;
11 | var curr_zoom = zoom_info.zoom_y;
12 | var tri_dim = d3.select(this).data()[0].tri_dim;
13 | var inst_zoom = constrain_zoom(curr_zoom, tri_dim);
14 | return 'translate('+ inst_x +',' + inst_y + ') ' + 'scale(1, '+ 1/inst_zoom +')';
15 | });
16 |
17 | } else {
18 |
19 | // transform icons (undo zoom on triangles)
20 | d3.select(params.root+' .col_dendro_icons_group')
21 | .selectAll('path')
22 | .attr('transform', function(d){
23 | var inst_x = d.pos_mid;
24 | var inst_y = params.viz.uni_margin;
25 | var curr_zoom = zoom_info.zoom_x;
26 | var tri_dim = d3.select(this).data()[0].tri_dim;
27 | var inst_zoom = constrain_zoom(curr_zoom, tri_dim);
28 | return 'translate('+ inst_x +',' + inst_y + ') ' + 'scale('+ 1/inst_zoom +', 1)';
29 | });
30 |
31 | }
32 |
33 | function constrain_zoom(curr_zoom, tri_height){
34 | var inst_zoom;
35 | var default_tri_height = 10;
36 | if (tri_height * curr_zoom < default_tri_height){
37 | inst_zoom = 1;
38 | } else {
39 | var max_zoom = default_tri_height/tri_height;
40 | inst_zoom = curr_zoom/max_zoom;
41 | }
42 | return inst_zoom;
43 | }
44 |
45 | };
--------------------------------------------------------------------------------
/src/zoom/zoom_rules_x.js:
--------------------------------------------------------------------------------
1 | module.exports = function zoom_rules_x(params, zoom_info){
2 |
3 | var viz = params.viz;
4 |
5 | // zoom in the y direction before zooming in the x direction
6 | if (viz.zoom_ratio.x > 1){
7 |
8 | if (zoom_info.zoom_x < viz.zoom_ratio.x) {
9 |
10 | // remove this
11 | // zoom_info.trans_x = - params.viz.clust.margin.left;
12 |
13 | zoom_info.zoom_x = 1;
14 | } else {
15 | zoom_info.zoom_x = zoom_info.zoom_x / viz.zoom_ratio.x;
16 |
17 | // console.log('********* zoom_x: ' + String(zoom_info.zoom_x))
18 |
19 | // zoom_info.trans_x = zoom_info.trans_x + params.viz.x_offset;
20 | // zoom_info.trans_x = zoom_info.trans_x * (params.zoom_info.zoom_x/params.zoom_info.zoom_y);
21 | }
22 | }
23 |
24 | // calculate panning room available in the x direction
25 | zoom_info.pan_room_x = (zoom_info.zoom_x - 1) * viz.clust.dim.width;
26 |
27 | // console.log( 'pan_room_x: ' + String(zoom_info.pan_room_x) + ' trans_x: ' + String(-zoom_info.trans_x))
28 |
29 | // no positive panning or panning more than pan_room
30 | if (zoom_info.trans_x > 0) {
31 | zoom_info.trans_x = 0;
32 | // console.log('no positive panning\n\n')
33 | }
34 | else if (zoom_info.trans_x <= -zoom_info.pan_room_x) {
35 | zoom_info.trans_x = -zoom_info.pan_room_x;
36 | // console.log('******* restrict pan room\n\n')
37 | }
38 |
39 |
40 | return zoom_info;
41 | };
--------------------------------------------------------------------------------
/src/zoom/zoom_rules_y.js:
--------------------------------------------------------------------------------
1 | module.exports = function zoom_rules_y(params, zoom_info){
2 |
3 | var viz = params.viz;
4 | // zoom in the x direction before zooming in the y direction
5 | if (viz.zoom_ratio.y > 1){
6 | if (zoom_info.zoom_y < viz.zoom_ratio.y){
7 | zoom_info.trans_y = 0;
8 | zoom_info.zoom_y = 1;
9 | } else {
10 | zoom_info.zoom_y = zoom_info.zoom_y / viz.zoom_ratio.y;
11 | }
12 | }
13 |
14 | // calculate panning room available in the y direction
15 | zoom_info.pan_room_y = (zoom_info.zoom_y - 1) * viz.clust.dim.height;
16 |
17 | // console.log( 'pan_room_y: ' + String(zoom_info.pan_room_y) + ' ' + String(-zoom_info.trans_y))
18 |
19 | // no positive panning or panning more than pan_room
20 | if (zoom_info.trans_y >= 0) {
21 | zoom_info.trans_y = 0;
22 | // console.log('y no positive panning\n\n')
23 | }
24 | else if (zoom_info.trans_y <= -zoom_info.pan_room_y) {
25 | zoom_info.trans_y = -zoom_info.pan_room_y;
26 | // console.log('y restrict pan room \n\n')
27 | }
28 |
29 | return zoom_info;
30 | };
--------------------------------------------------------------------------------
/txt/missing_values.txt:
--------------------------------------------------------------------------------
1 | c1 c2 c3
2 | r1 7 NaN 6
3 | r2 NaN 4 3
4 | r3 4 5 9
5 | r4 22 3 2
--------------------------------------------------------------------------------
/txt/number_labels.txt:
--------------------------------------------------------------------------------
1 | 1 2 3
2 | 1 -3 3
3 | 1 -7 1 2 3
4 | 2 2 10 11 12
5 | 3 -1 7 -12 9
6 | 4 7 4 -1 6
--------------------------------------------------------------------------------
/txt/rc_val_cats.txt:
--------------------------------------------------------------------------------
1 | col-A col-B col-C
2 | 1 -3 3
3 | row-A -7 1 2 3
4 | row-B 2 10 11 12
5 | row-C -1 7 -12 9
6 | row-D 7 4 -1 6
--------------------------------------------------------------------------------
/txt/tuple_cats.txt:
--------------------------------------------------------------------------------
1 | ('Cell Line: A549', 'Male') ('Cell Line: H1299', 'Female') ('Cell Line: H661', 'Female')
2 | ('Gene: EGFR','Type: 11') -3.234 5.03 0.001
3 | ('Gene: TP53','Type: 0.5') 8.3 4.098 -12.2
4 | ('Gene: IRAK','Type: 99') 7.23 3.01 0.88
--------------------------------------------------------------------------------