From c34b7f6db08df653bc8ea6423597ddfbfdb9c0e4 Mon Sep 17 00:00:00 2001 From: Daniel Ji Date: Wed, 9 Oct 2024 12:18:36 -0700 Subject: [PATCH] fix jsdoc doxygen workflow and update jsdoc --- .../{worflows => workflows}/doxygen-pdf.yml | 0 docs/HIVTxNetwork.html | 7285 +++-- docs/classes.list.html | 5566 ---- docs/clusternetwork.js.html | 7758 ++++++ docs/clustersOfInterest.js.html | 1984 ++ docs/colorPicker.js.html | 109 + docs/column_definitions.js.html | 382 + docs/fonts/OpenSans-Bold-webfont.eot | Bin 0 -> 19544 bytes docs/fonts/OpenSans-Bold-webfont.svg | 1830 ++ docs/fonts/OpenSans-Bold-webfont.woff | Bin 0 -> 22432 bytes docs/fonts/OpenSans-BoldItalic-webfont.eot | Bin 0 -> 20133 bytes docs/fonts/OpenSans-BoldItalic-webfont.svg | 1830 ++ docs/fonts/OpenSans-BoldItalic-webfont.woff | Bin 0 -> 23048 bytes docs/fonts/OpenSans-Italic-webfont.eot | Bin 0 -> 20265 bytes docs/fonts/OpenSans-Italic-webfont.svg | 1830 ++ docs/fonts/OpenSans-Italic-webfont.woff | Bin 0 -> 23188 bytes docs/fonts/OpenSans-Light-webfont.eot | Bin 0 -> 19514 bytes docs/fonts/OpenSans-Light-webfont.svg | 1831 ++ docs/fonts/OpenSans-Light-webfont.woff | Bin 0 -> 22248 bytes docs/fonts/OpenSans-LightItalic-webfont.eot | Bin 0 -> 20535 bytes docs/fonts/OpenSans-LightItalic-webfont.svg | 1835 ++ docs/fonts/OpenSans-LightItalic-webfont.woff | Bin 0 -> 23400 bytes docs/fonts/OpenSans-Regular-webfont.eot | Bin 0 -> 19836 bytes docs/fonts/OpenSans-Regular-webfont.svg | 1831 ++ docs/fonts/OpenSans-Regular-webfont.woff | Bin 0 -> 22660 bytes docs/fonts/glyphicons-halflings-regular.eot | Bin 20127 -> 0 bytes docs/fonts/glyphicons-halflings-regular.svg | 288 - docs/fonts/glyphicons-halflings-regular.ttf | Bin 45404 -> 0 bytes docs/fonts/glyphicons-halflings-regular.woff | Bin 23424 -> 0 bytes docs/fonts/glyphicons-halflings-regular.woff2 | Bin 18028 -> 0 bytes docs/global.html | 18859 +++++++++---- docs/globals.js.html | 605 + docs/helpers.js.html | 563 + docs/histogram.js.html | 348 + docs/hiv_tx_network.js.html | 2121 ++ docs/hivtraceClusterGraphSummary.js.html | 194 + docs/hivtrace_generate_svg_polygon.html | 994 +- docs/img/glyphicons-halflings-white.png | Bin 8777 -> 0 bytes docs/img/glyphicons-halflings.png | Bin 12799 -> 0 bytes docs/index.html | 638 +- docs/misc.js.html | 1216 + docs/network.js.html | 333 + docs/quicksearch.html | 33 - docs/scatterplot.js.html | 168 + docs/scripts/docstrap.lib.js | 22646 ---------------- docs/scripts/fulltext-search-ui.js | 92 - docs/scripts/fulltext-search.js | 36 - docs/scripts/linenumber.js | 25 + docs/scripts/lunr.min.js | 855 - docs/scripts/prettify/jquery.min.js | 5153 ---- docs/scripts/prettify/lang-css.js | 38 +- docs/scripts/prettify/prettify.js | 826 +- docs/scripts/sunlight.js | 1415 - docs/scripts/toc.js | 214 - docs/styles/darkstrap.css | 1042 - docs/styles/jsdoc-default.css | 358 + docs/styles/prettify-jsdoc.css | 111 + docs/styles/prettify-tomorrow.css | 89 +- docs/styles/site.cerulean.css | 7376 ----- docs/styles/site.cosmo.css | 7429 ----- docs/styles/site.cyborg.css | 7416 ----- docs/styles/site.darkly.css | 7539 ----- docs/styles/site.darkstrap.css | 6055 ----- docs/styles/site.dibs-bootstrap.css | 9052 ------ docs/styles/site.flatly.css | 7515 ----- docs/styles/site.journal.css | 7341 ----- docs/styles/site.lumen.css | 7666 ------ docs/styles/site.paper.css | 7991 ------ docs/styles/site.readable.css | 7365 ----- docs/styles/site.sandstone.css | 7402 ----- docs/styles/site.simplex.css | 7391 ----- docs/styles/site.slate.css | 7711 ------ docs/styles/site.spacelab.css | 7423 ----- docs/styles/site.superhero.css | 7498 ----- docs/styles/site.united.css | 7263 ----- docs/styles/site.yeti.css | 7563 ------ docs/styles/sunlight.dark.css | 346 - docs/styles/sunlight.default.css | 344 - docs/tables.js.html | 776 + docs/timeDateUtil.js.html | 161 + 80 files changed, 47320 insertions(+), 182634 deletions(-) rename .github/{worflows => workflows}/doxygen-pdf.yml (100%) delete mode 100644 docs/classes.list.html create mode 100644 docs/clusternetwork.js.html create mode 100644 docs/clustersOfInterest.js.html create mode 100644 docs/colorPicker.js.html create mode 100644 docs/column_definitions.js.html create mode 100644 docs/fonts/OpenSans-Bold-webfont.eot create mode 100644 docs/fonts/OpenSans-Bold-webfont.svg create mode 100644 docs/fonts/OpenSans-Bold-webfont.woff create mode 100644 docs/fonts/OpenSans-BoldItalic-webfont.eot create mode 100644 docs/fonts/OpenSans-BoldItalic-webfont.svg create mode 100644 docs/fonts/OpenSans-BoldItalic-webfont.woff create mode 100644 docs/fonts/OpenSans-Italic-webfont.eot create mode 100644 docs/fonts/OpenSans-Italic-webfont.svg create mode 100644 docs/fonts/OpenSans-Italic-webfont.woff create mode 100644 docs/fonts/OpenSans-Light-webfont.eot create mode 100644 docs/fonts/OpenSans-Light-webfont.svg create mode 100644 docs/fonts/OpenSans-Light-webfont.woff create mode 100644 docs/fonts/OpenSans-LightItalic-webfont.eot create mode 100644 docs/fonts/OpenSans-LightItalic-webfont.svg create mode 100644 docs/fonts/OpenSans-LightItalic-webfont.woff create mode 100644 docs/fonts/OpenSans-Regular-webfont.eot create mode 100644 docs/fonts/OpenSans-Regular-webfont.svg create mode 100644 docs/fonts/OpenSans-Regular-webfont.woff delete mode 100644 docs/fonts/glyphicons-halflings-regular.eot delete mode 100644 docs/fonts/glyphicons-halflings-regular.svg delete mode 100644 docs/fonts/glyphicons-halflings-regular.ttf delete mode 100644 docs/fonts/glyphicons-halflings-regular.woff delete mode 100644 docs/fonts/glyphicons-halflings-regular.woff2 create mode 100644 docs/globals.js.html create mode 100644 docs/helpers.js.html create mode 100644 docs/histogram.js.html create mode 100644 docs/hiv_tx_network.js.html create mode 100644 docs/hivtraceClusterGraphSummary.js.html delete mode 100644 docs/img/glyphicons-halflings-white.png delete mode 100644 docs/img/glyphicons-halflings.png create mode 100644 docs/misc.js.html create mode 100644 docs/network.js.html delete mode 100644 docs/quicksearch.html create mode 100644 docs/scatterplot.js.html delete mode 100644 docs/scripts/docstrap.lib.js delete mode 100644 docs/scripts/fulltext-search-ui.js delete mode 100644 docs/scripts/fulltext-search.js create mode 100644 docs/scripts/linenumber.js delete mode 100644 docs/scripts/lunr.min.js delete mode 100644 docs/scripts/prettify/jquery.min.js delete mode 100644 docs/scripts/sunlight.js delete mode 100644 docs/scripts/toc.js delete mode 100644 docs/styles/darkstrap.css create mode 100644 docs/styles/jsdoc-default.css create mode 100644 docs/styles/prettify-jsdoc.css delete mode 100644 docs/styles/site.cerulean.css delete mode 100644 docs/styles/site.cosmo.css delete mode 100644 docs/styles/site.cyborg.css delete mode 100644 docs/styles/site.darkly.css delete mode 100644 docs/styles/site.darkstrap.css delete mode 100644 docs/styles/site.dibs-bootstrap.css delete mode 100644 docs/styles/site.flatly.css delete mode 100644 docs/styles/site.journal.css delete mode 100644 docs/styles/site.lumen.css delete mode 100644 docs/styles/site.paper.css delete mode 100644 docs/styles/site.readable.css delete mode 100644 docs/styles/site.sandstone.css delete mode 100644 docs/styles/site.simplex.css delete mode 100644 docs/styles/site.slate.css delete mode 100644 docs/styles/site.spacelab.css delete mode 100644 docs/styles/site.superhero.css delete mode 100644 docs/styles/site.united.css delete mode 100644 docs/styles/site.yeti.css delete mode 100644 docs/styles/sunlight.dark.css delete mode 100644 docs/styles/sunlight.default.css create mode 100644 docs/tables.js.html create mode 100644 docs/timeDateUtil.js.html diff --git a/.github/worflows/doxygen-pdf.yml b/.github/workflows/doxygen-pdf.yml similarity index 100% rename from .github/worflows/doxygen-pdf.yml rename to .github/workflows/doxygen-pdf.yml diff --git a/docs/HIVTxNetwork.html b/docs/HIVTxNetwork.html index 8064b61..31e3ca8 100644 --- a/docs/HIVTxNetwork.html +++ b/docs/HIVTxNetwork.html @@ -1,2026 +1,5315 @@ - - - - - Documentation Class: HIVTxNetwork + + + JSDoc: Class: HIVTxNetwork + + - - - - - - - + + + -
-
-
-
-

Class: HIVTxNetwork

-
-
-

HIVTxNetwork

-
- -
-
-
-
-

- new HIVTxNetwork(json, - button_bar_ui, cluster_attributes) -

-
-
-
- Represents an HIV transmission network with annotations -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
json - Object - - A JSON object containing the network data. -
button_bar_ui - HTMLElement - - A UI element for interacting with the network. -
cluster_attributes - Object - - Attributes related to clusters within the network. -
- -
-
-
- -

Members

- -
-
-
-

- _calc_country_nodes -

-
-
-
- this is a function which calculates country node centers - for the (experimental) option of rendering networks with - topo maps -
- -
-
- -
-
-

- auto_expand_pg_handler -

-
-
-
- Grow a CoI defined in @pg based on its growth mode -
- -
-
- -
-
-

- charge_correction -

-
-
-
d3 layout option setting
- -
-
- -
-
-

- check_for_time_series -

-
-
-
- Generate a function callback for attribute time series - data -
- -
-
- -
-
-

- cluster_filtering_functions -

-
-
-
- filters which control which clusters get rendered -
- -
-
- -
-
-

- colorizer -

-
-
-
default node colorizer
- -
-
- -
-
-

- defined_priority_groups -

-
-
-
- the list of defined clusters of interest, format as - follows (SLKP, 20240715: may need updating) { 'name' : - 'unique name', 'nodes' : [ { 'node_id' : text, 'added' : - date, 'kind' : text }], 'created' : date, 'description' : - 'text', 'modified' : date, 'kind' : 'text' } -
- -
-
- -
-
-

- filter_by_size -

-
-
-
-
- -
-
-

- filter_if_added -

-
-
-
-
- -
-
-

- filter_singletons -

-
-
-
-
- -
-
-

- filter_time_period -

-
-
-
-
- -
-
-

- highlight_unsuppored_edges -

-
-
-
- if there is computed support for network edges, use it to - highlight possible spurious edges -
- -
-
- -
-
-

- node_label_drag -

-
-
-
- define a D3 behavior to make node labels draggable -
- -
-
- -
-
-

- node_shaper -

-
-
-
default node shaper
- -
-
- -
-
-

- priority_groups_all_events -

-
-
-
- generate a set of all unique temporal events (when new - data were added to ANY CoI) return a Set of date strings - formatted with timeDateUtil.DateViewFormatSlider -
- -
-
- -
-
-

- priority_groups_compute_overlap -

-
-
-
- compute the overlap between CoI -
- -
-
- -
-
-

- priority_groups_edit_set_description -

-
-
-
- A function that updates the "freehand" description of a - specific CoI -
- -
-
- -
-
-

- priority_groups_export -

-
-
-
- export CoI records for interactions with the external DB -
- -
-
- -
-
-

- priority_groups_export_nodes -

-
-
-
- Export nodes that are members of CoI -
- -
-
- -
-
-

- priority_groups_export_sets -

-
-
-
Export CoI summary info
- -
-
- -
-
-

- priority_groups_find_by_name -

-
-
-
- lookup a CoI by name; null if not found -
- -
-
- -
-
-

- priority_groups_is_new_node -

-
-
-
- returns true is the node was added by the system during - CoI definition/expansion -
- -
-
- -
-
-

- priority_groups_remove_set -

-
-
-
- Remove a CoI from the list of defined CoI -
- -
-
- -
-
-

- priority_groups_update_node_sets -

-
-
-
- interact with the remote DB to send updates of CoI - operations -
- -
-
- -
-
-

- using_time_filter -

-
-
-
- time filter element for various displays -
- -
-
-
- -

Methods

- -
-
-
-

- annotate_cluster_changes() -

-
-
-
- annotate_cluster_changes If the network contains - information about cluster changes (new/moved/deleted - nodes, etc), this function will annotate cluster objects - (in place) with various attributes "delta" : change in the - size of the cluster "flag" : a status flag to be used in - the cluster display table if set to 2 then TBD if set to 3 - then TBD -
- -
-
- -
-
-

- attribute_node_value_by_id(d:, id:, number:) -

-
-
-
- Fetch the value of an attribute from the node -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
d:node object
id: - [string] the attribute whose value should be fetched -
number: - [bool] if true, only return numerical values -
- -
-
- -
-
-

- cluster_display_filter() -

-
-
-
-
- -
-
-

- define_attribute_COI_membership(network, data:) -

-
-
-
- define an attribute generator for subcluster membership - attribute -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - + - +
-
- - -
NameTypeDescription
network - : the network / cluster object to ise -
data: - reference date to use -
+

Class: HIVTxNetwork

-
+ -
Returns:
-
attribute definition
-
- -
-
-

- define_attribute_binned_vl(field:, title:) -

-
-
-
- define an attribute generator for binned viral loads -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
field: - the node attribute field to use -
title: - display this title for the attribute -
- -
-
Returns:
-
attribute definition dict
-
+
-
-
-

- define_attribute_dx_years(relative:, label:) -

-
-
-
- define an attribute generator for dx year -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
relative: - if T, compute dx date relative to the network date - in years -
label:use this label
- -
- -
Returns:
- -
attribute definition dict
-
- -
-
-

- define_attribute_network_update() -

-
-
-
- define an attribute generator for new network - nodes/clusters -
- -
- -
Returns:
- -
attribute definition dict
-
- -
-
-

- define_attribute_vl_interpretaion() -

-
-
-
- define an attribute generator for Viral load result - interpretatio -
- -
- -
Returns:
- -
attribute definition dict
-
- -
-
-

- display_warning() -

-
-
-
display a warning string
- -
-
- -
-
-

- extract_single_cluster(nodes, filter, no_clone) -

-
-
-
- Extract the nodes and edges between them into a separate - object -
- -
Parameters:
- - - - - - - - - - - - - - - +
+ +

HIVTxNetwork(json, button_bar_ui, cluster_attributes)

+ + +
- +
+
+ + -
- + - - + +

new HIVTxNetwork(json, button_bar_ui, cluster_attributes)

+ - - - - - - - - - - - - - -
NameTypeDescription
nodes - [array] the list of nodes to extract -
filter - [function, optional] (edge) -> bool filtering - function for deciding which edges will be used to - define clusters -
no_clone - [bool] if set to T, node objects are **not** shallow - cloned in the return object -
- -
- -
Returns:
- -
- [dict] the object representing "Nodes" and "Edges" in the - extracted cluster -
-
- -
-
-

- filter_by_date(cutoff, - date_file, start_date, node, count_newly_add) -

-
-
-
- Check if the date attribute of a node falls within a - pre-specified range -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - + - - - - - +
+ Represents an HIV transmission network with annotations +
+ + + + + + + + + +
Parameters:
+ + +
NameTypeDescription
cutoff
date_file
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
json + + +Object + + + + A JSON object containing the network data.
button_bar_ui + + +HTMLElement + + + + A UI element for interacting with the network.
cluster_attributes + + +Object + + + + Attributes related to clusters within the network.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
- - start_date - - - - - - node - - - - - - - - count_newly_add - - - - - [bool]; if true, then a "new node" attribute - overrides date checks, so all new (compared to the - previous network) nodes pass the check - - - - - -
-
- -
-
-

- generateClusterOfInterestID() -

-
-
-
- generate the name for a cluster of interest -
- -
-
- -
-
-

- get_ui_element_selector_by_role(role:, nested:) -

-
-
-
- retrive the DOM ID for an element given its - data-hivtrace-ui-role -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
role: - data-hivtrace-ui-role -
nested: - true if this is being called from a secondary - network or element (dialog, cluster view etc), which - does not have primary button_ui elements -
- -
-
- -
-
-

- initialize_ui_ux_elements() -

-
-
-
initialize UI/UX elements
- -
-
- -
-
-

- inject_attribute_description() -

-
-
-
- add an attribute description Given an attribute definition - (see comments elsewhere), and a key to associate it with - do -
- -
-
- -
-
-

- load_priority_sets(url, is_writeable) -

-
-
-
- read and process JSON files defining COI -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
url - [string]: load the data from here -
is_writeable - [string]: if "writeable", changes to COI lists will - be pushed back to the server This needs to be called - AFTER the clusters/subclusters have been annotated -
- -
-
- -
-
-

- map_ids_to_objects() -

-
-
-
- create a map between node IDs and node objects -
- -
-
- -
-
-

- parse_dates(value) -

-
-
-
parse a date record
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
value - (date object or string) -
- -
- -
Returns:
- -
date object
-
- -
-
-

- populate_predefined_attribute(computed, key) -

-
-
-
- populate_predefined_attribute Given an attribute - definition (see comments elsewhere), and a key to - associate it with do 0. Inject the definition of the - attribute into the network dictionary 1. Compute the value - of the attribute for all nodes 2. Compute unique values -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
computed - (dict) : attribute definition -
key - (string) : the key to associate with the attribute -
- -
-
- -
-
-

- priority_group_node_record(node_id, date, kind) -

-
-
-
Generate a CoI node record
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
node_id - [string] : node name, -
date - (optional) : creation date -
kind - (optional) : node creation mode -
- -
-
- -
-
-

- priority_groups_automatic() -

-
-
-
- filter the list of CoI to return those which have been - created by the system -
- -
-
- -
-
-

- priority_groups_compute_node_membership() -

-
-
-
- Compute which CoI do various nodes belong to, and define - additional attributes for each node -
- -
-
- -
-
-

- priority_groups_expanded() -

-
-
-
- filter the list of CoI to return those which have been - automatically expanded -
- -
-
- -
-
-

- priority_groups_pending() -

-
-
-
- filter the list of CoI to return those which have not been - reviewed/validated -
- -
-
- -
-
-

- priority_groups_validate(groups, auto_extend) -

-
-
-
validate the list of CoI
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
groups - array - - is a list of CoI name: unique string description: - string, nodes: { { 'id' : node id, 'added' : date, - 'kind' : _cdcPrioritySetNodeKind } }, created: date, - kind: kGlobals.CDCCOIKind, tracking: - kGlobals.CDCCOITrackingOptions createdBy : - kGlobals.CDCCOICreatedBySystem,kGlobals.CDCCOICreatedManually -
auto_extend - bool - - : if true, automatically expand existing CoI -
- -
-
- -
-
-

- <static> inject_attribute_node_value_by_id(node, id, value) -

-
-
-
- Add an attribute value to the node object -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
node[object] : node,
id - [string] : attribute id -
value: attribute value
- -
-
- -
-
-

- <static> is_edge_injected() -

-
-
-
- Is this node NOT genetic, i.e. added to the network via - social or other means -
- -
-
- -
-
-

- <static> is_new_node() -

-
-
-
- does the node have "new node" attribute -
- -
-
-
-
-
-
-
- -
- -
- -
-
-
- - - - - - - - - - - - - - - - - + + + + + + + + + + + + + +

Members

+ + + +

_calc_country_nodes

+ + + + +
+ this is a function which calculates country node centers + for the (experimental) option of rendering networks with + topo maps +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

auto_expand_pg_handler

+ + + + +
+ Grow a CoI defined in @pg based on its growth mode +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

charge_correction

+ + + + +
+ d3 layout option setting +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

check_for_time_series

+ + + + +
+ Generate a function callback for attribute time series data +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

cluster_filtering_functions

+ + + + +
+ filters which control which clusters get rendered +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

colorizer

+ + + + +
+ default node colorizer +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

defined_priority_groups

+ + + + +
+ the list of defined clusters of interest, + format as follows (SLKP, 20240715: may need updating) + { + 'name' : 'unique name', + 'nodes' : [ + { + 'node_id' : text, + 'added' : date, + 'kind' : text + }], + 'created' : date, + 'description' : 'text', + 'modified' : date, + 'kind' : 'text' + } +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

filter_by_size

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

filter_if_added

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

filter_singletons

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

filter_time_period

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

highlight_unsuppored_edges

+ + + + +
+ if there is computed support for network edges, use it to highlight + possible spurious edges +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

node_label_drag

+ + + + +
+ define a D3 behavior to make node labels draggable +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

node_shaper

+ + + + +
+ default node shaper +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_all_events

+ + + + +
+ generate a set of all unique temporal events (when new data were added to ANY CoI) + return a Set of date strings formatted with timeDateUtil.DateViewFormatSlider +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_compute_overlap

+ + + + +
+ compute the overlap between CoI +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_edit_set_description

+ + + + +
+ A function that updates the "freehand" description + of a specific CoI +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_export

+ + + + +
+ export CoI records for interactions with the external DB +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_export_nodes

+ + + + +
+ Export nodes that are members of CoI +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_export_sets

+ + + + +
+ Export CoI summary info +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_find_by_name

+ + + + +
+ lookup a CoI by name; null if not found +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_is_new_node

+ + + + +
+ returns true is the node was added by the system during CoI definition/expansion +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_remove_set

+ + + + +
+ Remove a CoI from the list of defined CoI +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

priority_groups_update_node_sets

+ + + + +
+ interact with the remote DB to send updates of CoI operations +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

using_time_filter

+ + + + +
+ time filter element for various displays +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

annotate_cluster_changes()

+ + + + + + +
+ annotate_cluster_changes + + If the network contains information about cluster changes (new/moved/deleted nodes, etc), + this function will annotate cluster objects (in place) with various attributes + "delta" : change in the size of the cluster + "flag" : a status flag to be used in the cluster display table + if set to 2 then TBD + if set to 3 then TBD +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

attribute_node_value_by_id(d:, id:, number:)

+ + + + + + +
+ Fetch the value of an attribute from the node +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
d: + + node object
id: + + [string] the attribute whose value should be fetched
number: + + [bool] if true, only return numerical values
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

cluster_display_filter()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

define_attribute_COI_membership(network, data:)

+ + + + + + +
+ define an attribute generator for subcluster membership attribute +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
network + + : the network / cluster object to ise
data: + + reference date to use
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ attribute definition +
+ + + + + + + + + + + + + + + +

define_attribute_binned_vl(field:, title:)

+ + + + + + +
+ define an attribute generator for binned viral loads +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
field: + + the node attribute field to use
title: + + display this title for the attribute
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ attribute definition dict +
+ + + + + + + + + + + + + + + +

define_attribute_dx_years(relative:, label:)

+ + + + + + +
+ define an attribute generator for dx year +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
relative: + + if T, compute dx date relative to the network date in years
label: + + use this label
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ attribute definition dict +
+ + + + + + + + + + + + + + + +

define_attribute_network_update()

+ + + + + + +
+ define an attribute generator for new network nodes/clusters +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ attribute definition dict +
+ + + + + + + + + + + + + + + +

define_attribute_vl_interpretaion()

+ + + + + + +
+ define an attribute generator for Viral load result interpretatio +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ attribute definition dict +
+ + + + + + + + + + + + + + + +

display_warning()

+ + + + + + +
+ display a warning string +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

extract_single_cluster(nodes, filter, no_clone)

+ + + + + + +
+ Extract the nodes and edges between them into a separate object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
nodes + + [array] the list of nodes to extract
filter + + [function, optional] (edge) -> bool filtering function for deciding which edges will be used to define clusters
no_clone + + [bool] if set to T, node objects are **not** shallow cloned in the return object
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ [dict] the object representing "Nodes" and "Edges" in the extracted cluster +
+ + + + + + + + + + + + + + + +

filter_by_date(cutoff, date_file, start_date, node, count_newly_add)

+ + + + + + +
+ Check if the date attribute of a node falls within a pre-specified range +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cutoff + +
date_file + +
start_date + +
node + +
count_newly_add + + [bool]; if true, then a "new node" attribute overrides date checks, + so all new (compared to the previous network) nodes pass the check
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

generateClusterOfInterestID()

+ + + + + + +
+ generate the name for a cluster of interest +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

get_ui_element_selector_by_role(role:, nested:)

+ + + + + + +
+ retrive the DOM ID for an element given its data-hivtrace-ui-role +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
role: + + data-hivtrace-ui-role
nested: + + true if this is being called from a secondary network or element (dialog, cluster view etc), + which does not have primary button_ui elements
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

initialize_ui_ux_elements()

+ + + + + + +
+ initialize UI/UX elements +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

inject_attribute_description()

+ + + + + + +
+ add an attribute description + + Given an attribute definition (see comments elsewhere), and a key to associate it with + do +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

load_priority_sets(url, is_writeable)

+ + + + + + +
+ read and process JSON files defining COI +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
url + + [string]: load the data from here
is_writeable + + [string]: if "writeable", changes to COI lists will be pushed back to the server + + This needs to be called AFTER the clusters/subclusters have been annotated
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

map_ids_to_objects()

+ + + + + + +
+ create a map between node IDs and node objects +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

parse_dates(value)

+ + + + + + +
+ parse a date record +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + (date object or string)
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ date object +
+ + + + + + + + + + + + + + + +

populate_predefined_attribute(computed, key)

+ + + + + + +
+ populate_predefined_attribute + + Given an attribute definition (see comments elsewhere), and a key to associate it with + do + + 0. Inject the definition of the attribute into the network dictionary + 1. Compute the value of the attribute for all nodes + 2. Compute unique values +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
computed + + (dict) : attribute definition
key + + (string) : the key to associate with the attribute
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

priority_group_node_record(node_id, date, kind)

+ + + + + + +
+ Generate a CoI node record +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
node_id + + [string] : node name,
date + + (optional) : creation date
kind + + (optional) : node creation mode
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

priority_groups_automatic()

+ + + + + + +
+ filter the list of CoI to return those which have been created by the system +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

priority_groups_compute_node_membership()

+ + + + + + +
+ Compute which CoI do various nodes belong to, and + define additional attributes for each node +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

priority_groups_expanded()

+ + + + + + +
+ filter the list of CoI to return those which have been automatically expanded +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

priority_groups_pending()

+ + + + + + +
+ filter the list of CoI to return those which have not been reviewed/validated +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

priority_groups_validate(groups, auto_extend)

+ + + + + + +
+ validate the list of CoI +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
groups + + +array + + + + is a list of CoI + name: unique string + description: string, + nodes: { + { + 'id' : node id, + 'added' : date, + 'kind' : _cdcPrioritySetNodeKind + } + }, + created: date, + kind: kGlobals.CDCCOIKind, + tracking: kGlobals.CDCCOITrackingOptions + createdBy : kGlobals.CDCCOICreatedBySystem,kGlobals.CDCCOICreatedManually
auto_extend + + +bool + + + + : if true, automatically expand existing CoI
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) inject_attribute_node_value_by_id(node, id, value)

+ + + + + + +
+ Add an attribute value to the node object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
node + + [object] : node,
id + + [string] : attribute id
value + + : attribute value
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) is_edge_injected()

+ + + + + + +
+ Is this node NOT genetic, i.e. added to the network via social or other means +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) is_new_node()

+ + + + + + +
+ does the node have "new node" attribute +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/classes.list.html b/docs/classes.list.html deleted file mode 100644 index 9df5d01..0000000 --- a/docs/classes.list.html +++ /dev/null @@ -1,5566 +0,0 @@ - - - - - - - Documentation Classes - - - - - - - - - - -
-
-
-
-

Classes

-
-
-

-
- -
-
-
-
- -

Classes

- -
-
HIVTxNetwork
-
- -
- hivtrace_generate_svg_polygon -
-
-
- -

Members

- -
-
-
-

- <constant> CDCCOICanAutoExpand -

-
-
-
- CDCCOITrackingOptions: Available tracking options for - Clusters of Interest Used as drop-downs for COI editors - and automatic filling -
- -
-
- -
-
-

- <constant> CDCCOIConciseTrackingOptions -

-
-
-
- CDCCOITrackingOptionsDateFilter: A filtering option - applied to cluster nodes when computing COI membership - under different tracking options Specifies the maximum - number of MONTHS (relative to the reference data) that a - node age must fall into -
- -
-
- -
-
-

- <constant> CDCCOICreatedBySystem -

-
-
-
- CDCCOINodeKind: Available options for how a COI member was - identified Used as drop-downs for COI editors and - automatic filling -
- -
-
- -
-
-

- <constant> CDCCOICreatedManually -

-
-
-
- CDCCOICreatedBySystem: The value of "createdBy" in a COI - record when the COI was created by the system - (automatically) -
- -
-
- -
-
-

- <constant> CDCCOIKind -

-
-
-
- ShapeOrdering: The range to which values for - categorical/ordinal variables will be mapped using the - "Shape" dropdown -
- -
-
- -
-
-

- <constant> CDCCOIKindAutomaticCreation -

-
-
-
- CDCJurisdictionLowMorbidity: The set of low-morbidity - jurisdictions for Secure HIV TRACE -
- -
-
- -
-
-

- <constant> CDCCOINodeKind -

-
-
-
- CDCCOIConciseTrackingOptions: Available shorter tracking - options for Clusters of Interest Used for COI exports -
- -
-
- -
-
-

- <constant> CDCCOINodeKindDefault -

-
-
-
- CDCCOIKindAutomaticCreation: The kind of COI that is - automatically created by the system -
- -
-
- -
-
-

- <constant> CDCCOITrackingOptions -

-
-
-
- CDCCOIKind: Available creation options for Clusters of - Interest -
- -
-
- -
-
-

- <constant> CDCCOITrackingOptionsDateFilter -

-
-
-
- CDCCOITrackingOptionsFilter: A filtering option is applied - to cluster edges when computing COI membership under - different tracking options Selects edges of different - lengths (0.5% vs 1.5%) -
- -
-
- -
-
-

- <constant> CDCCOITrackingOptionsDefault -

-
-
-
- CDCCOICanAutoExpand: The types of tracking modes which are - subject to automatic growth tracking -
- -
-
- -
-
-

- <constant> CDCCOITrackingOptionsDistanceFilter -

-
-
-
- CDCCOITrackingOptionsNone: The "no-tracking" option - assigned for COI -
- -
-
- -
-
-

- <constant> CDCCOITrackingOptionsNone -

-
-
-
- CDCCOITrackingOptionsDefault: The default tracking option - assigned to COI -
- -
-
- -
-
-

- <constant> CDCJurisdictionCodes -

-
-
-
- CDCCOICreatedManually: The value of "createdBy" in a COI - record when the COI was created manually -
- -
-
- -
-
-

- <constant> CDCJurisdictionLowMorbidity -

-
-
-
- CDCJurisdictionCodes: Mapping from full names to - two-letter codes for various Secure HIV-TRACE - jurisdictions -
- -
-
- -
-
-

- <constant> CDCNPMember -

-
-
-
- CDCCOINodeKindDefault: The method of node identification - used by default (and it automatically created COI) -
- -
-
- -
-
-

- <constant> Categorical -

-
-
-
- CategoricalBase: The default set of colors used for - displaying colors of categorical attributes -
- -
-
- -
-
-

- <constant> DateFormats -

-
-
-
- Used to generate pop-over labels for node displays, and - COI views -
- -
-
- -
-
-

- <constant> DateUpperBoundYear -

-
-
-
- Used in many places where alpha-numerically sorted dates - are desired -
- -
-
- -
-
-

- <constant> DateViewFormat -

-
-
-
- Used to generate legend labels for date-valued attributes - for network displayes -
- -
-
- -
-
-

- <constant> DateViewFormatClusterCreate -

-
-
-
- Maximum year value (no future dates) -
- -
-
- -
-
-

- <constant> DateViewFormatShort -

-
-
-
- this is currently used to display node addition dates to - COI -
- -
-
- -
-
-

- <constant> DateViewFormatSlider -

-
-
-
- List of accepted time formats for attribute values -
- -
-
- -
-
-

- <constant> EdgeColorBase -

-
-
-
- MaximumValuesInCategories: Maximum # of distinct values - that can be rendered for categorical variables -
- -
-
- -
-
-

- <constant> MaximumValuesInCategories -

-
-
-
- Categorical: Expanded color range using darker shades - based on `CategoricalBase` -
- -
-
- -
-
-

- <constant> PresetColorSchemes -

-
-
-
- EdgeColorBase: The default color range for shading network - EDGES -
- -
-
- -
-
-

- <constant> PresetShapeSchemes -

-
-
-
- PresetColorSchemes: Predefined (hard-coded) color schemes - for specific attribute fields. Keys are exactly matched by - categorical variable names These should be updated if a - specific attribute needs to use a particular color scheme - for value rendering -
- -
-
- -
-
-

- <constant> SequentialColor -

-
-
-
- PresetShapeSchemes: Predefined (hard-coded) shape schemes - for specific attribute fields. Keys are exactly matched by - categorical variable names These should be updated if a - specific attribute needs to use a particular shape scheme - for value rendering -
- -
-
- -
-
-

- <constant> ShapeOrdering -

-
-
-
- SequentialColor: The default color ranges for a fixed - number of values -
- -
-
- -
-
-

- <constant> SubclusterSeparator -

-
-
-
- network: Attributes and string constants for the network - object -
- -
-
- -
-
-

- cluster_time_scale -

-
-
-
- used as a part of auto-named COI, e.g. NC_202105_44.1 -
- -
-
- -
-
-

- d3 -

-
-
-
- A collection of table column definitions -
- -
-
- -
-
-

- d3 -

-
-
-
- Combined definitions and presets for various network - components. -
- -
-
- -
-
-

- d3 -

-
-
-
- Functions that help manipulate network JSON and perform - other utility operations -
- -
-
- -
-
-

- <constant> formats -

-
-
-
- missing: Values to use when displaying missing values -
- -
-
- -
-
-

- <constant> missing -

-
-
-
- CDCNPMember: The label for the auto-generated node - attribute (ever in NP CoI) -
- -
-
- -
-
-

- <constant> network -

-
-
-
- formats: Various formatters for numerical values -
- -
-
-
- -

Methods

- -
-
-
-

- _action_drop_down(self, pg) -

-
-
-
- Generates a dropdown menu for actions on a cluster of - interest (COI). -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - The main network visualization object. -
pg - Object - - The cluster of interest data. -
- -
- -
Returns:
- -
- An array of dropdown menu options. -
- -
-
Type
-
- Array -
-
-
- -
-
-

- add_a_sortable_table(container, headers, content [, - overwrite] [, caption] [, priority_set_editor]) -

-
-
-
- Adds a sortable table to a D3 selection container. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
container - d3.selection - - The D3 selection representing the container element - for the table. -
headers - Array.<string> - - An array of strings representing the table headers. -
content - Array.<Object> - - An array of objects representing the table content. - Each object should have properties that map to table - cells. -
overwrite - boolean - <optional>
- An optional flag indicating whether to overwrite any - existing table content (default: false). -
caption - string - <optional>
- An optional caption for the table. -
priority_set_editor - function - <optional>
- An optional function used to customize cell - formatting based on priority sets. The function - should accept four arguments: - `d`: The data object - for the current cell. - `i`: The index of the - current cell within its row. - `cell`: The D3 - selection of the current cell element (a ` - - ` element). - `priority_set_editor`: The - `priority_set_editor` function passed to - `add_a_sortable_table`. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- b64toBlob(b64, - onsuccess [, onerror]) -

-
-
-
- Converts a base64-encoded string to a Blob object. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
b64 - string - - The base64-encoded string. -
onsuccess - function - - A callback function to be called when the conversion - is successful. -
onerror - function - <optional>
- An optional callback function to be called if an - error occurs. -
- -
-
- -
-
-

- collapseLargeCategories(nodes, schema) -

-
-
-
- Collapses rare categories to "Other" category if there are - >CATEGORY_UNIQUE_VALUE_LIMIT categories -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
nodes - Array.<Object> - - An array of node objects, each containing patient - attributes. -
schema - Object - - An object defining the schema for the patient - attributes. -
- -
- -
Returns:
- -
- True if any categories were collapsed, false otherwise. -
- -
-
Type
-
- boolean -
-
-
- -
-
-

- colorPickerInput(id, - colorizer) -

-
-
-
- Creates a color picker input element with a label. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
id - string - - The ID for the color picker input element. -
colorizer - function - - A colorizer function that maps values to colors. -
- -
- -
Returns:
- -
- The HTML markup for the color picker input element with - the label. -
- -
-
Type
-
- string -
-
-
- -
-
-

- colorPickerInputContinuous(id, color) -

-
-
-
- Creates a color picker input element with a label for - continuous values. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
id - string - - The ID for the color picker input element. -
color - string - - The initial color value for the color picker. -
- -
- -
Returns:
- -
- The HTML markup for the color picker input element with - the label. -
- -
-
Type
-
- string -
-
-
- -
-
-

- colorStops(id, number) -

-
-
-
- Creates a color stop input element with a label. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
id - string - - The ID for the color stop input element. -
number - number - - The initial value for the color stop. -
- -
- -
Returns:
- -
- The HTML markup for the color stop input element with the - label. -
- -
-
Type
-
- string -
-
-
- -
-
-

- copyToClipboard(text) -

-
-
-
- Copies the given text to the clipboard. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
text - string - - The text to be copied. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- datamonkey_describe_vector(vector [, as_list]) -

-
-
-
- Calculates descriptive statistics for a numerical vector. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
vector - Array.<number> - - An array of numbers representing the data. -
as_list - boolean - <optional>
- An optional flag indicating whether to return the - statistics as a formatted string. -
- -
- -
Returns:
- -
- - If `as_list` is false, returns an object with the - following properties: - `min`: The minimum value. - `max`: - The maximum value. - `median`: The median value. - `Q1`: - The first quartile. - `Q3`: The third quartile. - `mean`: - The mean value. - If `as_list` is true, returns a - formatted string representing the statistics. -
- -
-
Type
-
- Object - | - - string -
-
-
- -
-
-

- datamonkey_export_csv_button(data [, name]) -

-
-
-
- Creates a downloadable CSV file for the provided data and - adds a button to trigger the download. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
data - Array.<Object> - - An array of objects representing the data to be - exported. -
name - string - <optional>
- An optional name for the exported CSV file. If not - provided, defaults to "export.csv". -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- datamonkey_export_handler(data [, filename] [, mimeType]) -

-
-
-
- Handles exporting data to a file based on browser - capabilities. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
data - string - - The data to be exported. -
filename - string - <optional>
- The desired filename for the downloaded file. - Defaults to "download.tsv". -
mimeType - string - <optional>
- The MIME type of the data. Defaults to "text/plain" - if not provided. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- datamonkey_export_json_button(data [, title]) -

-
-
-
- Creates a downloadable JSON file for the provided data and - adds a button to trigger the download. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
data - Object - | - - Array.<Object> - - The data to be exported, either a single object or - an array of objects. -
title - string - <optional>
- An optional title for the exported JSON file. If not - provided, defaults to "export". -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- datamonkey_save_image(type, container) -

-
-
-
- Saves the contents of an SVG element as an image file. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
type - string - - The desired image format (either "svg" or "png"). -
container - jQuery - | - - HTMLElement - - A jQuery selector or element reference containing - the SVG element. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- draw_priority_set_table(self, container, priority_groups) -

-
-
-
- Draws a table of priority sets (clusters of interest). -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - The main network visualization object. -
container - HTMLElement - - The HTML element where the table will be displayed - (optional). -
priority_groups - Array - - An array of objects representing the priority sets - (optional). -
- -
-
- -
-
-

- edge_typer(e, - edge_types, T) -

-
-
-
- Determines the type of an edge based on its length and - predefined edge types. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
e - Object - - The edge object to be classified. -
edge_types - Array.<string> - - An array of two edge types. The first type is used - for edges shorter than or equal to `T`, and the - second type is used for edges longer than `T`. -
T - number - - The threshold value for edge length classification. -
- -
- -
Returns:
- -
- The edge type corresponding to the edge's length. -
- -
-
Type
-
- string -
-
-
- -
-
-

- ensure_node_attributes_exist() -

-
-
-
- ensure_node_attributes_exist Iterate over nodes in the - network. If a node does not have an array of attributes or - data dictionary records, create an empty one. This makes - error checking less complex downstream. -
- -
-
- -
-
-

- exportColorScheme(uniqValues, colorizer) -

-
-
-
- Exports a color scheme based on unique values and a - colorizer function. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
uniqValues - Object - - An object containing unique values for each - attribute, as returned by `getUniqueValues`. -
colorizer - function - - A colorizer function that maps values to colors. -
- -
- -
Returns:
- -
- An object where the keys are unique values and the values - are the corresponding colors. -
- -
-
Type
-
- Object -
-
-
- -
-
-

- filter_parse(filter_value) -

-
-
-
- Parses a filter string into an array of filter objects. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
filter_value - string - - The filter string to be parsed. -
- -
- -
Returns:
- -
- An array of filter objects, each with a `type` property - and a corresponding `value` property. The `type` can be - "re" for regular expression, "date" for date range, or - "distance" for numerical comparison. -
- -
-
Type
-
- Array.<Object> -
-
-
- -
-
-

- filter_table(element) -

-
-
-
- Filters a D3 table based on user-defined filters in column - headers. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
element - d3.selection - | - - HTMLElement - - The D3 selection or HTML element representing a - table header cell that triggered the filter -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- filter_table_by_column_handler(datum, conditions) -

-
-
-
- Filters a table based on specified conditions applied to a - column. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
datum - * - - The data object representing a row in the table. -
conditions - Array.<Object> - - An array of condition objects, each with the - following properties: - `type`: The type of - condition ("re" for regular expression, "date" for - date range, "distance" for numerical comparison). - - `value`: The value or range for the condition: - For - "re": A regular expression object. - For "date": An - array of two Date objects representing the start and - end dates. - For "distance": A number representing - the threshold value. - `greater_than` (optional): A - boolean indicating whether to use greater-than - comparison for "distance" conditions. -
- -
- -
Returns:
- -
- True if the row matches at least one condition, false - otherwise. -
- -
-
Type
-
- boolean -
-
-
- -
-
-

- format_a_cell(data, - index, item [, priority_set_editor]) -

-
-
-
- Formats a cell in a table based on provided data. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
data - Object - - The data object representing the table cell. It - should have properties like: - `value`: The cell - value. - `format` (optional): A function used to - format the value. - `html` (optional): A flag - indicating whether the value should be set as HTML. - - `callback` (optional): A function used to - customize cell content and behavior. - `filter` - (optional): A flag indicating whether to enable - filtering for the column. - `column_id` (optional): - The index of the column (used for filtering). - - `sort` (optional): A flag indicating whether to - enable sorting for the column. - `presort` - (optional): A string ("asc" or "desc") for initial - sort direction. - `actions` (optional): An array of - button configurations for cell actions. - `help` - (optional): A string describing the cell content - (used as a tooltip). -
index - number - - The index of the cell within its row. -
item - d3.selection - - The D3 selection of the table cell element (a ` - ` element).
priority_set_editor - function - <optional>
- An optional function used for priority set - functionality (internal). -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- getUniqueValues(nodes, - schema) -

-
-
-
- Retrieves unique values for each attribute in a given - dataset. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
nodes - Array.<Object> - - An array of node objects, each containing patient - attributes. -
schema - Object - - An object defining the schema for the patient - attributes. -
- -
- -
Returns:
- -
- An object where each key represents an attribute name and - the corresponding value is an array of unique values for - that attribute. -
- -
-
Type
-
- Object -
-
-
- -
-
-

- get_editor() -

-
-
-
- Gets the current priority set editor object. -
- -
- -
Returns:
- -
- The priority set editor object, or null if not open. -
- -
-
Type
-
- Object -
-
-
- -
-
-

- get_ui_element_selector_by_role(role) -

-
-
-
- Retrieves a CSS selector for UI elements based on their - `data-hivtrace-ui-role` attribute. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
role - string - - The value of the `data-hivtrace-ui-role` attribute. -
- -
- -
Returns:
- -
- A CSS selector string targeting elements with the - specified role. -
- -
-
Type
-
- string -
-
-
- -
-
-

- handle_cluster_click(self:, cluster, release) -

-
-
-
- handle_cluster_click Handle contextual menus for clusters - and cluster drag -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self:network object
cluster - [optional]: the cluster object to act on -
release - [optional]: the cluster object to release the - "fixed" flag from -
- -
-
- -
-
-

- handle_inline_confirm(this_button, generator, text, - action, disabled) -

-
-
-
- Handles inline confirmation popovers. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
this_button - HTMLElement - - The button element that triggers the popover. -
generator - function - - A function that generates the HTML content for the - popover body. -
text - string - - The initial text to display in the popover's text - area (optional). -
action - function - - A callback function to be executed when the user - confirms the action. Takes the value from the text - area as input. -
disabled - boolean - - A flag indicating if the text area should be - disabled (optional). -
- -
-
- -
-
-

- hiv_trace_export_table_to_text(parent_id, table_id, csv - [, file_name_placeholder]) -

-
-
-
- This function creates a download button that, when - clicked, exports the data from the specified table as - either a CSV or TSV file. It uses D3 for DOM manipulation - and assumes the existence of a `helpers` object with - `table_to_text` and `export_handler` methods. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
parent_id - string - - The selector for the parent element where the button - will be appended. -
table_id - string - - The selector for the table to be exported. -
csv - boolean - - If true, exports as CSV; if false, exports as TSV. -
- file_name_placeholder - - string - <optional>
- The base name for the exported file. If not - provided, it defaults to the table_id without the - first character. -
- -
- -
Requires:
-
    -
  • module:d3
  • - -
  • module:helpers
  • -
- -
Returns:
- -
- The D3 selection of the created button. -
- -
-
Type
-
- d3.Selection -
-
- -
Example
- -
-hiv_trace_export_table_to_text("#parent-div", "#data-table", true, "export-data");
-
- -
-
-

- hivtraceClusterGraphSummary() -

-
-
-
- ## hivtraceClusterGraphSummary Function Creates and - populates a summary table for an HIV trace cluster graph. - #### Parameters `graph`: The input graph data. `tag`: The - HTML element to append the summary table to. `not_CDC`: A - flag indicating whether to include CDC-specific statistics - or not (optional). #### Returns None -
- -
-
- -
-
-

- hivtrace_cluster_depthwise_traversal(nodes, edges [, - edge_filter] [, save_edges] [, seed_nodes] [, white_list]) -

-
-
-
- Performs a depth-wise traversal on a cluster of nodes, - considering edges and optional filters. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
nodes - Array.<Object> - - An array of node objects. Each node should have an - `id` property. -
edges - Array.<Object> - - An array of edge objects. Each edge should have - `source` and `target` properties referencing node - IDs. -
edge_filter - function - <optional>
- An optional filtering function applied to edges - before traversal. The function should accept an edge - object and return a boolean indicating whether to - include the edge. -
save_edges - function - <optional>
- An optional function used to store traversed edges. - It should be called with an array where each element - represents the edges within a cluster. -
seed_nodes - Array.<Object> - <optional>
- An optional array of node objects to use as starting - points for traversal. If not provided, all nodes - will be considered. -
white_list - Set - <optional>
- An optional set of node IDs restricting traversal to - nodes within the set. -
- -
- -
Throws:
- -
-
-
- If an edge references non-existent nodes. -
-
-
-
-
Type
-
- Error -
-
-
-
- -
Returns:
- -
- An array of clusters, where each cluster is an array of - node objects. -
- -
-
Type
-
- Array.<Array.<Object>> -
-
-
- -
-
-

- hivtrace_coi_timeseries(cluster, element [, plot_width]) -

-
-
-
- This function creates a detailed time series visualization - for a cluster of interest (COI). It displays nodes and - events over time, with interactive features for - highlighting and displaying additional information. The - visualization includes: - A time axis - Lines representing - nodes - Circles representing events - Interactive - highlighting and tooltips - Time range boxes for context -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDefaultDescription
cluster - Object - - The cluster object containing node and event - information. -
- Properties -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
node_info - Object - - Information about nodes in the cluster. -
event_info - Object - - Information about events in the cluster. -
-
element - d3.Selection - - The D3 selection of the element where the - visualization will be rendered. -
plot_width - number - <optional>
1000 - The width of the plot in pixels. -
- -
- -
Requires:
-
    -
  • module:d3
  • - -
  • module:lodash
  • -
- -
Example
- -
-const cluster = {
-  node_info: {...},
-  event_info: {...}
-};
-const element = d3.select("#visualization-container");
-hivtrace_coi_timeseries(cluster, element, 1200);
-
- -
-
-

- hivtrace_compute_node_degrees(obj) -

-
-
-
- This function modifies the input object by adding a - 'degree' property to each node. The degree of a node is - the number of edges connected to it. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
obj - Object - - The graph object containing nodes and edges. -
- Properties -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
Nodes - Object - - An object representing the nodes of the - graph. -
Edges - Object - - An object representing the edges of the - graph. -
- Edges[].source - - string - - The source node of an edge. -
- Edges[].target - - string - - The target node of an edge. -
-
- -
- -
Example
- -
-const graph = {
-  Nodes: {
-    "1": {},
-    "2": {}
-  },
-  Edges: {
-    "e1": { source: "1", target: "2" }
-  }
-};
-hivtrace_compute_node_degrees(graph);
-// graph.Nodes["1"].degree === 1
-// graph.Nodes["2"].degree === 1
-
- -
-
-

- hivtrace_date_or_na_if_missing(date [, formatter]) -

-
-
-
- Formats a date using a specified formatter, or returns - "N/A" if the date is missing. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
date - Date - - The date object to be formatted. -
formatter - function - <optional>
- An optional formatter function used to format the - date. If not provided, `DateViewFormatExport` is - used. -
- -
- -
Returns:
- -
- The formatted date string, or "N/A" if the date is - missing. -
- -
-
Type
-
- string -
-
-
- -
-
-

- hivtrace_generate_svg_symbol(type) -

-
-
-
- Generates an SVG symbol based on the specified type. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
type - string - - The type of symbol to generate. Possible values are: - - "circle" - "cross" - "diamond" - "square" - - "triangle-down" - "triangle-up" - "triangle" - - "pentagon" - "hexagon" - "septagon" - "octagon" - - "ellipse" -
- -
- -
Requires:
-
    -
  • module:d3
  • - -
  • module:hivtrace_generate_svg_polygon
  • - -
  • module:hivtrace_generate_svg_ellipse
  • -
- -
Returns:
- -
- A D3 symbol generator or a custom polygon/ellipse - generator. - For "circle", "cross", "diamond", "square", - "triangle-down", "triangle-up": Returns a D3 symbol - generator of the specified type. - For "triangle", - "pentagon", "hexagon", "septagon", "octagon": Returns a - custom polygon generator with the specified number of - sides. - For "ellipse": Returns a custom ellipse - generator. - For any other input: Returns a D3 symbol - generator of type "circle" as default. -
- -
-
Type
-
- Object -
-
-
- -
-
-

- hivtrace_histogram(graph, histogram_tag, histogram_label) -

-
-
-
- Renders a histogram for a graph property and displays a - descriptive label. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
graph - Object - - An object containing graph data, including - distribution and fitted data for the property. -
histogram_tag - string - - The ID of the HTML element where the histogram will - be rendered. -
histogram_label - string - - The ID of the HTML element where the descriptive - label will be displayed. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- hivtrace_histogram_distances(graph, histogram_tag, - histogram_label) -

-
-
-
- Renders a histogram for edge lengths (genetic distances) - and displays a label. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
graph - Object - - An object containing graph data, including edges. -
histogram_tag - string - - The ID of the HTML element where the histogram will - be rendered. -
histogram_label - string - - The ID of the HTML element where the descriptive - label will be displayed. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- hivtrace_plot_cluster_dynamics(time_series, container, - x_title, y_title [, y_scale] [, bin_by] [, options]) -

-
-
-
- Generates a plot visualizing cluster dynamics over time. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
time_series - Array.<Object> - - An array of data points, each with a required `time` - property (a date object) and optional properties - representing attributes. -
container - d3.selection - - A D3 selection representing the container element - for the plot. -
x_title - string - - The title for the x-axis. -
y_title - string - - The title for the y-axis. -
y_scale - d3.scale - <optional>
- An optional D3 scale for the y-axis. If not - provided, a linear scale will be used. -
bin_by - function - <optional>
- An optional function used to bin data points into - time intervals. The function should accept a date - object and return an array with three elements: - - The bin label (e.g., "Q1 2023"). - The start date of - the bin. - The middle date of the bin (used for - x-axis positioning). If not provided, a default - function that bins by quarters is used. -
options - Object - <optional>
- An optional configuration object for the plot. - - `base_line`: (number, default: 20) The baseline - value for the y-axis. - `top`: (number, default: 40) - The top padding for the plot. - `right`: (number, - default: 30) The right padding for the plot. - - `bottom`: (number, default: 60) The bottom padding - for the plot. - `left`: (number, default: 100) The - left padding for the plot. - `font_size`: (number, - default: 18) The font size for labels and text - elements. - `rect_size`: (number, default: 22) The - size of rectangles used in the legend. - `width`: - (number, default: 1024) The width of the plot - container. - `height`: (number, default: 600) The - height of the plot container. - `barchart`: - (boolean, default: false) If true, the plot will be - displayed as a bar chart. - `skip_cumulative`: - (boolean, default: false) If true, the cumulative - area will not be displayed. - `x-tick-format`: - (Function) An optional function for formatting - x-axis tick labels. - `prefix`: (string) An optional - prefix to add to attribute names displayed in the - legend. - `colorizer`: (Object) An optional - colorizer object for attributes. Keys should be - attribute names, and values should be D3 scales used - for coloring lines/bars. - `drag`: (Object) An - optional drag object for enabling dragging the plot. -
- -
- -
Throws:
- -
-
-
- If no data points are provided. -
-
-
-
-
Type
-
- Error -
-
-
-
-
- -
-
-

- hivtrace_render_histogram(counts [, fit], w, h, id) -

-
-
-
- Renders a histogram for discrete data using D3.js. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
counts - Array.<number> - - An array of counts for each category. -
fit - Array.<number> - <optional>
- (optional) - An array of fitted values for each - category. -
w - number - - The width of the plot area. -
h - number - - The height of the plot area. -
id - string - - The ID of the HTML element where the histogram will - be rendered. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- hivtrace_render_histogram_continuous(data, w, h, id) -

-
-
-
- Renders a histogram for continuous data using D3.js. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
data - Array.<number> - - An array of numerical values. -
w - number - - The width of the plot area. -
h - number - - The height of the plot area. -
id - string - - The ID of the HTML element where the histogram will - be rendered. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- hivtrace_render_scatterplot(points, w, h, id, labels [, - dates]) -

-
-
-
- Renders a scatter plot using D3.js. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDefaultDescription
points - Array.<Object> - - An array of data points, each with x and y - coordinates (and optionally a title). -
w - number - - The width of the plot area. -
h - number - - The height of the plot area. -
id - string - - The ID of the HTML element where the plot will be - rendered. -
labels - Object - - An object containing labels for the x and y axes. -
dates - boolean - <optional>
false - A flag indicating whether the x-axis should - represent dates. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- init(self) -

-
-
-
- Initializes the component, setting up event listeners and - UI elements. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - The component object itself. -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- n_months_ago(reference_date, months) -

-
-
-
- Calculates a date that is `months` months ago from a given - reference date. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
reference_date - Date - - The reference date from which to calculate the past - date. -
months - number - - The number of months to go back. -
- -
- -
Returns:
- -
- A new Date object representing the date `months` months - ago from the reference date. -
- -
-
Type
-
- Date -
-
-
- -
-
-

- normalize_node_attributes() -

-
-
-
- normalize_node_attributes Iterate over node attributes, - lower case all the keys for mapping. If attributes are - found that are not in the data dictionary, attempt to map - them using "labels". -
- -
-
- -
-
-

- open_editor(self, - node_set, name, description, cluster_kind, kind_options, - validation_mode, existing_set, cluster_tracking, - created_by) -

-
-
-
- Opens a priority node set editor. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - The main network visualization object. -
node_set - Array - - An existing priority node set (optional). -
name - string - - Name of the priority node set (optional for new - sets). -
description - string - - Description of the priority node set (optional). -
cluster_kind - string - - The method used to identify the cluster (optional). -
kind_options - Array - - Available options for cluster identification - methods. -
validation_mode - string - - Indicates the mode (create, validate, revise). -
existing_set - Object - - Reference to the existing priority node set (for - revisions). -
cluster_tracking - string - - Method for tracking cluster growth (optional). -
created_by - string - - Who created the node set (system or manual). -
- -
-
- -
-
-

- priority_groups_add_set(self, nodeset, update_table, - not_validated, prior_name, op_code) -

-
-
-
- Adds a new priority set to the network visualization. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - The main network visualization object. -
nodeset - Object - - The object representing the new priority set. -
update_table - boolean - - Flag indicating whether to update the priority set - table. (optional) -
not_validated - boolean - - Flag indicating whether to perform validation before - adding. (optional) -
prior_name - string - - Optional name of an existing priority set to - replace. -
op_code - string - - Optional operation code (defaults to "insert"). -
- -
- -
Returns:
- -
- True if the set was added successfully, false otherwise. -
- -
-
Type
-
- boolean -
-
-
- -
-
-

- priority_groups_check_name(defined_priority_groups, - string [, prior_name]) -

-
-
-
- A valid name must: - Have a length between 1 and 35 - characters. - Not be a duplicate among existing priority - groups (excluding itself if editing). -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
- defined_priority_groups - - Array.<Object> - - An array of existing priority group objects. -
string - string - - The name to be validated. -
prior_name - string - <optional>
- (optional) - The previous name of the priority group - (used for edit case). -
- -
- -
Returns:
- -
- True if the name is valid, false otherwise. -
- -
-
Type
-
- boolean -
-
-
- -
-
-

- priority_set_inject_node_attibutes(self, nodes, - node_attributes) -

-
-
-
- Injects priority set related attributes into network - nodes. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - The main network visualization object. -
nodes - Array - - Array of network nodes. -
node_attributes - Array - - Array of priority set attributes for specific nodes - (identified by name). -
- -
-
- -
-
-

- priority_set_view(self, priority_set, options) -

-
-
-
- Creates a subcluster view for a specific priority set. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - The main network visualization object. -
priority_set - Object - - The priority set object. -
options - Object - - Optional configuration options for the view. -
- -
-
- -
-
-

- random_id( [alphabet] - [, length]) -

-
-
-
- Generates a random ID string using a specified alphabet - and length. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
alphabet - Array.<string> - <optional>
- An optional array of characters to use in the ID. If - not provided, a default alphabet of letters "a" to - "g" is used. -
length - number - <optional>
- An optional length for the ID. If not provided, a - default length of 32 is used. -
- -
- -
Returns:
- -
- A randomly generated ID string. -
- -
-
Type
-
- string -
-
-
- -
-
-

- secure_hiv_trace_subcluster_columns(self) -

-
-
-
- Defines secure column definitions for HIV Trace subcluster - data. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
self - Object - - (optional) - The object containing context for - calculations (presumably the component using this - function). -
- -
- -
Returns:
- -
- An array of column definition objects. Each object has the - following properties: - `description`: - `value`: (string) - The human-readable name of the column. - `sort`: - (function) A function used to sort the column data. - - `presort` (string, optional): The default sort direction - ("asc" or "desc"). - `help`: (string) Help text displayed - when hovering over the column header. - `generator`: - (function) A function that generates the value and actions - for each cluster based on the provided cluster object. - - The generator function receives the cluster object as an - argument. - It should return an object with the following - properties: - `html`: (boolean) Whether the column value - should be rendered as HTML. - `value`: (array|string) The - actual data for the column. - `volatile`: (boolean, - optional) Whether the value needs to be recalculated - frequently. - `format`: (function, optional) A function - used to format the column value for display. - `actions`: - (function, optional) A function used to generate actions - for the column. - The actions function receives two - arguments: - `item`: (object) The current cluster object. - - `value`: (array|string) The value of the column for the - current cluster. - It should return an array of action - objects, each with the following properties: - `icon`: - (string) The icon class name to display for the action. - - `action`: (function) The function executed when the action - is clicked. - The action function receives two arguments: - - `button`: (jQuery object) The button element - representing the action. - `v`: (array|string) The value - of the column for the current cluster. - `help`: (string) - The help text displayed when hovering over the action - icon. -
- -
-
Type
-
- Array.<Object> -
-
-
- -
-
-

- sort_table_by_column(element, datum) -

-
-
-
- Sorts a D3 table based on the clicked column header. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
element - d3.selection - | - - HTMLElement - - HTML element representing the clicked column header. -
datum - * - - (optional) - The data object associated with the - table (used internally). -
- -
- -
Returns:
- -
-
Type
-
- void -
-
-
- -
-
-

- sort_table_toggle_icon(element [, value]) -

-
-
-
- Toggles the sort icon on a column header and returns a - sorting function. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
element - d3.selection - | - - HTMLElement - - The D3 selection or HTML element representing the - column header. -
value - string - <optional>
- (optional) - The desired sort direction ("asc", - "desc", or "unsorted"). -
- -
- -
Returns:
- -
- - If `value` is provided, returns nothing. - If `value` is - not provided, returns a sorting function (`d3.ascending` - or `d3.descending`) based on the current sort state. -
- -
-
Type
-
- function - | - - void -
-
-
- -
-
-

- table_get_cell_value(data) -

-
-
-
- Retrieves the value of a cell in a table data object. -
- -
Parameters:
- - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
data - Object - - The data object representing the table cell. It - should have a `value` property. -
- -
- -
Returns:
- -
- The value of the cell, or the result of calling - `data.value()` if it's a function. -
- -
-
Type
-
- * -
-
-
- -
-
-

- unpack_compact_json() -

-
-
-
- unpack_compact_json: If the input network JSON is in - compact form, i.e. instead of storing key : value it - stores key : integer index of value unique_values: list of - values convert it to key: value The operation is performed - in place on the `json` argument -
- -
-
-
-
-
-
-
- -
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - diff --git a/docs/clusternetwork.js.html b/docs/clusternetwork.js.html new file mode 100644 index 0000000..087f354 --- /dev/null +++ b/docs/clusternetwork.js.html @@ -0,0 +1,7758 @@ + + + + + JSDoc: Source: clusternetwork.js + + + + + + + + + + +
+ +

Source: clusternetwork.js

+ + + + + + +
+
+
import * as d3 from "d3";
+import _ from "underscore";
+import jsConvert from "js-convert-case";
+import * as topojson from "topojson";
+import * as helpers from "./helpers.js";
+import * as colorPicker from "./colorPicker.js";
+import * as scatterPlot from "./scatterplot.js";
+import * as tables from "./tables.js";
+import * as timeDateUtil from "./timeDateUtil.js";
+import * as nodesTab from "./nodesTab.js";
+import * as clustersOfInterest from "./clustersOfInterest.js";
+import { hivtrace_cluster_depthwise_traversal } from "./misc";
+import * as misc from "./misc";
+import * as kGlobals from "./globals.js";
+import * as network from "./network.js";
+import * as HTX from "./hiv_tx_network.js";
+import * as columnDefinitions from "./column_definitions.js";
+
+var hivtrace_cluster_network_graph = function (
+  json,
+  network_container,
+  network_status_string,
+  network_warning_tag,
+  button_bar_ui,
+  attributes,
+  filter_edges_toggle,
+  clusters_table,
+  nodes_table,
+  parent_container,
+  options
+) {
+  // [REQ] json                        :          the JSON object containing network nodes, edges, and meta-information
+  // [REQ] network_container           :          the CSS selector of the DOM element where the SVG containing the network will be placed (e.g. '#element')
+  // [OPT] network_status_string       :          the CSS selector of the DOM element where the text describing the current state of the network is shown (e.g. '#element')
+  // [OPT] network_warning_tag         :          the CSS selector of the DOM element where the any warning messages would go (e.g. '#element')
+  // [OPT] button_bar_ui               :          the ID of the control bar which can contain the following elements (prefix = button_bar_ui value)
+  //                                                - [prefix]_cluster_operations_container : a drop-down for operations on clusters
+  //                                                - [prefix]_attributes :  a drop-down for operations on attributes
+  //                                                - [prefix]_filter : a text box used to search the graph
+  // [OPT] network_status_string       :          the CSS selector of the DOM element where the text describing the current state of the network is shown (e.g. '#element')
+  // [OPT] attributes                  :          A JSON object with mapped node attributes
+
+  // unpack compact JSON if needed
+
+  if (json.Settings && json.Settings.compact_json) {
+    network.unpack_compact_json(json);
+  }
+
+  // if schema is not set, set to an empty dictionary
+  if (!json[kGlobals.network.GraphAttrbuteID]) {
+    json[kGlobals.network.GraphAttrbuteID] = {};
+  }
+
+  // Make attributes case-insensitive by LowerCasing all keys in schema
+  json[kGlobals.network.GraphAttrbuteID] = Object.fromEntries(
+    Object.entries(json[kGlobals.network.GraphAttrbuteID]).map(([k, v]) => [
+      k.toLowerCase(),
+      v,
+    ])
+  );
+
+  // Attempt Translations
+  $("#filter_input")
+    .val("")
+    .attr("placeholder", __("network_tab")["text_in_attributes"]);
+  $("#show_as").html(__("attributes_tab")["show_as"]);
+
+  network.normalize_node_attributes(json);
+  network.ensure_node_attributes_exist(json);
+
+  /** SLKP 20190902: somehow some of our networks have malformed edges! This will remove them */
+  json.Edges = _.filter(json.Edges, (e) => "source" in e && "target" in e);
+
+  var self = new HTX.HIVTxNetwork(json, button_bar_ui);
+
+  self._is_CDC_ = options && options["no_cdc"] ? false : true;
+  self._is_seguro = network.check_network_option(
+    options,
+    "seguro",
+    false,
+    true
+  );
+  self._is_CDC_executive_mode = network.check_network_option(
+    options,
+    "cdc-executive-mode",
+    false
+  );
+
+  self.uniqValues = helpers.getUniqueValues(
+    json.Nodes,
+    json[kGlobals.network.GraphAttrbuteID]
+  );
+  self.uniqs = _.mapObject(self.uniqValues, (d) => d.length);
+
+  self.schema = json[kGlobals.network.GraphAttrbuteID];
+  // set initial color schemes
+  self.networkColorScheme = kGlobals.PresetColorSchemes;
+  self.networkShapeScheme = kGlobals.PresetShapeSchemes;
+
+  self.ww = network.check_network_option(
+    options,
+    "width",
+    d3.select(parent_container).property("clientWidth")
+  );
+
+  self.margin = {
+    top: 20,
+    right: 10,
+    bottom: 30,
+    left: 10,
+  };
+  self.width = self.ww - self.margin.left - self.margin.right;
+  self.height = (self.width * 9) / 16;
+
+  self.container = network_container;
+  self.nodes = [];
+  self.edges = [];
+  self.clusters = [];
+  self.cluster_sizes = [];
+  self.cluster_mapping = {};
+  self.percent_format = kGlobals.formats.PercentFormat;
+  self.missing = kGlobals.missing.label;
+  self.cluster_attributes = json["Cluster description"] || null;
+  self.precomputed_subclusters = json["Subclusters"] || null;
+  self.network_warning_tag = network_warning_tag;
+
+  self.annotate_cluster_changes();
+
+  self.filter_edges = true;
+  self.hide_hxb2 = false;
+  self.cluster_table = d3.select(clusters_table);
+
+  if (self._is_CDC_) {
+    self.priority_set_table = network.check_network_option(
+      options,
+      "priority-table"
+    );
+    self.priority_set_table_write = network.check_network_option(
+      options,
+      "priority-table-writeback"
+    );
+    if (self.priority_set_table)
+      self.priority_set_table = d3.select(self.priority_set_table);
+  } else {
+    self.priority_set_table = null;
+    self.priority_set_table_write = null;
+  }
+
+  self.needs_an_update = false;
+  self.hide_unselected = false;
+  self.show_percent_in_pairwise_table = false;
+
+  self.priority_set_table_writeable = true;
+
+  /** if there's a function passed as "init_code", run it now */
+
+  if (options && _.isFunction(options["init_code"])) {
+    options["init_code"].call(null, self, options);
+  }
+
+  /** Whenever the code creates a DOM element, it will be done using this prefix 
+      to generate element IDs
+   */
+
+  self.dom_prefix = network.check_network_option(
+    options,
+    "prefix",
+    "hiv-trace"
+  );
+
+  /** Retrieve additional columns (as dict, see comments further down in the code)
+      for the "clusters" table
+  
+   */
+  self.extra_cluster_table_columns = network.check_network_option(
+    options,
+    "cluster-table-columns",
+    null
+  );
+
+  /** Not primary networks are individual cluster/subcluster views.
+      They don't interfere with the primary network object, and UI elements
+  
+   */
+
+  self.isPrimaryGraph = network.check_network_option(
+    options,
+    "secondary",
+    true,
+    false
+  );
+
+  self.parent_graph_object = network.check_network_option(
+    options,
+    "parent_graph",
+    null
+  );
+
+  /** set the TODAY date for the network*/
+
+  if (json.Settings && json.Settings.created) {
+    self.today = new Date(json.Settings.created);
+  } else {
+    self.today = network.check_network_option(
+      options,
+      "today",
+      timeDateUtil.getCurrentDate()
+    );
+  }
+
+  /** get the reference (creation) date for the network.
+      it's the same as "today" for primary networks,
+      but is inherited from parent networks for secondary graphs (e.g. cluster or subcluster views)
+  */
+
+  if (self._is_CDC_) {
+    // define various CDC settings
+
+    /** Do not automatically create CoI */
+    self._is_CDC_auto_mode = network.check_network_option(
+      options,
+      "cdc-no-auto-priority-set-mode",
+      true,
+      false
+    );
+
+    /** these are the default columns selected in the "nodes" table */
+
+    self.displayed_node_subset = network.check_network_option(
+      options,
+      "node-attributes",
+      [
+        tables._networkNodeIDField,
+        "sex_trans",
+        "race_cat",
+        "hiv_aids_dx_dt",
+        "cur_city_name",
+      ]
+    );
+
+    /** retrieve the target DOM ID for placing the "subcluster" table into */
+    self.subcluster_table = network.check_network_option(
+      options,
+      "subcluster-table",
+      null,
+      d3.select(options["subcluster-table"])
+    );
+
+    /** extra column definitions for the subcluster table */
+    self.extra_subcluster_table_columns = null;
+
+    // SLKP 20200727 issues
+
+    /** Secure HIV-TRACE specific settings */
+    self.CDC_data = {
+      jurisdiction: self
+        .lookup_option("jurisdiction", "unknown", options)
+        .toLowerCase()
+        .replace(/\s/g, ""),
+      timestamp: self.today,
+      "autocreate-priority-set-size": 5,
+    };
+
+    /** What jurisdiction are we using for Secure HIV-TRACE?
+        This determines the two-letter prefix for auto-naming Clusters of Interest
+        If none, use PG prefix
+     */
+
+    if (self.CDC_data.jurisdiction in kGlobals.CDCJurisdictionCodes) {
+      self.CDC_data["jurisdiction_code"] =
+        kGlobals.CDCJurisdictionCodes[self.CDC_data.jurisdiction].toUpperCase();
+    } else {
+      self.CDC_data["jurisdiction_code"] = "PG";
+    }
+
+    /** Check if this is a low morbidity jurisdiction */
+    if (
+      kGlobals.CDCJurisdictionLowMorbidity.has(self.CDC_data["jurisdiction"])
+    ) {
+      self.CDC_data["autocreate-priority-set-size"] = 3;
+    }
+
+    /** Populate column table definitions */
+    if (self.subcluster_table) {
+      self.extra_subcluster_table_columns =
+        columnDefinitions.secure_hiv_trace_subcluster_columns(self);
+    } else if (self.extra_cluster_table_columns) {
+      self.extra_cluster_table_columns =
+        self.extra_cluster_table_columns.concat(
+          columnDefinitions.secure_hiv_trace_subcluster_columns(self)
+        );
+    } else {
+      self.extra_cluster_table_columns =
+        columnDefinitions.secure_hiv_trace_subcluster_columns(self);
+    }
+  } // end self._is_CDC_
+
+  if (self._is_CDC_) {
+    self.extra_node_table_columns = null;
+  } else {
+    self.extra_node_table_columns = network.check_network_option(
+      options,
+      "node-table-columns"
+    );
+  }
+
+  /** default subcluster definition threshold */
+  self.subcluster_threshold = network.check_network_option(
+    options,
+    "subcluster-thershold",
+    0.005
+  );
+
+  clustersOfInterest.init(self);
+  nodesTab.init(d3.select(nodes_table));
+
+  self.countryCentersObject = network.check_network_option(
+    options,
+    "country-centers"
+  );
+  self.countryOutlines = network.check_network_option(
+    options,
+    "country-outlines"
+  );
+
+  if (self.countryCentersObject && self.countryOutlines) {
+    self._calc_country_nodes(options);
+    self.showing_on_map = options.showing_on_map;
+  } else {
+    self.showing_on_map = false;
+  }
+
+  /** this array contains fields that will be appended to node pop-overs in the network tab
+      they will precede all the fields that are shown based on selected labeling */
+  self._additional_node_pop_fields = [];
+
+  self.minimum_cluster_size = network.check_network_option(
+    options,
+    "minimum size",
+    5
+  );
+
+  timeDateUtil.init(options, self._is_CDC_, timeDateUtil._networkCDCDateField);
+
+  if (self._is_CDC_) {
+    self._additional_node_pop_fields.push(timeDateUtil._networkCDCDateField);
+  }
+
+  self.core_link_length = network.check_network_option(
+    options,
+    "core-link",
+    -1
+  );
+  self.additional_edge_styler = network.check_network_option(
+    options,
+    "edge-styler"
+  );
+
+  if (self.json.Notes) {
+    _.each(self.json.Notes, (s) => (self.warning_string += s + "<br>"));
+  }
+
+  /**
+    the true branch is taken if the network JSON contains "Cluster description"
+  */
+  if (self.cluster_attributes) {
+    self.warning_string += __("network_tab")["cluster_display_info"];
+    self.showing_diff = true;
+    self.cluster_filtering_functions["new"] = self.filter_if_added;
+  } else {
+    self.showing_diff = false;
+    if (
+      timeDateUtil.getClusterTimeScale() &&
+      "Cluster sizes" in self.json &&
+      self.json["Cluster sizes"].length > 250
+    ) {
+      self.using_time_filter = timeDateUtil.getCurrentDate();
+      self.warning_string += __("network_tab")["cluster_display_info"];
+      self.using_time_filter.setFullYear(
+        self.using_time_filter.getFullYear() - 1
+      );
+      self.cluster_filtering_functions["recent"] = self.filter_time_period;
+    }
+  }
+
+  self.initial_packed =
+    options && options["initial_layout"] === "tiled" ? false : true;
+
+  self._networkPredefinedAttributeTransforms = {
+    /** runtime computed node attributes, e.g. transforms of existing attributes */
+
+    binned_vl_recent_value: self.define_attribute_binned_vl(
+      "vl_recent_value",
+      "Most Recent Viral Load Category Binned"
+    ),
+
+    binned_vl_recent_value_adj: self.define_attribute_binned_vl(
+      "vl_recent_value_adj",
+      "Most Recent Viral Load Category Binned"
+    ),
+
+    vl_result_interpretation: self.define_attribute_vl_interpretaion(),
+
+    age_dx_normalized: self.define_attribute_age_dx(),
+
+    years_since_dx: self.define_attribute_dx_years(
+      true,
+      "Years since diagnosis"
+    ),
+
+    hiv_aids_dx_dt_year: self.define_attribute_dx_years(
+      false,
+      "Diagnosis Year"
+    ),
+  };
+
+  if (self.cluster_attributes) {
+    self._networkPredefinedAttributeTransforms["_newly_added"] =
+      self.define_attribute_network_update();
+  }
+
+  /** inject any attributes passed through "computed-attributes" */
+
+  if (options && options["computed-attributes"]) {
+    _.extend(
+      self._networkPredefinedAttributeTransforms,
+      options["computed-attributes"]
+    );
+  }
+
+  /*------------ Network layout code ---------------*/
+
+  self._get_node_country = function (node) {
+    var countryCodeAlpha2 = self.attribute_node_value_by_id(node, "country");
+    if (countryCodeAlpha2 === kGlobals.missing.label) {
+      countryCodeAlpha2 = self.attribute_node_value_by_id(node, "Country");
+    }
+    return countryCodeAlpha2;
+  };
+
+  self._draw_topomap = function (no_redraw) {
+    if (options && "showing_on_map" in options) {
+      var countries = topojson.feature(
+        self.countryOutlines,
+        self.countryOutlines.objects.countries
+      ).features;
+      var mapsvg = d3.select("#" + self.dom_prefix + "-network-svg");
+      var path = d3.geo.path().projection(self.mapProjection);
+      countries = mapsvg.selectAll(".country").data(countries);
+
+      countries.enter().append("path");
+      countries.exit().remove();
+
+      self.countries_in_cluster = {};
+
+      _.each(self.nodes, (node) => {
+        var countryCodeAlpha2 = self._get_node_country(node);
+        var countryCodeNumeric =
+          self.countryCentersObject[countryCodeAlpha2].countryCodeNumeric;
+        if (!(countryCodeNumeric in self.countries_in_cluster)) {
+          self.countries_in_cluster[countryCodeNumeric] = true;
+        }
+      });
+
+      countries
+        .attr("class", "country")
+        .attr("d", path)
+        .attr("stroke", "saddlebrown")
+        .attr("fill", (d) => {
+          if (d.id in self.countries_in_cluster) {
+            return "navajowhite";
+          }
+          return "bisque";
+        })
+        .attr("stroke-width", (d) => {
+          if (d.id in self.countries_in_cluster) {
+            return 1.5;
+          }
+          return 0.5;
+        });
+    }
+    return self;
+  };
+
+  self.open_exclusive_tab_close = function (
+    tab_element,
+    tab_content,
+    restore_to_tag
+  ) {
+    //console.log (restore_to_tag);
+    $(restore_to_tag).tab("show");
+    $("#" + tab_element).remove();
+    $("#" + tab_content).remove();
+  };
+
+  self.open_exclusive_tab_view = function (
+    cluster_id,
+    custom_filter,
+    custom_name,
+    additional_options,
+    include_injected_edges
+  ) {
+    var cluster = _.find(
+      self.clusters,
+      (c) => String(c.cluster_id) === String(cluster_id)
+    );
+
+    if (!cluster) {
+      return;
+    }
+
+    additional_options = additional_options || {};
+
+    additional_options["parent_graph"] = self;
+
+    var filtered_json = self.extract_single_cluster(
+      custom_filter
+        ? _.filter(self.json.Nodes, custom_filter)
+        : cluster.children,
+      null,
+      null,
+      null,
+      include_injected_edges
+    );
+
+    if (kGlobals.network.GraphAttrbuteID in json) {
+      filtered_json[kGlobals.network.GraphAttrbuteID] = {};
+      $.extend(
+        true,
+        filtered_json[kGlobals.network.GraphAttrbuteID],
+        json[kGlobals.network.GraphAttrbuteID]
+      );
+    }
+
+    var export_items = [];
+    if (!self._is_CDC_executive_mode) {
+      export_items.push([
+        "Export cluster to .CSV",
+        function (network) {
+          helpers.export_csv_button(
+            self._extract_attributes_for_nodes(
+              self._extract_nodes_by_id(cluster_id),
+              self._extract_exportable_attributes()
+            )
+          );
+        },
+      ]);
+    }
+
+    //self._check_for_time_series(export_items);
+
+    if ("extra_menu" in additional_options) {
+      _.each(export_items, (item) => {
+        additional_options["extra_menu"]["items"].push(item);
+      });
+    } else {
+      _.extend(additional_options, {
+        extra_menu: {
+          title: "Action",
+          items: export_items,
+        },
+      });
+    }
+
+    return self.open_exclusive_tab_view_aux(
+      filtered_json,
+      custom_name ? custom_name(cluster_id) : "Cluster " + cluster_id,
+      additional_options
+    );
+  };
+
+  self.open_exclusive_tab_view_aux = function (
+    filtered_json,
+    title,
+    option_extras
+  ) {
+    var random_prefix = misc.random_id();
+    var random_tab_id = random_prefix + "_tab";
+    var random_content_id = random_prefix + "_div";
+    var random_button_bar = random_prefix + "_ui";
+
+    while (
+      $("#" + random_tab_id).length ||
+      $("#" + random_content_id).length ||
+      $("#" + random_button_bar).length
+    ) {
+      random_prefix = misc.random_id();
+      random_tab_id = random_prefix + "_tab";
+      random_content_id = random_prefix + "_div";
+      random_button_bar = random_prefix + "_ui";
+    }
+
+    var tab_container = "top_level_tab_container";
+    var content_container = "top_level_tab_content";
+    var go_here_when_closed = "#trace-default-tab";
+
+    // add new tab to the menu bar and switch to it
+    var new_tab_header = $("<li></li>").attr("id", random_tab_id);
+
+    var new_link = $("<a></a>")
+      .attr("href", "#" + random_content_id)
+      .attr("data-toggle", "tab")
+      .text(title);
+    $(
+      '<button type="button" class="close" aria-label="Close"><span aria-hidden="true">&times;</span></button>'
+    )
+      .appendTo(new_link)
+      .on("click", () => {
+        self.open_exclusive_tab_close(
+          random_tab_id,
+          random_content_id,
+          go_here_when_closed
+        );
+      });
+
+    new_link.appendTo(new_tab_header);
+    $("#" + tab_container).append(new_tab_header);
+
+    var new_tab_content = $("<div></div>")
+      .addClass("tab-pane")
+      .attr("id", random_content_id)
+      .data("cluster", option_extras.cluster_id);
+
+    if (option_extras.type === "subcluster") {
+      new_tab_content
+        .addClass("subcluster-view")
+        .addClass("subcluster-" + option_extras.cluster_id.replace(".", "_"));
+    }
+
+    //     <li class='disabled' id="attributes-tab"><a href="#trace-attributes" data-toggle="tab">Attributes</a></li>
+    var new_button_bar;
+    if (filtered_json) {
+      new_button_bar = $('[data-hivtrace="cluster-clone"]')
+        .clone()
+        .attr("data-hivtrace", null);
+      new_button_bar
+        .find("[data-hivtrace-button-bar='yes']")
+        .attr("id", random_button_bar)
+        .addClass("cloned-cluster-tab")
+        .attr("data-hivtrace-button-bar", null);
+
+      new_button_bar.appendTo(new_tab_content);
+    }
+    new_tab_content.appendTo("#" + content_container);
+
+    $(new_link).on("show.bs.tab", (e) => {
+      //console.log (e);
+      if (e.relatedTarget) {
+        //console.log (e.relatedTarget);
+        go_here_when_closed = e.relatedTarget;
+      }
+    });
+
+    // show the new tab
+    $(new_link).tab("show");
+
+    var cluster_view;
+
+    if (filtered_json) {
+      var cluster_options = {
+        no_cdc: options && options["no_cdc"],
+        "minimum size": 0,
+        secondary: true,
+        prefix: random_prefix,
+        extra_menu:
+          options && "extra_menu" in options ? options["extra_menu"] : null,
+        "edge-styler":
+          options && "edge-styler" in options ? options["edge-styler"] : null,
+        "no-subclusters": true,
+        "no-subcluster-compute": false,
+      };
+
+      if (option_extras) {
+        _.extend(cluster_options, option_extras);
+      }
+
+      if (
+        option_extras.showing_on_map &&
+        self.countryCentersObject &&
+        self.countryOutlines
+      ) {
+        cluster_options["showing_on_map"] = true;
+        cluster_options["country-centers"] = self.countryCentersObject;
+        cluster_options["country-outlines"] = self.countryOutlines;
+
+        // Create an array of the countries in the selected cluster for use in styling the map.
+        if ("extra-graphics" in cluster_options) {
+          var draw_map = function (other_code, network) {
+            other_code(network);
+            return network._draw_topomap();
+          };
+
+          cluster_options["extra-graphics"] = _.wrap(
+            draw_map,
+            cluster_options["extra-graphics"]
+          );
+        } else {
+          cluster_options["extra-graphics"] = function (network) {
+            return network._draw_topomap();
+          };
+        }
+      }
+
+      cluster_options["today"] = self.today;
+
+      cluster_view = hivtrace_cluster_network_graph(
+        filtered_json,
+        "#" + random_content_id,
+        null,
+        null,
+        random_button_bar,
+        attributes,
+        null,
+        null,
+        null,
+        parent_container,
+        cluster_options
+      );
+
+      if (self.colorizer["category_id"]) {
+        if (self.colorizer["continuous"]) {
+          cluster_view.handle_attribute_continuous(
+            self.colorizer["category_id"]
+          );
+        } else {
+          cluster_view.handle_attribute_categorical(
+            self.colorizer["category_id"]
+          );
+        }
+      }
+
+      if (self.node_shaper["id"]) {
+        cluster_view.handle_shape_categorical(self.node_shaper["id"]);
+      }
+
+      if (self.colorizer["opacity_id"]) {
+        cluster_view.handle_attribute_opacity(self.colorizer["opacity_id"]);
+      }
+
+      cluster_view.expand_cluster_handler(cluster_view.clusters[0], true);
+    } else {
+      return new_tab_content.attr("id");
+    }
+    return cluster_view;
+  };
+
+  // ensure all checkboxes are unchecked at initialization
+  $('input[type="checkbox"]').prop("checked", false);
+
+  var handle_node_click = function (node) {
+    if (d3.event.defaultPrevented) return;
+    var container = d3.select(self.container);
+    var id = "d3_context_menu_id";
+    var menu_object = container.select("#" + id);
+
+    if (menu_object.empty()) {
+      menu_object = container
+        .append("ul")
+        .attr("id", id)
+        .attr("class", "dropdown-menu")
+        .attr("role", "menu");
+    }
+
+    menu_object.selectAll("li").remove();
+
+    if (node) {
+      node.fixed = 1;
+      menu_object
+        .append("li")
+        .append("a")
+        .attr("tabindex", "-1")
+        .text(__("clusters_main")["collapse_cluster"])
+        .on("click", (d) => {
+          node.fixed = 0;
+          collapse_cluster_handler(node, true);
+          menu_object.style("display", "none");
+        });
+
+      menu_object
+        .append("li")
+        .append("a")
+        .attr("tabindex", "-1")
+        .text((d) => (node.show_label ? "Hide text label" : "Show text label"))
+        .on("click", (d) => {
+          node.fixed = 0;
+          //node.show_label = !node.show_label;
+          handle_node_label(container, node);
+          //collapse_cluster_handler(node, true);
+          menu_object.style("display", "none");
+        });
+
+      if (clustersOfInterest.get_editor()) {
+        menu_object
+          .append("li")
+          .append("a")
+          .attr("tabindex", "-1")
+          .text((d) => "Add this node to the cluster of interest")
+          .on("click", (d) => {
+            clustersOfInterest.get_editor().append_node(node.id, true);
+          });
+      }
+
+      // SW20180605 : To be implemented
+
+      //menu_object
+      //  .append("li")
+      //  .append("a")
+      //  .attr("tabindex", "-1")
+      //  .text("Show sequences used to make cluster")
+      //  .on("click", function(d) {
+      //    node.fixed = 0;
+      //    show_sequences_in_cluster (node, true);
+      //    menu_object.style("display", "none");
+      //  });
+
+      menu_object
+        .style("position", "absolute")
+        .style("left", String(d3.event.offsetX) + "px")
+        .style("top", String(d3.event.offsetY) + "px")
+        .style("display", "block");
+    } else {
+      menu_object.style("display", "none");
+    }
+
+    container.on(
+      "click",
+      (d) => {
+        handle_node_click(null);
+      },
+      true
+    );
+  };
+
+  function get_initial_xy(packed) {
+    // create clusters from nodes
+    var mapped_clusters = get_all_clusters(self.nodes);
+
+    var d_clusters = {
+      id: "root",
+      children: [],
+    };
+
+    // filter out clusters that are to be excluded
+    if (self.exclude_cluster_ids) {
+      mapped_clusters = _.omit(mapped_clusters, self.exclude_cluster_ids);
+    }
+
+    d_clusters.children = _.map(mapped_clusters, (value, key) => ({
+      cluster_id: key,
+      children: value,
+    }));
+
+    var treemap = packed
+      ? d3.layout
+          .pack()
+          .size([self.width, self.height])
+          //.sticky(true)
+          .children((d) => d.children)
+          .value((d) => d.parent.children.length ** 1.5)
+          .sort((a, b) => b.value - a.value)
+          .padding(5)
+      : d3.layout
+          .treemap()
+          .size([self.width, self.height])
+          //.sticky(true)
+          .children((d) => d.children)
+          .value((d) => d.parent.children.length ** 1.0)
+          .sort((a, b) => a.value - b.value)
+          .ratio(1);
+
+    var clusters = treemap.nodes(d_clusters);
+    _.each(clusters, (c) => {
+      //c.fixed = true;
+    });
+    return clusters;
+  }
+
+  function prepare_data_to_graph() {
+    var graphMe = {};
+    graphMe.all = [];
+    graphMe.edges = [];
+    graphMe.nodes = [];
+    graphMe.clusters = [];
+
+    var expandedClusters = [];
+    var drawnNodes = [];
+
+    self.clusters.forEach((x) => {
+      if (self.cluster_display_filter(x)) {
+        // Check if hxb2_linked is in a child
+        var hxb2_exists =
+          x.children.some((c) => c.hxb2_linked) && self.hide_hxb2;
+        if (!hxb2_exists) {
+          if (x.collapsed) {
+            graphMe.clusters.push(x);
+            graphMe.all.push(x);
+          } else {
+            expandedClusters[x.cluster_id] = true;
+          }
+        }
+      }
+    });
+
+    self.nodes.forEach((x, i) => {
+      if (expandedClusters[x.cluster]) {
+        drawnNodes[i] = graphMe.nodes.length + graphMe.clusters.length;
+        graphMe.nodes.push(x);
+        graphMe.all.push(x);
+      }
+    });
+
+    self.edges.forEach((x) => {
+      if (!(x.removed && self.filter_edges)) {
+        if (
+          drawnNodes[x.source] !== undefined &&
+          drawnNodes[x.target] !== undefined
+        ) {
+          var y = {};
+          for (var prop in x) {
+            y[prop] = x[prop];
+          }
+
+          y.source = drawnNodes[x.source];
+          y.target = drawnNodes[x.target];
+          y.ref = x;
+          graphMe.edges.push(y);
+        }
+      }
+    });
+
+    return graphMe;
+  }
+
+  self._refresh_subcluster_view = function (set_date) {
+    self.annotate_priority_clusters(
+      timeDateUtil._networkCDCDateField,
+      36,
+      12,
+      set_date
+    );
+
+    var field_def = self.define_attribute_COI_membership(self, set_date);
+
+    //console.log (field_def.dimension);
+
+    if (field_def) {
+      _.each(self.nodes, (node) => {
+        const attr_v = field_def["map"](node, self);
+        HTX.HIVTxNetwork.inject_attribute_node_value_by_id(
+          node,
+          "subcluster_temporal_view",
+          attr_v
+        );
+      });
+
+      self.inject_attribute_description("subcluster_temporal_view", field_def);
+      self._aux_process_category_values(
+        self._aux_populate_category_fields(
+          field_def,
+          "subcluster_temporal_view"
+        )
+      );
+      self.handle_attribute_categorical("subcluster_temporal_view");
+    }
+  };
+
+  self.view_subcluster = function (
+    cluster,
+    custom_filter,
+    custom_name,
+    view_sub_options,
+    custom_edge_filter,
+    include_injected_edges,
+    length_threshold
+  ) {
+    length_threshold = length_threshold || self.subcluster_threshold;
+    let nodes = cluster.children;
+    if (custom_filter) {
+      if (_.isArray(custom_filter)) {
+        nodes = custom_filter;
+      } else {
+        nodes = _.filter(self.json.Nodes, custom_filter);
+      }
+    }
+    var filtered_json = self.extract_single_cluster(
+      nodes,
+      custom_edge_filter || ((e) => e.length <= length_threshold),
+      false,
+      null,
+      include_injected_edges
+    );
+
+    _.each(filtered_json.Nodes, (n) => {
+      n.subcluster_label = "1.1";
+    });
+
+    if (kGlobals.network.GraphAttrbuteID in json) {
+      filtered_json[kGlobals.network.GraphAttrbuteID] = {};
+      $.extend(
+        true,
+        filtered_json[kGlobals.network.GraphAttrbuteID],
+        json[kGlobals.network.GraphAttrbuteID]
+      );
+    }
+
+    view_sub_options = view_sub_options || {};
+
+    view_sub_options["parent_graph"] = self;
+
+    var extra_menu_items = [
+      [
+        function (network, item) {
+          var enclosure = item.append("div").classed("form-group", true);
+          enclosure
+            .append("label")
+            .text("Recalculate National Priority from ")
+            .classed("control-label", true);
+          enclosure
+            .append("input")
+            .attr("type", "date")
+            .classed("form-control", true)
+            .attr("value", timeDateUtil.DateViewFormatSlider(self.today))
+            .attr("max", timeDateUtil.DateViewFormatSlider(self.today))
+            .attr(
+              "min",
+              timeDateUtil.DateViewFormatSlider(
+                d3.min(network.nodes, (node) =>
+                  network.attribute_node_value_by_id(
+                    node,
+                    timeDateUtil._networkCDCDateField
+                  )
+                )
+              )
+            )
+            .on("change", function (e) {
+              //d3.event.preventDefault();
+              var set_date = timeDateUtil.DateViewFormatSlider.parse(
+                this.value
+              );
+              if (this.value) {
+                network._refresh_subcluster_view(set_date);
+
+                enclosure
+                  .classed("has-success", true)
+                  .classed("has-error", false);
+              } else {
+                enclosure
+                  .classed("has-success", false)
+                  .classed("has-error", true);
+              }
+            })
+            .on("click", (e) => {
+              d3.event.stopPropagation();
+            });
+        },
+        null,
+      ],
+    ];
+    if (!self._is_CDC_executive_mode) {
+      extra_menu_items.push([
+        "Export cluster to .CSV",
+        function (network) {
+          helpers.export_csv_button(
+            network._extract_attributes_for_nodes(
+              network._extract_nodes_by_id("1.1"),
+              network._extract_exportable_attributes()
+            )
+          );
+        },
+      ]);
+    }
+
+    view_sub_options["type"] = "subcluster";
+    view_sub_options["cluster_id"] = cluster.cluster_id || "N/A";
+    if ("extra_menu" in view_sub_options) {
+      view_sub_options["extra_menu"]["items"] =
+        view_sub_options["extra_menu"]["items"].concat(extra_menu_items);
+    } else {
+      view_sub_options["extra_menu"] = {
+        title: "Action",
+        items: extra_menu_items,
+      };
+    }
+
+    //self._check_for_time_series(extra_menu_items);
+    var cluster_view = self.open_exclusive_tab_view_aux(
+      filtered_json,
+      custom_name || "Subcluster " + cluster.cluster_id,
+      view_sub_options
+    );
+    if (!view_sub_options.skip_recent_rapid)
+      cluster_view.handle_attribute_categorical("subcluster_or_priority_node");
+    return cluster_view;
+
+    /*var selector =
+      ".subcluster-" +
+      cluster.id.replace(".", "_") +
+      " .show-small-clusters-button";
+
+    var item = $(
+      '<span class="input-group-addon btn view-parent-btn">View Parent</span>'
+    )
+      .data("cluster_id", cluster.parent_cluster.cluster_id)
+      .insertAfter(selector);
+
+    item.on("click", function(e) {
+      self.open_exclusive_tab_view($(this).data("cluster_id"));
+    });*/
+  };
+
+  var oldest_nodes_first = function (n1, n2) {
+    const date_field = date_field || timeDateUtil._networkCDCDateField;
+
+    // consistent node sorting, older nodes first
+    var node1_dx = self.attribute_node_value_by_id(n1, date_field);
+    var node2_dx = self.attribute_node_value_by_id(n2, date_field);
+
+    if (node1_dx === node2_dx) {
+      return n1.id < n2.id ? -1 : 1;
+    }
+    return node1_dx < node2_dx ? -1 : 1;
+  };
+
+  self.annotate_priority_clusters = function (
+    date_field,
+    span_months,
+    recent_months,
+    start_date
+  ) {
+    /* 
+        values for priority_flag
+            0: 0.5% subcluster
+            1: last 12 months NOT in a priority cluster
+            2: last 12 month IN priority cluster
+            3: in priority cluster but not in 12 months
+            4-7 is only computed for start dates different from the network date
+            4: date present but is in the FUTURE compared to start_date
+            5: date present but is between 1900 and start_date
+            6: date missing
+            7: in 0.5% cluster 12<dx<36 months but not a CoI
+            
+            
+        SLKP 20221128:
+            Add a calculation for simple classification of priority clusters
+            
+            0: not in a national priority CoI
+            1: IN a national priority CoI ≤12 months
+            2: IN a national priority CoI 12 - 36 months
+            3: IN a national priority CoI >36 months
+    */
+
+    try {
+      start_date = start_date || self.get_reference_date();
+
+      var cutoff_long = timeDateUtil.n_months_ago(start_date, span_months);
+      var cutoff_short = timeDateUtil.n_months_ago(start_date, recent_months);
+
+      var node_iterator;
+
+      if (start_date === self.today) {
+        node_iterator = self.nodes;
+      } else {
+        var beginning_of_time = timeDateUtil.getCurrentDate();
+        beginning_of_time.setYear(1900);
+        node_iterator = [];
+        _.each(self.nodes, (node) => {
+          var filter_result = self.filter_by_date(
+            beginning_of_time,
+            date_field,
+            start_date,
+            node
+            //true
+          );
+          if (_.isUndefined(filter_result)) {
+            node.priority_flag = 6;
+          } else if (filter_result) {
+            node.priority_flag = 5;
+            node_iterator.push(node);
+          } else {
+            node.priority_flag = 4;
+          }
+        });
+      }
+
+      // extract all clusters at once to avoid inefficiencies of multiple edge-set traversals
+
+      var split_clusters = {};
+      var node_id_to_local_cluster = {};
+
+      // reset all annotations
+
+      _.each(node_iterator, (node) => {
+        node.nationalCOI = 0;
+        if (node.cluster) {
+          if (!(node.cluster in split_clusters)) {
+            split_clusters[node.cluster] = { Nodes: [], Edges: [] };
+          }
+          node_id_to_local_cluster[node.id] =
+            split_clusters[node.cluster]["Nodes"].length;
+          split_clusters[node.cluster]["Nodes"].push(node);
+        }
+      });
+
+      _.each(self.edges, (edge) => {
+        if (edge.length <= self.subcluster_threshold) {
+          var edge_cluster = self.nodes[edge.source].cluster;
+
+          var source_id = self.nodes[edge.source].id;
+          var target_id = self.nodes[edge.target].id;
+
+          if (
+            source_id in node_id_to_local_cluster &&
+            target_id in node_id_to_local_cluster
+          ) {
+            var copied_edge = _.clone(edge);
+
+            copied_edge.source = node_id_to_local_cluster[source_id];
+            copied_edge.target = node_id_to_local_cluster[target_id];
+
+            split_clusters[edge_cluster]["Edges"].push(copied_edge);
+          }
+        }
+      });
+
+      const cluster_id_match =
+        self.precomputed_subclusters &&
+        self.subcluster_threshold in self.precomputed_subclusters
+          ? self.precomputed_subclusters
+          : null;
+
+      _.each(split_clusters, (cluster_nodes, cluster_index) => {
+        /** extract subclusters; all nodes at given threshold */
+        /** Sub-Cluster: all nodes connected at 0.005 subs/site; there can be multiple sub-clusters per cluster */
+
+        //var cluster_nodes       = self.extract_single_cluster (cluster.children, null, true);
+
+        var array_index = self.cluster_mapping[cluster_index];
+
+        self.clusters[array_index].priority_score = 0;
+
+        var edges = [];
+
+        /** all clusters with more than one member connected at 'threshold' edge length */
+        var subclusters = _.filter(
+          hivtrace_cluster_depthwise_traversal(
+            cluster_nodes.Nodes,
+            cluster_nodes.Edges,
+            null,
+            edges
+          ),
+          (cc) => cc.length > 1
+        );
+
+        /** all edge sets with more than one edge */
+        edges = _.filter(edges, (es) => es.length > 1);
+
+        /** sort subclusters by oldest node */
+        _.each(subclusters, (c, i) => {
+          c.sort(oldest_nodes_first);
+        });
+
+        subclusters.sort((c1, c2) => oldest_nodes_first(c1[0], c2[0]));
+
+        let next_id = subclusters.length + 1;
+
+        subclusters = _.map(subclusters, (c, i) => {
+          let subcluster_id = i + 1;
+
+          if (cluster_id_match) {
+            const precomputed_values = {};
+            _.each(c, (n) => {
+              if ("subcluster" in n) {
+                var sub_at_k = _.find(
+                  n.subcluster,
+                  (t) => t[0] === self.subcluster_threshold
+                );
+                if (sub_at_k) {
+                  precomputed_values[
+                    sub_at_k[1].split(kGlobals.SubclusterSeparator)[1]
+                  ] = 1;
+                  return;
+                }
+              }
+
+              precomputed_values[null] = 1;
+            });
+
+            if (
+              null in precomputed_values ||
+              _.keys(precomputed_values).length !== 1
+            ) {
+              subcluster_id = next_id++;
+            } else {
+              subcluster_id = _.keys(precomputed_values)[0];
+            }
+
+            /*if ((i+1) !== 0 + subcluster_id) {
+                console.log (self.clusters[array_index].cluster_id, i, "=>", subcluster_id, _.keys(precomputed_values));
+             }*/
+          }
+
+          var label =
+            self.clusters[array_index].cluster_id +
+            kGlobals.SubclusterSeparator +
+            subcluster_id;
+
+          _.each(c, (n) => {
+            //if (!("subcluster_label" in n)) {
+            n.subcluster_label = label;
+            //}
+            n.priority_flag = 0;
+          });
+
+          return {
+            children: _.clone(c),
+            parent_cluster: self.clusters[array_index],
+            cluster_id: label,
+            distances: helpers.describe_vector(
+              _.map(edges[i], (e) => e.length)
+            ),
+          };
+        });
+
+        _.each(subclusters, (c) => {
+          _compute_cluster_degrees(c);
+        });
+
+        self.clusters[array_index].subclusters = subclusters;
+
+        /** now, for each subcluster, extract the recent and rapid part */
+
+        /** Recent & Rapid (National Priority) Cluster: the part of the Sub-Cluster inferred using only cases diagnosed in the previous 36 months
+                and at least two cases dx-ed in the previous 12 months; there is a path between all nodes in a National Priority Cluster
+
+            20180406 SLKP: while unlikely, this definition could result in multiple National Priority clusters
+            per subclusters; for now we will add up all the cases for prioritization, and
+            display the largest National Priority cluster if there is more than one
+        */
+
+        _.each(subclusters, (sub) => {
+          // extract nodes based on dates
+
+          const date_filter = (n) =>
+            self.filter_by_date(cutoff_long, date_field, start_date, n);
+
+          var subcluster_json = self.extract_single_cluster(
+            _.filter(sub.children, date_filter),
+            null,
+            true,
+            cluster_nodes
+          );
+
+          var rr_cluster = _.filter(
+            hivtrace_cluster_depthwise_traversal(
+              subcluster_json.Nodes,
+              _.filter(
+                subcluster_json.Edges,
+                (e) => e.length <= self.subcluster_threshold
+              )
+            ),
+            (cc) => cc.length > 1
+          );
+
+          sub.rr_count = rr_cluster.length;
+
+          rr_cluster.sort((a, b) => b.length - a.length);
+
+          sub.priority_score = [];
+          sub.recent_nodes = [];
+
+          const future_date = new Date(start_date.getTime() + 1e13);
+
+          _.each(rr_cluster, (recent_cluster) => {
+            var priority_nodes = _.groupBy(recent_cluster, (n) =>
+              self.filter_by_date(cutoff_short, date_field, start_date, n)
+            );
+
+            sub.recent_nodes.push(_.map(recent_cluster, (n) => n.id));
+            const meets_priority_def =
+              true in priority_nodes &&
+              priority_nodes[true].length >=
+                (self.CDC_data
+                  ? self.CDC_data["autocreate-priority-set-size"]
+                  : 3);
+
+            if (true in priority_nodes) {
+              // recent
+              sub.priority_score.push(_.map(priority_nodes[true], (n) => n.id));
+              _.each(priority_nodes[true], (n) => {
+                n.priority_flag = self.filter_by_date(
+                  start_date,
+                  date_field,
+                  future_date,
+                  n
+                )
+                  ? 4
+                  : 1;
+
+                if (meets_priority_def) {
+                  if (n.priority_flag === 1) {
+                    n.priority_flag = 2;
+                  }
+                  n.nationalCOI = 1;
+                }
+              });
+            }
+
+            if (false in priority_nodes) {
+              // not recent
+              _.each(priority_nodes[false], (n) => {
+                n.priority_flag = 3;
+
+                if (meets_priority_def) {
+                  if (
+                    self.filter_by_date(cutoff_long, date_field, start_date, n)
+                  ) {
+                    n.nationalCOI = 2;
+                  } else {
+                    n.nationalCOI = 3;
+                  }
+                } else {
+                  n.priority_flag = 7;
+                }
+              });
+            }
+          });
+
+          //console.log (sub.recent_nodes);
+          self.clusters[array_index].priority_score = sub.priority_score;
+        });
+      });
+    } catch (err) {
+      console.log(err);
+    }
+  };
+
+  function default_layout(packed) {
+    // let's create an array of clusters from the json
+
+    var init_layout = get_initial_xy(packed);
+
+    if (self.clusters.length === 0) {
+      self.clusters = init_layout.filter(
+        (v, i, obj) => !(typeof v.cluster_id === "undefined")
+      );
+    } else {
+      var coordinate_update = {};
+      _.each(self.clusters, (c) => {
+        coordinate_update[c.cluster_id] = c;
+      });
+      _.each(init_layout, (c) => {
+        if ("cluster_id" in c) {
+          _.extendOwn(coordinate_update[c.cluster_id], c);
+        }
+      });
+    }
+
+    //var sizes = network_layout.size();
+
+    var set_init_coords = packed
+      ? function (n) {
+          n.x += n.r * 0.5;
+          n.y += n.r * 0.5;
+        }
+      : function (n) {
+          n.x += n.dx * 0.5;
+          n.y += n.dy * 0.5;
+        };
+
+    _.each([self.nodes, self.clusters], (list) => {
+      _.each(list, set_init_coords);
+    });
+
+    self.clusters.forEach(collapse_cluster);
+  }
+
+  function change_spacing(delta) {
+    self.charge_correction *= delta;
+    network_layout.start();
+  }
+
+  function change_window_size(delta, trigger) {
+    if (delta) {
+      var x_scale = (self.width + delta / 2) / self.width;
+      var y_scale = (self.height + delta / 2) / self.height;
+
+      self.width += delta;
+      self.height += delta;
+
+      var rescale_x = d3.scale
+        .linear()
+        .domain(d3.extent(network_layout.nodes(), (node) => node.x));
+      rescale_x.range(_.map(rescale_x.domain(), (v) => v * x_scale));
+      //.range ([50,self.width-50]),
+      var rescale_y = d3.scale
+        .linear()
+        .domain(d3.extent(network_layout.nodes(), (node) => node.y));
+      rescale_y.range(_.map(rescale_y.domain(), (v) => v * y_scale));
+
+      _.each(network_layout.nodes(), (node) => {
+        node.x = rescale_x(node.x);
+        node.y = rescale_y(node.y);
+      });
+    }
+
+    self.width = Math.min(Math.max(self.width, 200), 4000);
+    self.height = Math.min(Math.max(self.height, 200), 4000);
+
+    network_layout.size([self.width, self.height]);
+    self.network_svg.attr("width", self.width).attr("height", self.height);
+    self._calc_country_nodes(options);
+    self._draw_topomap(true);
+    if (trigger) {
+      network_layout.start();
+    } else if (delta) {
+      self.update(true);
+    }
+  }
+
+  self.compute_adjacency_list = _.once(() => {
+    self.nodes.forEach((n) => {
+      n.neighbors = d3.set();
+    });
+
+    self.edges.forEach((e) => {
+      self.nodes[e.source].neighbors.add(e.target);
+      self.nodes[e.target].neighbors.add(e.source);
+    });
+  });
+
+  self.compute_local_clustering_coefficients = _.once(() => {
+    self.compute_adjacency_list();
+
+    self.nodes.forEach((n) => {
+      _.defer((a_node) => {
+        const neighborhood_size = a_node.neighbors.size();
+        if (neighborhood_size < 2) {
+          a_node.lcc = misc.undefined;
+        } else if (neighborhood_size > 500) {
+          a_node.lcc = misc.too_large;
+        } else {
+          // count triangles
+          const neighborhood = a_node.neighbors.values();
+          let counter = 0;
+          for (let n1 = 0; n1 < neighborhood_size; n1 += 1) {
+            for (let n2 = n1 + 1; n2 < neighborhood_size; n2 += 1) {
+              if (
+                self.nodes[neighborhood[n1]].neighbors.has(neighborhood[n2])
+              ) {
+                counter++;
+              }
+            }
+          }
+
+          a_node.lcc =
+            (2 * counter) / neighborhood_size / (neighborhood_size - 1);
+        }
+      }, n);
+    });
+  });
+
+  self.get_node_by_id = function (id) {
+    return self.nodes.filter((n) => n.id === id)[0];
+  };
+
+  self.compute_local_clustering_coefficients_worker = _.once(() => {
+    var worker = new Worker("workers/lcc.js");
+
+    worker.onmessage = function (event) {
+      var nodes = event.data.Nodes;
+
+      nodes.forEach((n) => {
+        const node_to_update = self.get_node_by_id(n.id);
+        node_to_update.lcc = n.lcc ? n.lcc : misc.undefined;
+      });
+    };
+
+    var worker_obj = {};
+    worker_obj["Nodes"] = self.nodes;
+    worker_obj["Edges"] = self.edges;
+    worker.postMessage(worker_obj);
+  });
+
+  var estimate_cubic_compute_cost = _.memoize(
+    (c) => {
+      self.compute_adjacency_list();
+      return _.reduce(
+        _.first(_.pluck(c.children, "degree").sort(d3.descending), 3),
+        (memo, value) => memo * value,
+        1
+      );
+    },
+    (c) => c.cluster_id
+  );
+
+  self.compute_global_clustering_coefficients = _.once(() => {
+    self.compute_adjacency_list();
+
+    self.clusters.forEach((c) => {
+      _.defer((a_cluster) => {
+        const cluster_size = a_cluster.children.length;
+        if (cluster_size < 3) {
+          a_cluster.cc = misc.undefined;
+        } else if (estimate_cubic_compute_cost(a_cluster, true) >= 5000000) {
+          a_cluster.cc = misc.too_large;
+        } else {
+          // pull out all the nodes that have this cluster id
+          const member_nodes = [];
+
+          var triads = 0;
+          var triangles = 0;
+
+          self.nodes.forEach((n, i) => {
+            if (n.cluster === a_cluster.cluster_id) {
+              member_nodes.push(i);
+            }
+          });
+          member_nodes.forEach((node) => {
+            const my_neighbors = self.nodes[node].neighbors
+              .values()
+              .map((d) => Number(d))
+              .sort(d3.ascending);
+            for (let n1 = 0; n1 < my_neighbors.length; n1 += 1) {
+              for (let n2 = n1 + 1; n2 < my_neighbors.length; n2 += 1) {
+                triads += 1;
+                if (
+                  self.nodes[my_neighbors[n1]].neighbors.has(my_neighbors[n2])
+                ) {
+                  triangles += 1;
+                }
+              }
+            }
+          });
+
+          a_cluster.cc = triangles / triads;
+        }
+      }, c);
+    });
+  });
+
+  self.mark_nodes_as_processing = function (property) {
+    self.nodes.forEach((n) => {
+      n[property] = misc.processing;
+    });
+  };
+
+  self.compute_graph_stats = function () {
+    d3.select(this).classed("disabled", true).select("i").classed({
+      "fa-calculator": false,
+      "fa-cog": true,
+      "fa-spin": true,
+    });
+    self.mark_nodes_as_processing("lcc");
+    self.compute_local_clustering_coefficients_worker();
+    self.compute_global_clustering_coefficients();
+    d3.select(this).remove();
+  };
+
+  /*------------ Constructor ---------------*/
+  function initial_json_load() {
+    var connected_links = {};
+    var total = 0;
+    self.exclude_cluster_ids = {};
+    self.has_hxb2_links = false;
+    self.cluster_sizes = [];
+
+    graph_data.Nodes.forEach((d) => {
+      if (typeof self.cluster_sizes[d.cluster - 1] === "undefined") {
+        self.cluster_sizes[d.cluster - 1] = 1;
+      } else {
+        self.cluster_sizes[d.cluster - 1]++;
+      }
+      if ("is_lanl" in d) {
+        d.is_lanl = d.is_lanl === "true";
+      }
+
+      if (!("attributes" in d)) {
+        d.attributes = [];
+      }
+
+      if (d.attributes.indexOf("problematic") >= 0) {
+        self.has_hxb2_links = true;
+        d.hxb2_linked = true;
+      }
+    });
+
+    /* add buttons and handlers */
+    /* clusters first */
+
+    self._extract_attributes_for_nodes = function (nodes, column_names) {
+      var result = [_.map(column_names, (c) => c.raw_attribute_key)];
+
+      _.each(nodes, (n) => {
+        result.push(
+          _.map(column_names, (c) => {
+            if (c.raw_attribute_key === tables._networkNodeIDField) {
+              if (HTX.HIVTxNetwork.is_new_node(n)) {
+                return n.id + tables._networkNewNodeMarker;
+              }
+              return n.id;
+            }
+            if (_.has(n, c.raw_attribute_key)) {
+              return n[c.raw_attribute_key];
+            }
+            return self.attribute_node_value_by_id(n, c.raw_attribute_key);
+          })
+        );
+      });
+      return result;
+    };
+
+    self._extract_exportable_attributes = function (extended) {
+      var allowed_types = {
+        String: 1,
+        Date: 1,
+        Number: 1,
+      };
+
+      var return_array = [];
+
+      if (extended) {
+        return_array = [
+          {
+            raw_attribute_key: tables._networkNodeIDField,
+            type: "String",
+            label: "Node ID",
+            format: function () {
+              return "Node ID";
+            },
+          },
+          {
+            raw_attribute_key: "cluster",
+            type: "String",
+            label: "Which cluster the individual belongs to",
+            format: function () {
+              return __("clusters_tab")["cluster_id"];
+            },
+          },
+        ];
+      }
+
+      return_array.push(
+        _.filter(
+          self.json[kGlobals.network.GraphAttrbuteID],
+          (d) => d.type in allowed_types
+        )
+      );
+
+      return _.flatten(return_array, true);
+    };
+
+    self._extract_nodes_by_id = function (id) {
+      return _.filter(
+        self.nodes,
+        (n) =>
+          n.cluster.toString() === id.toString() ||
+          n.subcluster_label === id.toString()
+      );
+    };
+
+    self._cluster_list_view_render = function (
+      cluster_id,
+      group_by_attribute,
+      the_list,
+      priority_group
+    ) {
+      the_list.selectAll("*").remove();
+      var column_ids = self._extract_exportable_attributes();
+      var cluster_nodes;
+
+      if (priority_group) {
+        cluster_nodes = self.priority_groups_find_by_name(priority_group);
+        if (cluster_nodes) {
+          cluster_nodes = cluster_nodes.node_objects;
+        } else {
+          return;
+        }
+      } else {
+        cluster_nodes = self._extract_nodes_by_id(cluster_id);
+      }
+
+      d3.select(
+        self.get_ui_element_selector_by_role("cluster_list_data_export", true)
+      ).on("click", (d) => {
+        if (self._is_CDC_executive_mode) {
+          alert(kGlobals.network.WarnExecutiveMode);
+        } else {
+          helpers.export_csv_button(
+            self._extract_attributes_for_nodes(cluster_nodes, column_ids)
+          );
+        }
+      });
+
+      if (group_by_attribute) {
+        _.each(column_ids, (column) => {
+          var binned = _.groupBy(cluster_nodes, (n) =>
+            self.attribute_node_value_by_id(n, column.raw_attribute_key)
+          );
+          var sorted_keys = _.keys(binned).sort();
+          var attribute_record = the_list.append("li");
+          attribute_record
+            .append("code")
+            .text(column.label || column.raw_attribute_key);
+          var attribute_list = attribute_record
+            .append("dl")
+            .classed("dl-horizontal", true);
+          _.each(sorted_keys, (key) => {
+            attribute_list.append("dt").text(key);
+            attribute_list
+              .append("dd")
+              .text(_.map(binned[key], (n) => n.id).join(", "));
+          });
+        });
+      } else {
+        _.each(cluster_nodes, (node) => {
+          var patient_record = the_list.append("li");
+          patient_record.append("code").text(node.id);
+          var patient_list = patient_record
+            .append("dl")
+            .classed("dl-horizontal", true);
+          _.each(column_ids, (column) => {
+            patient_list
+              .append("dt")
+              .text(column.label || column.raw_attribute_key);
+            patient_list
+              .append("dd")
+              .text(
+                self.attribute_node_value_by_id(node, column.raw_attribute_key)
+              );
+          });
+        });
+      }
+    };
+
+    self._setup_cluster_list_view = function () {
+      d3.select(
+        self.get_ui_element_selector_by_role("cluster_list_view_toggle", true)
+      ).on("click", function () {
+        d3.event.preventDefault();
+        var group_by_id;
+
+        var button_clicked = $(this);
+        if (button_clicked.data(__("clusters_tab")["view"]) === "id") {
+          button_clicked.data(__("clusters_tab")["view"], "attribute");
+          button_clicked.text(__("clusters_tab")["group_by_id"]);
+          group_by_id = false;
+        } else {
+          button_clicked.data(__("clusters_tab")["view"], "id");
+          button_clicked.text(__("clusters_tab")["group_by_attribute"]);
+          group_by_id = true;
+        }
+
+        var cluster_id = button_clicked.data("cluster");
+
+        self._cluster_list_view_render(
+          cluster_id ? cluster_id.toString() : "",
+          !group_by_id,
+          d3.select(
+            self.get_ui_element_selector_by_role("cluster_list_payload", true)
+          ),
+          button_clicked.data("priority_list")
+        );
+      });
+
+      $(self.get_ui_element_selector_by_role("cluster_list", true)).on(
+        "show.bs.modal",
+        (event) => {
+          var link_clicked = $(event.relatedTarget);
+          var cluster_id = link_clicked.data("cluster");
+          var priority_list = link_clicked.data("priority_set");
+
+          var modal = d3.select(
+            self.get_ui_element_selector_by_role("cluster_list", true)
+          );
+          modal
+            .selectAll(".modal-title")
+            .text(
+              __("clusters_tab")["listing_nodes"] +
+                (priority_list
+                  ? " in cluster of interest " + priority_list
+                  : " " + __("general")["cluster"] + " " + cluster_id)
+            );
+
+          var view_toggle = $(
+            self.get_ui_element_selector_by_role(
+              "cluster_list_view_toggle",
+              true
+            )
+          );
+
+          if (priority_list) {
+            view_toggle.data("priority_list", priority_list);
+            view_toggle.data("cluster", "");
+          } else {
+            view_toggle.data("cluster", cluster_id);
+            view_toggle.data("priority_list", null);
+          }
+
+          self._cluster_list_view_render(
+            cluster_id,
+            //cluster_id,
+            $(
+              self.get_ui_element_selector_by_role(
+                "cluster_list_view_toggle",
+                true
+              )
+            ).data(__("clusters_tab")["view"]) !== "id",
+            modal.select(
+              self.get_ui_element_selector_by_role("cluster_list_payload", true)
+            ),
+            priority_list
+          );
+        }
+      );
+
+      $(self.get_ui_element_selector_by_role("overlap_list", true)).on(
+        "show.bs.modal",
+        (event) => {
+          var link_clicked = $(event.relatedTarget);
+          var priority_list = link_clicked.data("priority_set");
+
+          var modal = d3.select(
+            self.get_ui_element_selector_by_role("overlap_list", true)
+          );
+          modal
+            .selectAll(".modal-title")
+            .text(
+              "View how nodes in cluster of interest " +
+                priority_list +
+                " overlap with other clusterOI"
+            );
+
+          const ps = self.priority_groups_find_by_name(priority_list);
+          if (!(ps && self.priority_node_overlap)) return;
+
+          var headers = [
+            [
+              {
+                value: "Node",
+                help: "EHARS_ID of the node that overlaps with other clusterOI",
+                sort: "value",
+              },
+              {
+                value: "Other Cluster(s) of Interest",
+                help: "Names of other clusterOI where this node is included",
+                sort: "value",
+              },
+            ],
+          ];
+
+          var rows = [];
+          var rows_for_export = [
+            ["Overlapping Cluster of Interest", "Node", "Other clusterOI"],
+          ];
+          _.each(ps.nodes, (n) => {
+            const overlap = self.priority_node_overlap[n.name];
+            let other_sets = "None";
+            if (overlap.size > 1) {
+              other_sets = _.sortBy(
+                _.filter([...overlap], (d) => d !== priority_list)
+              ).join("; ");
+            }
+            rows.push([{ value: n.name }, { value: other_sets }]);
+            rows_for_export.push([ps.name, n.name, other_sets]);
+          });
+
+          d3.select(
+            self.get_ui_element_selector_by_role(
+              "overlap_list_data_export",
+              true
+            )
+          ).on("click", (d) => {
+            helpers.export_csv_button(rows_for_export, "overlap");
+          });
+
+          tables.add_a_sortable_table(
+            modal.select(
+              self.get_ui_element_selector_by_role(
+                "overlap_list_data_table",
+                true
+              )
+            ),
+            headers,
+            rows,
+            true,
+            null,
+            clustersOfInterest.get_editor()
+          );
+        }
+      );
+    };
+
+    $(self.get_ui_element_selector_by_role("priority_set_merge", true)).on(
+      "show.bs.modal",
+      (event) => {
+        var modal = d3.select(
+          self.get_ui_element_selector_by_role("priority_set_merge", true)
+        );
+
+        const desc = modal.selectAll(".modal-desc");
+
+        const proceed_btn = d3.select(
+          self.get_ui_element_selector_by_role(
+            "priority_set_merge_table_proceed",
+            true
+          )
+        );
+
+        if (
+          self.defined_priority_groups &&
+          self.defined_priority_groups.length > 1
+        ) {
+          desc.text("Select two or more clusters of interest to merge");
+
+          var headers = [
+            [
+              {
+                value: "Select",
+              },
+              {
+                value: "Cluster of interest",
+                help: "Cluster of interest Name",
+                sort: "value",
+              },
+              {
+                value: "Nodes",
+                help: "How many nodes are in this cluster of interest",
+                sort: "value",
+              },
+              {
+                value: "Overlaps",
+                help: "Overlaps with",
+                sort: "value",
+              },
+            ],
+          ];
+
+          const current_selection = new Set();
+          let current_node_set = null;
+          let current_node_objects = null;
+
+          const handle_selection = (name, selected) => {
+            if (selected) {
+              current_selection.add(name);
+            } else {
+              current_selection.delete(name);
+            }
+            if (current_selection.size > 1) {
+              let clusterOITotalNOdes = 0;
+              current_node_set = new Set();
+              current_node_objects = {};
+              _.each(self.defined_priority_groups, (pg) => {
+                if (current_selection.has(pg.name)) {
+                  clusterOITotalNOdes += pg.nodes.length;
+                  _.each(pg.nodes, (n) => {
+                    current_node_set.add(n.name);
+                    current_node_objects[n.name] = {
+                      _priority_set_date: n.added,
+                      _priority_set_kind: n.kind,
+                    };
+                  });
+                }
+              });
+              desc.html(
+                "Merge " +
+                  current_selection.size +
+                  " clusterOI with " +
+                  clusterOITotalNOdes +
+                  " nodes, creating a new clusterOI with " +
+                  current_node_set.size +
+                  " nodes. <br><small>Note that the clusters of interest being merged will <b>not</b> be automatically deleted</small>"
+              );
+              proceed_btn.attr("disabled", null);
+            } else {
+              desc.text("Select two or more clusters of interest to merge");
+              proceed_btn.attr("disabled", "disabled");
+            }
+          };
+
+          const handle_merge = () => {
+            if (current_node_set) {
+              clustersOfInterest.open_editor(
+                self,
+                [],
+                "",
+                "Merged from " + [...current_selection].join(" and ")
+              );
+              clustersOfInterest
+                .get_editor()
+                .append_nodes([...current_node_set], current_node_objects);
+            }
+            $(modal.node()).modal("hide");
+          };
+
+          proceed_btn.attr("disabled", "disabled").on("click", handle_merge);
+
+          var rows = [];
+          _.each(self.defined_priority_groups, (pg) => {
+            const my_overlaps = new Set();
+            _.each(pg.nodes, (n) => {
+              _.each([...self.priority_node_overlap[n.name]], (ps) => {
+                if (ps !== pg.name) {
+                  my_overlaps.add(ps);
+                }
+              });
+            });
+
+            rows.push([
+              {
+                value: pg,
+                callback: function (element, payload) {
+                  var this_cell = d3.select(element);
+                  this_cell
+                    .append("input")
+                    .attr("type", "checkbox")
+                    .style("margin-left", "1em")
+                    .on("click", function (e) {
+                      handle_selection(payload.name, $(this).prop("checked"));
+                    });
+                },
+              },
+              { value: pg.name },
+              { value: pg.nodes.length },
+              {
+                value: [...my_overlaps],
+                format: (d) => d.join("<br>"),
+                html: true,
+              },
+            ]);
+          });
+
+          tables.add_a_sortable_table(
+            modal.select(
+              self.get_ui_element_selector_by_role(
+                "priority_set_merge_table",
+                true
+              )
+            ),
+            headers,
+            rows,
+            true,
+            null,
+            clustersOfInterest.get_editor()
+          );
+        }
+      }
+    );
+
+    if (button_bar_ui) {
+      self._setup_cluster_list_view();
+
+      var cluster_ui_container = d3.select(
+        self.get_ui_element_selector_by_role("cluster_operations_container")
+      );
+
+      cluster_ui_container.selectAll("li").remove();
+
+      var fix_handler = function (do_fix) {
+        _.each([self.clusters, self.nodes], (list) => {
+          _.each(list, (obj) => {
+            obj.fixed = do_fix;
+          });
+        });
+      };
+
+      var node_label_handler = function (do_show) {
+        var shown_nodes = self.network_svg.selectAll(".node");
+        if (!shown_nodes.empty()) {
+          shown_nodes.each((node) => {
+            node.show_label = do_show;
+          });
+          self.update(true);
+        }
+      };
+
+      var layout_reset_handler = function (packed) {
+        var fixed = [];
+        _.each(self.clusters, (obj) => {
+          if (obj.fixed) {
+            fixed.push(obj);
+          }
+          obj.fixed = false;
+        });
+        default_layout(packed);
+        network_layout.tick();
+        self.update();
+        _.each(fixed, (obj) => {
+          obj.fixed = true;
+        });
+      };
+
+      var cluster_commands = [
+        [
+          __("clusters_main")["export_colors"],
+          () => {
+            const colorScheme = helpers.exportColorScheme(
+              self.uniqValues,
+              self.colorizer
+            );
+
+            //TODO: If using database backend, use api instead
+            helpers.copyToClipboard(JSON.stringify(colorScheme));
+          },
+          true,
+          "hivtrace-export-color-scheme",
+        ],
+        [
+          __("clusters_main")["expand_all"],
+          function () {
+            return self.expand_some_clusters();
+          },
+          true,
+          "hivtrace-expand-all",
+        ],
+        [
+          __("clusters_main")["collapse_all"],
+          function () {
+            return self.collapse_some_clusters();
+          },
+          true,
+          "hivtrace-collapse-all",
+        ],
+        [
+          __("clusters_main")["expand_filtered"],
+          function () {
+            return self.expand_some_clusters(
+              self.select_some_clusters((n) => n.match_filter)
+            );
+          },
+          true,
+          "hivtrace-expand-filtered",
+        ],
+        [
+          __("clusters_main")["collapse_filtered"],
+          function () {
+            return self.collapse_some_clusters(
+              self.select_some_clusters((n) => n.match_filter)
+            );
+          },
+          true,
+          "hivtrace-collapse-filtered",
+        ],
+        [
+          __("clusters_main")["fix_all_objects_in_place"],
+          _.partial(fix_handler, true),
+          true,
+          "hivtrace-fix-in-place",
+        ],
+        [
+          __("clusters_main")["allow_all_objects_to_float"],
+          _.partial(fix_handler, false),
+          true,
+          "hivtrace-allow-to-float",
+        ],
+        [
+          __("clusters_main")["reset_layout"] + " [packed]",
+          _.partial(layout_reset_handler, true),
+          true,
+          "hivtrace-reset-layout",
+        ],
+        [
+          __("clusters_main")["reset_layout"] + " [tiled]",
+          _.partial(layout_reset_handler, false),
+          true,
+          "hivtrace-reset-layout",
+        ],
+        [
+          __("network_tab")["show_labels_for_all"],
+          _.partial(node_label_handler, true),
+          true,
+          "hivtrace-node-labels-on",
+        ],
+        [
+          __("network_tab")["hide_labels_for_all"],
+          _.partial(node_label_handler, false),
+          true,
+          "hivtrace-node-labels-off",
+        ],
+        [
+          "Hide problematic clusters",
+          function (item) {
+            d3.select(item).text(
+              self.hide_hxb2
+                ? "Hide problematic clusters"
+                : "Show problematic clusters"
+            );
+            self.toggle_hxb2();
+          },
+          self.has_hxb2_links,
+          "hivtrace-hide-problematic-clusters",
+        ],
+        [
+          __("network_tab")["highlight_unsupported_edges"],
+          function (item) {
+            if (self.highlight_unsuppored_edges) {
+              d3.select(item).selectAll(".fa-check-square").remove();
+            } else {
+              d3.select(item)
+                .insert("i", ":first-child")
+                .classed("fa fa-check-square", true);
+            }
+            self.toggle_highlight_unsupported_edges();
+          },
+          true,
+          "hivtrace-highlight-unsuppored_edges",
+          self.highlight_unsuppored_edges,
+        ],
+      ];
+
+      if (self.cluster_attributes) {
+        cluster_commands.push([
+          "Show only changes since last network update",
+          function (item) {
+            if (self.showing_diff) {
+              d3.select(item).selectAll(".fa-check-square").remove();
+            } else {
+              d3.select(item)
+                .insert("i", ":first-child")
+                .classed("fa fa-check-square", true);
+            }
+            self.toggle_diff();
+          },
+          true,
+          "hivtrace-show-network-diff",
+          self.showing_diff,
+        ]);
+      }
+
+      if (timeDateUtil.getClusterTimeScale()) {
+        cluster_commands.push([
+          __("network_tab")["only_recent_clusters"],
+          function (item) {
+            if (self.using_time_filter) {
+              d3.select(item).selectAll(".fa-check-square").remove();
+            } else {
+              d3.select(item)
+                .insert("i", ":first-child")
+                .classed("fa fa-check-square", true);
+            }
+            self.toggle_time_filter();
+          },
+          true,
+          "hivtrace-show-using-time-filter",
+          self.using_time_filter,
+        ]);
+      }
+
+      if (!self._is_CDC_) {
+        cluster_commands.push([
+          "Show removed edges",
+          function (item) {
+            self.filter_edges = !self.filter_edges;
+            d3.select(item).text(
+              self.filter_edges ? "Show removed edges" : "Hide removed edges"
+            );
+            self.update(false);
+          },
+          function () {
+            return _.some(self.edges, (d) => d.removed);
+          },
+          "hivtrace-show-removed-edges",
+        ]);
+      } else {
+        cluster_commands.push([
+          "Add filtered objects to cluster of interest",
+          function (item) {
+            if (clustersOfInterest.get_editor())
+              clustersOfInterest
+                .get_editor()
+                .append_node_objects(
+                  _.filter(json["Nodes"], (n) => n.match_filter)
+                );
+          },
+          clustersOfInterest.get_editor,
+          "hivtrace-add-filtered-to-panel",
+        ]);
+      }
+
+      cluster_commands.forEach(function (item, index) {
+        let shown = item[2];
+        if (_.isFunction(shown)) {
+          shown = shown(item);
+        }
+        if (shown) {
+          var handler_callback = item[1];
+          var line_item = this.append("li")
+            .append("a")
+            .text(item[0])
+            .attr("href", "#")
+            //.attr("id", item[3])
+            .on("click", function (e) {
+              handler_callback(this);
+              //d3.event.stopPropagation();
+              //d3.event.preventDefault();
+            });
+
+          if (item.length > 4) {
+            // checkbox
+            line_item.text("");
+            if (item[4]) {
+              line_item
+                .insert("i", ":first-child")
+                .classed("fa fa-check-square", true);
+            }
+            line_item.insert("span").text(item[0]);
+          }
+        }
+      }, cluster_ui_container);
+
+      var button_group = d3.select(
+        self.get_ui_element_selector_by_role("button_group")
+      );
+
+      if (!button_group.empty()) {
+        button_group.selectAll("button").remove();
+        button_group
+          .append("button")
+          .classed("btn btn-default btn-sm", true)
+          .attr("title", __("network_tab")["expand_spacing"])
+          .on("click", (d) => {
+            change_spacing(5 / 4);
+          })
+          .append("i")
+          .classed("fa fa-plus", true);
+        button_group
+          .append("button")
+          .classed("btn btn-default btn-sm", true)
+          .attr("title", __("network_tab")["compress_spacing"])
+          .on("click", (d) => {
+            change_spacing(4 / 5);
+          })
+          .append("i")
+          .classed("fa fa-minus", true);
+        button_group
+          .append("button")
+          .classed("btn btn-default btn-sm", true)
+          .attr("title", __("network_tab")["enlarge_window"])
+          .on("click", (d) => {
+            change_window_size(100, true);
+          })
+          .append("i")
+          .classed("fa fa-expand", true);
+        button_group
+          .append("button")
+          .classed("btn btn-default btn-sm", true)
+          .attr("title", __("network_tab")["shrink_window"])
+          .on("click", (d) => {
+            change_window_size(-100, true);
+          })
+          .append("i")
+          .classed("fa fa-compress", true);
+
+        if (!self._is_CDC_) {
+          button_group
+            .append("button")
+            .classed("btn btn-default btn-sm", true)
+            .attr("title", "Compute graph statistics")
+            .attr("id", "hivtrace-compute-graph-statistics")
+            .on("click", function (d) {
+              _.bind(self.compute_graph_stats, this)();
+            })
+            .append("i")
+            .classed("fa fa-calculator", true);
+        } else {
+          button_group
+            .append("button")
+            .classed("btn btn-default btn-sm", true)
+            .attr("title", __("network_tab")["toggle_epicurve"])
+            .attr("id", "hivtrace-toggle-epi-curve")
+            .on("click", (d) => {
+              self.check_for_time_series();
+            })
+            .append("i")
+            .classed("fa fa-line-chart", true);
+        }
+
+        var export_image = d3.select(
+          self.get_ui_element_selector_by_role("export_image")
+        );
+
+        if (!export_image.empty()) {
+          export_image.selectAll("div").remove();
+
+          const buttonGroupDropdown = export_image
+            .insert("div", ":first-child")
+            .classed("input-group-btn dropdown-img", true);
+
+          const dropdownList = buttonGroupDropdown
+            .append("ul")
+            .classed("dropdown-menu", true)
+            .attr("aria-labelledby", "dropdownImg");
+
+          dropdownList
+            .append("li")
+            .classed("dropdown-item export-img-item", true)
+            .append("a")
+            .attr("href", "#")
+            .text("SVG")
+            .on("click", (d) => {
+              helpers.save_image("svg", "#" + self.dom_prefix + "-network-svg");
+            });
+
+          dropdownList
+            .append("li")
+            .classed("dropdown-item export-img-item", true)
+            .append("a")
+            .attr("href", "#")
+            .text("PNG")
+            .on("click", (d) => {
+              helpers.save_image("png", "#" + self.dom_prefix + "-network-svg");
+            });
+
+          const imgBtn = buttonGroupDropdown
+            .append("button")
+            .attr("id", "dropdownImg")
+            .attr("data-toggle", "dropdown")
+            .classed("btn btn-default btn-sm dropdown-toggle", true)
+            .attr("title", __("network_tab")["save_image"])
+            .attr("id", "hivtrace-export-image");
+
+          imgBtn.append("i").classed("fa fa-image", true);
+
+          imgBtn.append("span").classed("caret", true);
+        }
+      }
+
+      $(self.get_ui_element_selector_by_role("filter"))
+        .off("input propertychange")
+        .on(
+          "input propertychange",
+          _.throttle(function (e) {
+            var filter_value = $(this).val();
+            self.filter(tables.filter_parse(filter_value));
+          }, 250)
+        );
+
+      $(self.get_ui_element_selector_by_role("hide_filter"))
+        .off("change")
+        .on(
+          "change",
+          _.throttle((e) => {
+            self.hide_unselected = !self.hide_unselected;
+            self.filter_visibility();
+            self.update(true);
+          }, 250)
+        );
+
+      $(self.get_ui_element_selector_by_role("show_small_clusters"))
+        .off("change")
+        .on(
+          "change",
+          _.throttle((e) => {
+            if ("size" in self.cluster_filtering_functions) {
+              delete self.cluster_filtering_functions["size"];
+            } else {
+              self.cluster_filtering_functions["size"] = self.filter_by_size;
+            }
+
+            self.update(false);
+          }, 250)
+        );
+
+      $(self.get_ui_element_selector_by_role("set_min_cluster_size"))
+        .off("change")
+        .on(
+          "change",
+          _.throttle((e) => {
+            self.minimum_cluster_size = e.target.value;
+            self.update(false);
+          }, 250)
+        );
+
+      $(self.get_ui_element_selector_by_role("pairwise_table_pecentage", true))
+        .off("change")
+        .on(
+          "change",
+          _.throttle((e) => {
+            self.show_percent_in_pairwise_table =
+              !self.show_percent_in_pairwise_table;
+            render_binned_table(
+              "attribute_table",
+              self.colorizer["category_map"],
+              self.colorizer["category_pairwise"]
+            );
+          }, 250)
+        );
+    }
+
+    if (kGlobals.network.GraphAttrbuteID in json) {
+      attributes = json[kGlobals.network.GraphAttrbuteID];
+    } else if (attributes && "hivtrace" in attributes) {
+      attributes = attributes["hivtrace"];
+    }
+
+    // Initialize class attributes
+    singletons = graph_data.Nodes.filter((v, i) => v.cluster === null).length;
+
+    self.nodes_by_cluster = {};
+
+    self.nodes = graph_data.Nodes.filter((v, i) => {
+      if (
+        v.cluster &&
+        typeof self.exclude_cluster_ids[v.cluster] === "undefined"
+      ) {
+        if (v.cluster in self.nodes_by_cluster) {
+          self.nodes_by_cluster[v.cluster].push(v);
+        } else {
+          self.nodes_by_cluster[v.cluster] = [v];
+        }
+
+        connected_links[i] = total++;
+        return true;
+      }
+      return false;
+    });
+
+    self.edges = graph_data.Edges.filter(
+      (v, i) => v.source in connected_links && v.target in connected_links
+    );
+
+    self.edges = self.edges.map((v, i) => {
+      var cp_v = _.clone(v);
+      cp_v.source = connected_links[v.source];
+      cp_v.target = connected_links[v.target];
+      cp_v.id = i;
+      return cp_v;
+    });
+
+    compute_node_degrees(self.nodes, self.edges);
+
+    default_layout(self.initial_packed);
+    self.clusters.forEach((d, i) => {
+      self.cluster_mapping[d.cluster_id] = i;
+      d.hxb2_linked = d.children.some((c) => c.hxb2_linked);
+      _compute_cluster_degrees(d);
+      d.distances = [];
+    });
+
+    try {
+      if (options && options["extra_menu"]) {
+        var extra_ui_container = d3.select(
+          self.get_ui_element_selector_by_role("extra_operations_container")
+        );
+
+        d3.select(
+          self.get_ui_element_selector_by_role("extra_operations_enclosure")
+        )
+          .selectAll("button")
+          .text(options["extra_menu"]["title"])
+          .append("span")
+          .classed("caret", "true");
+        //extra_ui_container
+        extra_ui_container.selectAll("li").remove();
+
+        options["extra_menu"]["items"].forEach(function (item, index) {
+          //console.log (item);
+          var handler_callback = item[1];
+          if (_.isFunction(item[0])) {
+            item[0](self, this.append("li"));
+          } else {
+            this.append("li")
+              .append("a")
+              .text(item[0])
+              .attr("href", "#")
+              .on("click", function (e) {
+                handler_callback(self, this);
+                d3.event.preventDefault();
+              });
+          }
+        }, extra_ui_container);
+
+        d3.select(
+          self.get_ui_element_selector_by_role("extra_operations_enclosure")
+        ).style("display", null);
+      }
+    } catch (err) {
+      console.log(err);
+    }
+
+    self._aux_populate_category_menus = function () {
+      if (button_bar_ui) {
+        // decide if the variable can be considered categorical by examining its range
+
+        //console.log ("self._aux_populate_category_menus");
+        var valid_cats = _.filter(
+          _.map(
+            graph_data[kGlobals.network.GraphAttrbuteID],
+            self._aux_populate_category_fields
+          ),
+          (d) =>
+            /*if (d.discrete) {
+              console.log (d["value_range"].length);
+          }*/
+            d.discrete &&
+            "value_range" in d &&
+            /*d["value_range"].length <= kGlobals.MaximumValuesInCategories &&*/
+            !d["_hidden_"]
+        );
+
+        var valid_shapes = _.filter(
+          valid_cats,
+          (d) =>
+            (d.discrete && d.dimension <= 7) ||
+            (d["raw_attribute_key"] in self.networkShapeScheme &&
+              !d["_hidden_"])
+        );
+
+        // sort values alphabetically for consistent coloring
+
+        _.each([valid_cats, valid_shapes], (list) => {
+          _.each(list, self._aux_process_category_values);
+        });
+
+        const colorStopsPath = [
+          kGlobals.network.GraphAttrbuteID,
+          self.colorizer["category_id"],
+          "color_stops",
+        ];
+
+        const color_stops = _.get(
+          graph_data,
+          colorStopsPath,
+          kGlobals.network.ContinuousColorStops
+        );
+
+        var valid_scales = _.filter(
+          _.map(graph_data[kGlobals.network.GraphAttrbuteID], (d, k) => {
+            function determine_scaling(d, values, scales) {
+              var low_var = Infinity;
+              _.each(scales, (scl, i) => {
+                d["value_range"] = d3.extent(values);
+                var bins = _.map(_.range(color_stops), () => 0);
+                scl.range([0, color_stops - 1]).domain(d["value_range"]);
+                _.each(values, (v) => {
+                  bins[Math.floor(scl(v))]++;
+                });
+
+                var mean = values.length / color_stops;
+                var vrnc = _.reduce(
+                  bins,
+                  (p, c) => p + (c - mean) * (c - mean)
+                );
+
+                if (vrnc < low_var) {
+                  low_var = vrnc;
+                  d["scale"] = scl;
+                }
+              });
+            }
+
+            d["raw_attribute_key"] = k;
+
+            if (d.type === "Number" || d.type === "Number-categories") {
+              var values = _.filter(
+                _.map(graph_data.Nodes, (nd) =>
+                  self.attribute_node_value_by_id(nd, k, d.type === "Number")
+                ),
+                (v) => _.isNumber(v)
+              );
+              // automatically determine the scale and see what spaces the values most evenly
+              const range = d3.extent(values);
+              const scales_to_consider = [d3.scale.linear()];
+              if (range[0] > 0) {
+                scales_to_consider.push(d3.scale.log());
+              }
+              if (range[0] >= 0) {
+                scales_to_consider.push(d3.scale.pow().exponent(1 / 3));
+                scales_to_consider.push(d3.scale.pow().exponent(1 / 4));
+                scales_to_consider.push(d3.scale.pow().exponent(1 / 2));
+                scales_to_consider.push(d3.scale.pow().exponent(1 / 8));
+                scales_to_consider.push(d3.scale.pow().exponent(1 / 16));
+              }
+              determine_scaling(d, values, scales_to_consider);
+            } else if (d.type === "Date") {
+              values = _.filter(
+                _.map(graph_data.Nodes, (nd) => {
+                  try {
+                    var a_date = self.attribute_node_value_by_id(nd, k);
+                    if (d.raw_attribute_key === "hiv_aids_dx_dt") {
+                      //console.log (nd, k, a_date);
+                    }
+                    HTX.HIVTxNetwork.inject_attribute_node_value_by_id(
+                      nd,
+                      k,
+                      this.parse_dates(a_date)
+                    );
+                  } catch (err) {
+                    HTX.HIVTxNetwork.inject_attribute_node_value_by_id(
+                      nd,
+                      k,
+                      kGlobals.missing.label
+                    );
+                  }
+                  return self.attribute_node_value_by_id(nd, k);
+                }),
+                (v) => (v === kGlobals.missing.label ? null : v)
+              );
+              // automatically determine the scale and see what spaces the values most evenly
+              if (values.length === 0) {
+                // invalid scale
+                return {};
+              }
+
+              determine_scaling(d, values, [d3.time.scale()]);
+            }
+            return d;
+          }),
+          (d) =>
+            (d.type === "Number" ||
+              d.type === "Date" ||
+              d.type === "Number-categories") &&
+            !d["_hidden_"]
+        );
+
+        const _menu_label_gen = (d) =>
+          (d["annotation"] ? "[" + d["annotation"] + "] " : "") + d["label"];
+
+        //console.log (valid_scales);
+        //valid_cats.splice (0,0, {'label' : 'None', 'index' : -1});
+
+        [
+          d3.select(self.get_ui_element_selector_by_role("attributes")),
+          d3.select(
+            self.get_ui_element_selector_by_role("attributes_cat", true)
+          ),
+        ].forEach((m) => {
+          //console.log (m);
+
+          if (m.empty()) {
+            return;
+          }
+          m.selectAll("li").remove();
+
+          var menu_items = [
+            [
+              [
+                "None",
+                null,
+                _.partial(self.handle_attribute_categorical, null),
+              ],
+            ],
+            [[__("network_tab")["categorical"], "heading", null]],
+          ].concat(
+            valid_cats.map((d, i) => [
+              [
+                _menu_label_gen(d),
+                d["raw_attribute_key"],
+                _.partial(
+                  self.handle_attribute_categorical,
+                  d["raw_attribute_key"]
+                ),
+              ],
+            ])
+          );
+
+          if (valid_scales.length) {
+            menu_items = menu_items
+              .concat([[[__("network_tab")["continuous"], "heading", null]]])
+              .concat(
+                valid_scales.map((d, i) => [
+                  [
+                    _menu_label_gen(d),
+                    d["raw_attribute_key"],
+                    _.partial(
+                      self.handle_attribute_continuous,
+                      d["raw_attribute_key"]
+                    ),
+                  ],
+                ])
+              );
+          }
+
+          var cat_menu = m.selectAll("li").data(menu_items);
+
+          cat_menu
+            .enter()
+            .append("li")
+            .classed("disabled", (d) => d[0][1] === "heading")
+            .style("font-variant", (d) =>
+              d[0][1] < -1 ? "small-caps" : "normal"
+            );
+
+          cat_menu
+            .selectAll("a")
+            .data((d) => d)
+            .enter()
+            .append("a")
+            .html((d, i, j) => {
+              let htm = d[0];
+              let type = "unknown";
+
+              if (d[1] in self.schema) {
+                type = self.schema[d[1]].type;
+              }
+
+              if (d[1] in self.uniqs && type === "String") {
+                htm =
+                  htm +
+                  '<span title="Number of unique values" class="badge pull-right">' +
+                  self.uniqs[d[1]] +
+                  "</span>";
+              }
+
+              return htm;
+            })
+            .attr("style", (d, i, j) => {
+              if (d[1] === "heading") return "font-style: italic";
+              if (j === 0) {
+                return " font-weight: bold;";
+              }
+              return null;
+            })
+            .attr("href", "#")
+            .on("click", (d) => {
+              if (d[2]) {
+                d[2].call();
+              }
+            });
+        });
+
+        [d3.select(self.get_ui_element_selector_by_role("shapes"))].forEach(
+          (m) => {
+            m.selectAll("li").remove();
+            var cat_menu = m
+              .selectAll("li")
+              .data(
+                [
+                  [
+                    [
+                      "None",
+                      null,
+                      _.partial(self.handle_shape_categorical, null),
+                    ],
+                  ],
+                ].concat(
+                  valid_shapes.map((d, i) => [
+                    [
+                      _menu_label_gen(d),
+                      d["raw_attribute_key"],
+                      _.partial(
+                        self.handle_shape_categorical,
+                        d["raw_attribute_key"]
+                      ),
+                    ],
+                  ])
+                )
+              );
+
+            cat_menu
+              .enter()
+              .append("li")
+              .style("font-variant", (d) =>
+                d[0][1] < -1 ? "small-caps" : "normal"
+              );
+
+            cat_menu
+              .selectAll("a")
+              .data((d) => d)
+              .enter()
+              .append("a")
+              .html((d, i, j) => {
+                let htm = d[0];
+                let type = "unknown";
+
+                if (_.contains(_.keys(self.schema), d[1])) {
+                  type = self.schema[d[1]].type;
+                }
+
+                if (_.contains(_.keys(self.uniqs), d[1]) && type === "String") {
+                  htm =
+                    htm +
+                    '<span title="Number of unique values" class="badge pull-right">' +
+                    self.uniqs[d[1]] +
+                    "</span>";
+                }
+
+                return htm;
+              })
+              .attr("style", (d, i, j) => {
+                if (j === 0) {
+                  return " font-weight: bold;";
+                }
+                return null;
+              })
+              .attr("href", "#")
+              .on("click", (d) => {
+                if (d[2]) {
+                  d[2].call();
+                }
+              });
+          }
+        );
+
+        $(self.get_ui_element_selector_by_role("opacity_invert"))
+          .off("click")
+          .on("click", function (e) {
+            if (self.colorizer["opacity_scale"]) {
+              self.colorizer["opacity_scale"].range(
+                self.colorizer["opacity_scale"].range().reverse()
+              );
+              self.update(true);
+              self.draw_attribute_labels();
+            }
+            $(this).toggleClass("btn-active btn-default");
+          });
+
+        $(self.get_ui_element_selector_by_role("attributes_invert"))
+          .off("click")
+          .on("click", function (e) {
+            if (self.colorizer["category_id"]) {
+              graph_data[kGlobals.network.GraphAttrbuteID][
+                self.colorizer["category_id"]
+              ]["scale"].range(
+                graph_data[kGlobals.network.GraphAttrbuteID][
+                  self.colorizer["category_id"]
+                ]["scale"]
+                  .range()
+                  .reverse()
+              );
+              self.clusters.forEach((the_cluster) => {
+                the_cluster["gradient"] = compute_cluster_gradient(
+                  the_cluster,
+                  self.colorizer["category_id"]
+                );
+              });
+              self.update(true);
+              self.draw_attribute_labels();
+            }
+            $(this).toggleClass("btn-active btn-default");
+          });
+
+        [d3.select(self.get_ui_element_selector_by_role("opacity"))].forEach(
+          (m) => {
+            m.selectAll("li").remove();
+            var cat_menu = m
+              .selectAll("li")
+              .data(
+                [
+                  [
+                    [
+                      "None",
+                      null,
+                      _.partial(self.handle_attribute_opacity, null),
+                    ],
+                  ],
+                ].concat(
+                  valid_scales.map((d, i) => [
+                    [
+                      d["label"],
+                      d["raw_attribute_key"],
+                      _.partial(
+                        self.handle_attribute_opacity,
+                        d["raw_attribute_key"]
+                      ),
+                    ],
+                  ])
+                )
+              );
+
+            cat_menu
+              .enter()
+              .append("li")
+              .style("font-variant", (d) =>
+                d[0][1] < -1 ? "small-caps" : "normal"
+              );
+            cat_menu
+              .selectAll("a")
+              .data((d) => d)
+              .enter()
+              .append("a")
+              .text((d, i, j) => d[0])
+              .attr("style", (d, i, j) => {
+                if (j === 0) {
+                  return " font-weight: bold;";
+                }
+                return null;
+              })
+              .attr("href", "#")
+              .on("click", (d) => {
+                if (d[2]) {
+                  d[2].call();
+                }
+              });
+          }
+        );
+      }
+    };
+
+    if (attributes) {
+      /*
+         map attributes into nodes and into the graph object itself using
+         kGlobals.network.GraphAttrbuteID as the key
+      */
+
+      if ("attribute_map" in attributes) {
+        var attribute_map = attributes["attribute_map"];
+
+        if ("map" in attribute_map && attribute_map["map"].length > 0) {
+          graph_data[kGlobals.network.GraphAttrbuteID] = attribute_map[
+            "map"
+          ].map((a, i) => ({
+            label: a,
+            type: null,
+            values: {},
+            index: i,
+            range: 0,
+          }));
+
+          graph_data.Nodes.forEach((n) => {
+            n[kGlobals.network.GraphAttrbuteID] = n.id.split(
+              attribute_map["delimiter"]
+            );
+            n[kGlobals.network.GraphAttrbuteID].forEach((v, i) => {
+              if (i < graph_data[kGlobals.network.GraphAttrbuteID].length) {
+                if (
+                  !(
+                    v in
+                    graph_data[kGlobals.network.GraphAttrbuteID][i]["values"]
+                  )
+                ) {
+                  graph_data[kGlobals.network.GraphAttrbuteID][i]["values"][v] =
+                    graph_data[kGlobals.network.GraphAttrbuteID][i]["range"];
+                  graph_data[kGlobals.network.GraphAttrbuteID][i]["range"] += 1;
+                }
+              }
+              //graph_data [kGlobals.network.GraphAttrbuteID][i]["values"][v] = 1 + (graph_data [kGlobals.network.GraphAttrbuteID][i]["values"][v] ? graph_data [kGlobals.network.GraphAttrbuteID][i]["values"][v] : 0);
+            });
+          });
+
+          graph_data[kGlobals.network.GraphAttrbuteID].forEach((d) => {
+            if (
+              d["range"] < graph_data.Nodes.length &&
+              d["range"] > 1 &&
+              d["range"] <= 20
+            ) {
+              d["type"] = "category";
+            }
+          });
+        }
+      }
+
+      for (const [key, def] of Object.entries(
+        self._networkPredefinedAttributeTransforms
+      )) {
+        self.populate_predefined_attribute(def, key);
+      }
+
+      self._aux_populate_category_menus();
+
+      // populate the UI elements
+    }
+
+    if (self.cluster_sizes.length > max_points_to_render) {
+      var sorted_array = self.cluster_sizes
+        .map((d, i) => [d, i + 1])
+        .sort((a, b) => a[0] - b[0]);
+
+      for (var k = 0; k < sorted_array.length - max_points_to_render; k++) {
+        self.exclude_cluster_ids[sorted_array[k][1]] = 1;
+      }
+
+      self.warning_string +=
+        (self.warning_string.length ? "<br>" : "") +
+        "Excluded " +
+        (sorted_array.length - max_points_to_render) +
+        " clusters (maximum size " +
+        sorted_array[k - 1][0] +
+        " nodes) because only " +
+        max_points_to_render +
+        " objects can be shown at once.";
+    }
+
+    self.edges.forEach((e, i) => {
+      self.clusters[
+        self.cluster_mapping[self.nodes[e.target].cluster]
+      ].distances.push(e.length);
+    });
+
+    self.clusters.forEach((d, i) => {
+      d.distances = helpers.describe_vector(d.distances);
+    });
+    //self.clusters
+
+    self.update();
+  }
+
+  function _cluster_table_draw_id(element, payload) {
+    var this_cell = d3.select(element);
+    this_cell.selectAll("*").remove();
+    const _is_subcluster = payload[1];
+    var cluster_id = payload[0];
+
+    if (_is_subcluster) {
+      //console.log (payload);
+
+      //this_cell.append("i")
+      //      .classed("fa fa-arrow-circle-o-right", true).style("padding-right", "0.25em");
+
+      /*if (payload[2].rr_count) {
+        this_cell
+          .append("i")
+          .classed("fa fa-exclamation-triangle", true)
+          .attr("title", "Subcluster has recent/rapid nodes");
+      }*/
+      this_cell.append("span").text(cluster_id).style("padding-right", "0.5em");
+
+      this_cell
+        .append("button")
+        .classed("btn btn-sm pull-right", true)
+        //.text(__("clusters_tab")["view"])
+        .on("click", (e) => {
+          self.view_subcluster(payload[2]);
+        })
+        .append("i")
+        .classed("fa fa-eye", true)
+        .attr("title", __("clusters_tab")["view"]);
+    } else {
+      this_cell.append("span").text(cluster_id).style("padding-right", "0.5em");
+      this_cell
+        .append("button")
+        .classed("btn btn-sm pull-right", true)
+        .style("margin-right", "0.25em")
+        .on("click", (e) => {
+          self.open_exclusive_tab_view(cluster_id);
+        })
+        .append("i")
+        .classed("fa fa-eye", true)
+        .attr("title", __("clusters_tab")["view"]);
+    }
+    this_cell
+      .append("button")
+      .classed("btn btn-sm pull-right", true)
+      .style("margin-right", "0.25em")
+      //.text(__("clusters_tab")["list"])
+      .attr("data-toggle", "modal")
+      .attr(
+        "data-target",
+        self.get_ui_element_selector_by_role("cluster_list", true)
+      )
+      .attr("data-cluster", cluster_id)
+      .append("i")
+      .classed("fa fa-list", true)
+      .attr("title", __("clusters_tab")["list"]);
+  }
+
+  function _cluster_table_draw_buttons(element, payload) {
+    var this_cell = d3.select(element);
+    const label_diff = function (c_info) {
+      const d = c_info["delta"];
+      const moved = c_info["moved"];
+      const deleted = c_info["deleted"];
+      const new_count = c_info["new_nodes"] ? c_info["new_nodes"] : 0;
+
+      let label_str = "";
+      if (moved) label_str = " " + moved + " moved ";
+      if (new_count) label_str += "+" + new_count + " new ";
+      if (deleted) label_str += "-" + deleted + " previous ";
+      return label_str;
+    };
+
+    var labels = [];
+
+    if (payload[4]) {
+      if (payload[4]["type"] === "new") {
+        if (payload[4]["moved"]) {
+          labels.push(["renamed " + label_diff(payload[4]), 2]);
+        } else {
+          labels.push(["new", 3]);
+        }
+      } else if (payload[4]["type"] === "extended") {
+        labels.push([label_diff(payload[4]), payload["4"]["flag"]]);
+      } else if (payload[4]["type"] === "merged") {
+        labels.push([
+          "Merged " +
+            payload[4]["old_clusters"].join(", ") +
+            " " +
+            label_diff(payload[4]),
+          payload["4"]["flag"],
+        ]);
+      }
+    }
+
+    labels.push([
+      [
+        payload[0]
+          ? __("clusters_tab")["expand"]
+          : __("clusters_tab")["collapse"],
+        payload[0] ? "fa-expand" : "fa-compress",
+      ],
+      0,
+    ]);
+    if (payload[1]) {
+      labels.push([["problematic", "fa-exclamation-circle"], 1]);
+    }
+    if (payload[2]) {
+      labels.push([["match", "fa-check-square"], 1]);
+    }
+    var buttons = this_cell.selectAll("button").data(labels);
+    buttons.enter().append("button");
+    buttons.exit().remove();
+    buttons
+      .classed("btn btn-xs", true)
+      .classed("btn-default", (d) => d[1] !== 1 && d[1] !== 2)
+      .classed("btn-danger", (d) => d[1] === 2)
+      .classed("btn-success", (d) => d[1] === 3)
+      /*.text(function(d) {
+        return d[0];
+      })*/
+      .style("margin-right", "0.25em")
+      .attr("disabled", (d) => (d[1] === 1 ? "disabled" : null))
+      .on("click", (d) => {
+        if (d[1] === 0) {
+          if (payload[0]) {
+            expand_cluster(self.clusters[payload[3] - 1], true);
+          } else {
+            collapse_cluster(self.clusters[payload[3] - 1]);
+          }
+          self.update_volatile_elements(self.cluster_table);
+          if (self.subcluster_table) {
+            self.update_volatile_elements(self.subcluster_table);
+          }
+        } else if (d[1] === 2 || d[1] === 3) {
+          //_social_view_options (labeled_links, shown_types),
+
+          var shown_types = { Existing: 1, "Newly added": 1 },
+            link_class = ["Existing", "Newly added"];
+
+          self
+            .open_exclusive_tab_view(
+              payload[3],
+              null,
+              (cluster_id) => "Cluster " + cluster_id + " [changes view]",
+              self._social_view_options(link_class, shown_types, (e) => {
+                if (
+                  _.isObject(e.source) &&
+                  HTX.HIVTxNetwork.is_new_node(e.source)
+                )
+                  return "Newly added";
+                if (
+                  _.isObject(e.target) &&
+                  HTX.HIVTxNetwork.is_new_node(e.target)
+                )
+                  return "Newly added";
+
+                return e.attributes.indexOf("added-to-prior") >= 0
+                  ? "Newly added"
+                  : "Existing";
+              })
+            )
+            .handle_attribute_categorical("_newly_added");
+        }
+      });
+    buttons.each(function (d, i) {
+      var this_e = d3.select(this);
+      if (_.isString(d[0])) {
+        this_e.selectAll("i").remove();
+        this_e.text(d[0]);
+      } else {
+        var i_span = this_e.selectAll("i").data([d[0]]);
+        i_span.enter().append("i");
+        i_span
+          .attr("class", (d) => "fa " + d[1], true)
+          .attr("title", (d) => d[0]);
+      }
+    });
+  }
+
+  function _node_table_draw_buttons(element, payload) {
+    var this_cell = d3.select(element);
+    let labels;
+    if (payload.length === 1) {
+      if (_.isString(payload[0])) {
+        labels = [[payload[0], 1, "btn-warning"]];
+      } else {
+        labels = ["can't be shown", 1];
+      }
+    } else {
+      labels = [[payload[0] ? "hide" : "show", 0]];
+      // TODO: deprecated? remove if not needed (5/22/2024 meeting with @spond, @daniel-ji, @stevenweaver)
+    }
+
+    if (payload.length === 2 && payload[1] >= 1) {
+      labels.push([
+        "view cluster",
+        function () {
+          self.open_exclusive_tab_view(payload[1]);
+        },
+      ]);
+    }
+
+    var buttons = this_cell.selectAll("button").data(labels);
+    buttons.enter().append("button");
+    buttons.exit().remove();
+    buttons
+      .classed("btn btn-xs btn-node-property", true)
+      .classed("btn-primary", true)
+      //.classed(function (d) {return d.length >=3 ? d[2] : "";}, function (d) {return d.length >= 3;})
+      .text((d) => d[0])
+      .attr("disabled", (d) =>
+        d[1] && !_.isFunction(d[1]) ? "disabled" : null
+      )
+      .on("click", (d) => {
+        if (_.isFunction(d[1])) {
+          d[1].call(d);
+        } else if (d[1] === 0) {
+          if (payload[0]) {
+            collapse_cluster(self.clusters[payload[3] - 1], true);
+          } else {
+            expand_cluster(self.clusters[payload[3] - 1]);
+          }
+          //format_a_cell(d3.select(element).datum(), null, element);
+          self.update_volatile_elements(nodesTab.getNodeTable());
+        }
+      });
+    buttons.each(function (d, e) {
+      if (d.length >= 3) {
+        d3.select(this).classed("btn-primary", false).classed(d[2], true);
+      }
+    });
+  }
+
+  /*self.process_table_volatile_event = function (e) {
+    console.log (e);
+    e.detail
+      .selectAll("td")
+      .filter(function(d) {
+        return "volatile" in d;
+      })
+      .each(function(d, i) {
+        format_a_cell(d, i, this);
+      });
+  };*/
+
+  self.update_volatile_elements = function (container) {
+    //var event = new CustomEvent('hiv-trace-viz-volatile-update', { detail: container });
+    //container.node().dispatchEvent (event);
+
+    container
+      .selectAll("td, th")
+      .filter((d) => "volatile" in d)
+      .each(function (d, i) {
+        // TODO: QUESTION: Should this have priority_set_editor arg passed in as well?
+        tables.format_a_cell(d, i, this);
+      });
+  };
+
+  self.redraw_tables = function () {
+    self.update_volatile_elements(self.cluster_table);
+    if (self.subcluster_table) {
+      self.update_volatile_elements(self.subcluster_table);
+    }
+    self.update_volatile_elements(nodesTab.getNodeTable());
+    if (self.priority_set_table) {
+      self.update_volatile_elements(self.priority_set_table);
+    }
+  };
+
+  self.draw_extended_node_table = function (
+    node_list,
+    container,
+    extra_columns
+  ) {
+    container = container || nodesTab.getNodeTable();
+
+    if (container) {
+      node_list = node_list || self.nodes;
+      var column_ids = self._extract_exportable_attributes(true);
+
+      self.displayed_node_subset = _.filter(
+        _.map(self.displayed_node_subset, (n, i) => {
+          if (_.isString(n)) {
+            n = _.find(column_ids, (cd) => cd.raw_attribute_key === n);
+
+            if (n) {
+              return n;
+            }
+            return column_ids[i];
+          }
+          return n;
+        }),
+        (c) => c
+      );
+
+      var node_data = self._extract_attributes_for_nodes(
+        node_list,
+        self.displayed_node_subset
+      );
+      node_data.splice(0, 1);
+      var table_headers = _.map(self.displayed_node_subset, (n, col_id) => ({
+        value: n.raw_attribute_key,
+        sort: "value",
+        filter: true,
+        volatile: true,
+        help: "label" in n ? n.label : n.raw_attribute_key,
+        //format: (d) => "label" in d ? d.label : d.raw_attribute_key,
+        callback: function (element, payload) {
+          var dropdown = d3
+            .select(element)
+            .append("div")
+            .classed("dropdown", true);
+          // add col_id to ensure that the dropdowns are unique
+          var menu_id = "hivtrace_node_column_" + payload + "_" + col_id;
+          var dropdown_button = dropdown
+            .append("button")
+            .classed({
+              btn: true,
+              "btn-default": true,
+              "btn-xs": true,
+              "dropdown-toggle": true,
+            })
+            .attr("type", "button")
+            .attr("data-toggle", "dropdown")
+            .attr("aria-haspopup", "true")
+            .attr("aria-expanded", "false")
+            .attr("id", menu_id);
+
+          function format_key(key) {
+            const formattedKey = jsConvert.toHeaderCase(key);
+            const words = formattedKey.split(" ");
+            const mappedWords = _.map(words, (word) => {
+              if (word.toLowerCase() === "hivtrace") {
+                return "HIV-TRACE";
+              }
+              if (word.toLowerCase() === "id") {
+                return "ID";
+              }
+
+              return word;
+            });
+            return mappedWords.join(" ");
+          }
+
+          function get_text_label(key) {
+            return key in json.patient_attribute_schema
+              ? json.patient_attribute_schema[key].label
+              : format_key(key);
+          }
+
+          dropdown_button.text(get_text_label(payload));
+
+          dropdown_button.append("i").classed({
+            fa: true,
+            "fa-caret-down": true,
+            "fa-lg": true,
+          });
+          var dropdown_list = dropdown
+            .append("ul")
+            .classed("dropdown-menu", true)
+            .attr("aria-labelledby", menu_id);
+
+          dropdown_list = dropdown_list
+            .selectAll("li")
+            .data(
+              _.filter(
+                column_ids,
+                (alt) => alt.raw_attribute_key !== n.raw_attribute_key
+              )
+            );
+          dropdown_list.enter().append("li");
+          dropdown_list.each(function (data, i) {
+            var handle_change = d3
+              .select(this)
+              .append("a")
+              .attr("href", "#")
+              .text((data) => get_text_label(data.raw_attribute_key));
+            handle_change.on("click", (d) => {
+              self.displayed_node_subset[col_id] = d;
+              self.draw_extended_node_table(
+                node_list,
+                container,
+                extra_columns
+              );
+            });
+          });
+          return dropdown;
+        },
+      }));
+
+      if (extra_columns) {
+        _.each(extra_columns, (d) => {
+          if (d.prepend) {
+            table_headers.splice(0, 0, d.description);
+          } else {
+            table_headers.push(d.description);
+          }
+        });
+      }
+      //console.log (self.displayed_node_subset);
+
+      var table_rows = node_data.map((n, i) => {
+        var this_row = _.map(n, (cell, c) => {
+          let cell_definition = null;
+
+          if (self.displayed_node_subset[c].type === "Date") {
+            cell_definition = {
+              value: cell,
+              format: function (v) {
+                if (v === kGlobals.missing.label) {
+                  return v;
+                }
+                return timeDateUtil.DateViewFormatSlider(v);
+              },
+            };
+          } else if (self.displayed_node_subset[c].type === "Number") {
+            cell_definition = { value: cell, format: d3.format(".2f") };
+          }
+          if (!cell_definition) {
+            cell_definition = { value: cell };
+          }
+
+          // this makes the table rendering too slow
+
+          /*if (c === 0 && self._is_CDC_) {
+             cell_definition.volatile = true;
+             cell_definition.actions = function (item, value) {
+              if (!clustersOfInterest.get_editor()) {
+                    return null;
+              } else {
+                    return [
+                        {
+                            "icon"   : "fa-plus-square",
+                            "action" : function (button,v) {
+                                if (clustersOfInterest.get_editor()) {
+                                    clustersOfInterest.get_editor().append_node_objects (d.children);
+                                }
+                                return false;
+                            },
+                            "help"   : "Add to priority set"
+                        }
+                    ];
+                }
+            };
+          }*/
+
+          return cell_definition;
+        });
+
+        if (extra_columns) {
+          _.each(extra_columns, (ed) => {
+            if (ed.prepend) {
+              this_row.splice(0, 0, ed.generator(node_list[i], self));
+            } else {
+              this_row.push(ed.generator(node_list[i], self));
+            }
+          });
+        }
+
+        return this_row;
+      });
+
+      self.draw_node_table(
+        null,
+        null,
+        [table_headers],
+        table_rows,
+        container,
+        'Showing <span class="badge" data-hivtrace-ui-role="table-count-shown">--</span>/<span class="badge" data-hivtrace-ui-role="table-count-total">--</span> network nodes'
+      );
+    }
+  };
+
+  self.generate_coi_temporal_report = function (ref_set, D) {
+    if (!ref_set) return {};
+    D = D || 0.005;
+
+    const nodesD = hivtrace_cluster_depthwise_traversal(
+      json["Nodes"],
+      json["Edges"],
+      (e) => e.length <= D,
+      null,
+      ref_set.node_objects
+    );
+
+    const full_subclusters = _.map(nodesD, (cc) =>
+      self.extract_single_cluster(cc, (e) => e.length <= D)
+    );
+    // the nodes in full_subclusters are now shallow clones
+    // const nodeid2cc = _.chain(nodesD) // unused var
+    //   .map((cc, i) => _.map(cc, (n) => [n.id, i]))
+    //   .flatten(1)
+    //   .object()
+    //   .value();
+    // node id => index of its connected component in the full_subclusters array
+    const pg_nodes = new Set(_.map(ref_set.node_objects, (n) => n.id));
+    // set of node IDs in the CoI
+    const seed_nodes = _.map(full_subclusters, (fc) =>
+      _.filter(fc["Nodes"], (n) => pg_nodes.has(n.id))
+    );
+    // for each connected component, store the list of nodes that are both in the CC and the CoI
+    // these are shallow copies
+    _.each(seed_nodes, (sn) => _.each(sn, (n) => (n.visited = false)));
+
+    var beginning_of_time = timeDateUtil.getCurrentDate();
+    beginning_of_time.setFullYear(1900);
+
+    // unused var
+    // const nodesD2 = _.map(full_subclusters, (fc, i) => hivtrace_cluster_depthwise_traversal(
+    //   fc["Nodes"],
+    //   fc["Edges"],
+    //   (e) => (e.length <= D),
+    //   null,
+    //   seed_nodes[i]
+    // ));
+
+    const network_events = _.sortBy([...self.priority_groups_all_events()]);
+    network_events.reverse();
+    const info_by_event = {};
+
+    _.each(network_events, (DT) => {
+      const event_date = timeDateUtil.DateViewFormatSlider.parse(DT);
+      const event_date_m3y = timeDateUtil.DateViewFormatSlider.parse(DT);
+      event_date_m3y.setFullYear(event_date.getFullYear() - 3);
+      const event_date_m1y = timeDateUtil.DateViewFormatSlider.parse(DT);
+      event_date_m1y.setFullYear(event_date.getFullYear() - 1);
+      const n_filter = (n) =>
+        self.filter_by_date(
+          beginning_of_time,
+          timeDateUtil._networkCDCDateField,
+          event_date,
+          n
+        );
+      const n_filter3 = (n) =>
+        self.filter_by_date(
+          event_date_m3y,
+          timeDateUtil._networkCDCDateField,
+          event_date,
+          n
+        );
+      const n_filter1 = (n) =>
+        self.filter_by_date(
+          event_date_m1y,
+          timeDateUtil._networkCDCDateField,
+          event_date,
+          n
+        );
+
+      let nodesD2 = _.map(full_subclusters, (fc, i) => {
+        const white_list = new Set(
+          _.map(_.filter(fc["Nodes"], n_filter), (n) => n.id)
+        );
+        const cc_nodes = fc["Nodes"];
+        return hivtrace_cluster_depthwise_traversal(
+          cc_nodes,
+          fc["Edges"],
+          (e) =>
+            e.length <= D &&
+            n_filter3(cc_nodes[e.source]) &&
+            n_filter3(cc_nodes[e.target]),
+          null,
+          _.filter(seed_nodes[i], n_filter),
+          white_list
+        );
+      });
+
+      nodesD2 = _.flatten(nodesD2, 1);
+      //console.log (nodesD2);
+
+      info_by_event[DT] = {
+        connected_componets: _.map(nodesD2, (nd) => nd.length),
+        priority_nodes: _.map(nodesD2, (nd) =>
+          _.map(_.filter(nd, n_filter1), (n) => n.id)
+        ),
+      };
+
+      info_by_event[DT]["national_priority"] = _.map(
+        info_by_event[DT].priority_nodes,
+        (m) => m.length >= self.CDC_data["autocreate-priority-set-size"]
+      );
+    });
+
+    const report = {
+      node_info: _.map(ref_set.node_objects, (n) => [
+        n.id,
+        timeDateUtil.DateViewFormatSlider(
+          self.attribute_node_value_by_id(n, timeDateUtil._networkCDCDateField)
+        ),
+      ]),
+      event_info: info_by_event,
+    };
+
+    /*let options = ["0","1","2","3","4","5","6","7","8","9","10"];
+          let rename = {};
+          _.each (report.node_info, (n)=> {
+                rename[n[0]] = "N" + _.sample (options, 9).join ("");
+                n[0] = rename[n[0]];
+          });
+          _.each (report.event_info, (d)=> {
+              d.priority_nodes = _.map (d.priority_nodes, (d)=>_.map (d, (n)=>rename[n]));
+          });
+          //console.log (report);
+          */
+
+    //helpers.export_json_button(report);
+    return report;
+  };
+
+  self.draw_node_table = function (
+    extra_columns,
+    node_list,
+    headers,
+    rows,
+    container,
+    table_caption
+  ) {
+    container = container || nodesTab.getNodeTable();
+
+    if (container) {
+      node_list = node_list || self.nodes;
+
+      if (!headers) {
+        headers = [
+          [
+            {
+              value: "ID",
+              sort: "value",
+              help: "Node ID",
+            },
+            {
+              value: "Action",
+              sort: "value",
+            },
+            {
+              value: "# of links",
+              sort: "value",
+              help: "Number of links (Node degree)",
+            },
+            {
+              value: "Cluster",
+              sort: "value",
+              help: "Which cluster does the node belong to",
+            },
+          ],
+        ];
+
+        if (extra_columns) {
+          _.each(extra_columns, (d) => {
+            if (d.prepend) {
+              headers[0].splice(0, 0, d.description);
+            } else {
+              headers[0].push(d.description);
+            }
+          });
+        }
+
+        rows = node_list.map((n, i) => {
+          var this_row = [
+            {
+              value: n.id,
+              help: "Node ID",
+            },
+            {
+              value: function () {
+                if (n.node_class !== "injected") {
+                  try {
+                    if (self.exclude_cluster_ids[n.cluster]) {
+                      // parent cluster can't be rendered
+                      // because of size restrictions
+                      return [n.cluster];
+                    }
+                    return [
+                      !self.clusters[self.cluster_mapping[n.cluster]].collapsed,
+                      n.cluster,
+                    ];
+                  } catch (err) {
+                    return [-1];
+                  }
+                } else {
+                  return [n.node_annotation];
+                }
+              },
+              callback: _node_table_draw_buttons,
+              volatile: true,
+            },
+            {
+              value: "degree" in n ? n.degree : "Not defined",
+              help: "Node degree",
+            },
+            {
+              value: "cluster" in n ? n.cluster : "Not defined",
+              help: "Which cluster does the node belong to",
+            },
+          ];
+
+          if (extra_columns) {
+            _.each(extra_columns, (ed) => {
+              if (ed.prepend) {
+                this_row.splice(0, 0, ed.generator(n, self));
+              } else {
+                this_row.push(ed.generator(n, self));
+              }
+            });
+          }
+          return this_row;
+        });
+      }
+
+      tables.add_a_sortable_table(
+        container,
+        headers,
+        rows,
+        true,
+        table_caption,
+        clustersOfInterest.get_editor()
+        // rows
+      );
+    }
+  };
+
+  self.draw_cluster_table = function (extra_columns, element, options) {
+    var skip_clusters = options && options["no-clusters"];
+    var skip_subclusters = !(options && options["subclusters"]);
+
+    element = element || self.cluster_table;
+
+    if (element) {
+      var headers = [
+        [
+          {
+            value: __("general")["cluster"] + " ID",
+            sort: function (c) {
+              return _.map(
+                c.value[0].split(kGlobals.SubclusterSeparator),
+                (ss) => kGlobals.formats.DotFormatPadder(Number(ss))
+              ).join("|");
+            },
+            help: "Unique cluster ID",
+          },
+          {
+            value: __("general")["attributes"],
+            sort: function (c) {
+              c = c.value();
+              if (c[4]) {
+                // has attributes
+                return c[4]["delta"];
+              }
+              return c[0];
+            },
+            help: "Visibility in the network tab and other attributes",
+          },
+          {
+            value: __("clusters_tab")["size"],
+            sort: "value",
+            help: "Number of nodes in the cluster",
+          },
+        ],
+      ];
+
+      if (self.cluster_attributes) {
+        headers[0][1]["presort"] = "desc";
+      }
+
+      if (self._is_seguro) {
+        headers[0].push({
+          value: __("clusters_tab")["number_of_genotypes_in_past_2_months"],
+          sort: "value",
+          help: "# of cases in cluster genotyped in the last 2 months",
+        });
+
+        headers[0].push({
+          value:
+            __("clusters_tab")["scaled_number_of_genotypes_in_past_2_months"],
+          sort: "value",
+          help: "# of cases in cluster genotyped in the last 2 months divided by the square-root of the cluster size",
+        });
+      }
+
+      if (!self._is_CDC_) {
+        headers[0].push({
+          value:
+            __("statistics")["links_per_node"] +
+            "<br>" +
+            __("statistics")["mean"] +
+            "[" +
+            __("statistics")["median"] +
+            ", IQR]",
+          html: true,
+        });
+
+        headers[0].push({
+          value:
+            __("statistics")["genetic_distances_among_linked_nodes"] +
+            "<br>" +
+            __("statistics")["mean"] +
+            "[" +
+            __("statistics")["median"] +
+            ", IQR]",
+          help: "Genetic distance among nodes in the cluster",
+          html: true,
+        });
+      }
+
+      if (extra_columns) {
+        _.each(extra_columns, (d) => {
+          headers[0].push(d.description);
+        });
+      }
+
+      if (options && options["headers"]) {
+        options["headers"](headers);
+      }
+
+      var rows = [];
+
+      _.each(self.clusters, (cluster) => {
+        var make_row = function (d, is_subcluster) {
+          var this_row = [
+            {
+              value: [d.cluster_id, is_subcluster, d], //.cluster_id,
+              callback: _cluster_table_draw_id,
+            },
+            {
+              value: function () {
+                var actual_cluster = is_subcluster ? d.parent_cluster : d;
+
+                return [
+                  actual_cluster.collapsed,
+                  actual_cluster.hxb2_linked,
+                  actual_cluster.match_filter,
+                  actual_cluster.cluster_id,
+                  is_subcluster
+                    ? null
+                    : self.cluster_attributes
+                    ? self.cluster_attributes[actual_cluster.cluster_id]
+                    : null,
+                ];
+              },
+              callback: _cluster_table_draw_buttons,
+              volatile: true,
+            },
+            {
+              value: d.children.length,
+            },
+          ];
+
+          if (self._is_CDC_) {
+            this_row[2].volatile = true;
+            this_row[2].actions = function (item, value) {
+              if (!clustersOfInterest.get_editor()) {
+                return null;
+              }
+              return [
+                {
+                  icon: "fa-plus",
+                  action: function (button, v) {
+                    if (clustersOfInterest.get_editor()) {
+                      clustersOfInterest
+                        .get_editor()
+                        .append_node_objects(d.children);
+                    }
+                    return false;
+                  },
+                  help: "Add to cluster of interest",
+                },
+              ];
+            };
+          }
+
+          if (self._is_seguro) {
+            this_row.push({
+              value: d,
+              format: function (d) {
+                return _.filter(
+                  d.children,
+                  (child) =>
+                    d3.time.months(
+                      child.patient_attributes["sample_dt"],
+                      timeDateUtil.getCurrentDate()
+                    ).length <= 2
+                ).length;
+              },
+            });
+
+            this_row.push({
+              value: d,
+              format: function (d) {
+                const recent = _.filter(
+                  d.children,
+                  (child) =>
+                    d3.time.months(
+                      child.patient_attributes["sample_dt"],
+                      timeDateUtil.getCurrentDate()
+                    ).length <= 2
+                ).length;
+                return recent / Math.sqrt(d.children.length);
+              },
+            });
+          }
+
+          if (!self._is_CDC_) {
+            this_row.push({
+              value: d.degrees,
+              format: function (d) {
+                try {
+                  return (
+                    kGlobals.formats.FloatFormat(d["mean"]) +
+                    " [" +
+                    kGlobals.formats.FloatFormat(d["median"]) +
+                    ", " +
+                    kGlobals.formats.FloatFormat(d["Q1"]) +
+                    " - " +
+                    kGlobals.formats.FloatFormat(d["Q3"]) +
+                    "]"
+                  );
+                } catch (e) {
+                  return "";
+                }
+              },
+            });
+            this_row.push({
+              value: d.distances,
+              format: function (d) {
+                try {
+                  return (
+                    kGlobals.formats.FloatFormat(d["mean"]) +
+                    " [" +
+                    kGlobals.formats.FloatFormat(d["median"]) +
+                    ", " +
+                    kGlobals.formats.FloatFormat(d["Q1"]) +
+                    " - " +
+                    kGlobals.formats.FloatFormat(d["Q3"]) +
+                    "]"
+                  );
+                } catch (e) {
+                  return "";
+                }
+              },
+            });
+          }
+          if (extra_columns) {
+            _.each(extra_columns, (ed) => {
+              this_row.push(ed.generator(d, self));
+            });
+          }
+
+          return this_row;
+        };
+
+        if (!skip_clusters) {
+          rows.push(make_row(cluster, false));
+        }
+
+        if (!skip_subclusters) {
+          _.each(cluster.subclusters, (sub_cluster) => {
+            rows.push(make_row(sub_cluster, true));
+          });
+        }
+      });
+
+      tables.add_a_sortable_table(
+        element,
+        headers,
+        rows,
+        true,
+        options && options["caption"] ? options["caption"] : null,
+        clustersOfInterest.get_editor()
+      );
+    }
+  };
+
+  /*------------ Update layout code ---------------*/
+  function update_network_string(node_count, edge_count) {
+    if (network_status_string) {
+      const clusters_shown = _.filter(
+        self.clusters,
+        (c) => !c.collapsed
+      ).length;
+
+      const clusters_selected = _.filter(
+        self.clusters,
+        (c) =>
+          !c.is_hidden && c.match_filter !== undefined && c.match_filter > 0
+      ).length;
+
+      const nodes_selected = _.filter(
+        self.nodes,
+        (n) => n.match_filter && !n.is_hidden
+      ).length;
+
+      // const clusters_removed = self.cluster_sizes.length - self.clusters.length;
+      // const nodes_removed = graph_data.Nodes.length - singletons - self.nodes.length;
+      // const networkString = "Displaying a network on <strong>" + self.nodes.length + "</strong> nodes, <strong>" + self.clusters.length + "</strong> clusters"
+      //         + (clusters_removed > 0 ? " (an additional " + clusters_removed + " clusters and " + nodes_removed + " nodes have been removed due to network size constraints)" : "") + ". <strong>"
+      //         + clusters_shown +"</strong> clusters are expanded. Of <strong>" + self.edges.length + "</strong> edges, <strong>" + draw_me.edges.length + "</strong>, and of  <strong>" + self.nodes.length  + " </strong> nodes,  <strong>" + draw_me.nodes.length + " </strong> are displayed. ";
+      // if (singletons > 0) {
+      //   networkString += "<strong>" +singletons + "</strong> singleton nodes are not shown. ";
+      // }
+
+      const networkString =
+        "<span class = 'badge'>" +
+        self.clusters.length +
+        "</span> clusters <span class = 'label label-primary'>" +
+        clusters_shown +
+        " expanded / " +
+        clusters_selected +
+        " match </span> <span class = 'badge'> " +
+        self.nodes.length +
+        "</span> nodes <span class = 'label label-primary'>" +
+        node_count +
+        " shown / " +
+        nodes_selected +
+        " match </span> <span class = 'badge'> " +
+        self.edges.length +
+        "</span> " +
+        (self._is_CDC_ ? "links" : "edges") +
+        " <span class = 'label label-primary'>" +
+        edge_count +
+        " shown</span>";
+
+      d3.select(network_status_string).html(networkString);
+    }
+  }
+
+  function draw_a_node(container, node) {
+    if (node) {
+      container = d3.select(container);
+      //console.log (container.selectAll ("path"));
+      //var path_component = containter.selectAll ("path");
+
+      let symbol_type;
+
+      if (node.hxb2_linked && !node.is_lanl) {
+        symbol_type = "cross";
+      } else if (node.is_lanl) {
+        symbol_type = "triangle-down";
+      } else {
+        symbol_type = self.node_shaper["shaper"](node);
+      }
+
+      node.rendered_size = Math.sqrt(node_size(node)) / 2 + 2;
+
+      container
+        .selectAll("path")
+        .attr("d", misc.symbol(symbol_type).size(node_size(node)))
+        .style("fill", (d) => node_color(d));
+
+      if (node.show_label) {
+        if (container.selectAll("text").empty()) {
+          node.label_x = 0;
+          node.label_y = 0;
+          container
+            .append("text")
+            .classed("node-label", true)
+            .text(node.id)
+            .attr(
+              "transform",
+              "translate(" +
+                node.rendered_size * 1.25 +
+                "," +
+                node.rendered_size * 0.5 +
+                ")"
+            )
+            .datum(node)
+            .call(self.node_label_drag);
+        }
+      } else {
+        container.selectAll("text").remove();
+      }
+
+      container
+        //.attr("d", misc.symbol(symbol_type).size(node_size(node)))
+        .attr("class", "node")
+        .classed(
+          "selected_object",
+          (d) => d.match_filter && !self.hide_unselected
+        )
+        .classed("injected_object", (d) => d.node_class === "injected")
+        .attr("transform", (d) => "translate(" + d.x + "," + d.y + ")")
+        .style("opacity", (d) => node_opacity(d))
+        .style("display", (d) => {
+          if (d.is_hidden) return "none";
+          return null;
+        })
+        .call(
+          network_layout.drag().on("dragstart", (d) => {
+            d3.event.sourceEvent.stopPropagation();
+            node_pop_off();
+          })
+        )
+        .on("dragend", (d) => {
+          d3.event.sourceEvent.stopPropagation();
+        })
+        .on("click", handle_node_click)
+        .on("mouseover", node_pop_on)
+        .on("mouseout", node_pop_off);
+    }
+  }
+
+  function draw_a_cluster(container, the_cluster) {
+    var container_group = d3.select(container);
+
+    var draw_from = the_cluster["binned_attributes"]
+      ? the_cluster["binned_attributes"].map((d) => d.concat([0]))
+      : [[null, 1, 0]];
+
+    if (the_cluster.match_filter) {
+      draw_from = draw_from.concat([
+        ["selected", the_cluster.match_filter, 1],
+        [
+          "not selected",
+          the_cluster.children.length - the_cluster.match_filter,
+          1,
+        ],
+      ]);
+    }
+
+    var sums = [
+      d3.sum(
+        draw_from.filter((d) => d[2] === 0),
+        (d) => d[1]
+      ),
+      d3.sum(
+        draw_from.filter((d) => d[2] !== 0),
+        (d) => d[1]
+      ),
+    ];
+
+    var running_totals = [0, 0];
+
+    draw_from = draw_from.map((d) => {
+      var index = d[2];
+      var v = {
+        container: container,
+        cluster: the_cluster,
+        startAngle: (running_totals[index] / sums[index]) * 2 * Math.PI,
+        endAngle: ((running_totals[index] + d[1]) / sums[index]) * 2 * Math.PI,
+        name: d[0],
+        rim: index > 0,
+      };
+      running_totals[index] += d[1];
+      return v;
+    });
+
+    var arc_radius = cluster_box_size(the_cluster) * 0.5;
+    the_cluster.rendered_size = arc_radius + 2;
+    var paths = container_group.selectAll("path").data(draw_from);
+    paths.enter().append("path");
+    paths.exit().remove();
+
+    paths
+      .classed("cluster", true)
+      .classed(
+        "hiv-trace-problematic",
+        (d) => the_cluster.hxb2_linked && !d.rim
+      )
+      .classed("hiv-trace-selected", (d) => d.rim)
+      .attr("d", (d) =>
+        (d.rim
+          ? d3.svg
+              .arc()
+              .innerRadius(arc_radius + 2)
+              .outerRadius(arc_radius + 5)
+          : d3.svg.arc().innerRadius(0).outerRadius(arc_radius))(d)
+      )
+      .style("fill", (d, i) => {
+        if (d.rim) {
+          return self.colorizer["selected"](d.name);
+        }
+
+        if (the_cluster["gradient"]) {
+          return "url(#" + the_cluster["gradient"] + ")";
+        }
+
+        return cluster_color(the_cluster, d.name);
+      })
+      .style("stroke-linejoin", (d, i) => (draw_from.length > 1 ? "round" : ""))
+      .style("display", (d) => {
+        if (the_cluster.is_hidden) return "none";
+        return null;
+      });
+  }
+
+  function check_for_predefined_shapes(cat_id) {
+    //console.log (cat_id);
+
+    if (cat_id in self.networkShapeScheme) {
+      var domain = _.range(
+        0,
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["value_range"]
+          .length
+      );
+
+      return {
+        domain: domain,
+        range: _.map(
+          domain,
+          (v) =>
+            self.networkShapeScheme[cat_id][
+              graph_data[kGlobals.network.GraphAttrbuteID][cat_id][
+                "value_range"
+              ][v]
+            ]
+        ),
+      };
+    }
+    return {
+      domain: _.range(
+        0,
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id].dimension
+      ),
+      range: kGlobals.ShapeOrdering,
+    };
+  }
+
+  self.handle_shape_categorical = function (cat_id) {
+    var set_attr = "None";
+
+    ["shapes"].forEach((lbl) => {
+      d3.select(self.get_ui_element_selector_by_role(lbl))
+        .selectAll("li")
+        .selectAll("a")
+        .attr("style", (d, i) => {
+          if (d[1] === cat_id) {
+            set_attr = d[0];
+            return " font-weight: bold;";
+          }
+          return null;
+        });
+      d3.select(self.get_ui_element_selector_by_role(lbl + "_label")).html(
+        __("network_tab")["shape"] +
+          ": " +
+          set_attr +
+          ' <span class="caret"></span>'
+      );
+    });
+
+    if (cat_id) {
+      var domain_range = check_for_predefined_shapes(cat_id);
+
+      var shape_mapper = d3.scale
+        .ordinal()
+        .domain(domain_range["domain"])
+        .range(domain_range["range"]);
+      self.node_shaper["id"] = cat_id;
+      self.node_shaper["shaper"] = function (d) {
+        return shape_mapper(
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["value_map"](
+            self.attribute_node_value_by_id(d, cat_id)
+          )
+        );
+      };
+      self.node_shaper["category_map"] =
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["value_map"];
+    } else {
+      self.node_shaper.id = null;
+      self.node_shaper.shaper = () => "circle";
+      self.node_shaper["category_map"] = null;
+    }
+    //console.log (graph_data [kGlobals.network.GraphAttrbuteID][cat_id]['value_map'], self.node_shaper.domain(), self.node_shaper.range());
+    self.draw_attribute_labels();
+    self.update(true);
+    d3.event.preventDefault();
+  };
+
+  self.renderColorPicker = function (cat_id, type) {
+    const renderColorPickerCategorical = function (cat_id) {
+      // For each unique value, render item.
+      let colorizer = self.colorizer;
+      let items = _.map(_.filter(self.uniqValues[cat_id]), (d) =>
+        colorPicker.colorPickerInput(d, colorizer)
+      );
+
+      $("#colorPickerRow").html(items.join(""));
+
+      // Set onchange event for items
+      $(".hivtrace-color-picker").change((e) => {
+        let color = e.target.value;
+        let name = e.target.name;
+
+        // Set color in user-defined colorizer
+        if (
+          _.isUndefined(
+            graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"]
+          )
+        ) {
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"] =
+            {};
+        }
+
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"][
+          name
+        ] = color;
+        self.handle_attribute_categorical(cat_id);
+      });
+    };
+
+    const renderColorPickerContinuous = function (cat_id, color_stops) {
+      // For each unique value, render item.
+      // Min and max range for continuous values
+      let items = [
+        colorPicker.colorStops("Color Stops", color_stops),
+        colorPicker.colorPickerInputContinuous(
+          "Min",
+          self.uniqValues[cat_id]["min"]
+        ),
+        colorPicker.colorPickerInputContinuous(
+          "Max",
+          self.uniqValues[cat_id]["max"]
+        ),
+      ];
+
+      $("#colorPickerRow").html(items.join(""));
+
+      // Set onchange event for items
+      $(".hivtrace-color-picker").change((e) => {
+        let color = e.target.value;
+        let name = e.target.name;
+
+        // Set color in user-defined colorizer
+        if (
+          _.isUndefined(
+            graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"]
+          )
+        ) {
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"] =
+            {};
+        }
+
+        // get both for user-defined
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"][
+          name
+        ] = color;
+        self.handle_attribute_continuous(cat_id);
+      });
+
+      // Set onchange event for items
+      $(".hivtrace-color-stops").change((e) => {
+        let num = parseInt(e.target.value);
+        graph_data[kGlobals.network.GraphAttrbuteID][
+          self.colorizer["category_id"]
+        ]["color_stops"] = num;
+
+        self._aux_populate_category_menus();
+        self.handle_attribute_continuous(cat_id);
+        self.update();
+      });
+    };
+
+    if (type === "categorical") {
+      renderColorPickerCategorical(cat_id);
+    } else if (type === "continuous") {
+      renderColorPickerContinuous(
+        cat_id,
+        graph_data[kGlobals.network.GraphAttrbuteID][
+          self.colorizer["category_id"]
+        ]["color_stops"]
+      );
+    } else {
+      console.log("Error: type not recognized");
+    }
+
+    if (cat_id !== null) {
+      $("#colorPickerOption").show();
+    } else {
+      $("#colorPickerOption").hide();
+    }
+  };
+
+  self.draw_attribute_labels = function () {
+    // draw color legend in the network SVG
+
+    var determine_label_format_cont = function (field_data) {
+      if ("label_format" in field_data) {
+        return field_data["label_format"];
+      }
+      if (field_data["type"] === "Date") {
+        return timeDateUtil.DateViewFormatShort;
+      }
+      return d3.format(",.4r");
+    };
+
+    self.legend_svg.selectAll("g.hiv-trace-legend").remove();
+
+    var offset = 10;
+
+    if (self.legend_caption) {
+      self.legend_svg
+        .append("g")
+        .attr("transform", "translate(0," + offset + ")")
+        .classed("hiv-trace-legend", true)
+        .append("text")
+        .text(self.legend_caption)
+        .style("font-weight", "bold");
+      offset += 18;
+    }
+
+    if (self.edge_legend) {
+      self.legend_svg
+        .append("g")
+        .attr("transform", "translate(0," + offset + ")")
+        .classed("hiv-trace-legend", true)
+        .append("text")
+        .text(self.edge_legend["caption"])
+        .style("font-weight", "bold");
+      offset += 18;
+
+      _.each(self.edge_legend["types"], (value, key) => {
+        self.legend_svg
+          .append("g")
+          .classed("hiv-trace-legend", true)
+          .attr("transform", "translate(20," + offset + ")")
+          .append("text")
+          .text(key);
+
+        value.call(
+          self.legend_svg
+            .append("g")
+            .classed("hiv-trace-legend", true)
+            .attr("transform", "translate(0," + offset + ")")
+            .append("line")
+            .attr("x1", "0")
+            .attr("y1", "-4")
+            .attr("x2", "12")
+            .attr("y2", "-4")
+            .classed("legend", true)
+        );
+
+        offset += 18;
+      });
+    }
+
+    if (self.colorizer["category_id"]) {
+      //_.each (self.colorizer["category_map"](null, "map"), function (v){ console.log (v); });
+
+      self.legend_svg
+        .append("g")
+        .attr("transform", "translate(0," + offset + ")")
+        .classed("hiv-trace-legend", true)
+        .append("text")
+        .text(
+          "Color: " +
+            self.json[kGlobals.network.GraphAttrbuteID][
+              self.colorizer["category_id"]
+            ].label
+        )
+        .style("font-weight", "bold");
+      offset += 18;
+
+      if (self.colorizer["continuous"]) {
+        var anchor_format = determine_label_format_cont(
+          graph_data[kGlobals.network.GraphAttrbuteID][
+            self.colorizer["category_id"]
+          ]
+        );
+
+        var color_stops =
+          graph_data[kGlobals.network.GraphAttrbuteID][
+            self.colorizer["category_id"]
+          ]["color_stops"] || kGlobals.network.ContinuousColorStops;
+
+        var scale =
+          graph_data[kGlobals.network.GraphAttrbuteID][
+            self.colorizer["category_id"]
+          ]["scale"];
+
+        _.each(_.range(color_stops), (value) => {
+          var x = scale.invert(value);
+          self.legend_svg
+            .append("g")
+            .classed("hiv-trace-legend", true)
+            .attr("transform", "translate(20," + offset + ")")
+            .append("text")
+            .text(anchor_format(x));
+          self.legend_svg
+            .append("g")
+            .classed("hiv-trace-legend", true)
+            .attr("transform", "translate(0," + offset + ")")
+            .append("circle")
+            .attr("cx", "8")
+            .attr("cy", "-4")
+            .attr("r", "8")
+            .classed("legend", true)
+            .style("fill", self.colorizer["category"](x));
+          offset += 18;
+        });
+
+        if (
+          "category_values" in
+          graph_data[kGlobals.network.GraphAttrbuteID][
+            self.colorizer["category_id"]
+          ]
+        ) {
+          _.each(
+            graph_data[kGlobals.network.GraphAttrbuteID][
+              self.colorizer["category_id"]
+            ]["category_values"],
+            (value) => {
+              self.legend_svg
+                .append("g")
+                .classed("hiv-trace-legend", true)
+                .attr("transform", "translate(20," + offset + ")")
+                .append("text")
+                .text(value);
+              self.legend_svg
+                .append("g")
+                .classed("hiv-trace-legend", true)
+                .attr("transform", "translate(0," + offset + ")")
+                .append("circle")
+                .attr("cx", "8")
+                .attr("cy", "-4")
+                .attr("r", "8")
+                .classed("legend", true)
+                .style("fill", self.colorizer["category"](value));
+
+              offset += 18;
+            }
+          );
+        }
+
+        self.legend_svg
+          .append("g")
+          .classed("hiv-trace-legend", true)
+          .attr("transform", "translate(20," + offset + ")")
+          .append("text")
+          .text("missing");
+        self.legend_svg
+          .append("g")
+          .classed("hiv-trace-legend", true)
+          .attr("transform", "translate(0," + offset + ")")
+          .append("circle")
+          .attr("cx", "8")
+          .attr("cy", "-4")
+          .attr("r", "8")
+          .classed("legend", true)
+          .style("fill", kGlobals.missing.color);
+
+        offset += 18;
+      } else {
+        _.each(self.colorizer["category_map"](null, "map"), (value, key) => {
+          self.legend_svg
+            .append("g")
+            .classed("hiv-trace-legend", true)
+            .attr("transform", "translate(20," + offset + ")")
+            .append("text")
+            .text(key);
+          self.legend_svg
+            .append("g")
+            .classed("hiv-trace-legend", true)
+            .attr("transform", "translate(0," + offset + ")")
+            .append("circle")
+            .attr("cx", "8")
+            .attr("cy", "-4")
+            .attr("r", "8")
+            .classed("legend", true)
+            .style("fill", self.colorizer["category"](key));
+
+          offset += 18;
+        });
+      }
+    }
+
+    if (self.node_shaper["id"]) {
+      self.legend_svg
+        .append("g")
+        .attr("transform", "translate(0," + offset + ")")
+        .classed("hiv-trace-legend", true)
+        .append("text")
+        .text(
+          "Shape: " +
+            self.json[kGlobals.network.GraphAttrbuteID][self.node_shaper["id"]]
+              .label
+        )
+        .style("font-weight", "bold");
+      offset += 18;
+
+      var domain_range = check_for_predefined_shapes(self.node_shaper["id"]);
+      var shape_mapper = d3.scale
+        .ordinal()
+        .domain(domain_range["domain"])
+        .range(domain_range["range"]);
+
+      _.each(self.node_shaper["category_map"](null, "map"), (value, key) => {
+        self.legend_svg
+          .append("g")
+          .classed("hiv-trace-legend", true)
+          .attr("transform", "translate(20," + offset + ")")
+          .append("text")
+          .text(key);
+
+        self.legend_svg
+          .append("g")
+          .classed("hiv-trace-legend", true)
+          .attr("transform", "translate(0," + offset + ")")
+          .append("path")
+          .attr("transform", "translate(5,-5)")
+          .attr("d", misc.symbol(shape_mapper(value)).size(128))
+          .classed("legend", true)
+          .style("fill", "none");
+
+        offset += 18;
+      });
+    }
+
+    if (self.colorizer["opacity_id"]) {
+      self.legend_svg
+        .append("g")
+        .attr("transform", "translate(0," + offset + ")")
+        .classed("hiv-trace-legend", true)
+        .append("text")
+        .text(
+          __("network_tab")["opacity"] +
+            ": " +
+            self.json[kGlobals.network.GraphAttrbuteID][
+              self.colorizer["opacity_id"]
+            ].label
+        )
+        .style("font-weight", "bold");
+      offset += 18;
+
+      anchor_format = determine_label_format_cont(
+        graph_data[kGlobals.network.GraphAttrbuteID][
+          self.colorizer["opacity_id"]
+        ]
+      );
+
+      scale =
+        graph_data[kGlobals.network.GraphAttrbuteID][
+          self.colorizer["opacity_id"]
+        ]["scale"];
+
+      _.each(_.range(kGlobals.network.ContinuousColorStops), (value) => {
+        var x = scale.invert(value);
+        self.legend_svg
+          .append("g")
+          .classed("hiv-trace-legend", true)
+          .attr("transform", "translate(20," + offset + ")")
+          .append("text")
+          .text(anchor_format(x));
+        self.legend_svg
+          .append("g")
+          .classed("hiv-trace-legend", true)
+          .attr("transform", "translate(0," + offset + ")")
+          .append("circle")
+          .attr("cx", "8")
+          .attr("cy", "-4")
+          .attr("r", "8")
+          .classed("legend", true)
+          .style("fill", "black")
+          .style("opacity", self.colorizer["opacity"](x));
+
+        offset += 18;
+      });
+
+      self.legend_svg
+        .append("g")
+        .classed("hiv-trace-legend", true)
+        .attr("transform", "translate(20," + offset + ")")
+        .append("text")
+        .text("missing");
+      self.legend_svg
+        .append("g")
+        .classed("hiv-trace-legend", true)
+        .attr("transform", "translate(0," + offset + ")")
+        .append("circle")
+        .attr("cx", "8")
+        .attr("cy", "-4")
+        .attr("r", "8")
+        .classed("legend", true)
+        .style("fill", "black")
+        .style("opacity", kGlobals.missing.opacity);
+
+      offset += 18;
+    }
+  };
+
+  function compute_cluster_gradient(cluster, cat_id) {
+    if (cat_id) {
+      var id = self.dom_prefix + "-cluster-gradient-" + self.gradient_id++;
+      var gradient = self.network_svg
+        .selectAll("defs")
+        .append("radialGradient")
+        .attr("id", id);
+      var values = _.map(cluster.children, (node) => {
+        var value = self.attribute_node_value_by_id(node, cat_id);
+        return value === kGlobals.missing.label ? Infinity : value;
+      }).sort((a, b) => 0 + a - (0 + b));
+      var finite = _.filter(values, (d) => d < Infinity);
+      var infinite = values.length - finite.length;
+
+      if (infinite) {
+        gradient
+          .append("stop")
+          .attr("offset", "0%")
+          .attr("stop-color", kGlobals.missing.color);
+        gradient
+          .append("stop")
+          .attr("offset", String((infinite / values.length) * 100) + "%")
+          .attr("stop-color", kGlobals.missing.color);
+      }
+
+      _.each(finite, (value, index) => {
+        gradient
+          .append("stop")
+          .attr(
+            "offset",
+            String(((1 + index + infinite) * 100) / values.length) + "%"
+          )
+          .attr("stop-color", self.colorizer["category"](value));
+      });
+      //gradient.append ("stop").attr ("offset", "100%").attr ("stop-color", self.colorizer['category'] (dom[1]));
+
+      return id;
+    }
+    return null;
+  }
+
+  self.handle_attribute_opacity = function (cat_id) {
+    var set_attr = "None";
+
+    ["opacity"].forEach((lbl) => {
+      d3.select(self.get_ui_element_selector_by_role(lbl))
+        .selectAll("li")
+        .selectAll("a")
+        .attr("style", (d, i) => {
+          if (d[1] === cat_id) {
+            set_attr = d[0];
+            return " font-weight: bold;";
+          }
+          return null;
+        });
+      d3.select(self.get_ui_element_selector_by_role(lbl + "_label")).html(
+        __("network_tab")["opacity"] +
+          ": " +
+          set_attr +
+          ' <span class="caret"></span>'
+      );
+    });
+
+    d3.select(self.get_ui_element_selector_by_role("opacity_invert"))
+      .style("display", set_attr === "None" ? "none" : "inline")
+      .classed("btn-active", false)
+      .classed("btn-default", true);
+
+    self.colorizer["opacity_id"] = cat_id;
+    if (cat_id) {
+      var scale = graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["scale"];
+      self.colorizer["opacity_scale"] = d3.scale
+        .linear()
+        .domain([0, kGlobals.network.ContinuousColorStops - 1])
+        .range([0.25, 1]);
+      self.colorizer["opacity"] = function (v) {
+        if (v === kGlobals.missing.label) {
+          return kGlobals.missing.opacity;
+        }
+        return self.colorizer["opacity_scale"](scale(v));
+      };
+    } else {
+      self.colorizer["opacity"] = null;
+      self.colorizer["opacity_scale"] = null;
+    }
+
+    self.draw_attribute_labels();
+    self.update(true);
+    d3.event.preventDefault();
+  };
+
+  self.handle_attribute_continuous = function (cat_id) {
+    var set_attr = "None";
+
+    render_chord_diagram("aux_svg_holder", null, null);
+    render_binned_table("attribute_table", null, null);
+
+    self.network_svg.selectAll("radialGradient").remove();
+
+    self.clusters.forEach((the_cluster) => {
+      delete the_cluster["binned_attributes"];
+      delete the_cluster["gradient"];
+    });
+
+    [
+      ["attributes", false],
+      ["attributes_cat", true],
+    ].forEach((lbl) => {
+      d3.select(self.get_ui_element_selector_by_role(lbl[0], lbl[1]))
+        .selectAll("li")
+        .selectAll("a")
+        .attr("style", (d, i) => {
+          if (d[1] === cat_id) {
+            set_attr = d[0];
+            return " font-weight: bold;";
+          }
+          return null;
+        });
+      d3.select(
+        self.get_ui_element_selector_by_role(lbl[0] + "_label", lbl[1])
+      ).html("Color: " + set_attr + ' <span class="caret"></span>');
+    });
+
+    d3.select(self.get_ui_element_selector_by_role("attributes_invert"))
+      .style("display", set_attr === "None" ? "none" : "inline")
+      .classed("btn-active", false)
+      .classed("btn-default", true);
+
+    if (cat_id) {
+      // map values to inverted scale
+      const color_stops =
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["color_stops"] ||
+        kGlobals.network.ContinuousColorStops;
+
+      if (graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["color_scale"]) {
+        self.colorizer["category"] = graph_data[
+          kGlobals.network.GraphAttrbuteID
+        ][cat_id]["color_scale"](
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id],
+          self
+        );
+
+        self.uniqValues[cat_id]["min"] =
+          self.colorizer["category"](color_stops);
+        self.uniqValues[cat_id]["max"] =
+          self.colorizer["category"](color_stops);
+      } else {
+        self.colorizer["category"] = _.wrap(
+          d3.scale
+            .linear()
+            .domain(_.range(kGlobals.network.ContinuousColorStops))
+            .range(["#fff7ec", "#7f0000"])
+            .interpolate(d3.interpolateRgb),
+          (func, arg) => {
+            self.uniqValues[cat_id]["min"] = "#fff7ec";
+            self.uniqValues[cat_id]["max"] = "#7f0000";
+
+            return func(
+              graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["scale"](
+                arg
+              ) *
+                (1 / kGlobals.network.ContinuousColorStops)
+            );
+          }
+        );
+      }
+
+      if (
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"]
+      ) {
+        // get min and max
+        const min =
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"][
+            "min"
+          ] || self.uniqValues[cat_id]["min"];
+        const max =
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"][
+            "max"
+          ] || self.uniqValues[cat_id]["max"];
+
+        self.uniqValues[cat_id]["min"] =
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"][
+            "min"
+          ] || self.uniqValues[cat_id]["min"];
+        self.uniqValues[cat_id]["max"] =
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"][
+            "max"
+          ] || self.uniqValues[cat_id]["max"];
+
+        self.colorizer["category"] = _.wrap(
+          d3.scale
+            .linear()
+            .domain(_.range(color_stops))
+            .range([min, max])
+            .interpolate(d3.interpolateRgb),
+          (func, arg) =>
+            func(
+              graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["scale"](
+                arg
+              ) *
+                (1 / color_stops)
+            )
+        );
+      }
+
+      self.colorizer["category_id"] = cat_id;
+      self.colorizer["continuous"] = true;
+      self.clusters.forEach((the_cluster) => {
+        the_cluster["gradient"] = compute_cluster_gradient(the_cluster, cat_id);
+      });
+
+      var points = [];
+
+      _.each(self.edges, (e) => {
+        var src = self.attribute_node_value_by_id(
+            self.nodes[e.source],
+            cat_id,
+            true
+          ),
+          tgt = self.attribute_node_value_by_id(
+            self.nodes[e.target],
+            cat_id,
+            true
+          );
+
+        if (src !== kGlobals.missing.label && tgt !== kGlobals.missing.label) {
+          points.push({
+            x: src,
+            y: tgt,
+            title:
+              self.nodes[e.source].id +
+              " (" +
+              src +
+              ") -- " +
+              self.nodes[e.target].id +
+              " (" +
+              tgt +
+              ")",
+          });
+        }
+      });
+      d3.select(
+        self.get_ui_element_selector_by_role("aux_svg_holder_enclosed", true)
+      ).style("display", null);
+
+      scatterPlot.scatterPlot(
+        points,
+        400,
+        400,
+        self.get_ui_element_selector_by_role("aux_svg_holder", true),
+        {
+          x: "Source",
+          y: "Target",
+        },
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["type"] === "Date"
+      );
+    } else {
+      self.colorizer["category"] = null;
+      self.colorizer["category_id"] = null;
+      self.colorizer["continuous"] = false;
+      self.colorizer["category_pairwise"] = null;
+      self.colorizer["category_map"] = null;
+    }
+
+    // Draw color picker for manual override
+    self.renderColorPicker(cat_id, "continuous");
+
+    self.draw_attribute_labels();
+    self.update(true);
+
+    if (d3.event) {
+      d3.event.preventDefault();
+    }
+  };
+
+  self.handle_attribute_categorical = function (cat_id, skip_update) {
+    var set_attr = "None";
+
+    d3.select(self.get_ui_element_selector_by_role("attributes_invert")).style(
+      "display",
+      "none"
+    );
+
+    self.network_svg.selectAll("radialGradient").remove();
+
+    [
+      ["attributes", false],
+      ["attributes_cat", true],
+    ].forEach((lbl) => {
+      d3.select(self.get_ui_element_selector_by_role(lbl[0], lbl[1]))
+        .selectAll("li")
+        .selectAll("a")
+        .attr("style", (d, i) => {
+          if (d[1] === cat_id) {
+            set_attr = d[0];
+            return " font-weight: bold;";
+          }
+          return null;
+        });
+      d3.select(
+        self.get_ui_element_selector_by_role(lbl[0] + "_label", lbl[1])
+      ).html("Color: " + set_attr + ' <span class="caret"></span>');
+    });
+
+    self.clusters.forEach((the_cluster) => {
+      delete the_cluster["gradient"];
+      the_cluster["binned_attributes"] = stratify(
+        attribute_cluster_distribution(the_cluster, cat_id)
+      );
+    });
+
+    self.colorizer["continuous"] = false;
+
+    //TODO -- if preset color scheme does not exist, create one and always use the logic here.
+
+    if (cat_id) {
+      if (cat_id in self.networkColorScheme) {
+        let cat_data =
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["enum"];
+        if (cat_data) {
+          cat_data = new Set(_.map(cat_data, (d) => d.toLowerCase()));
+        }
+        var domain = [],
+          range = [];
+        _.each(self.networkColorScheme[cat_id], (value, key) => {
+          if (cat_data) {
+            if (!cat_data.has(key.toLowerCase())) {
+              return;
+            }
+          }
+          domain.push(key);
+          range.push(value);
+        });
+        self.colorizer["category"] = d3.scale
+          .ordinal()
+          .domain(domain)
+          .range(range);
+      } else if (
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["color_scale"]
+      ) {
+        self.colorizer["category"] = graph_data[
+          kGlobals.network.GraphAttrbuteID
+        ][cat_id]["color_scale"](
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id],
+          self
+        );
+      } else {
+        self.colorizer["category"] = d3.scale
+          .ordinal()
+          .range(kGlobals.Categorical);
+
+        var extended_range = _.clone(self.colorizer["category"].range());
+        extended_range.push(kGlobals.missing.color);
+
+        self.colorizer["category"].domain(
+          _.range(kGlobals.MaximumValuesInCategories + 1)
+        );
+
+        self.colorizer["category"].range(extended_range);
+
+        if (
+          graph_data[kGlobals.network.GraphAttrbuteID][cat_id][
+            "stable-ish order"
+          ]
+        ) {
+          self.colorizer["category"] = _.wrap(
+            self.colorizer["category"],
+            (func, arg) => {
+              if (arg === kGlobals.missing.label) {
+                return func(kGlobals.MaximumValuesInCategories);
+              }
+
+              const ci = graph_data[kGlobals.network.GraphAttrbuteID][cat_id];
+
+              if (ci["reduced_value_range"]) {
+                if (!(arg in ci["reduced_value_range"])) {
+                  arg = kGlobals.network.ReducedValue;
+                }
+              }
+
+              return func(ci["stable-ish order"][arg]);
+            }
+          );
+          //console.log (graph_data[kGlobals.network.GraphAttrbuteID][cat_id]['stable-ish order']);
+        }
+      }
+
+      if (
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["user-defined"]
+      ) {
+        self.colorizer["category"] = _.wrap(
+          self.colorizer["category"],
+          (func, arg) => {
+            if (
+              arg in
+              graph_data[kGlobals.network.GraphAttrbuteID][cat_id][
+                "user-defined"
+              ]
+            ) {
+              return graph_data[kGlobals.network.GraphAttrbuteID][cat_id][
+                "user-defined"
+              ][arg];
+            }
+            return func(arg);
+          }
+        );
+      }
+
+      self.colorizer["category_id"] = cat_id;
+      self.colorizer["category_map"] =
+        graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["value_map"];
+
+      //console.log (cat_id, self.json[kGlobals.network.GraphAttrbuteID][cat_id], graph_data[kGlobals.network.GraphAttrbuteID][cat_id]["value_map"] (null, "lookup"));
+      //self.colorizer['category_map'][null] =  graph_data [kGlobals.network.GraphAttrbuteID][cat_id]['range'];
+
+      //try {
+      //console.log (self.colorizer["category_map"]);
+      self.colorizer["category_pairwise"] = attribute_pairwise_distribution(
+        cat_id,
+        self._aux_get_attribute_dimension(cat_id),
+        self.colorizer["category_map"]
+      );
+      //} catch (err) {
+      // TODO: there are still lingering issues with this "category_map"
+      //}
+
+      render_chord_diagram(
+        "aux_svg_holder",
+        self.colorizer["category_map"],
+        self.colorizer["category_pairwise"]
+      );
+      render_binned_table(
+        "attribute_table",
+        self.colorizer["category_map"],
+        self.colorizer["category_pairwise"]
+      );
+    } else {
+      self.colorizer["category"] = null;
+      self.colorizer["category_id"] = null;
+      self.colorizer["category_pairwise"] = null;
+      self.colorizer["category_map"] = null;
+      render_chord_diagram("aux_svg_holder", null, null);
+      render_binned_table("attribute_table", null, null);
+    }
+    if (self.handle_inline_charts) {
+      self.handle_inline_charts();
+    }
+
+    self.draw_attribute_labels();
+    self.update(true);
+    if (d3.event) {
+      d3.event.preventDefault();
+    }
+
+    // Draw color picker for manual override
+    self.renderColorPicker(cat_id, "categorical");
+  };
+
+  self.filter_visibility = function () {
+    self.clusters.forEach((c) => {
+      c.is_hidden = self.hide_unselected && !c.match_filter;
+    });
+    self.nodes.forEach((n) => {
+      n.is_hidden = self.hide_unselected && !n.match_filter;
+    });
+  };
+
+  self.filter = function (conditions, skip_update) {
+    var anything_changed = false;
+
+    conditions = _.map(["re", "distance", "date"], (cnd) =>
+      _.map(
+        _.filter(conditions, (v) => v.type === cnd),
+        (v) => (cnd === "distance" ? v : v.value)
+      )
+    );
+
+    if (conditions[1].length) {
+      self.nodes.forEach((n) => {
+        n.length_filter = false;
+      });
+
+      _.each(self.edges, (e) => {
+        var did_match = _.some(conditions[1], (d) =>
+          d.greater_than ? e.length >= d.value : e.length < d.value
+        );
+
+        if (did_match) {
+          self.nodes[e.source].length_filter = true;
+          self.nodes[e.target].length_filter = true;
+        }
+        e.length_filter = did_match;
+      });
+    } else {
+      self.nodes.forEach((n) => {
+        n.length_filter = false;
+      });
+      self.edges.forEach((e) => {
+        e.length_filter = false;
+      });
+    }
+
+    if (conditions[2].length) {
+      self.nodes.forEach((n) => {
+        var node_T = self.attribute_node_value_by_id(
+          n,
+          timeDateUtil.getClusterTimeScale()
+        );
+        n.date_filter = _.some(
+          conditions[2],
+          (d) => node_T >= d[0] && node_T <= d[1]
+        );
+      });
+    } else {
+      self.nodes.forEach((n) => {
+        n.date_filter = false;
+      });
+    }
+
+    self.clusters.forEach((c) => {
+      c.match_filter = 0;
+    });
+
+    self.edges.forEach((e) => {
+      if (e.length_filter) {
+        anything_changed = true;
+      }
+    });
+
+    self.nodes.forEach((n) => {
+      var did_match = _.some(
+        conditions[0],
+        (regexp) =>
+          regexp.test(n.id) ||
+          _.some(n[kGlobals.network.NodeAttributeID], (attr) =>
+            regexp.test(attr)
+          )
+      );
+
+      did_match = did_match || n.length_filter || n.date_filter;
+
+      if (did_match !== n.match_filter) {
+        n.match_filter = did_match;
+        anything_changed = true;
+      }
+
+      if (n.match_filter) {
+        n.parent.match_filter += 1;
+      }
+    });
+
+    if (anything_changed && self.handle_inline_charts) {
+      self.handle_inline_charts((n) => n.match_filter);
+    }
+
+    if (anything_changed && !skip_update) {
+      if (self.hide_unselected) {
+        self.filter_visibility();
+      }
+
+      self.update(true);
+    }
+  };
+
+  self.is_empty = function () {
+    return self.cluster_sizes.length === 0;
+  };
+
+  self.link_generator_function = function (d) {
+    var pull = d.pull || 0.0;
+    var path;
+
+    if (pull !== 0.0) {
+      var dist_x = d.target.x - d.source.x;
+      var dist_y = d.target.y - d.source.y;
+      pull *= Math.sqrt(dist_x * dist_x + dist_y * dist_y);
+
+      var theta = Math.PI / 6; // 18deg additive angle
+
+      var alpha = dist_x ? Math.atan(-dist_y / dist_x) : Math.PI / 2; // angle with the X axis
+
+      if (pull < 0) {
+        theta = -theta;
+        pull = -pull;
+      }
+
+      var dx = Math.cos(theta + alpha) * pull,
+        dx2 = Math.cos(theta - alpha) * pull;
+
+      var dy = Math.sin(theta + alpha) * pull,
+        dy2 = Math.sin(theta - alpha) * pull;
+
+      var s1, s2;
+      if (d.target.x >= d.source.x) {
+        s1 = [dx, -dy];
+        s2 = [-dx2, -dy2];
+      } else {
+        s1 = [-dx2, -dy2];
+        s2 = [dx, -dy];
+      }
+
+      path =
+        "M" +
+        d.source.x +
+        " " +
+        d.source.y +
+        " C " +
+        (d.source.x + s1[0]) +
+        " " +
+        (d.source.y + s1[1]) +
+        ", " +
+        (d.target.x + s2[0]) +
+        " " +
+        (d.target.y + s2[1]) +
+        ", " +
+        d.target.x +
+        " " +
+        d.target.y;
+    } else {
+      path =
+        "M" +
+        d.source.x +
+        " " +
+        d.source.y +
+        " L " +
+        d.target.x +
+        " " +
+        d.target.y;
+    }
+
+    d3.select(this).attr("d", path);
+  };
+
+  self.update = function (soft, friction) {
+    self.needs_an_update = false;
+
+    if (options && options["extra-graphics"]) {
+      options["extra-graphics"].call(null, self, options);
+    }
+
+    if (friction) {
+      network_layout.friction(friction);
+    }
+    self.display_warning(self.warning_string, true);
+
+    var rendered_nodes, rendered_clusters, link;
+
+    if (!soft) {
+      var draw_me = prepare_data_to_graph();
+
+      network_layout.nodes(draw_me.all).links(draw_me.edges);
+      update_network_string(draw_me.nodes.length, draw_me.edges.length);
+
+      var edge_set = {};
+
+      _.each(draw_me.edges, (d) => {
+        d.pull = 0.0;
+        var tag;
+
+        if (d.source < d.target) {
+          tag = String(d.source) + "|" + d.target;
+        } else {
+          tag = String(d.target) + "|" + d.source;
+        }
+        if (tag in edge_set) {
+          edge_set[tag].push(d);
+        } else {
+          edge_set[tag] = [d];
+        }
+      });
+
+      _.each(edge_set, (v) => {
+        if (v.length > 1) {
+          var step = 1 / (v.length - 1);
+          _.each(v, (edge, index) => {
+            edge.pull = -0.5 + index * step;
+          });
+        }
+      });
+
+      link = self.network_svg
+        .selectAll(".link")
+        .data(draw_me.edges, (d) => d.id);
+
+      //link.enter().append("line").classed("link", true);
+      link.enter().append("path").classed("link", true);
+      link.exit().remove();
+
+      link
+        .classed("removed", (d) => self.highlight_unsuppored_edges && d.removed)
+        .classed(
+          "unsupported",
+          (d) =>
+            self.highlight_unsuppored_edges &&
+            "support" in d &&
+            d["support"] > 0.05
+        )
+        .classed(
+          "core-link",
+          (d) =>
+            //console.log (d["length"] <= self.core_link_length);
+            d["length"] <= self.core_link_length
+          //return false;
+        );
+
+      link
+        .on("mouseover", edge_pop_on)
+        .on("mouseout", edge_pop_off)
+        .filter((d) => d.directed)
+        .attr("marker-end", "url(#" + self.dom_prefix + "_arrowhead)");
+
+      rendered_nodes = self.network_svg
+        .selectAll(".node")
+        .data(draw_me.nodes, (d) => d.id);
+
+      rendered_nodes.exit().remove();
+
+      /*rendered_nodes.enter().each (function (d) {
+        this.append ("path");
+      });*/
+
+      rendered_nodes.enter().append("g").append("path");
+
+      rendered_clusters = self.network_svg.selectAll(".cluster-group").data(
+        draw_me.clusters.map((d) => d),
+        (d) => d.cluster_id
+      );
+
+      rendered_clusters.exit().remove();
+      rendered_clusters
+        .enter()
+        .append("g")
+        .attr("class", "cluster-group")
+        .attr("transform", (d) => "translate(" + d.x + "," + d.y + ")")
+        .on("click", (d) => network.handle_cluster_click(self, d))
+        .on("mouseover", cluster_pop_on)
+        .on("mouseout", cluster_pop_off)
+        .call(network_layout.drag().on("dragstart", cluster_pop_off));
+
+      self.draw_cluster_table(
+        self.extra_cluster_table_columns,
+        self.cluster_table
+      );
+
+      if (
+        self._is_CDC_ &&
+        !(
+          options &&
+          options["no-subclusters"] &&
+          options["no-subcluster-compute"]
+        )
+      ) {
+        // compute priority clusters
+        self.annotate_priority_clusters(
+          timeDateUtil._networkCDCDateField,
+          36,
+          12
+        );
+
+        try {
+          if (self.isPrimaryGraph) {
+            self.priority_groups_compute_node_membership();
+          }
+        } catch (err) {
+          console.log(err);
+        }
+      }
+
+      if (
+        self._is_CDC_ &&
+        !(options && options["no-subclusters"]) &&
+        options &&
+        options["no-subcluster-compute"]
+      ) {
+        // use precomputed subclusters
+
+        _.each(self.clusters, (cluster_nodes, cluster_index) => {
+          /** extract subclusters; all nodes at given threshold */
+          /** Sub-Cluster: all nodes connected at 0.005 subs/site; there can be multiple sub-clusters per cluster */
+          let subclusters = _.groupBy(
+            cluster_nodes.children,
+            (n) => n.subcluster_id
+          );
+          subclusters = _.values(
+            _.reject(subclusters, (v, k) => k === "undefined")
+          );
+
+          /** sort subclusters by oldest node */
+          _.each(subclusters, (c, i) => {
+            c.sort(oldest_nodes_first);
+          });
+
+          subclusters.sort((c1, c2) => oldest_nodes_first(c1[0], c2[0]));
+
+          subclusters = _.map(subclusters, (c, i) => {
+            const parent_cluster_id = c[0].parent_cluster_id;
+            const subcluster_id = c[0].subcluster_id;
+            const label = c[0].subcluster_label;
+
+            var edges = [];
+
+            // unused var
+            // var meta_data = _.filter(
+            //   hivtrace_cluster_depthwise_traversal(
+            //     cluster_nodes.Nodes,
+            //     cluster_nodes.Edges,
+            //     null,
+            //     edges
+            //   ),
+            //   (cc) => {
+            //     return cc.length > 1;
+            //   }
+            // );
+
+            edges = _.filter(edges, (es) => es.length > 1);
+
+            var stats =
+              self.json.subcluster_summary_stats[parent_cluster_id][
+                subcluster_id
+              ];
+
+            return {
+              children: _.clone(c),
+              parent_cluster: cluster_nodes,
+              cluster_id: label,
+              subcluster_label: subcluster_id,
+              recent_nodes: stats.recent_nodes,
+              priority_score: stats.priority_score,
+              distances: helpers.describe_vector(
+                _.map(edges[i], (e) => e.length)
+              ),
+            };
+          });
+
+          _.each(subclusters, (c) => {
+            _compute_cluster_degrees(c);
+          });
+
+          cluster_nodes.subclusters = subclusters || [];
+
+          // add additional information
+          const stats =
+            self.json.subcluster_summary_stats[cluster_nodes.cluster_id];
+          cluster_nodes.recent_nodes = _.map(
+            _.values(stats),
+            (d) => d.recent_nodes[0] || 0
+          );
+          cluster_nodes.priority_score = _.map(
+            _.values(stats),
+            (d) => d.priority_score[0] || 0
+          );
+        });
+      }
+
+      if (self.subcluster_table) {
+        /*
+            SLKP 20200727 scan subclusters and identify which, if any
+            will need to be automatically created as priority sets
+        */
+
+        // draw subcluster tables
+
+        self.draw_cluster_table(
+          self.extra_subcluster_table_columns,
+          self.subcluster_table,
+          {
+            "no-clusters": true,
+            subclusters: true,
+            headers: function (headers) {
+              headers[0][0].value = "Subcluster ID";
+              headers[0][0].help = "Unique subcluster ID";
+              headers[0][2].help = "Number of total cases in the subcluster";
+            },
+          }
+        );
+      }
+      if (self._is_CDC_) {
+        self.draw_extended_node_table();
+      } else {
+        self.draw_node_table(self.extra_node_table_columns);
+      }
+    } else {
+      rendered_nodes = self.network_svg.selectAll(".node");
+      rendered_clusters = self.network_svg.selectAll(".cluster-group");
+      link = self.network_svg.selectAll(".link");
+      update_network_string(rendered_nodes.size(), link.size());
+    }
+
+    rendered_nodes.each(function (d) {
+      draw_a_node(this, d);
+    });
+
+    rendered_clusters.each(function (d) {
+      draw_a_cluster(this, d);
+    });
+
+    link.style("opacity", (d) =>
+      Math.max(node_opacity(d.target), node_opacity(d.source))
+    );
+
+    if (self.additional_edge_styler) {
+      link.each(function (d) {
+        self.additional_edge_styler(this, d, self);
+      });
+    }
+
+    link
+      .style("display", (d) => {
+        if (d.target.is_hidden || d.source.is_hidden || d.is_hidden) {
+          return "none";
+        }
+        return null;
+      })
+      .classed(
+        "selected_object",
+        (d) => d.ref.length_filter && !self.hide_unselected
+      );
+
+    if (!soft) {
+      currently_displayed_objects =
+        rendered_clusters[0].length + rendered_nodes[0].length;
+
+      network_layout.on("tick", () => {
+        var sizes = network_layout.size();
+
+        rendered_nodes.attr("transform", (d) => {
+          // Defalut values (just to keep nodes in the svg container rectangle).
+          var xBoundLower = 10;
+          var xBoundUpper = sizes[0] - 10;
+          var yBoundLower = 10;
+          var yBoundUpper = sizes[1] - 10;
+
+          if (self.showing_on_map) {
+            const allowed_offset_from_center_of_country = 15;
+            // If the country is in the list that we have, override the default values for the bounds.
+            var country_code = self._get_node_country(d);
+
+            if (country_code in self.countryCentersObject) {
+              const center = self.countryCentersObject[country_code].countryXY;
+
+              xBoundLower = center[0] - allowed_offset_from_center_of_country;
+              xBoundUpper = center[0] + allowed_offset_from_center_of_country;
+              yBoundLower = center[1] - allowed_offset_from_center_of_country;
+              yBoundUpper = center[1] + allowed_offset_from_center_of_country;
+            }
+          }
+
+          return (
+            "translate(" +
+            (d.x = Math.max(xBoundLower, Math.min(xBoundUpper, d.x))) +
+            "," +
+            (d.y = Math.max(yBoundLower, Math.min(yBoundUpper, d.y))) +
+            ")"
+          );
+        });
+        rendered_clusters.attr(
+          "transform",
+          (d) =>
+            "translate(" +
+            (d.x = Math.max(
+              d.rendered_size,
+              Math.min(sizes[0] - d.rendered_size, d.x)
+            )) +
+            "," +
+            (d.y = Math.max(
+              d.rendered_size,
+              Math.min(sizes[1] - d.rendered_size, d.y)
+            )) +
+            ")"
+        );
+
+        link.each(self.link_generator_function);
+      });
+
+      network_layout.start();
+    } else {
+      link.each(self.link_generator_function);
+    }
+  };
+
+  function tick() {
+    var sizes = network_layout.size();
+
+    node
+      .attr("cx", (d) => (d.x = Math.max(10, Math.min(sizes[0] - 10, d.x))))
+      .attr("cy", (d) => (d.y = Math.max(10, Math.min(sizes[1] - 10, d.y))));
+
+    link
+      .attr("x1", (d) => d.source.x)
+      .attr("y1", (d) => d.source.y)
+      .attr("x2", (d) => d.target.x)
+      .attr("y2", (d) => d.target.y);
+  }
+
+  /*------------ Node Methods ---------------*/
+  function compute_node_degrees(nodes, edges) {
+    for (var n in nodes) {
+      nodes[n].degree = 0;
+    }
+
+    for (var e in edges) {
+      nodes[edges[e].source].degree++;
+      nodes[edges[e].target].degree++;
+    }
+  }
+
+  self.attribute_node_value_by_id = function (d, id, number) {
+    try {
+      if (kGlobals.network.NodeAttributeID in d && id) {
+        if (id in d[kGlobals.network.NodeAttributeID]) {
+          let v;
+
+          if (self.json[kGlobals.network.GraphAttrbuteID][id].volatile) {
+            v = self.json[kGlobals.network.GraphAttrbuteID][id].map(d, self);
+          } else {
+            v = d[kGlobals.network.NodeAttributeID][id];
+          }
+
+          if (_.isString(v)) {
+            if (v.length === 0) {
+              return kGlobals.missing.label;
+            } else if (number) {
+              v = Number(v);
+              return _.isNaN(v) ? kGlobals.missing.label : v;
+            }
+          }
+          return v;
+        }
+      }
+    } catch (e) {
+      console.log("self.attribute_node_value_by_id", e, d, id, number);
+    }
+    return kGlobals.missing.label;
+  };
+
+  self.has_network_attribute = function (key) {
+    if (kGlobals.network.GraphAttrbuteID in self.json) {
+      return key in self.json[kGlobals.network.GraphAttrbuteID];
+    }
+    return false;
+  };
+
+  function node_size(d) {
+    if (self.showing_on_map) {
+      return 50;
+    }
+    var r = 5 + Math.sqrt(d.degree); //return (d.match_filter ? 10 : 4)*r*r;
+    return 4 * r * r;
+  }
+
+  function node_color(d) {
+    /*if (d.match_filter) {
+        return "white";
+    }*/
+
+    if (self.colorizer["category_id"]) {
+      var v = self.attribute_node_value_by_id(d, self.colorizer["category_id"]);
+      if (self.colorizer["continuous"]) {
+        if (v === kGlobals.missing.label) {
+          return kGlobals.missing.color;
+        }
+        //console.log (v, self.colorizer['category'](v));
+      }
+      return self.colorizer["category"](v);
+    }
+
+    if (d.hxb2_linked) {
+      return "black";
+    }
+
+    if (d.is_lanl) {
+      return "red";
+    }
+
+    return "gray";
+  }
+
+  function node_opacity(d) {
+    if (self.colorizer["opacity"]) {
+      return self.colorizer["opacity"](
+        self.attribute_node_value_by_id(d, self.colorizer["opacity_id"], true)
+      );
+    }
+    return 1;
+  }
+
+  function cluster_color(d, type) {
+    if (d["binned_attributes"]) {
+      return self.colorizer["category"](type);
+    }
+    return "#bdbdbd";
+  }
+
+  function node_info_string(n) {
+    var str;
+
+    if (!self._is_CDC_) {
+      str =
+        "Degree <em>" +
+        n.degree +
+        "</em><br>Clustering coefficient <em> " +
+        misc.format_value(n.lcc, kGlobals.formats.FloatFormat) +
+        "</em>";
+    } else {
+      str = "# links <em>" + n.degree + "</em>";
+    }
+
+    _.each(
+      _.union(self._additional_node_pop_fields, [
+        self.colorizer["category_id"],
+        self.node_shaper["id"],
+        self.colorizer["opacity_id"],
+      ]),
+      (key) => {
+        if (key) {
+          if (key in graph_data[kGlobals.network.GraphAttrbuteID]) {
+            var attribute = self.attribute_node_value_by_id(n, key);
+
+            if (
+              graph_data[kGlobals.network.GraphAttrbuteID][key]["type"] ===
+              "Date"
+            ) {
+              try {
+                attribute = timeDateUtil.DateViewFormat(attribute);
+              } catch (err) {
+                // do nothing
+              }
+            }
+            if (attribute) {
+              str +=
+                "<br>" +
+                graph_data[kGlobals.network.GraphAttrbuteID][key].label +
+                " <em>" +
+                attribute +
+                "</em>";
+            }
+          }
+        }
+      }
+    );
+
+    return str;
+  }
+
+  function edge_info_string(n) {
+    var str = "Length <em>" + kGlobals.formats.FloatFormat(n.length) + "</em>";
+    if ("support" in n) {
+      str +=
+        "<br>Worst triangle-based support (p): <em>" +
+        kGlobals.formats.FloatFormat(n.support) +
+        "</em>";
+    }
+
+    return str;
+  }
+
+  function node_pop_on(d) {
+    if (d3.event.defaultPrevented) return;
+
+    toggle_tooltip(
+      this,
+      true,
+      (self._is_CDC_ ? "Individual " : "Node ") + d.id,
+      node_info_string(d),
+      self.container
+    );
+  }
+
+  function node_pop_off(d) {
+    if (d3.event.defaultPrevented) return;
+
+    toggle_tooltip(this, false);
+  }
+
+  function edge_pop_on(e) {
+    toggle_tooltip(
+      this,
+      true,
+      e.source.id + " - " + e.target.id,
+      edge_info_string(e),
+      self.container
+    );
+  }
+
+  function edge_pop_off(d) {
+    toggle_tooltip(this, false);
+  }
+
+  /*------------ Cluster Methods ---------------*/
+
+  /* Creates a new object that groups nodes by cluster
+   * @param nodes
+   * @returns clusters
+   */
+  function get_all_clusters(nodes) {
+    var by_cluster = _.groupBy(nodes, "cluster");
+    return by_cluster;
+  }
+
+  function compute_cluster_centroids(clusters) {
+    for (var c in clusters) {
+      var cls = clusters[c];
+      cls.x = 0;
+      cls.y = 0;
+      if (_.has(cls, "children")) {
+        cls.children.forEach((x) => {
+          cls.x += x.x;
+          cls.y += x.y;
+        });
+        cls.x /= cls.children.length;
+        cls.y /= cls.children.length;
+      }
+    }
+  }
+
+  function collapse_cluster(x, keep_in_q) {
+    self.needs_an_update = true;
+    x.collapsed = true;
+    currently_displayed_objects -= self.cluster_sizes[x.cluster_id - 1] - 1;
+    if (!keep_in_q) {
+      var idx = open_cluster_queue.indexOf(x.cluster_id);
+      if (idx >= 0) {
+        open_cluster_queue.splice(idx, 1);
+      }
+    }
+    compute_cluster_centroids([x]);
+    return x.children.length;
+  }
+
+  function expand_cluster(x, copy_coord) {
+    self.needs_an_update = true;
+    x.collapsed = false;
+    currently_displayed_objects += self.cluster_sizes[x.cluster_id - 1] - 1;
+    open_cluster_queue.push(x.cluster_id);
+
+    if (copy_coord) {
+      x.children.forEach((n) => {
+        n.x = x.x + (Math.random() - 0.5) * x.children.length;
+        n.y = x.y + (Math.random() - 0.5) * x.children.length;
+      });
+    } else {
+      x.children.forEach((n) => {
+        n.x = self.width * 0.25 + (Math.random() - 0.5) * x.children.length;
+        n.y = 0.25 * self.height + (Math.random() - 0.5) * x.children.length;
+      });
+    }
+  }
+
+  function render_binned_table(id, the_map, matrix) {
+    var the_table = d3.select(self.get_ui_element_selector_by_role(id, true));
+    if (the_table.empty()) {
+      return;
+    }
+
+    the_table.selectAll("thead").remove();
+    the_table.selectAll("tbody").remove();
+
+    d3.select(
+      self.get_ui_element_selector_by_role(id + "_enclosed", true)
+    ).style("display", matrix ? null : "none");
+
+    if (matrix) {
+      var fill = self.colorizer["category"];
+      var lookup = the_map(null, "lookup");
+
+      var headers = the_table
+        .append("thead")
+        .append("tr")
+        .selectAll("th")
+        .data([""].concat(matrix[0].map((d, i) => lookup[i])));
+
+      headers.enter().append("th");
+      headers
+        .html((d) => "<span>&nbsp;" + d + "</span>")
+        .each(function (d, i) {
+          if (i) {
+            d3.select(this)
+              .insert("i", ":first-child")
+              .classed("fa fa-circle", true)
+              .style("color", () => fill(d));
+          }
+        });
+
+      if (self.show_percent_in_pairwise_table) {
+        var sum = _.map(matrix, (row) => _.reduce(row, (p, c) => p + c, 0));
+
+        matrix = _.map(matrix, (row, row_index) =>
+          _.map(row, (c) => c / sum[row_index])
+        );
+      }
+
+      var rows = the_table
+        .append("tbody")
+        .selectAll("tr")
+        .data(matrix.map((d, i) => [lookup[i]].concat(d)));
+
+      rows.enter().append("tr");
+      rows
+        .selectAll("td")
+        .data((d) => d)
+        .enter()
+        .append("td")
+        .html((d, i) => {
+          if (i === 0) {
+            return "<span>&nbsp;" + d + "</span>";
+          } else if (self.show_percent_in_pairwise_table) {
+            return kGlobals.formats.PercentFormat(d);
+          }
+
+          return d;
+        })
+        .each(function (d, i) {
+          if (i === 0) {
+            d3.select(this)
+              .insert("i", ":first-child")
+              .classed("fa fa-circle", true)
+              .style("color", () => fill(d));
+          }
+        });
+    }
+  }
+
+  function render_chord_diagram(id, the_map, matrix) {
+    var container = d3.select(self.get_ui_element_selector_by_role(id, true));
+
+    if (container.empty()) {
+      return;
+    }
+
+    container.selectAll("svg").remove();
+
+    d3.select(
+      self.get_ui_element_selector_by_role(id + "_enclosed", true)
+    ).style("display", matrix ? null : "none");
+
+    if (matrix) {
+      var lookup = the_map(null, "lookup");
+
+      var svg = container.append("svg");
+
+      var chord = d3.layout
+        .chord()
+        .padding(0.05)
+        .sortSubgroups(d3.descending)
+        .matrix(matrix);
+
+      var text_offset = 20,
+        width = 450,
+        height = 450,
+        innerRadius = Math.min(width, height - text_offset) * 0.41,
+        outerRadius = innerRadius * 1.1;
+
+      var fill = self.colorizer["category"],
+        font_size = 12;
+
+      var text_label = svg
+        .append("g")
+        .attr(
+          "transform",
+          "translate(" + width / 2 + "," + (height - text_offset) + ")"
+        )
+        .append("text")
+        .attr("text-anchor", "middle")
+        .attr("font-size", font_size)
+        .text("");
+
+      svg = svg
+        .attr("width", width)
+        .attr("height", height - text_offset)
+        .append("g")
+        .attr(
+          "transform",
+          "translate(" + width / 2 + "," + (height - text_offset) / 2 + ")"
+        );
+
+      // Returns an event handler for fading a given chord group.
+      const fade = function (opacity, t) {
+        return function (g, i) {
+          text_label.text(t ? lookup[i] : "");
+          svg
+            .selectAll(".chord path")
+            .filter((d) => d.source.index !== i && d.target.index !== i)
+            .transition()
+            .style("opacity", opacity);
+        };
+      };
+
+      svg
+        .append("g")
+        .selectAll("path")
+        .data(chord.groups)
+        .enter()
+        .append("path")
+        .style("fill", (d) => fill(lookup[d.index]))
+        .style("stroke", (d) => fill(lookup[d.index]))
+        .attr(
+          "d",
+          d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius)
+        )
+        .on("mouseover", fade(0.1, true))
+        .on("mouseout", fade(1, false));
+
+      svg
+        .append("g")
+        .attr("class", "chord")
+        .selectAll("path")
+        .data(chord.chords)
+        .enter()
+        .append("path")
+        .attr("d", d3.svg.chord().radius(innerRadius))
+        .style("fill", (d) => fill(d.target.index))
+        .style("opacity", 1);
+    }
+  }
+
+  function attribute_pairwise_distribution(id, dim, the_map, only_expanded) {
+    var scan_from = only_expanded ? draw_me.edges : self.edges;
+    var the_matrix = [];
+    for (var i = 0; i < dim; i += 1) {
+      the_matrix.push([]);
+      for (var j = 0; j < dim; j += 1) {
+        the_matrix[i].push(0);
+      }
+    }
+
+    _.each(scan_from, (edge) => {
+      //console.log (self.attribute_node_value_by_id(self.nodes[edge.source], id), self.attribute_node_value_by_id(self.nodes[edge.target], id));
+      the_matrix[
+        the_map(self.attribute_node_value_by_id(self.nodes[edge.source], id))
+      ][
+        the_map(self.attribute_node_value_by_id(self.nodes[edge.target], id))
+      ] += 1;
+    });
+    // check if there are null values
+
+    var haz_null = the_matrix.some((d, i) => {
+      if (i === dim - 1) {
+        return d.some((d2) => d2 > 0);
+      }
+      return d[dim - 1] > 0;
+    });
+    if (!haz_null) {
+      the_matrix.pop();
+      for (let i = 0; i < dim - 1; i += 1) {
+        the_matrix[i].pop();
+      }
+    }
+
+    // symmetrize the matrix
+
+    dim = the_matrix.length;
+
+    for (let i = 0; i < dim; i += 1) {
+      for (let j = i; j < dim; j += 1) {
+        the_matrix[i][j] += the_matrix[j][i];
+        the_matrix[j][i] = the_matrix[i][j];
+      }
+    }
+
+    return the_matrix;
+  }
+
+  self._aux_populate_category_fields = function (d, k) {
+    d["raw_attribute_key"] = k;
+    if (!("label" in d)) {
+      d["label"] = k;
+    }
+    d.discrete = false;
+
+    if ("enum" in d) {
+      d.discrete = true;
+      d["value_range"] = new Set(d["enum"]);
+      d["value_range"].add(kGlobals.missing.label);
+
+      if (
+        _.every(graph_data.Nodes, (nd) =>
+          d["value_range"].has(self.attribute_node_value_by_id(nd, k))
+        )
+      ) {
+        d["value_range"] = _.clone(d["enum"]);
+        if (!(kGlobals.missing.label in d["value_range"])) {
+          d["value_range"].push(kGlobals.missing.label);
+        }
+        d["dimension"] = d["value_range"].length;
+        d["no-sort"] = true;
+        return d;
+      }
+
+      // confirm that the values in the range are actually in the enum
+    }
+
+    if (d["type"] === "String") {
+      d.discrete = true;
+      d["value_range"] = _.keys(
+        _.countBy(graph_data.Nodes, (nd) =>
+          self.attribute_node_value_by_id(nd, k)
+        )
+      );
+      d["dimension"] = d["value_range"].length;
+    }
+    return d;
+  };
+
+  self._aux_get_attribute_dimension = function (cat_id) {
+    if (cat_id in graph_data[kGlobals.network.GraphAttrbuteID]) {
+      const cinfo = graph_data[kGlobals.network.GraphAttrbuteID][cat_id];
+      if ("reduced_value_range" in cinfo) {
+        return _.size(cinfo["reduced_value_range"]);
+      }
+      return cinfo.dimension;
+    }
+    return 0;
+  };
+
+  self._aux_process_category_values = function (d) {
+    var values,
+      reduced_range = null;
+
+    delete d["reduced_value_range"];
+    if (d["no-sort"]) {
+      values = d["value_range"];
+    } else if (d["type"] === "String") {
+      values = d["value_range"].sort();
+
+      if (d.dimension > kGlobals.MaximumValuesInCategories) {
+        const compressed_values = _.chain(self.nodes)
+          .countBy((node) =>
+            self.attribute_node_value_by_id(node, d["raw_attribute_key"])
+          )
+          .pairs()
+          .sortBy((d) => -d[1])
+          .value();
+
+        reduced_range = [];
+        let i = 0;
+        while (
+          reduced_range.length < kGlobals.MaximumValuesInCategories - 1 &&
+          i < compressed_values.length
+        ) {
+          if (compressed_values[i][0] !== kGlobals.missing.label) {
+            reduced_range.push(compressed_values[i][0]);
+          }
+          i++;
+        }
+        reduced_range = reduced_range.sort();
+        reduced_range.push(kGlobals.network.ReducedValue);
+      }
+
+      var string_hash = function (str) {
+        var hash = 5801;
+        for (var ci = 0; ci < str.length; ci++) {
+          var charCode = str.charCodeAt(ci);
+          hash = (hash << (5 + hash)) + charCode;
+        }
+        return hash;
+      };
+
+      const use_these_values = reduced_range || values;
+
+      var hashed = _.map(use_these_values, string_hash);
+      var available_keys = {};
+      var reindexed = {};
+
+      for (var i = 0; i < kGlobals.MaximumValuesInCategories; i++) {
+        available_keys[i] = true;
+      }
+
+      _.each(hashed, (value, index) => {
+        if (value < 0) {
+          value = -value;
+        }
+
+        var first_try = value % kGlobals.MaximumValuesInCategories;
+        if (first_try in available_keys) {
+          reindexed[use_these_values[index]] = first_try;
+          delete available_keys[first_try];
+          return;
+        }
+
+        var second_try =
+          Math.floor(value / kGlobals.MaximumValuesInCategories) %
+          kGlobals.MaximumValuesInCategories;
+        if (second_try in available_keys) {
+          reindexed[use_these_values[index]] = second_try;
+          delete available_keys[second_try];
+          return;
+        }
+
+        var last_resort = parseInt(_.keys(available_keys).sort()[0]);
+        reindexed[use_these_values[index]] = last_resort;
+        delete available_keys[last_resort];
+      });
+
+      d["stable-ish order"] = reindexed;
+    }
+
+    var map = {};
+
+    if (reduced_range) {
+      const rrl = _.object(_.map(_.pairs(reduced_range), (d) => [d[1], d[0]]));
+
+      _.each(values, (d2, i) => {
+        if (d2 in rrl) {
+          map[d2] = rrl[d2];
+        } else {
+          map[d2] = rrl[kGlobals.network.ReducedValue];
+        }
+      });
+
+      d["reduced_value_range"] = rrl;
+      //console.log (rrl, map);
+      d["value_map"] = function (v, key) {
+        if (key) {
+          //console.log (key, map);
+          return key === "lookup" ? _.invert(rrl) : rrl;
+        }
+        return map[v];
+      };
+    } else {
+      _.each(values, (d2, i) => {
+        map[d2] = i;
+      });
+
+      d["value_map"] = function (v, key) {
+        if (key) {
+          //console.log (key, map);
+          return key === "lookup" ? _.invert(map) : map;
+        }
+        return map[v];
+      };
+    }
+
+    return d;
+  };
+
+  function attribute_cluster_distribution(the_cluster, attribute_id) {
+    if (attribute_id && the_cluster) {
+      return the_cluster.children.map((d) =>
+        self.attribute_node_value_by_id(d, attribute_id)
+      );
+    }
+    return null;
+  }
+
+  function cluster_info_string(id) {
+    var the_cluster = self.clusters[self.cluster_mapping[id]],
+      attr_info = the_cluster["binned_attributes"];
+
+    var str;
+
+    if (self._is_CDC_) {
+      str =
+        "<strong>" +
+        self.cluster_sizes[id - 1] +
+        "</strong> individuals." +
+        "<br>Mean links/individual <em> = " +
+        kGlobals.formats.FloatFormat(the_cluster.degrees["mean"]) +
+        "</em>" +
+        "<br>Max links/individual <em> = " +
+        the_cluster.degrees["max"] +
+        "</em>";
+    } else {
+      str =
+        "<strong>" +
+        self.cluster_sizes[id - 1] +
+        "</strong> nodes." +
+        "<br>Mean degree <em>" +
+        kGlobals.formats.FloatFormat(the_cluster.degrees["mean"]) +
+        "</em>" +
+        "<br>Max degree <em>" +
+        the_cluster.degrees["max"] +
+        "</em>" +
+        "<br>Clustering coefficient <em> " +
+        misc.format_value(the_cluster.cc, kGlobals.formats.FloatFormat) +
+        "</em>";
+    }
+
+    if (attr_info) {
+      attr_info.forEach((d) => {
+        str += "<br>" + d[0] + " <em>" + d[1] + "</em>";
+      });
+    }
+
+    return str;
+  }
+
+  function cluster_pop_on(d) {
+    toggle_tooltip(
+      this,
+      true,
+      "Cluster " + d.cluster_id,
+      cluster_info_string(d.cluster_id),
+      self.container
+    );
+  }
+
+  function cluster_pop_off(d) {
+    toggle_tooltip(this, false);
+  }
+
+  self.expand_cluster_handler = function (d, do_update, move_out) {
+    if (d.collapsed) {
+      var new_nodes = self.cluster_sizes[d.cluster_id - 1] - 1;
+
+      if (new_nodes > max_points_to_render) {
+        self.warning_string = "This cluster is too large to be displayed";
+      } else {
+        var leftover =
+          new_nodes + currently_displayed_objects - max_points_to_render;
+        if (leftover > 0) {
+          var k = 0;
+          for (; k < open_cluster_queue.length && leftover > 0; k++) {
+            var cluster =
+              self.clusters[self.cluster_mapping[open_cluster_queue[k]]];
+            leftover -= cluster.children.length - 1;
+            collapse_cluster(cluster, true);
+          }
+          if (k || open_cluster_queue.length) {
+            open_cluster_queue.splice(0, k);
+          }
+        }
+
+        if (leftover <= 0) {
+          expand_cluster(d, !move_out);
+        }
+      }
+
+      if (do_update) {
+        self.update(false, 0.6);
+      }
+    }
+    return "";
+  };
+
+  function show_sequences_in_cluster(d) {
+    var sequences = {};
+    _.each(
+      self.extract_single_cluster(
+        self.clusters[self.cluster_mapping[d.cluster]].children,
+        null,
+        true
+      ).Edges,
+      (e) => {
+        _.each(e.sequences, (s) => {
+          if (!(s in sequences)) {
+            sequences[s] = 1;
+          }
+        });
+      }
+    );
+    //console.log (_.keys(sequences));
+  }
+
+  function _compute_cluster_degrees(d) {
+    var degrees = d.children.map((c) => c.degree);
+    degrees.sort(d3.ascending);
+    d.degrees = helpers.describe_vector(degrees);
+  }
+
+  function handle_node_label(container, node) {
+    node.show_label = !node.show_label;
+    self.update(true);
+  }
+
+  function collapse_cluster_handler(d, do_update) {
+    collapse_cluster(self.clusters[self.cluster_mapping[d.cluster]]);
+    if (do_update) {
+      self.update(false, 0.4);
+    }
+  }
+
+  function cluster_box_size(c) {
+    return 8 * Math.sqrt(c.children.length);
+  }
+
+  self.extract_network_time_series = function (
+    time_attr,
+    other_attributes,
+    node_filter
+  ) {
+    var use_these_nodes = node_filter
+      ? _.filter(self.nodes, node_filter)
+      : self.nodes;
+
+    var result = _.map(use_these_nodes, (node) => {
+      var series = {
+        time: self.attribute_node_value_by_id(node, time_attr),
+      };
+      if (other_attributes) {
+        _.each(other_attributes, (attr, key) => {
+          series[attr] = self.attribute_node_value_by_id(node, key);
+        });
+      }
+      return series;
+    });
+
+    result.sort((a, b) => {
+      if (a.time < b.time) return -1;
+      if (a.time === b.time) return 0;
+      return 1;
+    });
+
+    return result;
+  };
+
+  self.expand_some_clusters = function (subset) {
+    subset = subset || self.clusters;
+    subset.forEach((x) => {
+      if (!x.is_hidden) {
+        self.expand_cluster_handler(x, false);
+      }
+    });
+    self.update();
+  };
+
+  self.select_some_clusters = function (condition) {
+    return self.clusters.filter((c, i) =>
+      _.some(c.children, (n) => condition(n))
+    );
+  };
+
+  self.collapse_some_clusters = function (subset) {
+    subset = subset || self.clusters;
+    subset.forEach((x) => {
+      if (!x.collapsed) collapse_cluster(x);
+    });
+    self.update();
+  };
+
+  self.toggle_hxb2 = function () {
+    self.hide_hxb2 = !self.hide_hxb2;
+    self.update();
+  };
+
+  self.toggle_diff = function () {
+    self.showing_diff = !self.showing_diff;
+    if (self.showing_diff) {
+      self.cluster_filtering_functions["new"] = self.filter_if_added;
+    } else {
+      delete self.cluster_filtering_functions["new"];
+    }
+    self.update();
+  };
+
+  self.toggle_highlight_unsupported_edges = function () {
+    self.highlight_unsuppored_edges = !self.highlight_unsuppored_edges;
+    self.update();
+  };
+
+  self.toggle_time_filter = function () {
+    if (self.using_time_filter) {
+      self.using_time_filter = null;
+    } else {
+      self.using_time_filter = timeDateUtil.getCurrentDate();
+      self.using_time_filter.setFullYear(
+        self.using_time_filter.getFullYear() - 1
+      );
+    }
+
+    if (self.using_time_filter) {
+      self.cluster_filtering_functions["recent"] = self.filter_time_period;
+    } else {
+      delete self.cluster_filtering_functions["recent"];
+    }
+    self.update();
+  };
+
+  function stratify(array) {
+    if (array) {
+      var dict = {},
+        stratified = [];
+
+      array.forEach((d) => {
+        if (d in dict) {
+          dict[d] += 1;
+        } else {
+          dict[d] = 1;
+        }
+      });
+      for (var uv in dict) {
+        stratified.push([uv, dict[uv]]);
+      }
+      return stratified.sort((a, b) => a[0] - b[0]);
+    }
+    return array;
+  }
+
+  self._distance_gate_options = function (threshold) {
+    threshold = threshold || 0.005;
+
+    return {
+      "edge-styler": function (element, d, network) {
+        var e_type = misc.edge_typer(
+          d,
+          network.edge_types,
+          network.edge_cluster_threshold
+        );
+        if (e_type !== "") {
+          d3.select(element).style(
+            "stroke",
+            network._edge_colorizer(
+              misc.edge_typer(
+                d,
+                network.edge_types,
+                network.edge_cluster_threshold
+              )
+            )
+          ); //.style ("stroke-dasharray", network._edge_dasher (d["edge_type"]));
+        }
+        d.is_hidden = !network.shown_types[e_type];
+        d3.select(element).style("stroke-width", "4px");
+      },
+
+      init_code: function (network) {
+        function style_edge(type) {
+          this.style("stroke-width", "5px");
+          if (type.length) {
+            this.style("stroke", network._edge_colorizer(type)); //.style ("stroke-dasharray", network._edge_dasher (type));
+          } else {
+            this.classed("link", true);
+            var def_color = this.style("stroke");
+            this.classed("link", null);
+            this.style("stroke", def_color);
+          }
+        }
+
+        network.update_cluster_threshold_display = (T) => {
+          network.edge_cluster_threshold = T;
+          network.edge_types = [
+            "≤" + network.edge_cluster_threshold,
+            ">" + network.edge_cluster_threshold,
+          ];
+
+          network._edge_colorizer = d3.scale
+            .ordinal()
+            .range(kGlobals.EdgeColorBase)
+            .domain(network.edge_types);
+          //network._edge_dasher   = _edge_dasher;
+          network.shown_types = _.object(
+            _.map(network.edge_types, (d) => [d, 1])
+          );
+          network.edge_legend = {
+            caption: "Links by distance",
+            types: {},
+          };
+
+          _.each(network.shown_types, (ignore, t) => {
+            if (t.length) {
+              network.edge_legend.types[t] = _.partial(style_edge, t);
+            }
+          });
+        };
+
+        network.update_cluster_threshold_display(threshold);
+      },
+
+      extra_menu: {
+        title: "Additional options",
+        items: [
+          [
+            function (network, item) {
+              //console.log(network.edge_cluster_threshold);
+              var enclosure = item.append("div").classed("form-group", true);
+              enclosure
+                .append("label")
+                .text("Genetic distance threshold ")
+                .classed("control-label", true);
+              enclosure
+                .append("input")
+                .classed("form-control", true)
+                .attr("value", String(network.edge_cluster_threshold))
+                .on("change", function (e) {
+                  //d3.event.preventDefault();
+                  if (this.value) {
+                    const newT = parseFloat(this.value);
+                    if (_.isNumber(newT) && newT > 0.0 && newT < 1) {
+                      network.update_cluster_threshold_display(newT);
+                      network.draw_attribute_labels();
+                      network.update(true);
+                      enclosure
+                        .classed("has-success", true)
+                        .classed("has-error", false);
+                      return;
+                    }
+                  }
+
+                  enclosure
+                    .classed("has-success", false)
+                    .classed("has-error", true);
+                })
+                .on("click", (e) => {
+                  d3.event.stopPropagation();
+                });
+            },
+            null,
+          ],
+        ],
+      },
+    };
+  };
+
+  self._social_view_options = function (
+    labeled_links,
+    shown_types,
+    edge_typer
+  ) {
+    edge_typer =
+      edge_typer ||
+      function (e) {
+        return _.has(e, "edge_type") ? e["edge_type"] : "";
+      };
+
+    return {
+      "edge-styler": function (element, d, network) {
+        var e_type = misc.edge_typer(d);
+        if (e_type !== "") {
+          d3.select(element).style(
+            "stroke",
+            network._edge_colorizer(misc.edge_typer(d))
+          ); //.style ("stroke-dasharray", network._edge_dasher (d["edge_type"]));
+
+          d.is_hidden = !network.shown_types[e_type];
+        } else {
+          d.is_hidden = !network.shown_types[""];
+        }
+        d3.select(element).style("stroke-width", "5px");
+      },
+
+      init_code: function (network) {
+        function style_edge(type) {
+          this.style("stroke-width", "5px");
+          if (type.length) {
+            this.style("stroke", network._edge_colorizer(type)); //.style ("stroke-dasharray", network._edge_dasher (type));
+          } else {
+            this.classed("link", true);
+            var def_color = this.style("stroke");
+            this.classed("link", null);
+            this.style("stroke", def_color);
+          }
+        }
+
+        var edge_types = _.keys(shown_types);
+        edge_types.sort();
+
+        network._edge_colorizer = d3.scale
+          .ordinal()
+          .range(kGlobals.CategoricalBase)
+          .domain(edge_types);
+        //network._edge_dasher   = _edge_dasher;
+        network.shown_types = _.clone(shown_types);
+        network.edge_legend = {
+          caption: "Network links",
+          types: {},
+        };
+
+        _.each(network.shown_types, (ignore, t) => {
+          if (t.length) {
+            network.edge_legend.types[t] = _.partial(style_edge, t);
+          } else {
+            network.edge_legend.types["Molecular links"] = _.partial(
+              style_edge,
+              t
+            );
+          }
+        });
+      },
+
+      extra_menu: {
+        title: "Additional options",
+        items: _.map(labeled_links, (edge_class) => [
+          function (network, element) {
+            function toggle_element() {
+              network.shown_types[edge_class] =
+                !network.shown_types[edge_class];
+              checkbox.attr(
+                "checked",
+                network.shown_types[edge_class] ? "" : null
+              );
+              network.update(true);
+            }
+
+            var link;
+
+            if (edge_class.length) {
+              link = element
+                .append("a")
+                .text(edge_class + " links")
+                .style("color", network._edge_colorizer(edge_class))
+                .on("click", toggle_element);
+            } else {
+              link = element
+                .append("a")
+                .text("Molecular links")
+                .on("click", toggle_element);
+            }
+            var checkbox = link
+              .append("input")
+              .attr("type", "checkbox")
+              .attr("checked", "");
+          },
+        ]),
+      },
+    };
+  };
+
+  /*------------ Node injection (social network) ---------------*/
+
+  self.load_nodes_edges = function (
+    nodes_and_attributes,
+    index_id,
+    edges_and_attributes,
+    annotation
+  ) {
+    annotation = annotation || "Social";
+    /**
+        1. Scan the list of nodes for
+            a. Nodes not present in the existing network
+            b. Attribute names
+            c. Attribute values
+
+        2. Scan the list of edges for
+            a. Edges not present in the existing network
+            b. Attribute names
+            c. Attribute values
+     */
+
+    var new_nodes = [];
+    var edge_types_dict = {};
+    var existing_nodes = 0;
+    var injected_nodes = {};
+    var node_attributes = {};
+    var existing_network_nodes = {};
+    var node_name_2_id = {};
+
+    _.each(self.json.Nodes, (n, i) => {
+      existing_network_nodes[n.id] = n;
+      node_name_2_id[n.id] = i;
+    });
+
+    const handle_node_attributes = (target, n) => {
+      _.each(n, (attribute_value, attribute_key) => {
+        if (attribute_key !== index_id) {
+          HTX.HIVTxNetwork.inject_attribute_node_value_by_id(
+            target,
+            attribute_key,
+            attribute_value
+          );
+        }
+      });
+    };
+
+    const inject_new_node = (node_name, n) => {
+      const new_node = {
+        node_class: "injected",
+        node_annotation: annotation,
+        attributes: [],
+        degree: 0,
+      };
+      new_node[kGlobals.network.NodeAttributeID] = {};
+      new_node.id = node_name;
+      handle_node_attributes(new_node, n);
+      node_name_2_id[node_name] = self.json.Nodes.length;
+      self.json.Nodes.push(new_node);
+      new_nodes.push(new_node);
+    };
+
+    if (nodes_and_attributes && nodes_and_attributes.length) {
+      if (!(index_id in nodes_and_attributes[0])) {
+        throw Error(
+          index_id +
+            " is not one of the attributes in the imported node records"
+        );
+      }
+
+      _.each(nodes_and_attributes[0], (r, i) => {
+        if (i !== index_id) {
+          var attribute_definition = {
+            label: i,
+            type: "String",
+            annotation: annotation,
+          };
+          self.inject_attribute_description(i, attribute_definition);
+        }
+      });
+
+      _.each(nodes_and_attributes, (n) => {
+        if (n[index_id] in existing_network_nodes) {
+          handle_node_attributes(existing_network_nodes[n[index_id]], n);
+          existing_nodes++;
+        } else {
+          inject_new_node(n[index_id], n);
+        }
+      });
+    }
+
+    if (edges_and_attributes && edges_and_attributes.length) {
+      const auto_inject = !(
+        nodes_and_attributes && nodes_and_attributes.length
+      );
+
+      if (auto_inject) {
+        _.map(existing_network_nodes, (e) => false);
+      }
+
+      _.each(edges_and_attributes, (e) => {
+        try {
+          if ("Index" in e && "Partner" in e && "Contact" in e) {
+            if (!(e["Index"] in node_name_2_id)) {
+              if (auto_inject) {
+                inject_new_node(e["Index"], []);
+              } else {
+                throw Error("Invalid index node");
+              }
+            } else if (auto_inject) {
+              existing_network_nodes[e["Index"]] = true;
+            }
+
+            if (!(e["Partner"] in node_name_2_id)) {
+              if (auto_inject) {
+                inject_new_node(e["Partner"], []);
+              } else {
+                throw Error("Invalid partner node");
+              }
+            } else if (auto_inject) {
+              existing_network_nodes[e["Partner"]] = true;
+            }
+
+            edge_types_dict[e["Contact"]] =
+              (edge_types_dict[e["Contact"]]
+                ? edge_types_dict[e["Contact"]]
+                : 0) + 1;
+
+            var new_edge = {
+              source: node_name_2_id[e["Index"]],
+              target: node_name_2_id[e["Partner"]],
+              edge_type: e["Contact"],
+              length: 0.005,
+              directed: true,
+            };
+
+            self.json.Edges.push(new_edge);
+          } else {
+            throw Error("Missing required attribute");
+          }
+        } catch (err) {
+          throw Error(
+            "Invalid edge specification ( " + err + ") " + JSON.stringify(e)
+          );
+        }
+      });
+
+      if (auto_inject) {
+        existing_nodes = _.size(_.filter(existing_network_nodes, (e) => e));
+      }
+
+      self._aux_populate_category_menus();
+
+      self.update_clusters_with_injected_nodes(null, null, annotation);
+      if (self._is_CDC_) {
+        self.draw_extended_node_table(self.json.Nodes);
+      } else {
+        self.draw_node_table(self.extra_node_table_columns, self.json.Nodes);
+      }
+      if (!self.extra_cluster_table_columns) {
+        self.extra_cluster_table_columns = [];
+      }
+      if (!self.extra_subcluster_table_columns) {
+        self.extra_subcluster_table_columns = [];
+      }
+
+      var edge_types_by_cluster = {};
+      _.each(self.json.Edges, (e) => {
+        try {
+          var edge_clusters = _.union(
+            _.keys(self.json.Nodes[e.source].extended_cluster),
+            _.keys(self.json.Nodes[e.target].extended_cluster)
+          );
+          _.each(edge_clusters, (c) => {
+            if (!(c in edge_types_by_cluster)) {
+              edge_types_by_cluster[c] = {};
+            }
+            if (e.edge_type) {
+              edge_types_by_cluster[c][e.edge_type] = 1;
+            }
+          });
+        } catch (err) {
+          console.log(err);
+        }
+      });
+
+      var edge_types_by_cluster_sorted = {};
+      _.each(edge_types_by_cluster, (v, c) => {
+        var my_keys = _.keys(v);
+        my_keys.sort();
+        edge_types_by_cluster_sorted[c] = my_keys;
+      });
+
+      /*var _edge_dasher = d3.scale
+        .ordinal()
+        .range(kGlobals.CategoricalDashPatterns)
+        .domain(edge_types);
+      */
+
+      var _social_view_handler = function (
+        id,
+        node_filter,
+        labeled_links,
+        shown_types,
+        title,
+        e
+      ) {
+        self.open_exclusive_tab_view(
+          id,
+          node_filter,
+          title,
+          self._social_view_options(labeled_links, shown_types),
+          true
+        );
+      };
+
+      var _injected_column_subcluster_button_handler = function (
+        payload,
+        edge_filter,
+        title,
+        e
+      ) {
+        function edge_filter_for_subclusters(edge) {
+          return (
+            HTX.HIVTxNetwork.is_edge_injected(edge) ||
+            edge.length <= self.subcluster_threshold
+          );
+        }
+
+        var subcluster_edges = [];
+
+        var direct_links_only = hivtrace_cluster_depthwise_traversal(
+          self.json.Nodes,
+          self.json.Edges,
+          edge_filter || edge_filter_for_subclusters,
+          //null,
+          subcluster_edges,
+          payload.children
+        );
+
+        var labeled_links = {},
+          shown_types = {};
+        _.each(subcluster_edges[0], (e) => {
+          if (e.edge_type) {
+            labeled_links[e.edge_type] = 1;
+            shown_types[e.edge_type] = 1;
+          }
+        });
+
+        labeled_links = _.keys(labeled_links);
+        labeled_links.sort();
+        labeled_links.push("");
+        shown_types[""] = 1;
+
+        title =
+          title ||
+          function (id) {
+            return (
+              "Subcluster " + payload.cluster_id + "[+ " + annotation + "]"
+            );
+          };
+
+        var cv = self.view_subcluster(
+          payload,
+          direct_links_only[0],
+          title(payload.cluster_id),
+          self._social_view_options(labeled_links, shown_types),
+          edge_filter_for_subclusters,
+          true
+        );
+        //cv.annotate_priority_clusters(timeDateUtil._networkCDCDateField, 36, 12);
+        //cv.handle_attribute_categorical("recent_rapid");
+        cv._refresh_subcluster_view(
+          self.today || timeDateUtil.getCurrentDate()
+        );
+      };
+
+      var injected_column_subcluster = [
+        {
+          description: {
+            value: annotation + " network",
+            help: "View subclusters with " + annotation + " data",
+          },
+
+          generator: function (cluster) {
+            return {
+              value: cluster,
+              callback: function (element, payload) {
+                var this_cell = d3.select(element);
+                this_cell
+                  .append("button")
+                  .classed("btn btn-primary btn-xs pull-right", true)
+                  .style("margin-left", "1em")
+                  .text("Complete " + annotation)
+                  .on(
+                    "click",
+                    _.partial(
+                      _injected_column_subcluster_button_handler,
+                      payload,
+                      null,
+                      null
+                    )
+                  );
+
+                var node_ids = {};
+
+                _.each(payload.children, (n) => {
+                  node_ids[n.id] = 1;
+                });
+
+                this_cell
+                  .append("button")
+                  .classed("btn btn-primary btn-xs pull-right", true)
+                  .text("Directly linked " + annotation)
+                  .on(
+                    "click",
+                    _.partial(
+                      _injected_column_subcluster_button_handler,
+                      payload,
+                      (edge) =>
+                        self.json.Nodes[edge.target].id in node_ids ||
+                        self.json.Nodes[edge.source].id in node_ids,
+                      (id) =>
+                        "Subcluster " +
+                        payload.cluster_id +
+                        "[+ direct  " +
+                        annotation +
+                        "]"
+                    )
+                  );
+              },
+            };
+          },
+        },
+      ];
+
+      var injected_column = [
+        {
+          description: {
+            value: annotation + " network",
+            sort: function (c) {
+              return c.value[0];
+            },
+            help: "Nodes added and clusters merged through " + annotation,
+          },
+          generator: function (cluster) {
+            return {
+              value: [
+                cluster.injected[annotation],
+                cluster.linked_clusters,
+                cluster.cluster_id,
+              ],
+
+              callback: function (element, payload) {
+                var this_cell = d3.select(element);
+                this_cell.text(
+                  Number(payload[0]) + " " + annotation + " nodes. "
+                );
+                var other_clusters = [];
+                if (payload[1]) {
+                  other_clusters = _.without(_.keys(payload[1]), payload[2]);
+                  if (other_clusters.length) {
+                    other_clusters.sort();
+                    this_cell
+                      .append("span")
+                      .classed("label label-info", true)
+                      .text("Bridges to " + other_clusters.length + " clusters")
+                      .attr("title", other_clusters.join(", "));
+                  }
+                }
+
+                var labeled_links = _.clone(
+                  edge_types_by_cluster_sorted[payload[2]]
+                );
+
+                if (
+                  payload[0] > 0 ||
+                  other_clusters.length ||
+                  (edge_types_by_cluster_sorted[payload[2]] &&
+                    labeled_links.length)
+                ) {
+                  labeled_links.push("");
+
+                  var shown_types = {};
+                  _.each(labeled_links, (t) => {
+                    shown_types[t] = 1;
+                  });
+
+                  this_cell
+                    .append("button")
+                    .classed("btn btn-primary btn-xs pull-right", true)
+                    .text("Directly linked " + annotation)
+                    .style("margin-left", "1em")
+                    .on("click", (e) => {
+                      var directly_linked_ids = {};
+                      var node_ids = {};
+
+                      _.each(cluster.children, (n) => {
+                        node_ids[n.id] = 1;
+                      });
+
+                      var direct_links_only =
+                        hivtrace_cluster_depthwise_traversal(
+                          self.json.Nodes,
+                          self.json.Edges,
+                          (edge) =>
+                            self.json.Nodes[edge.target].id in node_ids ||
+                            self.json.Nodes[edge.source].id in node_ids,
+                          false,
+                          cluster.children
+                        );
+
+                      _.each(direct_links_only[0], (n) => {
+                        directly_linked_ids[n.id] = true;
+                      });
+
+                      //console.log (directly_linked_ids);
+
+                      _social_view_handler(
+                        payload[2],
+                        (n) => n.id in directly_linked_ids,
+                        labeled_links,
+                        shown_types,
+                        (id) =>
+                          "Cluster " + id + "[+ direct " + annotation + "]",
+                        e
+                      );
+                    });
+
+                  this_cell
+                    .append("button")
+                    .classed("btn btn-primary btn-xs pull-right", true)
+                    .text("Complete " + annotation)
+                    .on(
+                      "click",
+                      _.partial(
+                        _social_view_handler,
+                        payload[2],
+                        (n) =>
+                          n.extended_cluster &&
+                          payload[2] in n.extended_cluster,
+                        labeled_links,
+                        shown_types,
+                        (id) => "Cluster " + id + "[+ " + annotation + "]"
+                      )
+                    );
+                }
+              },
+            };
+          },
+        },
+      ];
+
+      if (self.extra_cluster_table_columns) {
+        self.extra_cluster_table_columns =
+          self.extra_cluster_table_columns.concat(injected_column);
+      } else {
+        self.extra_cluster_table_columns = injected_column;
+      }
+
+      self.draw_cluster_table(
+        self.extra_cluster_table_columns,
+        self.cluster_table
+      );
+
+      if (self.subcluster_table) {
+        if (self.extra_subcluster_table_columns) {
+          self.extra_subcluster_table_columns =
+            self.extra_subcluster_table_columns.concat(
+              injected_column_subcluster
+            );
+        } else {
+          self.extra_subcluster_table_columns = injected_column_subcluster;
+        }
+        self.draw_cluster_table(
+          self.extra_subcluster_table_columns,
+          self.subcluster_table,
+          { subclusters: true, "no-clusters": true }
+        );
+      }
+    }
+
+    return {
+      nodes: new_nodes,
+      existing_nodes: existing_nodes,
+      edges: edge_types_dict,
+    };
+  };
+
+  self.update_clusters_with_injected_nodes = function (
+    node_filter,
+    edge_filter,
+    annotation
+  ) {
+    let recomputed_clusters;
+
+    try {
+      node_filter =
+        node_filter ||
+        function () {
+          return true;
+        };
+      edge_filter =
+        edge_filter ||
+        function () {
+          return true;
+        };
+
+      recomputed_clusters = hivtrace_cluster_depthwise_traversal(
+        _.filter(self.json.Nodes, node_filter),
+        self.json.Edges,
+        null,
+        false
+      );
+
+      _.each(recomputed_clusters, (c) => {
+        var cluster_ids = {};
+        var injected_count = 0;
+
+        _.each(c, (n) => {
+          cluster_ids[n.cluster] = 1;
+          injected_count += n.cluster ? 0 : 1;
+        });
+
+        //var cluster_ids = _.keys (cluster_ids);
+
+        //console.log (cluster_ids.length);
+
+        // count how many "injected" nodes are there in the new cluster
+
+        if (injected_count) {
+          delete cluster_ids[undefined];
+        }
+
+        _.each(c, (n) => {
+          if ("extended_cluster" in n) {
+            _.extend(n["extended_cluster"], cluster_ids);
+          } else {
+            n["extended_cluster"] = cluster_ids;
+          }
+        });
+
+        _.each(cluster_ids, (c, k) => {
+          var existing_cluster = self.clusters[self.cluster_mapping[k]];
+          if (!existing_cluster.injected) {
+            existing_cluster.injected = {};
+          }
+          existing_cluster.injected[annotation] = injected_count;
+          if ("linked_clusters" in existing_cluster) {
+            _.extend(existing_cluster["linked_clusters"], cluster_ids);
+          } else {
+            existing_cluster["linked_clusters"] = cluster_ids;
+          }
+        });
+      });
+    } catch (err) {
+      console.log(err);
+      throw err;
+    }
+
+    return recomputed_clusters;
+  };
+  /*------------ Event Functions ---------------*/
+  function toggle_tooltip(element, turn_on, title, tag, container) {
+    //if (d3.event.defaultPrevented) return;
+    if (!element) {
+      return;
+    }
+
+    if (turn_on && !element.tooltip) {
+      // check to see if there are any other tooltips shown
+      $("[role='tooltip']").each(function (d) {
+        $(this).remove();
+      });
+
+      var this_box = $(element);
+
+      // var this_data = d3.select(element).datum();
+      //this_data.fixed = true;
+
+      element.tooltip = this_box.tooltip({
+        title: title + "<br>" + tag,
+        html: true,
+        container: container ? container : "body",
+      });
+
+      _.delay(_.bind(element.tooltip.tooltip, element.tooltip), 500, "show");
+    } else if (!turn_on && element.tooltip) {
+      element.tooltip.tooltip("destroy");
+      element.tooltip = undefined;
+    }
+  }
+
+  /*------------ Init code ---------------*/
+
+  var l_scale = 5000, // link scale
+    graph_data = self.json, // the raw JSON network object
+    max_points_to_render = 2048,
+    singletons = 0,
+    open_cluster_queue = [],
+    currently_displayed_objects,
+    gravity_scale = d3.scale
+      .pow()
+      .exponent(0.5)
+      .domain([1, 100000])
+      .range([0.1, 0.15]),
+    link_scale = d3.scale.pow().exponent(1.25).clamp(true).domain([0, 0.1]);
+
+  /*------------ D3 globals and SVG elements ---------------*/
+
+  var network_layout = d3.layout
+    .force()
+    .on("tick", tick)
+    .charge((d) => {
+      if (self.showing_on_map) {
+        return -60;
+      }
+      if (d.cluster_id) {
+        return self.charge_correction * (-15 - 5 * d.children.length ** 0.4);
+      }
+      return self.charge_correction * (-10 - 5 * Math.sqrt(d.degree));
+    })
+    .linkDistance(
+      (d) => link_scale(d.length) * l_scale * 0.2 //Math.max(d.length, 0.005) * l_scale * 10;
+    )
+    .linkStrength((d) => {
+      if (self.showing_on_map) {
+        return 0.01;
+      }
+      if (d.support !== undefined) {
+        return 0.75 - 0.5 * d.support;
+      }
+      return 1;
+    })
+    .chargeDistance(l_scale * 0.1)
+    .gravity(self.showing_on_map ? 0 : gravity_scale(json.Nodes.length))
+    .friction(0.25);
+
+  d3.select(self.container).selectAll(".my_progress").style("display", "none");
+  d3.select(self.container).selectAll("svg").remove();
+  nodesTab.getNodeTable().selectAll("*").remove();
+  self.cluster_table.selectAll("*").remove();
+
+  self.network_svg = d3
+    .select(self.container)
+    .append("svg:svg")
+    //.style ("border", "solid black 1px")
+    .attr("id", self.dom_prefix + "-network-svg")
+    .attr("width", self.width + self.margin.left + self.margin.right)
+    .attr("height", self.height + self.margin.top + self.margin.bottom);
+
+  self.network_cluster_dynamics = null;
+
+  //.append("g")
+  // .attr("transform", "translate(" + self.margin.left + "," + self.margin.top + ")");
+
+  var legend_drag = d3.behavior
+    .drag()
+    .on("dragstart", () => {
+      d3.event.sourceEvent.stopPropagation();
+    })
+    .on("drag", function (d) {
+      d3.select(this).attr(
+        "transform",
+        "translate(" + [d3.event.x, d3.event.y] + ")"
+      );
+    });
+  const legend_vertical_offset = self.showing_on_map ? 100 : 5;
+  self.legend_svg = self.network_svg
+    .append("g")
+    .attr("transform", "translate(5," + legend_vertical_offset + ")")
+    .call(legend_drag);
+
+  self.network_svg
+    .append("defs")
+    .append("marker")
+    .attr("id", self.dom_prefix + "_arrowhead")
+    .attr("refX", 18)
+    .attr("refY", 6)
+    .attr("markerWidth", 20)
+    .attr("markerHeight", 16)
+    .attr("orient", "auto")
+    .attr("stroke", "#666666")
+    .attr("markerUnits", "userSpaceOnUse")
+    .attr("fill", "#AAAAAA")
+    .append("path")
+    .attr("d", "M 0,0 L 2,6 L 0,12 L14,6 Z"); //this is actual shape for arrowhead
+
+  change_window_size();
+
+  initial_json_load();
+
+  if (options) {
+    if (_.isNumber(options["charge"])) {
+      self.charge_correction = options["charge"];
+    }
+
+    if ("colorizer" in options) {
+      self.colorizer = options["colorizer"];
+    }
+
+    if ("node_shaper" in options) {
+      self.node_shaper = options["node_shaper"];
+    }
+
+    if ("callbacks" in options) {
+      options["callbacks"](self);
+    }
+
+    if (_.isArray(options["expand"])) {
+      self.expand_some_clusters(
+        _.filter(
+          self.clusters,
+          (c) => options["expand"].indexOf(c.cluster_id) >= 0
+        )
+      );
+    }
+
+    if (options["priority-sets-url"]) {
+      const is_writeable = options["is-writeable"];
+      self.load_priority_sets(options["priority-sets-url"], is_writeable);
+    }
+
+    if (self.showing_diff) {
+      self.handle_attribute_categorical("_newly_added");
+    }
+  }
+
+  self.draw_attribute_labels();
+  d3.select(self.container).selectAll(".my_progress").style("display", "none");
+  network_layout.start();
+
+  return self;
+};
+
+export {
+  hivtrace_cluster_network_graph as clusterNetwork,
+  hivtrace_cluster_depthwise_traversal as computeCluster,
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/clustersOfInterest.js.html b/docs/clustersOfInterest.js.html new file mode 100644 index 0000000..a34bcd6 --- /dev/null +++ b/docs/clustersOfInterest.js.html @@ -0,0 +1,1984 @@ + + + + + JSDoc: Source: clustersOfInterest.js + + + + + + + + + + +
+ +

Source: clustersOfInterest.js

+ + + + + + +
+
+
import * as d3 from "d3";
+import _ from "underscore";
+import { jsPanel } from "jspanel4";
+import autocomplete from "autocomplete.js";
+import * as timeDateUtil from "./timeDateUtil.js";
+import * as tables from "./tables.js";
+import * as helpers from "./helpers.js";
+import * as misc from "./misc.js";
+import { hivtrace_cluster_depthwise_traversal } from "./misc";
+import * as kGlobals from "./globals.js";
+
+let priority_set_editor = null;
+
+/**
+ * Initializes the component, setting up event listeners and UI elements.
+
+ * @param {Object} self - The component object itself.
+
+ * @returns {void}
+ */
+
+function init(self) {
+  if (self._is_CDC_ && self.isPrimaryGraph) {
+    let new_set = misc.get_ui_element_selector_by_role("new_priority_set");
+    if (new_set) {
+      window.addEventListener("beforeunload", (e) => {
+        if (self.priority_groups_pending() > 0) {
+          e.preventDefault();
+          return "There are clusters of interest that have not been confirmed. Closing the window now will not finalize their creation.";
+        }
+        return null;
+      });
+
+      d3.selectAll(new_set).on("click", (e) => {
+        open_editor(self, []);
+        self.redraw_tables();
+      });
+    }
+
+    let merge_sets = misc.get_ui_element_selector_by_role(
+      "merge_priority_sets"
+    );
+
+    if (merge_sets) {
+      d3.selectAll(merge_sets).on("click", (e) => {
+        $(misc.get_ui_element_selector_by_role("priority_set_merge")).modal();
+      });
+    }
+  }
+}
+
+/**
+ * Checks if a provided name for a priority group is valid.
+
+ * @param {Object[]} defined_priority_groups - An array of existing priority group objects.
+ * @param {string} string - The name to be validated.
+ * @param {string} [prior_name] (optional) - The previous name of the priority group (used for edit case).
+
+ * @returns {boolean} True if the name is valid, false otherwise.
+
+ * @description
+ * A valid name must:
+ *  - Have a length between 1 and 35 characters.
+ *  - Not be a duplicate among existing priority groups (excluding itself if editing).
+ */
+
+function priority_groups_check_name(
+  defined_priority_groups,
+  string,
+  prior_name
+) {
+  if (string.length) {
+    if (string.length >= 36) return false;
+    return !_.some(
+      defined_priority_groups,
+      (d) => d.name === string && d.name !== prior_name
+    );
+  }
+  return false;
+}
+
+/**
+ * Opens a priority node set editor.
+
+ * @param {Object} self - The main network visualization object.
+ * @param {Array} node_set - An existing priority node set (optional).
+ * @param {string} name - Name of the priority node set (optional for new sets).
+ * @param {string} description - Description of the priority node set (optional).
+ * @param {string} cluster_kind - The method used to identify the cluster (optional).
+ * @param {Array} kind_options - Available options for cluster identification methods.
+ * @param {string} validation_mode - Indicates the mode (create, validate, revise).
+ * @param {Object} existing_set - Reference to the existing priority node set (for revisions).
+ * @param {string} cluster_tracking - Method for tracking cluster growth (optional).
+ * @param {string} created_by - Who created the node set (system or manual).
+ */
+
+function open_editor(
+  self,
+  node_set,
+  name,
+  description,
+  cluster_kind,
+  kind_options,
+  validation_mode,
+  existing_set,
+  cluster_tracking,
+  created_by
+) {
+  /*
+      validation_mode could be
+        - null (create new set)
+        - "validate" (validate an automatically generated dataset)
+        - "revise" (revise a dataset)
+  */
+  if (priority_set_editor || !self.isPrimaryGraph) return;
+  // only open one editor at a time
+  // only primary network supports editor view
+
+  if (self._is_CDC_executive_mode) {
+    alert(kGlobals.network.WarnExecutiveMode);
+    return;
+  }
+
+  created_by = existing_set
+    ? existing_set.createdBy
+    : created_by || kGlobals.CDCCOICreatedManually;
+
+  priority_set_editor = jsPanel.create({
+    theme: "bootstrap-primary",
+    headerTitle: "Priority node set editor",
+    headerControls: { size: "lg", maximize: "remove" },
+    position: {
+      my: "center",
+      at: "center",
+      offsetX: 0,
+      offsetY: 0,
+    },
+    contentSize: {
+      width: function () {
+        return window.innerWidth * 0.8;
+      },
+      height: function () {
+        return window.innerHeight / 3;
+      },
+    },
+    content: "",
+    contentOverflow: "scroll",
+    callback: function () {
+      var panel_object = this;
+      panel_object.network_nodes = [];
+      panel_object.saved = false;
+      panel_object.prior_name =
+        validation_mode && validation_mode.length && existing_set
+          ? existing_set.name
+          : null;
+
+      panel_object.can_edit_kind = existing_set
+        ? existing_set.createdBy !== "System"
+        : true;
+
+      panel_object.can_edit_name = existing_set
+        ? existing_set.createdBy !== "System"
+        : true;
+
+      panel_object.can_edit_tracking = !existing_set;
+
+      panel_object.can_add = function (id) {
+        return !_.some(panel_object.network_nodes, (d) => d.id === id);
+      };
+
+      var panel_content = d3.select(panel_object.content);
+      panel_content.selectAll("*").remove();
+
+      var form = panel_content
+        .append("form")
+        .attr("action", "javascript:void(0);")
+        .classed("form-inline", true);
+
+      var form_grp = form.append("div").classed("form-group", true);
+
+      form_grp
+        .append("input")
+        .classed("form-control input-sm", true)
+        .attr("placeholder", "Add node by ID")
+        .attr("data-hivtrace-ui-role", "priority-panel-nodeids");
+
+      var submit_button = form
+        .append("button")
+        .classed("btn btn-primary btn-sm", true)
+        .attr("id", "priority-panel-add-node")
+        .attr("disabled", "disabled")
+        .on("click", (e) => {
+          panel_object.append_node();
+        });
+
+      submit_button.append("i").classed("fa fa-plus", true);
+
+      form
+        .append("p")
+        .classed("alert alert-warning", true)
+        .style("display", "inline")
+        .text(
+          "At this time, only nodes that cluster in the network at the 1.5% or 0.5% genetic distance threshold level are available for selection."
+        );
+      //var preview_grp = form.append ("div").classed ("form-group", true);
+
+      var form_save = panel_content
+        .append("form")
+        .classed("form", true)
+        .attr("action", "javascript:void(0);")
+        .style("display", "none");
+
+      var grp_name = form_save.append("div");
+
+      if (panel_object.prior_name) {
+        grp_name.classed("form-group has-success", true);
+      } else {
+        grp_name.classed("form-group has-error", true);
+      }
+
+      var grp_name_button = grp_name
+        .append("input")
+        .classed("form-control input-sm", true)
+        .attr("placeholder", "Name this cluster of interest")
+        .attr("data-hivtrace-ui-role", "priority-panel-name")
+        .attr("maxlength", 100);
+
+      var grp_name_box_label = grp_name
+        .append("p")
+        .classed("help-block", true)
+        .text("Name this cluster of interest");
+
+      var grp_kind = form_save.append("div").classed("form-group", true);
+
+      var grp_kind_select = grp_kind
+        .append("select")
+        .classed("form-control input-sm", true)
+        .attr("data-hivtrace-ui-role", "priority-panel-kind");
+
+      if (!panel_object.can_edit_kind) {
+        grp_kind_select.property("disabled", true);
+        grp_kind_select.attr(
+          "title",
+          "The method of cluster identification cannot be changed for system generated cluster of interest. However, after confirming this cluster of interest, you can clone it and then change this field as needed"
+        );
+      } else {
+        grp_kind_select.attr("title", null);
+      }
+
+      if (!panel_object.can_edit_name) {
+        grp_name_button.property("disabled", true);
+        grp_name_button.attr(
+          "title",
+          "The name cannot be changed for system generated cluster of interest. However, after confirming this cluster of interest, you can clone it and then change this field as needed"
+        );
+      } else {
+        grp_name_button.attr("title", null);
+      }
+
+      grp_kind_select
+        .selectAll("option")
+        .data(kind_options || kGlobals.CDCCOIKind)
+        .enter()
+        .insert("option")
+        .text((d) => d)
+        .property("selected", (d) => d === cluster_kind);
+
+      grp_kind
+        .append("p")
+        .classed("help-block", true)
+        .text("Cluster identification method");
+
+      var grp_tracking = form_save.append("div").classed("form-group", true);
+
+      var grp_tracking_select = grp_tracking
+        .append("select")
+        .classed("form-control input-sm", true)
+        .attr("data-hivtrace-ui-role", "priority-panel-tracking");
+
+      if (!panel_object.can_edit_tracking) {
+        grp_tracking_select.property("disabled", true);
+        grp_tracking_select.attr(
+          "title",
+          "The method of tracking cannot be changed for existing clusters (system generated or manual). However, you can clone this cluster of interest and then change this field as needed"
+        );
+      } else {
+        grp_tracking_select.attr("title", null);
+      }
+
+      cluster_tracking =
+        cluster_tracking || kGlobals.CDCCOITrackingOptionsDefault;
+
+      grp_tracking_select
+        .selectAll("option")
+        .data(kGlobals.CDCCOITrackingOptions)
+        .enter()
+        .insert("option")
+        .text((d) => d)
+        .property("selected", (d) => d === cluster_tracking);
+
+      grp_tracking
+        .append("p")
+        .classed("help-block", true)
+        .text("Method of tracking cluster of interest growth");
+
+      var grp_desc = form_save.append("div").classed("form-group", true);
+
+      grp_desc
+        .append("textarea")
+        .classed("form-control input-sm", true)
+        .attr("placeholder", "Cluster of Interest Description")
+        .attr("data-hivtrace-ui-role", "priority-panel-description")
+        .text(description);
+      grp_desc
+        .append("p")
+        .classed("help-block", true)
+        .text("Describe this cluster of interest");
+
+      panel_object.first_save = true;
+      panel_object.cleanup_attributes = function () {
+        _.each(self.nodes, (n) => {
+          _.each(
+            [
+              "_priority_set_fixed",
+              "_priority_set_date",
+              "_priority_set_kind",
+              "_priority_set_autoadded",
+            ],
+            (xtra) => {
+              delete n[xtra];
+            }
+          );
+        });
+      };
+
+      function is_node_editable(node) {
+        return !node["_priority_set_fixed"];
+      }
+
+      function is_node_deletable(node, cm) {
+        return (
+          cm === kGlobals.CDCCOICreatedManually || !node["_priority_set_fixed"]
+        );
+      }
+
+      let createdDate =
+        existing_set && validation_mode && validation_mode.length
+          ? existing_set.created
+          : timeDateUtil.getCurrentDate();
+
+      let modifiedDate =
+        validation_mode === "validate" &&
+        created_by === kGlobals.CDCCOICreatedBySystem
+          ? self.today
+          : timeDateUtil.getCurrentDate();
+
+      function save_priority_set() {
+        /**
+          handler for priority set save requests
+      */
+        form_save.style("display", null);
+
+        let res = true;
+
+        // check if can save (name set etc)
+        if (panel_object.network_nodes.length) {
+          let name, desc, kind, tracking;
+
+          [name, desc, kind, tracking] = _.map(
+            [
+              "priority-panel-name",
+              "priority-panel-description",
+              "priority-panel-kind",
+              "priority-panel-tracking",
+            ],
+            (k) =>
+              $(d3.select(misc.get_ui_element_selector_by_role(k)).node()).val()
+          );
+
+          if (
+            !panel_object.first_save &&
+            priority_groups_check_name(
+              self.defined_priority_groups,
+              name,
+              panel_object.prior_name
+            )
+          ) {
+            let set_description = {
+              name: name,
+              description: desc,
+              nodes: _.map(panel_object.network_nodes, (d) => ({
+                name: d.id,
+                added: d["_priority_set_date"],
+                kind: d["_priority_set_kind"],
+                autoadded: d["_priority_set_autoadded"],
+              })),
+              created: timeDateUtil.DateFormats[0](createdDate),
+              modified: timeDateUtil.DateFormats[0](modifiedDate),
+              kind: kind,
+              tracking: tracking,
+              createdBy: created_by,
+              expanded: false,
+              autocreated: existing_set ? existing_set.autocreated : false,
+              autoexpanded: existing_set ? existing_set.autoexpanded : false,
+              pending: false,
+            };
+
+            if (tracking !== kGlobals.CDCCOITrackingOptionsNone) {
+              let added_nodes = self.auto_expand_pg_handler(set_description);
+              if (added_nodes.size) {
+                if (
+                  confirm(
+                    'This cluster of interest does not include all the nodes in the current network that are eligible for membership by growth criterion  "' +
+                      tracking +
+                      '". These ' +
+                      added_nodes.size +
+                      " additional nodes will be automatically added to this cluster of interest when you save it. If you don’t want to add these nodes to the cluster of interest please select 'Cancel' and change the growth criterion."
+                  )
+                ) {
+                  _.each([...added_nodes], (nid) => {
+                    let n = self.json.Nodes[nid];
+                    set_description.nodes.push({
+                      name: n.id,
+                      added: timeDateUtil.getCurrentDate(),
+                      kind: kGlobals.CDCCOINodeKindDefault,
+                    });
+                  });
+                } else {
+                  return false;
+                }
+              }
+            }
+
+            let operation = null;
+            if (panel_object.prior_name) {
+              operation = existing_set.pending ? "insert" : "update";
+            }
+            res = priority_groups_add_set(
+              self,
+              set_description,
+              true,
+              true,
+              panel_object.prior_name,
+              operation
+            );
+            // clean up temporary flags from nodes
+            panel_object.saved = true;
+            panel_object.cleanup_attributes();
+            panel_object.close();
+            if (validation_mode === "validate") {
+              if (self.priority_set_table_writeable) {
+                let tab_pill = misc.get_ui_element_selector_by_role(
+                    "priority_set_counts"
+                  ),
+                  tab_pill_select = d3.select(tab_pill),
+                  remaining_sets = Number(tab_pill_select.text());
+                tab_pill_select.text(remaining_sets - 1);
+                d3.select("#banner_coi_counts").text(remaining_sets - 1);
+              }
+            }
+          }
+          panel_object.first_save = false;
+        }
+        let panel_to_focus = document.querySelector(
+          misc.get_ui_element_selector_by_role("priority-panel-name")
+        );
+        if (panel_to_focus) panel_to_focus.focus();
+        return res;
+      }
+
+      var save_set_button = form
+        .append("button")
+        .classed("btn btn-primary btn-sm pull-right", true)
+        .text(validation_mode === "validate" ? "Review & Save" : "Save")
+        .attr("disabled", "disabled")
+        .attr("id", "priority-panel-save")
+        .on("click", (e) => {
+          save_priority_set();
+        });
+
+      form
+        .append("button")
+        .classed("btn btn-info btn-sm pull-right", true)
+        .attr("id", "priority-panel-preview")
+        .text("Preview @1.5%")
+        .on("click", (e) => {
+          priority_set_view(self, priority_set_editor, {
+            "priority-edge-length": 0.015,
+            timestamp: createdDate,
+          });
+        });
+      form
+        .append("button")
+        .classed("btn btn-info btn-sm pull-right", true)
+        .attr("id", "priority-panel-preview-subcluster")
+        .text("Preview @" + self.subcluster_threshold * 100 + "%")
+        .on("click", (e) => {
+          priority_set_view(self, priority_set_editor, {
+            "priority-edge-length": self.subcluster_threshold,
+            timestamp: createdDate,
+          });
+        });
+
+      $(grp_name_button.node()).on("input propertychange", function (e) {
+        let current_text = $(this).val();
+        if (
+          priority_groups_check_name(
+            self.defined_priority_groups,
+            current_text,
+            panel_object.prior_name
+          )
+        ) {
+          grp_name.classed({
+            "has-success": true,
+            "has-error": false,
+            "has-warning": false,
+          });
+          grp_name_box_label.text("Name this cluster of interest");
+          if (panel_object.network_nodes.length) {
+            save_set_button.attr("disabled", null);
+          }
+        } else {
+          let too_long = current_text.length >= 36;
+          grp_name.classed({
+            "has-success": false,
+            "has-error": true,
+          });
+          let error_message = too_long
+            ? "MUST be shorter than 36 characters"
+            : "MUST be unique";
+          grp_name_box_label.text(
+            "Name this cluster of interest " + error_message
+          );
+          save_set_button.attr("disabled", "disabled");
+        }
+      });
+
+      if (name) {
+        grp_name_button.attr("value", name);
+        $(grp_name_button.node()).trigger("input");
+      }
+
+      var auto_object = autocomplete(
+        misc.get_ui_element_selector_by_role("priority-panel-nodeids"),
+        { hint: false },
+        [
+          {
+            source: function (query, callback) {
+              function escapeRegExp(string) {
+                return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+              }
+              var hits = [];
+              const pattern = new RegExp(escapeRegExp(query), "i");
+              for (
+                var i = 0;
+                hits.length < 10 && i < self.json["Nodes"].length;
+                i++
+              ) {
+                if (pattern.test(self.json["Nodes"][i].id)) {
+                  if (panel_object.can_add(self.json["Nodes"][i].id)) {
+                    hits.push(self.json["Nodes"][i].id);
+                  }
+                }
+              }
+              callback(hits);
+            },
+            templates: {
+              suggestion: function (suggestion) {
+                return suggestion;
+              },
+            },
+          },
+        ]
+      );
+
+      panel_object.validate_input = function (expression, skip_ui) {
+        expression = expression || auto_object.autocomplete.getVal();
+        const validator = _.filter(
+          self.json["Nodes"],
+          (n) => n.id === expression
+        );
+        if (validator.length === 1 && panel_object.can_add(validator[0].id)) {
+          if (!skip_ui) {
+            submit_button.attr("disabled", null);
+          }
+          return validator[0];
+        } else if (!skip_ui) {
+          submit_button.attr("disabled", "disabled");
+        }
+        return null;
+      };
+
+      panel_object._append_node = function (node) {
+        if (!("_priority_set_date" in node)) {
+          node["_priority_set_date"] = createdDate;
+        }
+        if (!("_priority_set_kind" in node)) {
+          node["_priority_set_kind"] = kGlobals.CDCCOINodeKindDefault;
+        }
+        panel_object.network_nodes.push(node);
+      };
+
+      panel_object.can_add_nodes = function () {
+        if (created_by !== kGlobals.CDCCOICreatedManually) {
+          alert(
+            "Cannot add nodes to system generated clusters of interest. You may clone this cluster of interest and then add nodes to it manually if necessary."
+          );
+          return false;
+        }
+        return true;
+      };
+
+      panel_object.append_node = function (id, skip_ui) {
+        if (!panel_object.can_add_nodes()) {
+          return;
+        }
+
+        var node_to_add = panel_object.validate_input(id, skip_ui);
+        if (node_to_add) {
+          panel_object._append_node(node_to_add);
+          panel_object.table_handler(panel_object);
+          panel_object.validate_input();
+        }
+      };
+
+      panel_object.append_nodes = function (nodes_to_add, existing_attributes) {
+        if (!panel_object.can_add_nodes()) {
+          return;
+        }
+        let existing_ids = {};
+
+        _.each(panel_object.network_nodes, (n) => {
+          existing_ids[n.id] = 1;
+        });
+
+        let need_update = false;
+        let valid_ids = {};
+        _.each(self.json["Nodes"], (n) => {
+          if (!existing_ids[n.id]) {
+            if (existing_attributes) {
+              valid_ids[n.id] = _.extend(n, existing_attributes[n.id]);
+            } else {
+              valid_ids[n.id] = n;
+            }
+          }
+        });
+
+        _.each(nodes_to_add, (n) => {
+          if (!(n in existing_ids) && n in valid_ids) {
+            panel_object._append_node(valid_ids[n]);
+            existing_ids[n] = 1;
+            need_update = true;
+          }
+        });
+
+        if (need_update) {
+          panel_object.table_handler(panel_object);
+        }
+      };
+
+      panel_object.append_node_objects = function (nodes_to_add) {
+        if (!panel_object.can_add_nodes()) {
+          return;
+        }
+
+        let existing_ids = {};
+
+        _.each(panel_object.network_nodes, (n) => {
+          existing_ids[n.id] = 1;
+        });
+
+        let need_update = false;
+
+        _.each(nodes_to_add, (n) => {
+          if (!(n.id in existing_ids)) {
+            panel_object._append_node(n);
+            existing_ids[n.id] = 1;
+            need_update = true;
+          }
+        });
+
+        if (need_update) {
+          panel_object.table_handler(panel_object);
+        }
+      };
+
+      panel_object.remove_node = function (n) {
+        panel_object.network_nodes = _.filter(
+          panel_object.network_nodes,
+          (nn) => nn !== n
+        );
+        panel_object.table_handler(panel_object);
+      };
+
+      auto_object
+        .on("autocomplete:selected", (event, suggestion, dataset, context) => {
+          auto_object.autocomplete.setVal(suggestion);
+          panel_object.validate_input();
+        })
+        .on("input propertychange", () => {
+          panel_object.validate_input();
+        });
+
+      panel_object.table_handler = function (panel) {
+        var table_container = panel_content.selectAll("table").data(["panel"]);
+        table_container.enter().append("table");
+        table_container
+          .classed(
+            "table table-striped table-condensed table-hover table-smaller",
+            true
+          )
+          .attr("id", "priority-panel-node-table");
+
+        panel.setHeaderTitle(
+          "clusterOI editor (" +
+            panel.network_nodes.length +
+            " nodes)" +
+            (validation_mode ? " [automatically created review] " : "")
+        );
+
+        save_set_button.attr(
+          "disabled",
+          panel.network_nodes.length ? null : "disabled"
+        );
+
+        var del_form_generator = function () {
+          return `<form class="form">
+  <div class="form-group">
+    <div class="input-group"> <textarea class="form-control input-sm" data-hivtrace-ui-role="priority-description-form"
+        cols="40" rows="3"></textarea> </div>
+  </div> <button data-hivtrace-ui-role="priority-description-dismiss" class="btn btn-sm btn-default">Cancel</button>
+  <button data-hivtrace-ui-role="priority-description-save" class="btn btn-sm btn-default">Delete</button>
+</form>`;
+        };
+
+        let extra_columns = [
+          {
+            prepend: true,
+            description: {
+              value: "Added",
+              help: "When was this person added to the cluster of interest?",
+            },
+            generator: function (node) {
+              return {
+                value: node,
+                callback: function (element, payload) {
+                  let this_cell = d3.select(element);
+                  if (payload["_priority_set_date"]) {
+                    if (payload["_priority_set_autoadded"]) {
+                      this_cell.style("color", "darkred");
+                    }
+                    if (!is_node_editable(payload)) {
+                      this_cell.text(
+                        timeDateUtil.DateViewFormatMMDDYYY(
+                          payload["_priority_set_date"]
+                        )
+                      );
+                    } else {
+                      this_cell
+                        .append("input")
+                        .attr("type", "date")
+                        .attr(
+                          "value",
+                          timeDateUtil.DateViewFormatSlider(
+                            payload["_priority_set_date"]
+                          )
+                        )
+                        .on("change", (e, d) => {
+                          try {
+                            payload["_priority_set_date"] =
+                              timeDateUtil.DateViewFormatSlider.parse(
+                                $(d3.event.target).val()
+                              );
+                          } catch {
+                            // do nothing
+                          }
+                        });
+                    }
+                  } else {
+                    this_cell.text("N/A");
+                  }
+                },
+              };
+            },
+          },
+          {
+            prepend: true,
+            description: {
+              value: "Person identification method",
+              help: "How was this person identified as part of this cluster of interest?",
+            },
+            generator: function (node) {
+              return {
+                value: node,
+                html: true,
+                actions: function (item, value) {
+                  if (is_node_editable(value)) {
+                    return [
+                      {
+                        //icon: "fa-caret-down",
+                        classed: { "btn-default": true },
+                        text: value["_priority_set_kind"], //.split(" ")[0],
+                        help: "How was this person identified?",
+                        dropdown: kGlobals.CDCCOINodeKind,
+                        action: function (button, menu_value) {
+                          value["_priority_set_kind"] = menu_value;
+                          button.text(
+                            value["_priority_set_kind"] //.split(" ")[0]
+                          );
+                        },
+                      },
+                    ];
+                  }
+                  return [];
+                },
+
+                callback: function (element, payload) {
+                  let this_cell = d3.select(element);
+                  if (!is_node_editable(payload)) {
+                    this_cell
+                      .append("abbr")
+                      .attr("title", payload["_priority_set_kind"])
+                      .text(payload["_priority_set_kind"] /*.split(" ")[0]*/);
+                  }
+                  return this_cell;
+                },
+              };
+            },
+          },
+          {
+            // delete object option
+            prepend: true,
+            description: {
+              value: "",
+              actions: [
+                {
+                  icon: "fa-trash",
+                  action: function (b, v) {
+                    // iterate through the table and remove shown nodes one at a time
+                    // checking that the row is shown to allow for filtering and such
+
+                    let remaining_nodes = new Set(panel.network_nodes);
+
+                    table_container
+                      .selectAll("tr")
+                      .filter(function (d) {
+                        return d3.select(this).style("display") !== "none";
+                      })
+                      .each(function (d) {
+                        d3.select(this)
+                          .selectAll("td:first-child > button")
+                          .each(function (d) {
+                            let this_node = d3.select(this).datum();
+                            if (is_node_editable(this_node)) {
+                              remaining_nodes.delete(this_node);
+                            }
+                          });
+                      });
+
+                    const leftovers = remaining_nodes.values();
+                    panel.network_nodes = [];
+                    for (let entry of leftovers) {
+                      panel.network_nodes.push(entry);
+                    }
+                    panel.table_handler(panel);
+                  },
+                },
+              ],
+            },
+            generator: function (node) {
+              return {
+                value: node,
+                callback: function (element, payload) {
+                  var this_cell = d3.select(element);
+                  if (!is_node_deletable(payload, created_by)) {
+                    this_cell
+                      .append("button")
+                      .classed("btn btn-default btn-xs", true)
+                      .style("margin-left", "1em")
+                      .datum(payload)
+                      .property("disabled", true)
+                      .append("i")
+                      .classed("fa fa-ban", true);
+                  } else {
+                    this_cell
+                      .append("button")
+                      .classed("btn btn-default btn-xs", true)
+                      .style("margin-left", "1em")
+                      .datum(payload)
+                      .on("click", function () {
+                        handle_inline_confirm(
+                          d3.select(this),
+                          del_form_generator,
+                          "Are you sure you wish to permanently delete this node from the cluster of interest?",
+                          (d) => {
+                            panel_object.remove_node(payload);
+                          },
+                          true
+                        );
+                        d3.event.preventDefault();
+                        //panel_object.remove_node(payload);
+                      })
+                      .append("i")
+                      .classed("fa fa-trash", true);
+                  }
+                },
+              };
+            },
+          },
+        ];
+        if (!self._is_CDC_auto_mode) {
+          extra_columns.splice(1, 1);
+        }
+
+        self.draw_extended_node_table(
+          panel.network_nodes,
+          table_container,
+          extra_columns
+        );
+      };
+
+      panel_object.content.style.padding = "5px";
+      panel_object.network_nodes = node_set;
+      // inject node attributes if available
+      if (validation_mode) {
+        // existing nodes cannot be deleted
+        _.each(panel_object.network_nodes, (n) => {
+          n["_priority_set_fixed"] = true;
+        });
+      }
+
+      if (existing_set) {
+        priority_set_inject_node_attibutes(
+          self,
+          panel_object.network_nodes,
+          existing_set.nodes
+        );
+      }
+
+      panel_object.table_handler(this);
+    },
+    dragit: {
+      containment: [50, 50, 100, 50],
+    },
+    resizeit: {
+      containment: [50, 50, 100, 50],
+    },
+    onbeforeclose: function () {
+      if (!this.saved) {
+        if (
+          confirm(
+            "Close cluster of interest editor? Unsaved changes will be lost."
+          )
+        ) {
+          if (existing_set) {
+            const existing_nodes = new Set(
+              _.map(existing_set.nodes, (n) => n.name)
+            );
+            existing_set.node_objects = _.filter(
+              existing_set.node_objects,
+              (n) => existing_nodes.has(n.id)
+            );
+          }
+          this.cleanup_attributes();
+          return true;
+        }
+        return false;
+      }
+      return true;
+    },
+    onclosed: function () {
+      priority_set_editor = null;
+      self.redraw_tables();
+    },
+  });
+}
+
+/**
+ * Handles inline confirmation popovers.
+
+ * @param {HTMLElement} this_button - The button element that triggers the popover.
+ * @param {Function} generator - A function that generates the HTML content for the popover body.
+ * @param {string} text - The initial text to display in the popover's text area (optional).
+ * @param {Function} action - A callback function to be executed when the user confirms the action. Takes the value from the text area as input.
+ * @param {boolean} disabled - A flag indicating if the text area should be disabled (optional).
+*/
+
+function handle_inline_confirm(this_button, generator, text, action, disabled) {
+  this_button = $(this_button.node());
+  if (this_button.data("popover_shown") !== "shown") {
+    const popover = this_button
+      .popover({
+        sanitize: false,
+        placement: "right",
+        container: "body",
+        html: true,
+        content: generator,
+        trigger: "manual",
+      })
+      .on("shown.bs.popover", function (e) {
+        var clicked_object = d3.select(this);
+        var popover_div = d3.select(
+          "#" + clicked_object.attr("aria-describedby")
+        );
+        var textarea_element = popover_div.selectAll(
+          misc.get_ui_element_selector_by_role("priority-description-form")
+        );
+        var button_element = popover_div.selectAll(
+          misc.get_ui_element_selector_by_role("priority-description-save")
+        );
+        textarea_element.text(text);
+        if (disabled) textarea_element.attr("disabled", true);
+        button_element.on("click", (d) => {
+          action($(textarea_element.node()).val());
+          d3.event.preventDefault();
+          this_button.click();
+        });
+        button_element = popover_div.selectAll(
+          misc.get_ui_element_selector_by_role("priority-description-dismiss")
+        );
+        button_element.on("click", (d) => {
+          d3.event.preventDefault();
+          this_button.click();
+        });
+      });
+
+    popover.popover("show");
+    this_button.data("popover_shown", "shown");
+    this_button.off("hidden.bs.popover").on("hidden.bs.popover", function () {
+      $(this).data("popover_shown", "hidden");
+    });
+  } else {
+    this_button.data("popover_shown", "hidden");
+    this_button.popover("destroy");
+  }
+}
+
+/**
+ * Generates a dropdown menu for actions on a cluster of interest (COI).
+
+ * @param {Object} self - The main network visualization object.
+ * @param {Object} pg - The cluster of interest data.
+ * @returns {Array} An array of dropdown menu options.
+*/
+
+function _action_drop_down(self, pg) {
+  let dropdown = _.flatten(
+    [
+      _.map([self.subcluster_threshold, 0.015], (threshold) => ({
+        label:
+          "View this cluster of interest at link distance of " +
+          kGlobals.formats.PercentFormatShort(threshold),
+        action: function (button, value) {
+          priority_set_view(self, pg, {
+            timestamp: pg.modified || pg.created,
+            priority_set: pg,
+            "priority-edge-length": threshold,
+            title: pg.name + " @" + kGlobals.formats.PercentFormat(threshold),
+          });
+        },
+      })),
+    ],
+    true
+  );
+
+  if (!self._is_CDC_executive_mode) {
+    dropdown.push({
+      label: "Clone this cluster of interest in a new editor panel",
+      action: function (button, value) {
+        let ref_set = self.priority_groups_find_by_name(pg.name);
+        let copied_node_objects = _.clone(ref_set.node_objects);
+        priority_set_inject_node_attibutes(self, copied_node_objects, pg.nodes);
+        open_editor(
+          self,
+          copied_node_objects,
+          "",
+          "Clone of " + pg.name,
+          ref_set.kind
+        );
+        self.redraw_tables();
+      },
+    });
+    if (pg.createdBy !== "System") {
+      dropdown.push({
+        label: "Delete this cluster of interest",
+        action: function (button, value) {
+          if (confirm("This action cannot be undone. Proceed?")) {
+            self.priority_groups_remove_set(pg.name, true);
+          }
+        },
+      });
+    }
+    dropdown.push({
+      label: "View nodes in this cluster of interest",
+      data: {
+        toggle: "modal",
+        target: misc.get_ui_element_selector_by_role("cluster_list"),
+        priority_set: pg.name,
+      },
+    });
+  }
+  dropdown.push({
+    label: "Modify this cluster of interest",
+    action: function (button, value) {
+      let ref_set = self.priority_groups_find_by_name(pg.name);
+
+      if (ref_set) {
+        /*if (ref_set.modified.getTime() > self.today.getTime()) {
+          if (
+            !confirm(
+              "Editing priority sets modified after the point at which this network was created is not recommended."
+            )
+          )
+            return;
+        }*/
+        open_editor(
+          self,
+          ref_set.node_objects,
+          ref_set.name,
+          ref_set.description,
+          ref_set.kind,
+          null,
+          "update",
+          ref_set,
+          ref_set.tracking
+        );
+        self.redraw_tables();
+      }
+    },
+  });
+
+  dropdown.push({
+    label: "View history over time",
+    action: function (button, value) {
+      let ref_set = self.priority_groups_find_by_name(pg.name);
+      let report = self.generate_coi_temporal_report(ref_set);
+      let container = self.open_exclusive_tab_view_aux(
+        null,
+        "History of " + pg.name,
+        {}
+      );
+      misc.coi_timeseries(
+        report,
+        d3.select("#" + container).style("padding", "20px"),
+        1000
+      );
+    },
+  });
+
+  return dropdown;
+}
+
+/**
+ * Draws a table of priority sets (clusters of interest).
+
+ * @param {Object} self - The main network visualization object.
+ * @param {HTMLElement} container - The HTML element where the table will be displayed (optional).
+ * @param {Array} priority_groups - An array of objects representing the priority sets (optional).
+*/
+
+function draw_priority_set_table(self, container, priority_groups) {
+  container = container || self.priority_set_table;
+  if (container) {
+    priority_groups = priority_groups || self.defined_priority_groups;
+    self.priority_groups_compute_node_membership();
+    self.priority_groups_compute_overlap(priority_groups);
+    var headers = [
+      [
+        {
+          value: "Type",
+          sort: function (c) {
+            return c.value;
+          },
+          help: "How was this cluster of interest created",
+          width: 50,
+        },
+        {
+          value: "Name",
+          sort: "value",
+          filter: true,
+          width: 325,
+          text_wrap: true,
+          help: "Cluster of interest name",
+        },
+        {
+          value: "Modified/created",
+          width: 180,
+          sort: function (c) {
+            return c.value[0];
+          },
+          help: "When was the cluster of interest created/last modified",
+        },
+        {
+          value: "Growth",
+          sort: "value",
+          help: "How growth is handled",
+          width: 100,
+          //text_wrap: true
+        },
+        {
+          value: "Size",
+          width: 100,
+          presort: "desc",
+          sort: function (c) {
+            c = c.value;
+            if (c) {
+              return c[1] + (c[2] ? 1e10 : 0) + (c[3] ? 1e5 : 0);
+            }
+            return 0;
+          },
+          help: "Number of nodes in the cluster of interest",
+        },
+        {
+          value: "Priority",
+          width: 60,
+          sort: "value",
+          help: "Does the cluster of interest continue to meet priority criteria?",
+        },
+        {
+          value: "DXs in last 12 mo.",
+          width: 50,
+          sort: "value",
+          help: "The number of cases in the cluster of interest diagnosed in the past 12 months",
+        },
+        {
+          value: "Overlap",
+          width: 140,
+          sort: function (c) {
+            c = c.value;
+            if (c) {
+              return c[1];
+            }
+            return 0;
+          },
+          help: "How many other ClusterOI have overlapping nodes with this ClusterOI, and (if overlapping ClusterOI exist) how many nodes in this ClusterOI overlap with ANY other ClusterOI?",
+        },
+        /*,
+          {
+            value: "Cluster",
+            sort: "value",
+            help: "Which cluster does the node belong to"
+          }*/
+      ],
+    ];
+
+    if (self._is_CDC_auto_mode) {
+      headers[0].splice(3, 0, {
+        value: "clusterOI identification method",
+        width: 100,
+        sort: function (c) {
+          return c.value;
+        },
+        help: "Method of cluster identification",
+      });
+    }
+
+    var edit_form_generator = function () {
+      return `<form class="form"> 
+                      <div class="form-group"> 
+                          <div class="input-group">
+                          <textarea class="form-control input-sm" data-hivtrace-ui-role = "priority-description-form" cols = "40" rows = "3"></textarea>
+                          </div>
+                      </div>
+                      <button data-hivtrace-ui-role = "priority-description-dismiss" class = "btn btn-sm btn-default">Dismiss</button>
+                      <button data-hivtrace-ui-role = "priority-description-save" class = "btn btn-sm btn-default">Save</button>
+                  </form>`;
+    };
+
+    var rows = [];
+    _.each(priority_groups, (pg) => {
+      var this_row = [
+        {
+          value: pg.createdBy,
+          html: true,
+          width: 50,
+          format: (value) =>
+            pg.createdBy === kGlobals.CDCCOICreatedBySystem
+              ? '<i class="fa fa-2x fa-desktop" title="' +
+                kGlobals.CDCCOICreatedBySystem +
+                '" data-text-export=' +
+                kGlobals.CDCCOICreatedBySystem +
+                "></i>"
+              : '<i class="fa fa-2x fa-user" title="' +
+                kGlobals.CDCCOICreatedManually +
+                '" data-text-export=' +
+                kGlobals.CDCCOICreatedManually +
+                "></i>",
+        },
+        {
+          value: pg.name,
+          width: 325,
+          help:
+            pg.description +
+            (pg.pending ? " (new, pending confirmation)" : "") +
+            (pg.expanded
+              ? " (" + pg.expanded + " new nodes; pending confirmation)"
+              : ""),
+          volatile: true,
+          format: (value) =>
+            "<div style = 'white-space: nowrap; overflow: hidden; text-overflow : ellipsis;'>" +
+            (pg.autocreated || pg.autoexpanded
+              ? (pg.autoexpanded
+                  ? '<span class="label label-default">Grew</span>'
+                  : '<span class="label label-danger">New</span>') +
+                "&nbsp;<span style = 'font-weight: 900;' data-text-export = '" +
+                value +
+                "'>" +
+                value +
+                "</span>"
+              : '<span data-text-export = "' +
+                value +
+                '">' +
+                value +
+                "</span>") +
+            "</div>",
+          html: true,
+          actions: [],
+        },
+        {
+          width: 180,
+          value: [pg.modified, pg.created],
+          format: function (value) {
+            let vs = _.map(value, (v) => timeDateUtil.DateViewFormat(v));
+
+            if (vs[0] !== vs[1]) {
+              return vs[0] + " / " + vs[1];
+            }
+            return vs[0];
+          },
+        },
+        {
+          width: 100,
+          //text_wrap: true,
+          value: pg.tracking,
+          format: function (value) {
+            return kGlobals.CDCCOIConciseTrackingOptions[value];
+          },
+        },
+        {
+          value: [
+            pg.node_objects.length,
+            _.filter(pg.nodes, (g) => self.priority_groups_is_new_node(g))
+              .length,
+            pg.createdBy === kGlobals.CDCCOICreatedBySystem && pg.pending,
+            pg.meets_priority_def,
+          ],
+          width: 100,
+          format: function (v) {
+            //console.log (pg);
+            if (v) {
+              return (
+                v[0] +
+                (v[1]
+                  ? ' <span title="Number of nodes added by the system since the last network update" class="label label-default">' +
+                    v[1] +
+                    " new</span>"
+                  : "")
+              );
+            }
+            return "N/A";
+          },
+          html: true,
+        },
+        {
+          width: 60,
+          value: pg.meets_priority_def ? "Yes" : "No",
+        },
+        {
+          width: 50,
+          value: pg.last12,
+        },
+        {
+          width: 140,
+          value: [
+            pg.overlap.sets,
+            pg.overlap.nodes,
+            pg.overlap.duplicate,
+            pg.overlap.superset,
+          ],
+          format: function (v) {
+            if (v) {
+              return (
+                String(v[0]) +
+                (v[1]
+                  ? ' <span title="Number of nodes in the overlap" class="label label-default pull-right">' +
+                    v[1] +
+                    " nodes</span>"
+                  : "") +
+                (v[2].length
+                  ? ' <span title="clusterOIs which are exact duplicates of this clusterOI: ' +
+                    v[2].join(", ") +
+                    '" class="label label-danger pull-right">' +
+                    v[2].length +
+                    " duplicate clusterOI</span>"
+                  : "") +
+                (v[3].length
+                  ? ' <span title="clusterOIs which contain this clusterOI: ' +
+                    v[3].join(", ") +
+                    '" class="label label-warning pull-right">Fully contained in ' +
+                    v[3].length +
+                    " clusterOI</span>"
+                  : "")
+              );
+            }
+            return "N/A";
+          },
+          html: true,
+          actions:
+            pg.overlap.sets === 0
+              ? []
+              : [
+                  {
+                    icon: "fa-eye",
+                    dropdown: [
+                      {
+                        label: "List overlaps",
+                        data: {
+                          toggle: "modal",
+                          target:
+                            misc.get_ui_element_selector_by_role(
+                              "overlap_list"
+                            ),
+                          priority_set: pg.name,
+                        },
+                      },
+                    ],
+                  },
+                ],
+        },
+      ];
+
+      if (self._is_CDC_auto_mode) {
+        this_row.splice(3, 0, {
+          value: pg.kind,
+          width: 100,
+          format: function (v) {
+            if (v) {
+              return v;
+              //"<abbr title = '" + v + "'>" + v.split(" ")[0] + "</abbr>"
+            }
+            return "N/A";
+          },
+          html: true,
+        });
+      }
+
+      if (pg.pending) {
+        // pending user review
+        this_row[1].actions = [
+          {
+            icon: "fa-eye",
+            help: "Review and adjust this cluster of interest",
+            action: function (button, value) {
+              let nodeset = self.priority_groups_find_by_name(value);
+              if (nodeset) {
+                if (get_editor()) {
+                  alert(
+                    "Cannot confirm a cluster of interest while an editor window is open"
+                  );
+                } else {
+                  open_editor(
+                    self,
+                    nodeset.node_objects,
+                    nodeset.name,
+                    nodeset.description,
+                    nodeset.kind,
+                    null,
+                    "validate",
+                    nodeset,
+                    pg.tracking,
+                    pg.createdBy
+                  );
+                  self.redraw_tables();
+                }
+              }
+            },
+          },
+        ];
+      } else {
+        this_row[1].actions = [_.clone(this_row[1].actions)];
+        this_row[1].actions[this_row[1].actions.length - 1].splice(
+          -1,
+          0,
+          {
+            icon: "fa-info-circle",
+            classed: { "view-edit-cluster": true },
+            help: "View/edit this cluster of interest",
+            dropdown: _action_drop_down(self, pg),
+            /*action: function (button, menu_value) {
+                console.log (menu_value);
+            }*/
+          },
+          {
+            icon: "fa-edit",
+            classed: { "btn-info": true },
+            help: "Edit description",
+            action: function (this_button, cv) {
+              handle_inline_confirm(
+                this_button,
+                edit_form_generator,
+                pg.description,
+                (d) => {
+                  self.priority_groups_edit_set_description(pg.name, d, true);
+                }
+              );
+            },
+          }
+        );
+        this_row[1].actions[this_row[1].actions.length - 1].splice(
+          -1,
+          0,
+          (button_group, value) => {
+            if (get_editor()) {
+              return {
+                icon: "fa-plus",
+                help: "Add nodes in this cluster of interest to the new cluster of interest",
+                action: function (button, value) {
+                  let nodeset = self.priority_groups_find_by_name(value);
+                  if (nodeset) {
+                    get_editor().append_node_objects(nodeset.node_objects);
+                  }
+                },
+              };
+            }
+            return null;
+          }
+        );
+      }
+      this_row[1].actions = _.flatten(this_row[1].actions);
+      //console.log (this_row[0]);
+      if (pg.not_in_network.length) {
+        this_row[2]["actions"] = [
+          {
+            text: String(pg.not_in_network.length) + " removed",
+            classed: { "btn-danger": true, disabled: true },
+            help:
+              "Nodes removed from the network: " + pg.not_in_network.join(", "),
+          },
+        ];
+      }
+      rows.push(this_row);
+    });
+
+    let has_required_actions = "";
+    /* let has_automatic = self.priority_groups_pending();
+    let has_expanded = self.priority_groups_expanded();
+
+    if (has_automatic + has_expanded) {
+      let labeler = (c, description, c2) => {
+        if (c) {
+          c2 = c2 ? " and " : "";
+          return c2 + c + " " + description;
+        }
+        return "";
+      };
+
+      has_required_actions =
+        '<div class="alert alert-info">There are ' +
+        "<span style = 'color: darkred'>" + labeler(has_automatic, "automatically created") + "</span>" +
+        "<span style = 'color: orange'>" + labeler(has_expanded, "automatically expanded", has_automatic) + "</span>" +
+        ' priority sets.</div>';
+    } else {
+      has_required_actions = "";
+    }*/
+
+    tables.add_a_sortable_table(
+      container,
+      headers,
+      rows,
+      true,
+      has_required_actions +
+        `Showing <span class="badge" data-hivtrace-ui-role="table-count-shown">--</span>/<span class="badge" data-hivtrace-ui-role="table-count-total">--</span> clusters of interest.
+          <button class = "btn btn-sm btn-warning pull-right" data-hivtrace-ui-role="priority-subclusters-export">Export to JSON</button>
+          <button class = "btn btn-sm btn-primary pull-right" data-hivtrace-ui-role="priority-subclusters-export-csv">Export to CSV</button>`,
+      get_editor()
+    );
+
+    d3.select(
+      misc.get_ui_element_selector_by_role("priority-subclusters-export")
+    ).on("click", (d) => {
+      helpers.export_json_button(
+        self.priority_groups_export(),
+        timeDateUtil.DateViewFormatSlider(self.today)
+      );
+    });
+    d3.select(
+      misc.get_ui_element_selector_by_role("priority-subclusters-export-csv")
+    ).on("click", (d) => {
+      helpers.export_csv_button(
+        self.priority_groups_export_nodes(),
+        "clusters-of-interest"
+      );
+    });
+    d3.select("#priority_set_table_download").on("click", (d) => {
+      helpers.export_csv_button(
+        self.priority_groups_export_sets(),
+        "clusters_of_interest_table"
+      );
+    });
+  }
+}
+
+/**
+ * Creates a subcluster view for a specific priority set.
+
+ * @param {Object} self - The main network visualization object.
+ * @param {Object} priority_set - The priority set object.
+ * @param {Object} options - Optional configuration options for the view.
+*/
+
+function priority_set_view(self, priority_set, options) {
+  options = options || {};
+
+  let nodes = priority_set.node_objects || priority_set.network_nodes;
+  let current_time = timeDateUtil.getCurrentDate();
+  let edge_length =
+    options["priority-edge-length"] || self.subcluster_threshold;
+  let reference_date = options["timestamp"] || self.today;
+  let title =
+    options["title"] ||
+    "clusterOI " + (priority_set.prior_name || priority_set.name || "unnamed");
+  let node_dates = {};
+
+  if (priority_set.nodes) {
+    _.each(priority_set.nodes, (nd) => {
+      node_dates[nd.name] = nd.added;
+    });
+  } else {
+    _.each(priority_set.network_nodes, (nd) => {
+      node_dates[nd.id] = nd["_priority_set_date"];
+    });
+  }
+
+  let nodeDates = {};
+  if (options.priority_set && options.priority_set.nodes) {
+    _.each(options.priority_set.nodes, (d) => {
+      nodeDates[d.name] = d.added;
+    });
+  }
+
+  _.each(nodes, (d) => {
+    //console.log (d);
+    d.priority_set = 1;
+    d._added_date = d.id in nodeDates ? nodeDates[d.id] : d._priority_set_date;
+    if (d._added_date)
+      d._added_date = timeDateUtil.DateViewFormatSlider(d._added_date);
+    else d._added_date = null;
+  });
+
+  let pgDates = _.sortBy(_.keys(_.groupBy(nodes, (d) => d._added_date)));
+
+  let node_set = _.flatten(
+    hivtrace_cluster_depthwise_traversal(
+      self.json["Nodes"],
+      self.json["Edges"],
+      (e) => e.length <= edge_length,
+      null,
+      nodes
+    )
+  );
+
+  let refDate = timeDateUtil.DateViewFormat(reference_date);
+
+  let dco = "fee8c8fdbb84e34a33";
+  let defColorsOther = d3.scale
+    .ordinal()
+    .range(_.map(_.range(0, dco.length, 6), (d) => "#" + dco.substr(d, 6)));
+
+  let maxColors = 4;
+  let dcpg = "7b3294c2a5cfa6dba0008837";
+  let defColorsPG = d3.scale
+    .ordinal()
+    .range(_.map(_.range(0, dcpg.length, 6), (d) => "#" + dcpg.substr(d, 6)));
+
+  let viewEnum = [];
+  let dateID = {};
+  _.each(pgDates, (d, i) => {
+    if (d) {
+      if (pgDates.length > maxColors) {
+        if (i < pgDates.length - maxColors) {
+          dateID[d] = 0;
+          return;
+        } else if (i === pgDates.length - maxColors) {
+          dateID[d] = viewEnum.length;
+          viewEnum.push(
+            "In cluster of interest (added on or before " + d + ")"
+          );
+          return;
+        }
+      }
+      dateID[d] = viewEnum.length;
+      viewEnum.push("In cluster of interest (added " + d + ")");
+    }
+  });
+
+  let priorityColorOffset = viewEnum.length;
+
+  viewEnum.push("Diagnosed and in network before " + refDate);
+  viewEnum.push(
+    "Diagnosed or in network on or after " +
+      refDate +
+      " [directly linked to cluster of interest]"
+  );
+  viewEnum.push(
+    "Diagnosed or in network on or after " +
+      refDate +
+      " [indirectly linked to cluster of interest]"
+  );
+  let viewEnumMissing = [...viewEnum, kGlobals.missing.label];
+
+  let viewEnumMissingColors = _.map(viewEnumMissing, (d, i) => {
+    if (d !== kGlobals.missing.label) {
+      if (i < priorityColorOffset) {
+        return defColorsPG(d);
+      }
+      return defColorsOther(d);
+    }
+    return "gray";
+  });
+
+  self
+    .view_subcluster(
+      -1,
+      node_set,
+      title,
+      {
+        skip_recent_rapid: true,
+        init_code: function (network) {
+          _.each(network.json.Edges, (e) => {
+            let other_node = null;
+            if (network.json.Nodes[e.target].priority_set === 1) {
+              other_node = network.json.Nodes[e.source];
+            } else if (network.json.Nodes[e.source].priority_set === 1) {
+              other_node = network.json.Nodes[e.target];
+            }
+            if (other_node && other_node.priority_set !== 1) {
+              other_node.priority_set = 2; // directly linked to a priority set node
+            }
+          });
+        },
+        "computed-attributes": {
+          date_added: {
+            depends: [timeDateUtil._networkCDCDateField],
+            label: "Date added to cluster of interest",
+            type: "Date",
+            map: function (node) {
+              return node.id in node_dates
+                ? node_dates[node.id]
+                : kGlobals.missing.label;
+            },
+          },
+          priority_set: {
+            depends: [timeDateUtil._networkCDCDateField],
+            label: "Cluster of Interest Status",
+            enum: viewEnum,
+            type: "String",
+            map: function (node) {
+              //console.log ("PS", node.id, node.priority_set);
+              if (node.priority_set === 1) {
+                if (node._added_date) {
+                  return viewEnum[dateID[node._added_date]];
+                }
+                return viewEnum[0];
+              }
+              if (
+                self.filter_by_date(
+                  reference_date,
+                  timeDateUtil._networkCDCDateField,
+                  current_time,
+                  node,
+                  true
+                )
+              ) {
+                if (node.priority_set === 2) {
+                  return viewEnum[priorityColorOffset + 1];
+                }
+                return viewEnum[priorityColorOffset + 2];
+              }
+              return viewEnum[priorityColorOffset];
+            },
+            color_scale: function () {
+              return d3.scale
+                .ordinal()
+                .domain(viewEnumMissing)
+                .range(viewEnumMissingColors);
+            },
+          },
+        },
+      },
+      null,
+      null,
+      edge_length
+    )
+    .handle_attribute_categorical("priority_set");
+
+  _.each(nodes, (d) => {
+    delete d.priority_set;
+  });
+}
+
+/**
+ * Adds a new priority set to the network visualization.
+
+ * @param {Object} self - The main network visualization object.
+ * @param {Object} nodeset - The object representing the new priority set.
+ * @param {boolean} update_table - Flag indicating whether to update the priority set table. (optional)
+ * @param {boolean} not_validated - Flag indicating whether to perform validation before adding. (optional)
+ * @param {string} prior_name - Optional name of an existing priority set to replace.
+ * @param {string} op_code - Optional operation code (defaults to "insert").
+
+ * @returns {boolean} True if the set was added successfully, false otherwise.
+*/
+
+function priority_groups_add_set(
+  self,
+  nodeset,
+  update_table,
+  not_validated,
+  prior_name,
+  op_code
+) {
+  function check_dup() {
+    if (
+      nodeset.name[0] === " " ||
+      nodeset.name[nodeset.name.length - 1] === " "
+    ) {
+      alert(
+        "Cluster of interest '" +
+          nodeset.name +
+          "' has spaces either at the beginning or end of the name. Secure HIV-TRACE does not allow names that start or end with spaces."
+      );
+      return true;
+    }
+    let my_nodes = new Set(_.map(nodeset.nodes, (d) => d.name));
+    return _.some(self.defined_priority_groups, (d) => {
+      if (d.nodes.length === my_nodes.size) {
+        const same_nodes =
+          d.nodes.filter((x) => my_nodes.has(x.name)).length === d.nodes.length;
+        if (same_nodes && d.tracking === nodeset.tracking) {
+          alert(
+            "Cluster of interest '" +
+              d.name +
+              "' has the same set of nodes and the same growth criterion as this new cluster of interest. Secure HIV-TRACE does not allow creating exact duplicates of clusters of interest."
+          );
+          return true;
+        } else if (same_nodes) {
+          let keep_duplicate = confirm(
+            "Warning! Cluster of interest '" +
+              d.name +
+              "' has the same set of nodes as this cluster of interest, but a different growth criterion'. Click 'OK' to create, or 'Cancel' to abort."
+          );
+          let is_duplicate = !keep_duplicate;
+          return is_duplicate;
+        }
+      }
+      return false;
+    });
+  }
+
+  op_code = op_code || "insert";
+  if (not_validated) {
+    self.priority_groups_validate([nodeset]);
+  }
+  if (prior_name) {
+    let prior_index = _.findIndex(
+      self.defined_priority_groups,
+      (d) => d.name === prior_name
+    );
+    if (prior_index >= 0) {
+      if (prior_name !== nodeset.name) {
+        self.priority_groups_update_node_sets(prior_name, "delete");
+        op_code = "insert";
+      }
+      self.defined_priority_groups[prior_index] = nodeset;
+    } else {
+      if (check_dup()) return false;
+      self.defined_priority_groups.push(nodeset);
+    }
+  } else {
+    if (check_dup()) return false;
+    self.defined_priority_groups.push(nodeset);
+  }
+  self.priority_groups_update_node_sets(nodeset.name, op_code);
+
+  if (update_table) {
+    draw_priority_set_table(self);
+  }
+
+  return true;
+}
+
+/**
+ * Injects priority set related attributes into network nodes.
+
+ * @param {Object} self - The main network visualization object.
+ * @param {Array} nodes - Array of network nodes.
+ * @param {Array} node_attributes - Array of priority set attributes for specific nodes (identified by name).
+*/
+
+function priority_set_inject_node_attibutes(self, nodes, node_attributes) {
+  let attr_by_id = {};
+  _.each(node_attributes, (n, i) => {
+    attr_by_id[n.name] = {
+      _priority_set_date: n.added || self.today,
+      _priority_set_kind: n.kind || kGlobals.CDCCOINodeKindDefault,
+      _priority_set_autoadded: n.autoadded || false,
+    };
+  });
+  _.each(nodes, (n) => {
+    if (n.id in attr_by_id) {
+      _.extend(n, attr_by_id[n.id]);
+    }
+  });
+}
+
+/**
+ * Gets the current priority set editor object.
+
+ * @returns {Object} The priority set editor object, or null if not open.
+ */
+
+function get_editor() {
+  return priority_set_editor;
+}
+
+export {
+  init,
+  open_editor,
+  priority_set_view,
+  draw_priority_set_table,
+  priority_set_inject_node_attibutes,
+  get_editor,
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/colorPicker.js.html b/docs/colorPicker.js.html new file mode 100644 index 0000000..c709d62 --- /dev/null +++ b/docs/colorPicker.js.html @@ -0,0 +1,109 @@ + + + + + JSDoc: Source: colorPicker.js + + + + + + + + + + +
+ +

Source: colorPicker.js

+ + + + + + +
+
+
/**
+ * Creates a color picker input element with a label.
+
+ * @param {string} id - The ID for the color picker input element.
+ * @param {Function} colorizer - A colorizer function that maps values to colors.
+
+ * @returns {string} The HTML markup for the color picker input element with the label.
+ */
+
+function colorPickerInput(id, colorizer) {
+  // set onchange event after template is rendered and returned from this function.
+  let colorPicker = `<div class="col-lg-2 hivtrace-color-picker">
+    <input type="color" name="${id}" value="${colorizer.category(id)}">
+    <label for="${id}">${id}</label>
+  </div>`;
+
+  return colorPicker;
+}
+
+/**
+ * Creates a color picker input element with a label for continuous values.
+
+ * @param {string} id - The ID for the color picker input element.
+ * @param {string} color - The initial color value for the color picker.
+
+ * @returns {string} The HTML markup for the color picker input element with the label.
+*/
+
+function colorPickerInputContinuous(id, color) {
+  // set onchange event after template is rendered and returned from this function.
+  let colorPicker = `<div class="col-lg-2 hivtrace-color-picker">
+    <input type="color" name="${id.toLowerCase()}" value="${color}">
+    <label for="${id.toLowerCase()}">${id}</label>
+  </div>`;
+
+  return colorPicker;
+}
+
+/**
+ * Creates a color stop input element with a label.
+
+ * @param {string} id - The ID for the color stop input element.
+ * @param {number} number - The initial value for the color stop.
+
+ * @returns {string} The HTML markup for the color stop input element with the label.
+*/
+
+function colorStops(id, number) {
+  // set onchange event after template is rendered and returned from this function.
+  let colorStops = `<div class="col-lg-2 hivtrace-color-stops">
+    <label for="color-stop">${id}</label>
+    <input type="number" name="color-stop" value="${number}" min="0" max="20"">
+  </div>`;
+
+  return colorStops;
+}
+
+export { colorPickerInput, colorPickerInputContinuous, colorStops };
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/column_definitions.js.html b/docs/column_definitions.js.html new file mode 100644 index 0000000..459295a --- /dev/null +++ b/docs/column_definitions.js.html @@ -0,0 +1,382 @@ + + + + + JSDoc: Source: column_definitions.js + + + + + + + + + + +
+ +

Source: column_definitions.js

+ + + + + + +
+
+
/**
+    A collection of table column definitions 
+*/
+
+var d3 = require("d3"),
+  _ = require("underscore"),
+  clustersOfInterest = require("./clustersOfInterest.js"),
+  HTX = require("./hiv_tx_network.js"),
+  kGlobals = require("./globals.js");
+
+/**
+    Column definitions for rendered tables
+    Each column definition is object-based and has the following components
+    
+    description:  [this relates to the heading]   
+        value (text): the displayed name of the column
+        sort (function): a function which takes the value associated with the table cell, and returns a value upon which to sort the column
+        help (text):  the text to display in a popover when the user hovers over the column name
+    generator: 
+        a function that returns a data-driven definition of a cell
+        it takes as an argument the value that is associated with a cell
+        and returns an object with the following values
+            
+            html (bool): whether or not the returned value should be rendered as HTML (default is no, i.e. text)
+            value: what is the value associated with the cell
+            volatile (bool): if set, this cell will be re-rendered under operations which could modify how its displayed (e.g. is a CoI editor open)
+            format (function): how to render the cell value
+            actions (function): generate context-specific menus for the cell
+                                returns null (none) or a vector (definitions of actions)
+                                
+                    An action is an object with the following fields
+                        icon (text): use this font awesome icon 
+                        action (function): a function that takes the clicked button and the cell value and does something
+                        help (text): the help message to display on hover over the button
+                
+        
+*/
+
+/**
+ * Defines secure column definitions for HIV Trace subcluster data.
+
+ * @param {Object} self (optional) - The object containing context for calculations (presumably the component using this function).
+
+ * @returns {Array<Object>} An array of column definition objects. Each object has the following properties:
+ *   - `description`:
+ *     - `value`: (string) The human-readable name of the column.
+ *     - `sort`: (function) A function used to sort the column data.
+ *     - `presort` (string, optional): The default sort direction ("asc" or "desc").
+ *     - `help`: (string) Help text displayed when hovering over the column header.
+ *   - `generator`: (function) A function that generates the value and actions for each cluster based on the provided cluster object.
+ *     - The generator function receives the cluster object as an argument.
+ *     - It should return an object with the following properties:
+ *       - `html`: (boolean) Whether the column value should be rendered as HTML.
+ *       - `value`: (array|string) The actual data for the column.
+ *       - `volatile`: (boolean, optional) Whether the value needs to be recalculated frequently.
+ *       - `format`: (function, optional) A function used to format the column value for display.
+ *       - `actions`: (function, optional) A function used to generate actions for the column.
+ *         - The actions function receives two arguments:
+ *           - `item`: (object) The current cluster object.
+ *           - `value`: (array|string) The value of the column for the current cluster.
+ *         - It should return an array of action objects, each with the following properties:
+ *           - `icon`: (string) The icon class name to display for the action.
+ *           - `action`: (function) The function executed when the action is clicked.
+ *             - The action function receives two arguments:
+ *               - `button`: (jQuery object) The button element representing the action.
+ *               - `v`: (array|string) The value of the column for the current cluster.
+ *           - `help`: (string) The help text displayed when hovering over the action icon.
+ */
+
+function secure_hiv_trace_subcluster_columns(self) {
+  return [
+    /** definition for the column which shows the #of cases dx'ed within 36 months
+         the value is an array, which enumerates the number of connected components of the 0.5% subcluster, which are ALL within 36 month dx, 
+         so can be more than one.
+         
+         The only action is to add the nodes in this subcluster to a CoI editor if open 
+         
+         Accepts a _self_ argument for transitive closure
+         
+       */
+    {
+      description: {
+        value: "Cases dx within 36 months",
+        sort: function (c) {
+          return c.value.length ? c.value[0].length : 0;
+        },
+        help: "Number of cases diagnosed in the past 36 months connected only through cases diagnosed within the past 36 months",
+      },
+      generator: function (cluster) {
+        return {
+          html: true,
+          value: cluster.recent_nodes,
+          volatile: true,
+          format: function (v) {
+            v = v || [];
+            if (v.length) {
+              return _.map(v, (e) => e.length).join(", ");
+            }
+            return "";
+          },
+          actions: function (item, value) {
+            if (
+              !clustersOfInterest.get_editor() ||
+              cluster.recent_nodes.length === 0
+            ) {
+              return null;
+            }
+            return _.map(cluster.recent_nodes, (c) => {
+              const nodeset = new Set(c);
+              return {
+                icon: "fa-plus",
+                action: function (button, v) {
+                  if (clustersOfInterest.get_editor()) {
+                    clustersOfInterest
+                      .get_editor()
+                      .append_node_objects(
+                        _.filter(
+                          cluster.children,
+                          (n) => nodeset.has(n.id) && n.priority_flag > 0
+                        )
+                      );
+                  }
+                  return false;
+                },
+                help: "Add to cluster of interest",
+              };
+            });
+          },
+        };
+      },
+    },
+
+    /** definition for the column which shows the #of cases dx'ed within 12 months
+         the value is an array, which enumerates the number of connected components of the 0.5% subcluster, which connect through nodes dx'ed 36 month dx, so can be more than one.
+         
+         The actions are to add the nodes in this subcluster to a CoI editor if open, and to determine if the nodes in this set are already a part of the CoI.
+         
+       */
+
+    {
+      description: {
+        value: "Cases dx within 12 months",
+        //"value",
+        sort: function (c) {
+          const v = c.value || [];
+          return v.length > 0 ? v[0].length : 0;
+        },
+        presort: "desc",
+        help: "Number of cases diagnosed in the past 12 months connected only through cases diagnosed within the past 36 months",
+      },
+      generator: function (cluster) {
+        const definition = {
+          html: true,
+          value: cluster.priority_score,
+          volatile: true,
+          format: function (v) {
+            v = v || [];
+            if (v.length) {
+              var str = _.map(v, (c) => c.length).join(", ");
+              if (
+                v[0].length >= self.CDC_data["autocreate-priority-set-size"]
+              ) {
+                var color = "red";
+                return "<span style='color:" + color + "'>" + str + "</span>";
+              }
+              return str;
+            }
+            return "";
+          },
+        };
+
+        definition["actions"] = function (item, value) {
+          let result = [];
+
+          if (cluster.priority_score.length > 0) {
+            result = result.concat(
+              _.map(cluster.priority_score, (c) => ({
+                icon: "fa-question",
+                help:
+                  "Do some of these " +
+                  c.length +
+                  " nodes belong to a cluster of interest?",
+                action: function (this_button, cv) {
+                  const nodeset = new Set(c);
+                  this_button = $(this_button.node());
+                  if (this_button.data("popover_shown") !== "shown") {
+                    const popover = this_button
+                      .popover({
+                        sanitize: false,
+                        placement: "right",
+                        container: "body",
+                        html: true,
+                        content: HTX.HIVTxNetwork.lookup_form_generator,
+                        trigger: "manual",
+                      })
+                      .on("shown.bs.popover", function (e) {
+                        var clicked_object = d3.select(this);
+                        var popover_div = d3.select(
+                          "#" + clicked_object.attr("aria-describedby")
+                        );
+                        var list_element = popover_div.selectAll(
+                          self.get_ui_element_selector_by_role(
+                            "priority-membership-list",
+                            true
+                          )
+                        );
+
+                        list_element.selectAll("li").remove();
+                        let check_membership = _.filter(
+                          _.map(self.defined_priority_groups, (g) =>
+                            //console.log(g);
+                            [
+                              g.name,
+                              _.filter(g.nodes, (n) => nodeset.has(n.name))
+                                .length,
+                              _.filter(
+                                g.partitioned_nodes[1]["new_direct"],
+                                (n) => nodeset.has(n.id)
+                              ).length,
+                              _.filter(
+                                g.partitioned_nodes[1]["new_indirect"],
+                                (n) => nodeset.has(n.id)
+                              ).length,
+                            ]
+                          ),
+                          (gg) => gg[1] + gg[2] + gg[3] > 0
+                        );
+
+                        if (check_membership.length === 0) {
+                          check_membership = [
+                            [
+                              "No nodes belong to any cluster of interest or are linked to any of the clusters of interest.",
+                            ],
+                          ];
+                        } else {
+                          check_membership = _.map(check_membership, (m) => {
+                            let description = "";
+                            if (m[1]) {
+                              description += " " + m[1] + " nodes belong";
+                            }
+                            if (m[2]) {
+                              description +=
+                                (description.length ? ", " : " ") +
+                                m[2] +
+                                " nodes are directly linked @ " +
+                                kGlobals.formats.PercentFormatShort(
+                                  self.subcluster_threshold
+                                );
+                            }
+                            if (m[3]) {
+                              description +=
+                                (description.length ? ", " : " ") +
+                                m[3] +
+                                " nodes are indirectly linked @ " +
+                                kGlobals.formats.PercentFormatShort(
+                                  self.subcluster_threshold
+                                );
+                            }
+
+                            description +=
+                              " to cluster of interest <code>" +
+                              m[0] +
+                              "</code>";
+                            return description;
+                          });
+                        }
+                        list_element = list_element
+                          .selectAll("li")
+                          .data(check_membership);
+                        list_element.enter().insert("li");
+                        list_element.html((d) => d);
+                      });
+
+                    popover.popover("show");
+                    this_button.data("popover_shown", "shown");
+                    this_button
+                      .off("hidden.bs.popover")
+                      .on("hidden.bs.popover", function () {
+                        $(this).data("popover_shown", "hidden");
+                      });
+                  } else {
+                    this_button.data("popover_shown", "hidden");
+                    this_button.popover("destroy");
+                  }
+                },
+              }))
+            );
+          }
+
+          if (
+            clustersOfInterest.get_editor() &&
+            cluster.priority_score.length > 0
+          ) {
+            result = result.concat(
+              _.map(cluster.priority_score, (c) => {
+                const nodeset = new Set(c);
+                return {
+                  icon: "fa-plus",
+                  action: function (button, v) {
+                    if (clustersOfInterest.get_editor()) {
+                      clustersOfInterest
+                        .get_editor()
+                        .append_node_objects(
+                          _.filter(
+                            cluster.children,
+                            (n) =>
+                              nodeset.has(n.id) &&
+                              (n.priority_flag === 2 || n.priority_flag === 1)
+                          )
+                        );
+                    }
+                    return false;
+                  },
+                  help: "Add to cluster of interest",
+                };
+              })
+            );
+          }
+
+          return result;
+        };
+
+        return definition;
+      },
+    },
+  ];
+}
+
+module.exports = {
+  secure_hiv_trace_subcluster_columns,
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/fonts/OpenSans-Bold-webfont.eot b/docs/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..5d20d916338a5890a033952e2e07ba7380f5a7d3 GIT binary patch literal 19544 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 literal 0 HcmV?d00001 diff --git a/docs/fonts/OpenSans-Bold-webfont.svg b/docs/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 0000000..3ed7be4 --- /dev/null +++ b/docs/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Bold-webfont.woff b/docs/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..1205787b0ed50db71ebd4f8a7f85d106721ff258 GIT binary patch literal 22432 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 ig3W + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-BoldItalic-webfont.woff b/docs/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..ed760c0628b6a0026041f5b8bba466a0471fd2e0 GIT binary patch literal 23048 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Italic-webfont.woff b/docs/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..ff652e64356b538c001423b6aedefcf1ee66cd17 GIT binary patch literal 23188 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 literal 0 HcmV?d00001 diff --git a/docs/fonts/OpenSans-Light-webfont.svg b/docs/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 0000000..11a472c --- /dev/null +++ b/docs/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Light-webfont.woff b/docs/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..e786074813a27d0a7a249047832988d5bf0fe756 GIT binary patch literal 22248 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 literal 0 HcmV?d00001 diff --git a/docs/fonts/OpenSans-LightItalic-webfont.eot b/docs/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..8f445929ffb03b50e98c2a2f7d831a0cb1b276a2 GIT binary patch literal 20535 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 Z%0#`NexefPFV?Xj51H#Y#AC7WXn+Jg($4?@ literal 0 HcmV?d00001 diff --git a/docs/fonts/OpenSans-LightItalic-webfont.svg b/docs/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 0000000..431d7e3 --- /dev/null +++ b/docs/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-LightItalic-webfont.woff b/docs/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..43e8b9e6cc061ff17fd2903075cbde12715512b3 GIT binary patch literal 23400 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 + + -
+ -
- -
- - + +

Requires

- +
    +
  • module:lodash
  • + +
  • module:hivtrace_generate_svg_polygon_lookup
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ Documentation generated by JSDoc 4.0.3 on Wed Oct 09 2024 12:14:37 GMT-0700 (Pacific Daylight Time) +
- - - - - - - - - - - - - - - - + + + + \ No newline at end of file diff --git a/docs/img/glyphicons-halflings-white.png b/docs/img/glyphicons-halflings-white.png deleted file mode 100644 index 3bf6484a29d8da269f9bc874b25493a45fae3bae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8777 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 B7G?kd diff --git a/docs/img/glyphicons-halflings.png b/docs/img/glyphicons-halflings.png deleted file mode 100644 index a9969993201f9cee63cf9f49217646347297b643..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12799 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 diff --git a/docs/index.html b/docs/index.html index 0f93f81..1ce7306 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,585 +1,65 @@ - - - - - Documentation Index + + + JSDoc: Home + + - - - - - - - - -
-
-
-
-
-
-

hivtrace-viz

-

- This repository contains the visualization code for HIV-TRACE. -

-

Dependencies

-
    -
  • Yarn or NPM
  • -
-

Development

-
git clone https://github.com/veg/hivtrace-viz.git
-cd hivtrace-viz
-yarn
-yarn develop
-
-

Navigate your browser to localhost:8273

-

Deployment

-

- The HIV-Trace webpage was formerly hosted using github-pages - at https://veg.github.io/hivtrace-viz/ but has been migrated - to using a pm2 process at hivtrace-viz.hyphy.org (see - veg/operations documentation for details). -

-

- The master branch of this repo should always be in sync with - what is published to NPM and is live on the production - website. With the exception of urgent bug fixes, all changes - to veg/master should be done via pull requests from - veg/develop. -

-
-
-
-
- -
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - + + + + + + +
+ +

Home

+ + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.3 on Wed Oct 09 2024 12:14:37 GMT-0700 (Pacific Daylight Time) +
+ + + + + \ No newline at end of file diff --git a/docs/misc.js.html b/docs/misc.js.html new file mode 100644 index 0000000..99d189a --- /dev/null +++ b/docs/misc.js.html @@ -0,0 +1,1216 @@ + + + + + JSDoc: Source: misc.js + + + + + + + + + + +
+ +

Source: misc.js

+ + + + + + +
+
+
var d3 = require("d3"),
+  _ = require("underscore"),
+  helpers = require("./helpers.js");
+
+var hivtrace_generate_svg_polygon_lookup = {};
+
+_.each(_.range(3, 20), (d) => {
+  var angle_step = (Math.PI * 2) / d;
+  hivtrace_generate_svg_polygon_lookup[d] = _.map(_.range(1, d), (i) => [
+    Math.cos(angle_step * i),
+    Math.sin(angle_step * i),
+  ]);
+});
+
+/**
+ * Creates and returns an SVG polygon generator.
+ *
+ * @constructor
+ * @returns {Object} An object with methods to generate and manipulate an SVG polygon.
+ * @property {function} polygon - Generates the SVG path for the polygon.
+ * @property {function} sides - Gets or sets the number of sides of the polygon.
+ *   When called with a number > 2, sets the sides and returns the polygon generator.
+ *   When called without arguments, returns the current number of sides.
+ * @property {function} type - Returns the polygon generator function.
+ * @property {function} size - Gets or sets the size of the polygon.
+ *   When called with a number, sets the size and returns the polygon generator.
+ *   When called without arguments, returns the current size.
+ *
+ * @example
+ * const polygonGenerator = hivtrace_generate_svg_polygon();
+ * const path = polygonGenerator();
+ * polygonGenerator.sides(8);
+ * polygonGenerator.size(100);
+ *
+ * @requires lodash
+ * @requires hivtrace_generate_svg_polygon_lookup
+ */
+
+function hivtrace_generate_svg_polygon() {
+  var self = this;
+
+  self.polygon = function () {
+    var path = " M" + self.radius + " 0";
+
+    if (self.sides in hivtrace_generate_svg_polygon_lookup) {
+      path += hivtrace_generate_svg_polygon_lookup[self.sides]
+        .map(
+          (value) =>
+            " L" + self.radius * value[0] + " " + self.radius * value[1]
+        )
+        .join(" ");
+    } else {
+      var angle_step = (Math.PI * 2) / self.sides,
+        current_angle = 0;
+      for (let i = 0; i < self.sides - 1; i++) {
+        current_angle += angle_step;
+        path +=
+          " L" +
+          self.radius * Math.cos(current_angle) +
+          " " +
+          self.radius * Math.sin(current_angle);
+      }
+    }
+
+    path += " Z";
+    return path;
+  };
+
+  self.polygon.sides = function (attr) {
+    if (_.isNumber(attr) && attr > 2) {
+      self.sides = attr;
+      return self.polygon;
+    }
+
+    return self.sides;
+  };
+
+  self.polygon.type = function () {
+    return self.polygon;
+  };
+
+  self.polygon.size = function (attr) {
+    if (_.isNumber(attr)) {
+      self.size = attr;
+      self.radius = Math.sqrt(attr / Math.PI);
+      return self.polygon;
+    }
+
+    return self.size;
+  };
+
+  self.polygon.size(64);
+  self.sides = 6;
+
+  return self.polygon;
+}
+
+/**
+ * Generates an SVG symbol based on the specified type.
+ *
+ * @param {string} type - The type of symbol to generate.
+ *   Possible values are:
+ *   - "circle"
+ *   - "cross"
+ *   - "diamond"
+ *   - "square"
+ *   - "triangle-down"
+ *   - "triangle-up"
+ *   - "triangle"
+ *   - "pentagon"
+ *   - "hexagon"
+ *   - "septagon"
+ *   - "octagon"
+ *   - "ellipse"
+ *
+ * @returns {Object} A D3 symbol generator or a custom polygon/ellipse generator.
+ *   - For "circle", "cross", "diamond", "square", "triangle-down", "triangle-up":
+ *     Returns a D3 symbol generator of the specified type.
+ *   - For "triangle", "pentagon", "hexagon", "septagon", "octagon":
+ *     Returns a custom polygon generator with the specified number of sides.
+ *   - For "ellipse":
+ *     Returns a custom ellipse generator.
+ *   - For any other input:
+ *     Returns a D3 symbol generator of type "circle" as default.
+ *
+ * @requires d3
+ * @requires hivtrace_generate_svg_polygon
+ * @requires hivtrace_generate_svg_ellipse
+ */
+
+function hivtrace_generate_svg_symbol(type) {
+  switch (type) {
+    case "circle":
+    case "cross":
+    case "diamond":
+    case "square":
+    case "triangle-down":
+    case "triangle-up":
+      return d3.svg.symbol().type(type);
+    case "triangle":
+      return new hivtrace_generate_svg_polygon().sides(3);
+    case "pentagon":
+      return new hivtrace_generate_svg_polygon().sides(5);
+    case "hexagon":
+      return new hivtrace_generate_svg_polygon().sides(6);
+    case "septagon":
+      return new hivtrace_generate_svg_polygon().sides(7);
+    case "octagon":
+      return new hivtrace_generate_svg_polygon().sides(8);
+    case "ellipse":
+      return new hivtrace_generate_svg_ellipse();
+    default:
+      return d3.svg.symbol().type("circle");
+  }
+}
+
+/**
+ * Computes the degree of each node in a graph.
+ *
+ * @param {Object} obj - The graph object containing nodes and edges.
+ * @param {Object} obj.Nodes - An object representing the nodes of the graph.
+ * @param {Object} obj.Edges - An object representing the edges of the graph.
+ * @param {string} obj.Edges[].source - The source node of an edge.
+ * @param {string} obj.Edges[].target - The target node of an edge.
+ *
+ * @description
+ * This function modifies the input object by adding a 'degree' property to each node.
+ * The degree of a node is the number of edges connected to it.
+ *
+ * @example
+ * const graph = {
+ *   Nodes: {
+ *     "1": {},
+ *     "2": {}
+ *   },
+ *   Edges: {
+ *     "e1": { source: "1", target: "2" }
+ *   }
+ * };
+ * hivtrace_compute_node_degrees(graph);
+ * // graph.Nodes["1"].degree === 1
+ * // graph.Nodes["2"].degree === 1
+ */
+
+function hivtrace_compute_node_degrees(obj) {
+  var nodes = obj.Nodes,
+    edges = obj.Edges;
+
+  for (var n in nodes) {
+    nodes[n].degree = 0;
+  }
+
+  for (var e in edges) {
+    nodes[edges[e].source].degree++;
+    nodes[edges[e].target].degree++;
+  }
+}
+
+/**
+ * Creates a download button for exporting table data to a text file.
+ *
+ * @param {string} parent_id - The selector for the parent element where the button will be appended.
+ * @param {string} table_id - The selector for the table to be exported.
+ * @param {boolean} csv - If true, exports as CSV; if false, exports as TSV.
+ * @param {string} [file_name_placeholder] - The base name for the exported file. If not provided, it defaults to the table_id without the first character.
+ * @returns {d3.Selection} The D3 selection of the created button.
+ *
+ * @requires d3
+ * @requires helpers
+ *
+ * @description
+ * This function creates a download button that, when clicked, exports the data from the specified table
+ * as either a CSV or TSV file. It uses D3 for DOM manipulation and assumes the existence of a `helpers`
+ * object with `table_to_text` and `export_handler` methods.
+ *
+ * @example
+ * hiv_trace_export_table_to_text("#parent-div", "#data-table", true, "export-data");
+ */
+
+function hiv_trace_export_table_to_text(
+  parent_id,
+  table_id,
+  csv,
+  file_name_placeholder
+) {
+  var the_button = d3.select(parent_id);
+  the_button.selectAll("[data-type='download-button']").remove();
+
+  the_button = the_button
+    .append("a")
+    .attr("target", "_blank")
+    .attr("data-type", "download-button")
+    .on("click", function (data, element) {
+      d3.event.preventDefault();
+      var table_tag = d3.select(this).attr("data-table");
+      var table_text = helpers.table_to_text(table_tag, csv ? "," : "\t");
+      file_name_placeholder = file_name_placeholder || table_tag.substring(1);
+      if (!csv) {
+        helpers.export_handler(
+          table_text,
+          file_name_placeholder + ".tsv",
+          "text/tab-separated-values"
+        );
+      } else {
+        helpers.export_handler(
+          table_text,
+          file_name_placeholder + ".csv",
+          "text/comma-separated-values"
+        );
+      }
+    })
+    .attr("data-table", table_id);
+
+  the_button.append("i").classed("fa fa-download fa-2x", true);
+  return the_button;
+}
+
+/**
+ * Generates a time series visualization for a cluster of interest (COI).
+ *
+ * @param {Object} cluster - The cluster object containing node and event information.
+ * @param {Object} cluster.node_info - Information about nodes in the cluster.
+ * @param {Object} cluster.event_info - Information about events in the cluster.
+ * @param {d3.Selection} element - The D3 selection of the element where the visualization will be rendered.
+ * @param {number} [plot_width=1000] - The width of the plot in pixels.
+ *
+ * @description
+ * This function creates a detailed time series visualization for a cluster of interest (COI).
+ * It displays nodes and events over time, with interactive features for highlighting
+ * and displaying additional information.
+ *
+ * The visualization includes:
+ * - A time axis
+ * - Lines representing nodes
+ * - Circles representing events
+ * - Interactive highlighting and tooltips
+ * - Time range boxes for context
+ *
+ * @requires d3
+ * @requires lodash
+ *
+ * @example
+ * const cluster = {
+ *   node_info: {...},
+ *   event_info: {...}
+ * };
+ * const element = d3.select("#visualization-container");
+ * hivtrace_coi_timeseries(cluster, element, 1200);
+ */
+
+function hivtrace_coi_timeseries(cluster, element, plot_width) {
+  const margin = { top: 30, right: 60, bottom: 10, left: 120 };
+  const formatTime = d3.time.format("%Y-%m-%d");
+  let data = _.sortBy(
+    _.map(cluster.node_info, (d) => [d[0], formatTime.parse(d[1])]),
+    (d) => d[1]
+  );
+  const barHeight = 15;
+  const height =
+    Math.ceil((data.length + 0.1) * barHeight) + margin.top + margin.bottom;
+  const events = _.map(cluster.event_info, (d, i) => [i, formatTime.parse(i)]);
+  const x_range = d3.extent(
+    _.map(data, (d) => d[1]).concat(_.map(events, (d) => d[1]))
+  );
+
+  plot_width = plot_width || 1000;
+
+  let x = d3.time
+    .scale()
+    .domain(x_range)
+    .rangeRound([margin.left, plot_width - margin.right]);
+
+  let y = d3.scale
+    .ordinal()
+    .domain(d3.range(data.length + 1))
+    .rangeRoundPoints([margin.top, height - margin.bottom], 0.1);
+
+  let x_axis_object = d3.svg
+    .axis()
+    .scale(x)
+    .orient("top")
+    .ticks(plot_width / 80)
+    .tickFormat(d3.time.format("%m/%y"));
+
+  element.selectAll("svg").remove();
+
+  const svg = element
+    .append("svg")
+    .attr("width", plot_width)
+    .attr("height", height)
+    .attr("viewBox", [0, 0, plot_width, height]);
+
+  svg
+    .append("g")
+    .attr("transform", "translate(0," + 0.6 * margin.top + ")")
+    .attr("class", "y time_axis")
+    //.style ("shape-rendering","crispEdges").style ("font-family", "sans-serif").style ("font-size","8").style ("fill", "none").style("stroke","black")
+    .call(x_axis_object)
+    .call((g) => g.select(".domain").remove());
+
+  svg
+    .append("g")
+    .attr("stroke", "#ddd")
+    .attr("stroke-width", 2)
+    .attr("opacity", 0.8)
+    .selectAll("line")
+    .data(events)
+    .enter()
+    .append("line")
+    .attr("x1", (d) => x(d[1]))
+    .attr("x2", (d) => x(d[1]))
+    .attr("y1", (d, i) => y(0))
+    .attr("y2", (d, i) => y(data.length));
+
+  let lines = svg
+    .append("g")
+    .selectAll("line")
+    .data(data)
+    .enter()
+    .append("line")
+    .attr("stroke", "#aaa")
+    .attr("stroke-width", 2)
+    .attr("x1", (d) => x(x_range[1]))
+    .attr("x2", (d) => x(d[1]))
+    .attr("y1", (d, i) => y(i))
+    .attr("y2", (d, i) => y(i));
+
+  let time_boxes = [null, null];
+  let highlight_nodes = new Set();
+
+  let titles = data.concat([["Nat'l priority", x_range[0]]]);
+  let text_labels = svg
+    .append("g")
+    .attr("font-family", "sans-serif")
+    .attr("font-size", 10)
+    .attr("font-weight", 700)
+    .selectAll("text")
+    .data(titles)
+    .enter()
+    .append("text")
+    .attr("text-anchor", "end")
+    .attr("x", (d) => x(d[1]))
+    .attr("y", (d, i) => y(i) + y.rangeBand() / 2)
+    .attr("dy", "0.35em")
+    .attr("dx", "-0.25em")
+    .attr("fill", "black")
+    .text((d) =>
+      d[0].indexOf(" ") < 0 ? _.map(d[0], (c) => "â–ˆ").join("") : d[0]
+    );
+
+  svg
+    .append("g")
+    .selectAll("circle")
+    .data(data)
+    .enter()
+    .append("circle")
+    .attr("fill", "black")
+    .attr("stroke", "black")
+    .attr("cx", (d) => x(d[1]))
+    .attr("cy", (d, i) => y(i))
+    .attr("r", 1);
+
+  svg
+    .append("g")
+    .selectAll("circle")
+    .data(events)
+    .enter()
+    .append("circle")
+    .attr("fill", (d, i) =>
+      _.some(cluster.event_info[d[0]].national_priority)
+        ? "firebrick"
+        : "steelblue"
+    )
+    .attr("stroke", "black")
+    .attr("cx", (d) => x(d[1]))
+    .attr("cy", (d, i) => y(data.length))
+    .attr(
+      "r",
+      (d) => 2 + Math.sqrt(d3.sum(cluster.event_info[d[0]].connected_componets))
+    )
+    .on("mouseover", (d, e) => {
+      const ed = cluster.event_info[d[0]];
+      _.each(ed.national_priority, (d, i) => {
+        if (d) {
+          _.each(ed.priority_nodes[i], (n) => highlight_nodes.add(n));
+        }
+      });
+      //console.log (highlight_nodes);
+      let years_ago = _.map([1, 3], (ya) => {
+        let some_years_ago = new Date(d[1]);
+        some_years_ago.setFullYear(d[1].getFullYear() - ya);
+        if (some_years_ago < x_range[0]) some_years_ago = x_range[0];
+        return some_years_ago;
+      });
+
+      let fills = ["firebrick", "grey"];
+      time_boxes = _.map(years_ago, (sya, i) =>
+        svg
+          .append("g")
+          .selectAll("rect")
+          .data([d])
+          .enter()
+          .append("rect")
+          .attr("fill", fills[i])
+          .attr("x", (d) => x(sya))
+          .attr("y", (d) => y(0))
+          .attr("width", x(d[1]) - x(sya))
+          .attr("height", (d) => -y(0) + y(data.length - 1))
+          .attr("opacity", 0.25)
+      );
+
+      lines
+        .attr("stroke-width", (d) => (highlight_nodes.has(d[0]) ? 5 : 2))
+        .attr("stroke", (d) => (highlight_nodes.has(d[0]) ? "black" : "#aaa"));
+      text_labels.attr("fill", (d) =>
+        highlight_nodes.has(d[0]) ? "firebrick" : "black"
+      );
+    })
+    .on("mouseout", (e, d) => {
+      lines.attr("stroke-width", 2).attr("stroke", "#aaa");
+      text_labels.attr("fill", "black");
+      highlight_nodes = new Set();
+      _.each(time_boxes, (box) => (box ? box.remove() : 0));
+      time_boxes = [null, null];
+    })
+    .append("title")
+    .text((d) => {
+      const ed = cluster.event_info[d[0]];
+      let text = d[0] + ". ";
+      if (_.some(ed.national_priority)) {
+        text += "National priority clusterOI. ";
+      }
+      text +=
+        String(d3.sum(ed.connected_componets)) +
+        " nodes in " +
+        ed.connected_componets.length +
+        " components. ";
+      text +=
+        "A total of " +
+        d3.sum(ed.priority_nodes, (d) => d.length) +
+        " nodes dx'ed in the previous 12 months; maximum of " +
+        d3.max(ed.priority_nodes, (d) => d.length) +
+        " in a subcluster";
+      return text;
+    });
+}
+
+/**
+ * Performs a depth-wise traversal on a cluster of nodes, considering edges and optional filters.
+ *
+ * @param {Object[]} nodes - An array of node objects. Each node should have an `id` property.
+ * @param {Object[]} edges - An array of edge objects. Each edge should have `source` and `target` properties
+ *   referencing node IDs.
+ * @param {Function} [edge_filter] - An optional filtering function applied to edges before traversal.
+ *   The function should accept an edge object and return a boolean indicating whether to include the edge.
+ * @param {Function} [save_edges] - An optional function used to store traversed edges. It should be called with
+ *   an array where each element represents the edges within a cluster.
+ * @param {Object[]} [seed_nodes] - An optional array of node objects to use as starting points for traversal.
+ *   If not provided, all nodes will be considered.
+ * @param {Set} [white_list] - An optional set of node IDs restricting traversal to nodes within the set.
+ *
+ * @throws {Error} If an edge references non-existent nodes.
+ *
+ * @returns {Object[][]} An array of clusters, where each cluster is an array of node objects.
+ */
+
+function hivtrace_cluster_depthwise_traversal(
+  nodes,
+  edges,
+  edge_filter,
+  save_edges,
+  seed_nodes,
+  white_list
+  // an optional set of node IDs (a subset of 'nodes') that will be considered for traversal
+  // it is further assumed that seed_nodes are a subset of white_list, if the latter is specified
+) {
+  var clusters = [],
+    adjacency = {},
+    by_node = {};
+
+  seed_nodes = seed_nodes || nodes;
+
+  _.each(nodes, (n) => {
+    n.visited = false;
+    adjacency[n.id] = [];
+  });
+
+  if (edge_filter) {
+    edges = _.filter(edges, edge_filter);
+  }
+
+  if (white_list) {
+    edges = _.filter(
+      edges,
+      (e) =>
+        white_list.has(nodes[e.source].id) && white_list.has(nodes[e.target].id)
+    );
+  }
+
+  _.each(edges, (e) => {
+    try {
+      adjacency[nodes[e.source].id].push([nodes[e.target], e]);
+      adjacency[nodes[e.target].id].push([nodes[e.source], e]);
+    } catch {
+      throw Error(
+        "Edge does not map to an existing node " + e.source + " to " + e.target
+      );
+    }
+  });
+
+  var traverse = function (node) {
+    if (!(node.id in by_node)) {
+      clusters.push([node]);
+      by_node[node.id] = clusters.length - 1;
+      if (save_edges) {
+        save_edges.push([]);
+      }
+    }
+    node.visited = true;
+
+    _.each(adjacency[node.id], (neighbor) => {
+      if (!neighbor[0].visited) {
+        by_node[neighbor[0].id] = by_node[node.id];
+        clusters[by_node[neighbor[0].id]].push(neighbor[0]);
+        if (save_edges) {
+          save_edges[by_node[neighbor[0].id]].push(neighbor[1]);
+        }
+        traverse(neighbor[0]);
+      }
+    });
+  };
+
+  _.each(seed_nodes, (n) => {
+    if (!n.visited) {
+      traverse(n);
+    }
+  });
+
+  return clusters;
+}
+
+/**
+ * Determines the type of an edge based on its length and predefined edge types.
+
+ * @param {Object} e - The edge object to be classified.
+ * @param {string[]} edge_types - An array of two edge types. The first type is used for edges shorter than or equal to `T`,
+ *   and the second type is used for edges longer than `T`.
+ * @param {number} T - The threshold value for edge length classification.
+
+ * @returns {string} The edge type corresponding to the edge's length.
+ */
+
+function edge_typer(e, edge_types, T) {
+  return edge_types[e.length <= T ? 0 : 1];
+}
+
+/**
+ * Generates a random ID string using a specified alphabet and length.
+
+ * @param {string[]} [alphabet] - An optional array of characters to use in the ID. If not provided, a default alphabet of letters "a" to "g" is used.
+ * @param {number} [length] - An optional length for the ID. If not provided, a default length of 32 is used.
+
+ * @returns {string} A randomly generated ID string.
+ */
+
+function random_id(alphabet, length) {
+  alphabet = alphabet || ["a", "b", "c", "d", "e", "f", "g"];
+  length = length || 32;
+  var s = "";
+  for (var i = 0; i < length; i++) {
+    s += _.sample(alphabet);
+  }
+  return s;
+}
+
+/**
+ * Generates a plot visualizing cluster dynamics over time.
+ *
+ * @param {Object[]} time_series - An array of data points, each with a required `time` property (a date object)
+ *   and optional properties representing attributes.
+ * @param {d3.selection} container - A D3 selection representing the container element for the plot.
+ * @param {string} x_title - The title for the x-axis.
+ * @param {string} y_title - The title for the y-axis.
+ * @param {d3.scale} [y_scale] - An optional D3 scale for the y-axis. If not provided, a linear scale will be used.
+ * @param {Function} [bin_by] - An optional function used to bin data points into time intervals.
+ *   The function should accept a date object and return an array with three elements:
+ *   - The bin label (e.g., "Q1 2023").
+ *   - The start date of the bin.
+ *   - The middle date of the bin (used for x-axis positioning).
+ *   If not provided, a default function that bins by quarters is used.
+ * @param {Object} [options] - An optional configuration object for the plot.
+ *   - `base_line`: (number, default: 20) The baseline value for the y-axis.
+ *   - `top`: (number, default: 40) The top padding for the plot.
+ *   - `right`: (number, default: 30) The right padding for the plot.
+ *   - `bottom`: (number, default: 60) The bottom padding for the plot.
+ *   - `left`: (number, default: 100) The left padding for the plot.
+ *   - `font_size`: (number, default: 18) The font size for labels and text elements.
+ *   - `rect_size`: (number, default: 22) The size of rectangles used in the legend.
+ *   - `width`: (number, default: 1024) The width of the plot container.
+ *   - `height`: (number, default: 600) The height of the plot container.
+ *   - `barchart`: (boolean, default: false) If true, the plot will be displayed as a bar chart.
+ *   - `skip_cumulative`: (boolean, default: false) If true, the cumulative area will not be displayed.
+ *   - `x-tick-format`: (Function) An optional function for formatting x-axis tick labels.
+ *   - `prefix`: (string) An optional prefix to add to attribute names displayed in the legend.
+ *   - `colorizer`: (Object) An optional colorizer object for attributes. Keys should be attribute names,
+ *     and values should be D3 scales used for coloring lines/bars.
+ *   - `drag`: (Object) An optional drag object for enabling dragging the plot.
+ *
+ * @throws {Error} If no data points are provided.
+ */
+
+function hivtrace_plot_cluster_dynamics(
+  time_series,
+  container,
+  x_title,
+  y_title,
+  y_scale,
+  bin_by,
+  options
+) {
+  options = options || {
+    base_line: 20,
+    top: 40,
+    right: 30,
+    bottom: 3 * 20,
+    left: 5 * 20,
+    font_size: 18,
+    rect_size: 22,
+    width: 1024,
+    height: 600,
+  };
+
+  // Only accept time_series with time that is a date
+  time_series = _.filter(time_series, (ts) => _.isDate(ts.time));
+
+  if (time_series.length === 0) {
+    return;
+  }
+
+  var do_barchart = options && options["barchart"];
+  var skip_cumulative = (options && options["skip_cumulative"]) || do_barchart;
+
+  var width = options.width - options.left - options.right;
+  var height = options.height - options.top - options.bottom;
+  var min_diff;
+
+  if (!bin_by) {
+    bin_by = function (date) {
+      var year = date.getFullYear(),
+        nearest_quarter = new Date(),
+        mid_point = new Date();
+
+      nearest_quarter.setDate(1);
+      nearest_quarter.setFullYear(year);
+      mid_point.setFullYear(year);
+
+      var quarter = Math.floor(date.getMonth() / 3);
+
+      nearest_quarter.setMonth(quarter * 3);
+      nearest_quarter.setHours(0, 0, 0);
+      mid_point.setHours(0, 0, 0);
+
+      nearest_quarter.setFullYear(year);
+      mid_point.setMonth(quarter * 3 + 1);
+      mid_point.setDate(15);
+
+      return ["Q" + (quarter + 1) + " " + year, nearest_quarter, mid_point];
+    };
+
+    min_diff = new Date(2018, 3, 0) - new Date(2018, 0, 0);
+  }
+
+  var x_tick_format = function (d) {
+    var year = d.getFullYear();
+    var quarter = Math.floor(d.getMonth() / 3) + 1;
+
+    return String(year) + "-Q" + quarter;
+  };
+
+  if (options && options["x-tick-format"]) {
+    x_tick_format = options["x-tick-format"];
+  }
+
+  /** plot_data is an array with entries like
+        {
+            "time": DATE,
+            "sex_trans":"IDU-Male"
+        }
+
+        "time" is required, everything else are optional attributes
+
+        1. First, we bin everything into ranges (like years or quarters, this is returned by the mapper callback)
+        2. Second, we compute growth dynamics of total counts and individual attributes
+        3. Third, if additional attributes are present, one that's tagged for display is stratified by values and
+           converted into time series
+
+    */
+
+  var x = d3.time.scale().range([0, width]);
+
+  var y = y_scale ? y_scale : d3.scale.linear();
+
+  if (!y_scale) {
+    y.rangeRound([height, 0]);
+  } else {
+    y.range([height, 0]);
+  }
+
+  var xAxis = d3.svg
+    .axis()
+    .scale(x)
+    .orient("bottom")
+    .ticks(d3.time.month, 3)
+    .tickFormat(d3.time.format("%m/%Y"));
+
+  if (x_tick_format) {
+    xAxis.tickFormat(x_tick_format);
+  }
+
+  var yAxis = d3.svg
+    .axis()
+    .scale(y)
+    .orient("left")
+    .tickFormat((v) => {
+      if (v << 0 === v) {
+        // an integer
+        return v;
+      }
+      return null;
+    });
+
+  var binned = {};
+  var values_by_attribute = {};
+  var total_id = "total";
+  var total_color = "#555555";
+  var prefix = options && options["prefix"] ? options["prefix"] : "";
+  var max_bin = 0;
+
+  _.each(time_series, (point, index) => {
+    var bin_tag = bin_by(point["time"]);
+
+    if (!(bin_tag[0] in binned)) {
+      binned[bin_tag[0]] = { time: bin_tag[1], x: bin_tag[2] };
+      binned[bin_tag[0]][total_id] = 0;
+      _.each(point, (v, k) => {
+        if (k !== "time") {
+          binned[bin_tag[0]][k] = {};
+        }
+      });
+    }
+
+    binned[bin_tag[0]][total_id] += 1;
+    max_bin = Math.max(max_bin, binned[bin_tag[0]][total_id]);
+
+    var y = {};
+    y[total_id] = index + 1;
+    _.each(point, (v, k) => {
+      if (k !== "time") {
+        binned[bin_tag[0]][k][v] = binned[bin_tag[0]][k][v]
+          ? binned[bin_tag[0]][k][v] + 1
+          : 1;
+        if (!(k in values_by_attribute)) {
+          values_by_attribute[k] = {};
+        }
+        if (v in values_by_attribute[k]) {
+          values_by_attribute[k][v]++;
+        } else {
+          values_by_attribute[k][v] = 1;
+        }
+        max_bin = Math.max(max_bin, binned[bin_tag[0]][k][v]);
+        y[k] = _.clone(values_by_attribute[k]);
+      }
+    });
+
+    point["y"] = y;
+    point["_bin"] = bin_tag[1];
+  });
+
+  var binned_array = [];
+  _.each(binned, (v, k) => {
+    v["id"] = k;
+    binned_array.push(v);
+  });
+
+  binned_array.sort((a, b) => b["time"] - a["time"]);
+
+  if (do_barchart) {
+    if (_.isUndefined(min_diff)) {
+      _.each(binned_array, (d, i) => {
+        if (i > 0) {
+          min_diff = Math.min(
+            min_diff,
+            -(d["time"] - binned_array[i - 1]["time"])
+          );
+        }
+      });
+    }
+    min_diff *= 0.8; // convert to seconds and shrink a bit
+  }
+
+  var min_x = d3.min(time_series, (d) =>
+    d["time"] < d["_bin"] ? d["time"] : d["_bin"]
+  );
+  var max_x = d3.max(time_series, (d) =>
+    d["time"] > d["_bin"] ? d["time"] : d["_bin"]
+  );
+
+  if (do_barchart) {
+    var max_x2 = new Date();
+    max_x2.setTime(max_x.getTime() + min_diff);
+    max_x = max_x2;
+    max_x2 = new Date();
+    max_x2.setTime(min_x.getTime() - min_diff);
+    min_x = max_x2;
+  }
+
+  let quarter_span = Math.floor((max_x - min_x) / 3600 / 24 / 1000 / 30);
+  if (quarter_span > 8) {
+    xAxis.ticks(d3.time.month, 3 * Math.ceil(quarter_span / 8));
+  }
+
+  x.domain([min_x, max_x]).clamp(true);
+  y.domain([
+    0.0,
+    Math.round(skip_cumulative ? max_bin + 1 : time_series.length * 1.2),
+  ]).clamp(true);
+
+  /* step-plot generator*/
+
+  /*var svg = container.append("svg")//.style("display", "table-cell")
+        .attr("width", width + options.left + options.right)
+        .attr("height", height + options.top + options.bottom);*/
+
+  container.selectAll("*").remove(); // clean up previous plots
+
+  var svg = container
+    .append("g")
+    .attr("transform", "translate(" + options.left + "," + options.top + ")");
+
+  var legend_area = container
+    .append("g")
+    .attr(
+      "transform",
+      "translate(" +
+        (options.left + options.font_size * 2.5) +
+        "," +
+        (options.top + options.font_size) +
+        ")"
+    );
+
+  /* set the domain for the codons */
+
+  var y_key = _.keys(values_by_attribute)[0];
+
+  var color_scale =
+    "colorizer" in options &&
+    options["colorizer"] &&
+    y_key in options["colorizer"]
+      ? options["colorizer"][y_key]
+      : d3.scale.category10();
+
+  color_scale = _.wrap(color_scale, (func, arg) => {
+    if (arg === total_id) return total_color;
+    return func(arg);
+  });
+
+  var plot_types = _.keys(values_by_attribute[y_key]);
+
+  if (do_barchart) {
+    if (plot_types.length === 0) {
+      plot_types.push(total_id);
+    }
+  } else {
+    plot_types.push(total_id);
+  }
+
+  plot_types.sort();
+
+  if (options && options["drag"]) {
+    var drag = d3.behavior.drag();
+    drag.on("drag", function () {
+      options["drag"].x += d3.event.dx;
+      options["drag"].y += d3.event.dy;
+      d3.select(this).attr(
+        "transform",
+        "translate(" + options["drag"].x + "," + options["drag"].y + ")"
+      );
+    });
+    container.call(drag);
+  }
+
+  function opacity_toggle(tag, on_off) {
+    if (do_barchart) {
+      d3.selectAll('[data-plotid="' + tag + '"]').style(
+        "stroke-width",
+        on_off ? 4 : 1
+      );
+    } else {
+      d3.selectAll('[data-plotid="' + tag + '"]').style(
+        "fill-opacity",
+        on_off ? 0.5 : 0.1
+      );
+    }
+    d3.selectAll('[data-curveid="' + tag + '"]').style(
+      "stroke-width",
+      on_off ? 3 : 1
+    );
+  }
+
+  if (!do_barchart || plot_types.length > 1 || plot_types[0] !== total_id) {
+    var legend_lines = legend_area.selectAll("g").data(plot_types);
+
+    legend_lines.enter().append("g").attr("class", "annotation-text");
+
+    legend_lines
+      .selectAll("text")
+      .data((d) => [d])
+      .enter()
+      .append("text")
+      .attr(
+        "transform",
+        (d, i, j) =>
+          "translate(" +
+          options.rect_size +
+          "," +
+          (options.rect_size * (plot_types.length - 1 - j) -
+            (options.rect_size - options.font_size)) +
+          ")"
+      )
+      .attr("dx", "0.2em")
+      .style("font-size", options.font_size)
+      .text((d) => d)
+      .on("mouseover", (d) => {
+        opacity_toggle(prefix + d, true);
+      })
+      .on("mouseout", (d) => {
+        opacity_toggle(prefix + d, false);
+      });
+
+    legend_lines
+      .selectAll("rect")
+      .data((d) => [d])
+      .enter()
+      .append("rect")
+      .attr("x", 0)
+      .attr("y", (d, i, j) => options.rect_size * (plot_types.length - 2 - j))
+      .attr("width", options.rect_size)
+      .attr("height", options.rect_size)
+      .attr("class", "area")
+      .style("fill", (d, i, j) => color_scale(d))
+      .on("mouseover", (d) => {
+        opacity_toggle(prefix + d, true);
+      })
+      .on("mouseout", (d) => {
+        opacity_toggle(prefix + d, false);
+      });
+  }
+
+  var last = _.clone(time_series[time_series.length - 1]);
+  last["time"] = x.domain()[1];
+  time_series.push(last);
+
+  _.each(plot_types, (plot_key, idx) => {
+    var plot_color = color_scale(plot_key);
+    var y_accessor = function (d) {
+      //console.log ((plot_key in d['y']) ? d['y'][plot_key] : 0);
+      if (plot_key in d["y"]) {
+        return d["y"][plot_key];
+      }
+      if (y_key in d["y"]) {
+        if (plot_key in d["y"][y_key]) {
+          return d["y"][y_key][plot_key];
+        }
+      }
+      return 0.0;
+    };
+
+    var bin_accessor = function (d) {
+      if (y_key && plot_key in d[y_key]) {
+        return d[y_key][plot_key];
+      } else if (plot_key in d) {
+        return d[plot_key];
+      }
+      return 0.0;
+    };
+
+    if (!skip_cumulative) {
+      var curve = d3.svg
+        .area()
+        .x((d) => x(d["time"]))
+        .y1((d) => y(y_accessor(d)))
+        .y0((d) => y(0))
+        .interpolate("step");
+
+      svg
+        .append("path")
+        .datum(time_series)
+        .classed("trend", true)
+        .style("fill", plot_color)
+        .style("stroke", plot_color)
+        .attr("d", curve)
+        .attr("data-plotid", prefix + plot_key);
+    }
+
+    if (do_barchart) {
+      binned_array.forEach((d) => {
+        var dd = new Date();
+        dd.setTime(d["time"].getTime() - min_diff * 0.5);
+        var dd2 = new Date();
+        dd2.setTime(d["time"].getTime() + min_diff * 0.5);
+        var xc = x(dd);
+        var w = x(dd2) - x(dd);
+        var last_y = "last_y" in d ? d["last_y"] : 0;
+        var new_y = bin_accessor(d);
+        svg
+          .append("rect")
+          .attr("x", xc)
+          .attr("y", y(last_y + new_y))
+          .attr("height", y(0) - y(new_y))
+          .attr("width", w)
+          .attr("data-plotid", prefix + plot_key)
+          .classed("tracer", true)
+          .style("fill", plot_color)
+          .style("stroke", d3.rgb(plot_color).darker(2))
+          .style("fill-opacity", 1)
+          .append("title")
+          .text(
+            plot_key +
+              " " +
+              new_y +
+              " cases in " +
+              (x_tick_format ? x_tick_format(d["time"]) : d["time"])
+          );
+
+        d["last_y"] = (d["last_y"] ? d["last_y"] : 0) + new_y;
+      });
+    } else {
+      binned_array.forEach((d) => {
+        svg
+          .append("circle")
+          .attr("cx", x(d["time"]))
+          .attr("cy", y(bin_accessor(d)))
+          .attr("r", "5")
+          .classed("node", true)
+          .style("fill", plot_color)
+          .style("stroke", plot_color)
+          .attr("title", plot_key + " : " + bin_accessor(d));
+      });
+
+      var curve_year = d3.svg
+        .line()
+        .x((d) => x(d["time"]))
+        .y((d) => y(bin_accessor(d)))
+        .interpolate("cardinal");
+
+      svg
+        .append("path")
+        .datum(binned_array)
+        .classed("tracer", true)
+        .style("stroke", plot_color)
+        .attr("d", curve_year)
+        .attr("data-curveid", prefix + plot_key);
+    }
+  });
+
+  /* x-axis */
+  var x_axis = svg
+    .append("g")
+    .attr("class", "x axis")
+    .attr("transform", "translate(0," + height + ")")
+    .style("font-size", options.font_size)
+    .call(xAxis);
+
+  x_axis
+    .selectAll("text")
+    .attr("transform", "rotate(-45)")
+    .attr("dy", "0.9em")
+    .attr("dx", "-1.75em");
+
+  x_axis
+    .append("text")
+    .attr("x", width / 2)
+    .attr("dy", "3.5em")
+    .style("text-anchor", "middle")
+    .style("font-size", options.font_size * 1.5)
+    .text(x_title);
+
+  /* y-axis*/
+  svg
+    .append("g")
+    .attr("class", "y axis")
+    .style("font-size", options.font_size)
+    .call(yAxis)
+    .append("text")
+    .style("font-size", options.font_size * 1.5)
+    .attr("transform", "rotate(-90)")
+    .attr("y", 6)
+    .attr("dy", "-2em")
+    //.attr("dx", "-1em")
+    .style("text-anchor", "end")
+    .text(y_title); // beta - alpha
+}
+
+/** Retrieves a CSS selector for UI elements based on their `data-hivtrace-ui-role` attribute.
+
+ * @param {string} role - The value of the `data-hivtrace-ui-role` attribute.
+
+ * @returns {string} A CSS selector string targeting elements with the specified role.
+*/
+
+function get_ui_element_selector_by_role(role) {
+  return ` [data-hivtrace-ui-role='${role}']`;
+}
+
+module.exports = {
+  edge_typer,
+  coi_timeseries: hivtrace_coi_timeseries,
+  compute_node_degrees: hivtrace_compute_node_degrees,
+  export_table_to_text: hiv_trace_export_table_to_text,
+  symbol: hivtrace_generate_svg_symbol,
+  cluster_dynamics: hivtrace_plot_cluster_dynamics,
+  hivtrace_cluster_depthwise_traversal,
+  random_id,
+  get_ui_element_selector_by_role,
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.3 on Wed Oct 09 2024 12:14:37 GMT-0700 (Pacific Daylight Time) +
+ + + + + diff --git a/docs/network.js.html b/docs/network.js.html new file mode 100644 index 0000000..2685d9d --- /dev/null +++ b/docs/network.js.html @@ -0,0 +1,333 @@ + + + + + JSDoc: Source: network.js + + + + + + + + + + +
+ +

Source: network.js

+ + + + + + +
+
+
/**
+    Functions that help manipulate network JSON and perform 
+    other utility operations
+*/
+
+var d3 = require("d3"),
+  _ = require("underscore"),
+  clustersOfInterest = require("./clustersOfInterest.js"),
+  kGlobals = require("./globals.js");
+
+/**
+    unpack_compact_json:
+    If the input network JSON is in compact form, i.e. instead of storing 
+        key : value
+    it stores
+        key : integer index of value
+        unique_values: list of values
+    convert it to 
+        key: value 
+        
+    The operation is performed in place on the `json` argument
+*/
+
+function unpack_compact_json(json) {
+  _.each(["Nodes", "Edges"], (key) => {
+    var fields = _.keys(json[key]);
+    var expanded = [];
+    _.each(fields, (f, idx) => {
+      var field_values = json[key][f];
+      if (!_.isArray(field_values) && "values" in field_values) {
+        var expanded_values = [];
+        _.each(field_values["values"], (v) => {
+          expanded_values.push(field_values["keys"][v]);
+        });
+        field_values = expanded_values;
+      }
+      _.each(field_values, (fv, j) => {
+        if (idx === 0) {
+          expanded.push({});
+        }
+        expanded[j][f] = fv;
+      });
+    });
+    json[key] = expanded;
+  });
+}
+
+/**
+    normalize_node_attributes
+    
+    Iterate over node attributes, lower case all the keys for mapping.
+    If attributes are found that are not in the data dictionary, attempt to map them using 
+    "labels". 
+*/
+function normalize_node_attributes(json) {
+  const label_key_map = _.object(
+    _.map(json[kGlobals.network.GraphAttrbuteID], (d, k) => [d.label, k])
+  );
+
+  _.each(json.Nodes, (n) => {
+    if (kGlobals.network.NodeAttributeID in n) {
+      let new_attrs = {};
+      if (n[kGlobals.network.NodeAttributeID] !== null) {
+        new_attrs = Object.fromEntries(
+          Object.entries(n[kGlobals.network.NodeAttributeID]).map(([k, v]) => [
+            k.toLowerCase(),
+            v,
+          ])
+        );
+      }
+
+      // Map attributes from patient_schema labels to keys, if necessary
+      const unrecognizedKeys = _.difference(
+        _.keys(new_attrs),
+        _.keys(json[kGlobals.network.GraphAttrbuteID])
+      );
+
+      if (unrecognizedKeys.length) {
+        _.each(unrecognizedKeys, (k) => {
+          if (_.contains(_.keys(label_key_map), k)) {
+            new_attrs[label_key_map[k]] = new_attrs[k];
+            delete new_attrs[k];
+          }
+        });
+      }
+
+      n[kGlobals.network.NodeAttributeID] = new_attrs;
+    }
+  });
+}
+/**
+    ensure_node_attributes_exist
+    
+    Iterate over nodes in the network. If a node does not have an array of attributes or 
+    data dictionary records, create an empty one. This makes error checking less complex downstream.
+*/
+
+function ensure_node_attributes_exist(json) {
+  const validate_these_keys = new Set([
+    "attributes",
+    kGlobals.network.NodeAttributeID,
+  ]);
+  json.Nodes.forEach((n) => {
+    for (const i of validate_these_keys) {
+      if (!n[i]) {
+        n[i] = [];
+      }
+    }
+  });
+}
+
+function check_network_option(options, key, if_absent, if_present) {
+  /**
+    check_network_option
+    
+    Given a dictionary option list (can be null) and a key
+    checks to see if the key is present
+    
+        if the key is absent or "options" is null, the return value will be "if_absent" (null by default)
+        if the key is present, and `if_present` is set, will return the if_present value, otherwise will return options[key]
+*/
+
+  if (options) {
+    if (key in options) {
+      return if_present === undefined ? options[key] : if_present;
+    }
+  }
+  return if_absent;
+}
+
+function center_cluster_handler(self, d) {
+  d.x = self.width / 2;
+  d.y = self.height / 2;
+  self.update(false, 0.4);
+}
+
+/**
+    handle_cluster_click
+    
+    Handle contextual menus for clusters and cluster drag 
+    
+    @param self: network object
+    @param cluster [optional]: the cluster object to act on
+    @param release [optional]: the cluster object to release the "fixed" flag from
+*/
+
+function handle_cluster_click(self, cluster, release) {
+  var container = d3.select(self.container);
+  var id = "d3_context_menu_id";
+  var menu_object = container.select("#" + id);
+
+  if (menu_object.empty()) {
+    menu_object = container
+      .append("ul")
+      .attr("id", id)
+      .attr("class", "dropdown-menu")
+      .attr("role", "menu");
+  }
+
+  menu_object.selectAll("li").remove();
+
+  var already_fixed = cluster && cluster.fixed;
+
+  if (cluster) {
+    menu_object
+      .append("li")
+      .append("a")
+      .attr("tabindex", "-1")
+      .text("Expand cluster")
+      .on("click", (d) => {
+        cluster.fixed = 0;
+        self.expand_cluster_handler(cluster, true);
+        menu_object.style("display", "none");
+      });
+
+    menu_object
+      .append("li")
+      .append("a")
+      .attr("tabindex", "-1")
+      .text("Center on screen")
+      .on("click", (d) => {
+        cluster.fixed = 0;
+        center_cluster_handler(self, cluster);
+        menu_object.style("display", "none");
+      });
+
+    menu_object
+      .append("li")
+      .append("a")
+      .attr("tabindex", "-1")
+      .text((d) => {
+        if (cluster.fixed) return "Allow cluster to float";
+        return "Hold cluster at current position";
+      })
+      .on("click", (d) => {
+        cluster.fixed = !cluster.fixed;
+        menu_object.style("display", "none");
+      });
+
+    if (self.isPrimaryGraph) {
+      menu_object
+        .append("li")
+        .append("a")
+        .attr("tabindex", "-1")
+        .text((d) => "Show this cluster in separate tab")
+        .on("click", (d) => {
+          self.open_exclusive_tab_view(
+            cluster.cluster_id,
+            null,
+            null,
+            self._distance_gate_options()
+          );
+          menu_object.style("display", "none");
+        });
+    }
+
+    if (clustersOfInterest.get_editor()) {
+      menu_object
+        .append("li")
+        .append("a")
+        .attr("tabindex", "-1")
+        .text((d) => "Add this cluster to the cluster of interest")
+        .on("click", (d) => {
+          clustersOfInterest
+            .get_editor()
+            .append_nodes(_.map(cluster.children, (c) => c.id));
+        });
+    }
+
+    // Only show the "Show on map" option for clusters with valid country info (for now just 2 letter codes) for each node.
+    const show_on_map_enabled = _.every(
+      cluster.children,
+      (node) => self._get_node_country(node).length === 2
+    );
+
+    if (show_on_map_enabled) {
+      menu_object
+        .append("li")
+        .append("a")
+        .attr("tabindex", "-1")
+        .text("Show on map")
+        .on("click", (d) => {
+          //console.log(cluster)
+          self.open_exclusive_tab_view(
+            cluster.cluster_id,
+            null,
+            (cluster_id) => "Map of cluster: " + cluster_id,
+            { showing_on_map: true }
+          );
+        });
+    }
+
+    //cluster.fixed = 1;
+
+    menu_object
+      .style("position", "absolute")
+      .style("left", String(d3.event.offsetX) + "px")
+      .style("top", String(d3.event.offsetY) + "px")
+      .style("display", "block");
+  } else {
+    if (release) {
+      release.fixed = 0;
+    }
+    menu_object.style("display", "none");
+  }
+
+  container.on(
+    "click",
+    (d) => {
+      handle_cluster_click(self, null, already_fixed ? null : cluster);
+    },
+    true
+  );
+}
+
+module.exports = {
+  check_network_option,
+  ensure_node_attributes_exist,
+  normalize_node_attributes,
+  unpack_compact_json,
+  handle_cluster_click,
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.3 on Wed Oct 09 2024 12:14:37 GMT-0700 (Pacific Daylight Time) +
+ + + + + diff --git a/docs/quicksearch.html b/docs/quicksearch.html deleted file mode 100644 index ac778a4..0000000 --- a/docs/quicksearch.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - diff --git a/docs/scatterplot.js.html b/docs/scatterplot.js.html new file mode 100644 index 0000000..de4947b --- /dev/null +++ b/docs/scatterplot.js.html @@ -0,0 +1,168 @@ + + + + + JSDoc: Source: scatterplot.js + + + + + + + + + + +
+ +

Source: scatterplot.js

+ + + + + + +
+
+
var d3 = require("d3");
+
+/**
+ * Renders a scatter plot using D3.js.
+
+ * @param {Object[]} points - An array of data points, each with x and y coordinates (and optionally a title).
+ * @param {number} w - The width of the plot area.
+ * @param {number} h - The height of the plot area.
+ * @param {string} id - The ID of the HTML element where the plot will be rendered.
+ * @param {Object} labels - An object containing labels for the x and y axes.
+ * @param {boolean} [dates=false] - A flag indicating whether the x-axis should represent dates.
+
+ * @returns {void}
+ */
+
+function hivtrace_render_scatterplot(points, w, h, id, labels, dates) {
+  var _defaultFloatFormat = d3.format(",.2r");
+  var _defaultDateViewFormatShort = d3.time.format("%B %Y");
+
+  var margin = {
+      top: 10,
+      right: 10,
+      bottom: 100,
+      left: 100,
+    },
+    width = w - margin.left - margin.right,
+    height = h - margin.top - margin.bottom;
+
+  var x = (dates ? d3.time.scale() : d3.scale.linear())
+    .domain(d3.extent(points, (p) => p.x))
+    .range([0, width]);
+
+  var y = (dates ? d3.time.scale() : d3.scale.linear())
+    .domain(d3.extent(points, (p) => p.y))
+    .range([height, 0]);
+
+  var xAxis = d3.svg
+    .axis()
+    .scale(x)
+    .orient("bottom")
+    .tickFormat(dates ? _defaultDateViewFormatShort : _defaultFloatFormat);
+
+  var yAxis = d3.svg
+    .axis()
+    .scale(y)
+    .orient("left")
+    .tickFormat(dates ? _defaultDateViewFormatShort : _defaultFloatFormat);
+
+  var histogram_svg = d3.select(id).selectAll("svg");
+
+  if (!histogram_svg.empty()) {
+    histogram_svg.remove();
+  }
+
+  histogram_svg = d3
+    .select(id)
+    .append("svg")
+    .attr("width", w)
+    .attr("height", h)
+    .append("g")
+    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+  points = histogram_svg.selectAll("circle").data(points);
+  points.enter().append("circle");
+
+  points
+    .attr("cx", (d) => x(d.x))
+    .attr("cy", (d) => y(d.y))
+    .attr("r", 3)
+    .classed("node scatter", true);
+
+  points.each(function (d) {
+    if ("title" in d) {
+      d3.select(this).append("title").text(d.title);
+    }
+  });
+
+  var x_axis = histogram_svg
+    .append("g")
+    .attr("class", "x axis")
+    .attr("transform", "translate(0," + height + ")")
+    .call(xAxis);
+
+  x_axis
+    .selectAll("text")
+    .attr("transform", "rotate(-45)")
+    .attr("dx", "-.5em")
+    .attr("dy", ".25em")
+    .style("text-anchor", "end");
+  x_axis
+    .append("text")
+    .text(labels.x)
+    .attr("transform", "translate(" + width + ",0)")
+    .attr("dy", "-1em")
+    .attr("text-anchor", "end");
+
+  var y_axis = histogram_svg
+    .append("g")
+    .attr("class", "y axis")
+    .attr("transform", "translate(0," + 0 + ")")
+    .call(yAxis);
+
+  y_axis
+    .selectAll("text")
+    .attr("transform", "rotate(-45)")
+    .attr("dx", "-.5em")
+    .attr("dy", ".25em")
+    .style("text-anchor", "end");
+  y_axis
+    .append("text")
+    .text(labels.y)
+    .attr("transform", "rotate(-90)")
+    .attr("dy", "1em")
+    .attr("text-anchor", "end");
+}
+
+module.exports.scatterPlot = hivtrace_render_scatterplot;
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.3 on Wed Oct 09 2024 12:14:37 GMT-0700 (Pacific Daylight Time) +
+ + + + + diff --git a/docs/scripts/docstrap.lib.js b/docs/scripts/docstrap.lib.js deleted file mode 100644 index 8d86c43..0000000 --- a/docs/scripts/docstrap.lib.js +++ /dev/null @@ -1,22646 +0,0 @@ -if ( - (!(function (a, b) { - "object" == typeof module && "object" == typeof module.exports - ? (module.exports = a.document - ? b(a, !0) - : function (a) { - if (!a.document) - throw new Error("jQuery requires a window with a document"); - return b(a); - }) - : b(a); - })("undefined" != typeof window ? window : this, function (a, b) { - function c(a) { - var b = "length" in a && a.length, - c = _.type(a); - return ( - "function" !== c && - !_.isWindow(a) && - (!(1 !== a.nodeType || !b) || - "array" === c || - 0 === b || - ("number" == typeof b && b > 0 && b - 1 in a)) - ); - } - function d(a, b, c) { - if (_.isFunction(b)) - return _.grep(a, function (a, d) { - return !!b.call(a, d, a) !== c; - }); - if (b.nodeType) - return _.grep(a, function (a) { - return (a === b) !== c; - }); - if ("string" == typeof b) { - if (ha.test(b)) return _.filter(b, a, c); - b = _.filter(b, a); - } - return _.grep(a, function (a) { - return U.call(b, a) >= 0 !== c; - }); - } - function e(a, b) { - for (; (a = a[b]) && 1 !== a.nodeType; ); - return a; - } - function f(a) { - var b = (oa[a] = {}); - return ( - _.each(a.match(na) || [], function (a, c) { - b[c] = !0; - }), - b - ); - } - function g() { - Z.removeEventListener("DOMContentLoaded", g, !1), - a.removeEventListener("load", g, !1), - _.ready(); - } - function h() { - Object.defineProperty((this.cache = {}), 0, { - get: function () { - return {}; - }, - }), - (this.expando = _.expando + h.uid++); - } - function i(a, b, c) { - var d; - if (void 0 === c && 1 === a.nodeType) - if ( - ((d = "data-" + b.replace(ua, "-$1").toLowerCase()), - (c = a.getAttribute(d)), - "string" == typeof c) - ) { - try { - c = - "true" === c || - ("false" !== c && - ("null" === c - ? null - : +c + "" === c - ? +c - : ta.test(c) - ? _.parseJSON(c) - : c)); - } catch (a) {} - sa.set(a, b, c); - } else c = void 0; - return c; - } - function j() { - return !0; - } - function k() { - return !1; - } - function l() { - try { - return Z.activeElement; - } catch (a) {} - } - function m(a, b) { - return _.nodeName(a, "table") && - _.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") - ? a.getElementsByTagName("tbody")[0] || - a.appendChild(a.ownerDocument.createElement("tbody")) - : a; - } - function n(a) { - return (a.type = (null !== a.getAttribute("type")) + "/" + a.type), a; - } - function o(a) { - var b = Ka.exec(a.type); - return b ? (a.type = b[1]) : a.removeAttribute("type"), a; - } - function p(a, b) { - for (var c = 0, d = a.length; d > c; c++) - ra.set(a[c], "globalEval", !b || ra.get(b[c], "globalEval")); - } - function q(a, b) { - var c, d, e, f, g, h, i, j; - if (1 === b.nodeType) { - if ( - ra.hasData(a) && - ((f = ra.access(a)), (g = ra.set(b, f)), (j = f.events)) - ) { - delete g.handle, (g.events = {}); - for (e in j) - for (c = 0, d = j[e].length; d > c; c++) _.event.add(b, e, j[e][c]); - } - sa.hasData(a) && - ((h = sa.access(a)), (i = _.extend({}, h)), sa.set(b, i)); - } - } - function r(a, b) { - var c = a.getElementsByTagName - ? a.getElementsByTagName(b || "*") - : a.querySelectorAll - ? a.querySelectorAll(b || "*") - : []; - return void 0 === b || (b && _.nodeName(a, b)) ? _.merge([a], c) : c; - } - function s(a, b) { - var c = b.nodeName.toLowerCase(); - "input" === c && ya.test(a.type) - ? (b.checked = a.checked) - : ("input" === c || "textarea" === c) && - (b.defaultValue = a.defaultValue); - } - function t(b, c) { - var d, - e = _(c.createElement(b)).appendTo(c.body), - f = - a.getDefaultComputedStyle && (d = a.getDefaultComputedStyle(e[0])) - ? d.display - : _.css(e[0], "display"); - return e.detach(), f; - } - function u(a) { - var b = Z, - c = Oa[a]; - return ( - c || - ((c = t(a, b)), - ("none" !== c && c) || - ((Na = ( - Na || _("

)CdQ3F!eKyF|9D2V!F-rhUpJ8J+l7g0OBBVM#THTI&O8)>EGR%u6Gd9D9pm5!S}%&6DxW}^f|7=Y zPoO3(pTZY#?(7(|!5}5Nn!D%DotZmlW)?smSMcEE<^aT$6gw#LlwubPI9BYTffL0! zyu-EPCnz{Y#ZR&1d{F!hr_NW!&#~mXis$jseXDo@U)-kR7sMBeUt-T&RQw9By@BF9 z3f?cpmw4m-R{RHncaC**(V--ipJ<~6LkW2fi6RVfh%vcYt9@z>&M0LBSf-Q|Et8wU zCt43_*JB)mHR71wb`K@~5Cizwp{`A2uuJ^_Bcl3k{7ree$8&@l?;^2nagS+NqCDBfkB?pJws=PbK~+A7|2 z{gCDJKI-i%m4LD$n{WIwWR|c+NRy`C1#)1sSBI7FiH6z-QkhY&Q_|%I3exQ zQ`X1M?cZH4^M&BSyr;2z$+^SZUMA*0001Z+HKHROw(}?!13=vX`$@Br+fGR zZ%e`5O6%Txi$Yrz0gF{}p>fY>OnlS0Uevf}oDXW;D{d2gcE<2)oFcV80@g$H)63L{HN*d{8kVzKVW(;E)$9N_%kx5Ku3R9WJbY?JW^G#k0Wdx>E$NBBVtKRLiL?sA*s%w`TdsNz1=+~FRNdB8&+@iBD0 zXFTC4C-8-Cwv(4U=LLQ~^Oa4^rG|OTr5?ItoaPMYxxh`%a*kVU z;HYGAjq6;IY{`*awo0DlOMw(hkrYdb(O28l;MYvSx*ChcQW4f^QL5UdE3HbqvbxB$pfSg`>Cj#;?~00;nMAg}==M6d%RaIhCe zARtS)01i=0um)3FSgr#ump{<1pq_<0a34Kp8x=7I1^|9 literal 0 HcmV?d00001 diff --git a/docs/fonts/OpenSans-Regular-webfont.eot b/docs/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..6bbc3cf58cb011a6b4bf3cb1612ce212608f7274 GIT binary patch literal 19836 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Regular-webfont.woff b/docs/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..e231183dce4c7b452afc9e7799586fd285e146f4 GIT binary patch literal 22660 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 ML;wL%uV=LY00kR;TmS$7 literal 0 HcmV?d00001 diff --git a/docs/fonts/glyphicons-halflings-regular.eot b/docs/fonts/glyphicons-halflings-regular.eot deleted file mode 100644 index b93a4953fff68df523aa7656497ee339d6026d64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20127 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/fonts/glyphicons-halflings-regular.ttf b/docs/fonts/glyphicons-halflings-regular.ttf deleted file mode 100644 index 1413fc609ab6f21774de0cb7e01360095584f65b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45404 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 G`u_lkUM?>H diff --git a/docs/fonts/glyphicons-halflings-regular.woff2 b/docs/fonts/glyphicons-halflings-regular.woff2 deleted file mode 100644 index 64539b54c3751a6d9adb44c8e3a45ba5a73b77f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18028 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 diff --git a/docs/global.html b/docs/global.html index 5c2800f..6d28239 100644 --- a/docs/global.html +++ b/docs/global.html @@ -1,5552 +1,13477 @@ - - - - - Documentation Global + + + JSDoc: Global + + - - - - - - -