diff --git a/R/visualizeNetworksWithHTML.R b/R/visualizeNetworksWithHTML.R index c244d98..35d8561 100644 --- a/R/visualizeNetworksWithHTML.R +++ b/R/visualizeNetworksWithHTML.R @@ -398,7 +398,8 @@ generateCytoscapeConfig <- function(nodes, edges, display_label_type = "id", container_id = "network-cy", event_handlers = NULL, - layout_options = NULL) { + layout_options = NULL, + node_font_size = 12) { # Create elements node_elements <- createNodeElements(nodes, display_label_type) @@ -435,7 +436,7 @@ generateCytoscapeConfig <- function(nodes, edges, width = "function(ele) { var label = ele.data('label') || ''; var labelLength = label.length; return Math.max(60, Math.min(labelLength * 8 + 20, 150)); }", height = "function(ele) { var label = ele.data('label') || ''; var labelLength = label.length; return Math.max(40, Math.min(labelLength * 2 + 30, 60)); }", shape = "round-rectangle", - `font-size` = "11px", + `font-size` = paste0(node_font_size, "px"), `font-weight` = "bold", color = "#000", `text-valign` = "center", @@ -462,7 +463,7 @@ generateCytoscapeConfig <- function(nodes, edges, `edge-text-rotation` = "autorotate", `text-margin-y` = -12, `text-halign` = "center", - `font-size` = "12px", + `font-size` = "16px", `font-weight` = "bold", color = "data(color)", `text-background-color` = "#ffffff", @@ -703,6 +704,7 @@ exportCytoscapeToHTML <- function(config, + ' controls_css <- ' @@ -720,6 +722,19 @@ exportCytoscapeToHTML <- function(config, } .control-btn:active { background-color: #dee2e6; + } + .export-btn { + background-color: #28a745; + color: white; + border-color: #28a745; + font-weight: bold; + } + .export-btn:hover { + background-color: #218838; + border-color: #1e7e34; + } + .export-btn:active { + background-color: #1e7e34; }' controls_js <- ' @@ -749,6 +764,55 @@ exportCytoscapeToHTML <- function(config, document.getElementById("reset-btn").addEventListener("click", function() { cy.reset(); cy.fit(); + }); + + // Export PNG functionality + document.getElementById("export-png-btn").addEventListener("click", function() { + const exportBtn = this; + const originalText = exportBtn.textContent; + + // Disable button and show loading state + exportBtn.disabled = true; + exportBtn.textContent = "Exporting..."; + + try { + // Generate high-resolution PNG (scale factor of 8 for high quality) + const png64 = cy.png({ + output: "base64uri", + bg: "white", + full: true, // Export the entire graph + scale: 10, // 10x resolution for publication quality + maxWidth: 10000, // Maximum width in pixels + maxHeight: 10000 // Maximum height in pixels + }); + + // Create download link + const link = document.createElement("a"); + link.href = png64; + link.download = "network_visualization_" + new Date().getTime() + ".png"; + + // Trigger download + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // Show success feedback + exportBtn.textContent = "Exported!"; + exportBtn.style.backgroundColor = "#28a745"; + + // Reset button after 2 seconds + setTimeout(function() { + exportBtn.disabled = false; + exportBtn.textContent = originalText; + exportBtn.style.backgroundColor = ""; + }, 2000); + + } catch (error) { + console.error("Error exporting PNG:", error); + alert("Error exporting PNG: " + error.message); + exportBtn.disabled = false; + exportBtn.textContent = originalText; + } });' } @@ -808,7 +872,7 @@ exportCytoscapeToHTML <- function(config, .legend-title { font-weight: bold; margin-bottom: 10px; - font-size: 14px; + font-size: 16px; color: #333; } @@ -841,7 +905,7 @@ exportCytoscapeToHTML <- function(config, flex-direction: column; justify-content: space-between; height: 120px; - font-size: 11px; + font-size: 14px; } .edge-legend { @@ -852,7 +916,7 @@ exportCytoscapeToHTML <- function(config, display: flex; align-items: center; margin-bottom: 6px; - font-size: 11px; + font-size: 14px; } .edge-legend-line { @@ -896,6 +960,7 @@ exportCytoscapeToHTML <- function(config, | Hover over edges to see PTM site overlap information | Click on nodes or edges to select them ', if(include_controls) '| Use the buttons above for common navigation actions' else '', ' + ', if(include_controls) '| Export as PNG to save the current view in high resolution' else '', ' @@ -929,7 +994,7 @@ exportCytoscapeToHTML <- function(config,
Downregulated
-
+
Log Fold Change values
`; @@ -943,40 +1008,49 @@ exportCytoscapeToHTML <- function(config, `; } - // Add edge legend - legendHTML += ` -
-
Edge Types
-
-
- Activation -
-
-
- Inhibition -
-
-
- Increase Amount -
-
-
- Decrease Amount -
-
-
- Phosphorylation + const edges = cy.edges(); + + const edgeTypeConfigs = [ + { type: "Activation", color: "#44AA44", label: "Activation", style: "" }, + { type: "Inhibition", color: "#FF4444", label: "Inhibition", style: "" }, + { type: "IncreaseAmount", color: "#4488FF", label: "Increase Amount", style: "" }, + { type: "DecreaseAmount", color: "#FF8844", label: "Decrease Amount", style: "" }, + { type: "Phosphorylation", color: "#9932CC", label: "Phosphorylation", style: "border-style: dashed; border-width: 1px; height: 0px; border-top-width: 2px;" }, + { type: "Complex", color: "#8B4513", label: "Complex", style: "" } + ]; + + const existingEdgeTypes = new Set(); + edges.forEach(edge => { + const edgeType = edge.data("interaction"); + if (edgeType) { + const normalizedType = edgeType.replace(" (bidirectional)", ""); + existingEdgeTypes.add(normalizedType); + } + }); + + let edgeLegendItems = ""; + edgeTypeConfigs.forEach(config => { + if (existingEdgeTypes.has(config.type)) { + const styleAttr = config.style ? `style="background-color: ${config.color}; ${config.style}"` : `style="background-color: ${config.color};"`; + edgeLegendItems += ` +
+
+ ${config.label} +
`; + } + }); + + if (edgeLegendItems) { + legendHTML += ` +
+
Edge Types
${edgeLegendItems}
-
-
- Complex +
+ PTM Site Info:
+ Hover over edges to see overlapping PTM sites between the edge target and node data
-
-
- PTM Site Info:
- Hover over edges to see overlapping PTM sites between the edge target and node data -
- `; + `; + } legendDiv.innerHTML = legendHTML; } @@ -1043,10 +1117,11 @@ exportCytoscapeToHTML <- function(config, exportNetworkToHTML <- function(nodes, edges, filename = "network_visualization.html", displayLabelType = "id", + nodeFontSize = 12, ...) { # Generate configuration - config <- generateCytoscapeConfig(nodes, edges, display_label_type = displayLabelType) + config <- generateCytoscapeConfig(nodes, edges, display_label_type = displayLabelType, node_font_size = nodeFontSize) # Export to HTML exportCytoscapeToHTML(config, filename, ...) @@ -1063,10 +1138,11 @@ exportNetworkToHTML <- function(nodes, edges, #' @param ... Additional arguments passed to exportCytoscapeToHTML() previewNetworkInBrowser <- function(nodes, edges, displayLabelType = "id", + nodeFontSize = 12, ...) { # Generate configuration - config <- generateCytoscapeConfig(nodes, edges, display_label_type = displayLabelType) + config <- generateCytoscapeConfig(nodes, edges, display_label_type = displayLabelType, node_font_size = nodeFontSize) # Create temporary filename temp_file <- tempfile(fileext = ".html")