--- a
+++ b/R/EnrichmentSpiralize.R
@@ -0,0 +1,301 @@
+#' Extract and Store Top Pathways for Each Sample
+#'
+#' This function processes a dataframe containing SSGSEA KEGG results. It allows specifying the number
+#' of top pathways to extract for each sample based on their scores, and stores these in a new dataframe
+#' with sample names and pathway scores.
+#'
+#' @param ssgsea_kegg Dataframe containing SSGSEA KEGG results with samples as columns and pathways as rows.
+#' @param nTop Integer, number of top pathways to select for each sample.
+#' @return A dataframe with columns 'Pathway', 'Sample', and 'Value' representing the top pathways for each sample.
+#' @importFrom utils head
+#' @export
+#' @examples
+#' # Example: Generating input data for the extract_ntop_pathways function
+#'
+#' # Define example pathways
+#' pathways <- c("Pathway_A", "Pathway_B", "Pathway_C", "Pathway_D", "Pathway_E",
+#'               "Pathway_F", "Pathway_G", "Pathway_H", "Pathway_I", "Pathway_J")
+#'
+#' # Define example samples
+#' samples <- c("Sample_1", "Sample_2", "Sample_3")
+#'
+#' # Generate random SSGSEA KEGG scores between 0 and 1
+#' set.seed(123)  # For reproducibility
+#' ssgsea_scores <- matrix(runif(length(pathways) * length(samples), min = 0, max = 1),
+#'                         nrow = length(pathways), ncol = length(samples),
+#'                         dimnames = list(pathways, samples))
+#'
+#' # Convert to a data frame
+#' ssgsea_kegg <- as.data.frame(ssgsea_scores)
+#'
+#' # Extract the top 3 pathways for each sample
+#' top_pathways <- extract_ntop_pathways(ssgsea_kegg, nTop = 3)
+#'
+extract_ntop_pathways <- function(ssgsea_kegg, nTop = 5) {
+  # Initialize an empty data frame to store the results
+  results <- data.frame(Pathway = character(), Sample = character(), Value = numeric(), stringsAsFactors = FALSE)
+
+  # Iterate through each sample, starting from the first column
+  for (i in 1:ncol(ssgsea_kegg)) {
+    sample_name <- colnames(ssgsea_kegg)[i]
+    # To avoid factor type errors, ensure the data is numeric
+    column_data <- as.numeric(ssgsea_kegg[[i]])
+    # Create a new data frame with numeric data for sorting and extracting
+    pathway_data <- data.frame(Pathway = rownames(ssgsea_kegg), Value = column_data, stringsAsFactors = FALSE)
+    # Sort by value in descending order and take the top nTop entries
+    top_paths <- utils::head(pathway_data[order(-pathway_data$Value),], nTop)
+    # Bind to the results data frame
+    results <- rbind(results, data.frame(Pathway = top_paths$Pathway, Sample = sample_name, Value = top_paths$Value))
+  }
+
+  return(results)
+}
+
+
+
+
+
+
+
+
+#' Extract Positive Pathways from SSGSEA Results and Select Random Samples
+#'
+#' This function processes the results of SSGSEA, specifically focusing on KEGG pathways.
+#' It extracts pathways with positive values from each sample and randomly selects a subset of them.
+#'
+#' @param ssgsea_kegg A matrix or data frame with pathways as rows and samples as columns.
+#' @param max_paths_per_sample Integer, maximum number of pathways to select per sample.
+#' @return A data frame with selected pathways, samples, and their corresponding values.
+#' @export
+#' @examples
+#' # Example: Generating input data for the extract_positive_pathways function
+#'
+#' # Define example pathways
+#' pathways <- c("Pathway_1", "Pathway_2", "Pathway_3", "Pathway_4", "Pathway_5",
+#'               "Pathway_6", "Pathway_7", "Pathway_8", "Pathway_9", "Pathway_10")
+#'
+#' # Define example samples
+#' samples <- c("Sample_A", "Sample_B", "Sample_C")
+#'
+#' # Generate random SSGSEA KEGG scores including both positive and negative values
+#' set.seed(456)  # For reproducibility
+#' ssgsea_scores <- matrix(rnorm(length(pathways) * length(samples), mean = 0, sd = 1),
+#'                         nrow = length(pathways), ncol = length(samples),
+#'                         dimnames = list(pathways, samples))
+#'
+#' # Convert to a data frame
+#' ssgsea_kegg <- as.data.frame(ssgsea_scores)
+#'
+#' # Use the extract_positive_pathways function to extract up to 3 positive pathways per sample
+#' selected_positive_pathways <- extract_positive_pathways(ssgsea_kegg, max_paths_per_sample = 3)
+#'
+extract_positive_pathways <- function(ssgsea_kegg, max_paths_per_sample = 5) {
+  # Initialize an empty data frame to store the results
+  results <- data.frame(Pathway = character(), Sample = character(), Value = numeric(), stringsAsFactors = FALSE)
+
+  # Iterate over each sample
+  for (i in 1:ncol(ssgsea_kegg)) {
+    sample_name <- colnames(ssgsea_kegg)[i]
+    # Ensure the data is numeric
+    column_data <- as.numeric(ssgsea_kegg[[i]])
+    # Create a new data frame with pathway names and values
+    pathway_data <- data.frame(Pathway = rownames(ssgsea_kegg), Value = column_data, stringsAsFactors = FALSE)
+    # Filter for positive values
+    positive_paths <- pathway_data[pathway_data$Value > 0,]
+    # If there are positive values, randomly select a few pathways
+    if (nrow(positive_paths) > 0) {
+      selected_paths <- positive_paths[sample(nrow(positive_paths), min(max_paths_per_sample, nrow(positive_paths))),]
+      # Bind to the results data frame
+      results <- rbind(results, data.frame(Pathway = selected_paths$Pathway, Sample = sample_name, Value = selected_paths$Value))
+    }
+  }
+  return(results)
+}
+
+
+
+
+
+
+
+
+
+#' Adjust Color Tone by Modifying Saturation and Luminance
+#'
+#' This function adjusts the saturation and luminance of a given color. It works by converting
+#' the color from RGB to Luv color space, applying the scaling factors to the saturation and luminance,
+#' and then converting it back to RGB.
+#'
+#' @param color A color in hexadecimal format (e.g., "#FF0000") or a valid R color name.
+#' @param saturation_scale Numeric, the scaling factor for saturation (values < 1 decrease saturation, values > 1 increase saturation).
+#' @param luminance_scale Numeric, the scaling factor for luminance (values < 1 darken the color, values > 1 lighten the color).
+#' @return Returns a color in hexadecimal format adjusted according to the provided scales.
+#' @importFrom grDevices convertColor col2rgb rgb
+#' @export
+#' @examples
+#'   adjusted_color <- adjust_color_tone("#FF0000", saturation_scale = 0.8, luminance_scale = 1.2)
+#'   print(adjusted_color)
+#'
+adjust_color_tone <- function(color, saturation_scale, luminance_scale) {
+  # Convert the input color to RGB, then to Luv color space
+  rgb <- t(grDevices::col2rgb(color) / 255)
+  luv <- grDevices::convertColor(rgb, from = "sRGB", to = "Luv")
+
+  # Apply scaling factors to saturation and luminance
+  luv[, 2:3] <- luv[, 2:3] * saturation_scale  # Adjust saturation
+  luv[, 1] <- luv[, 1] * luminance_scale       # Adjust luminance
+
+  # Convert back to RGB and correct color values to stay within the valid range
+  rgb_new <- grDevices::convertColor(luv, from = "Luv", to = "sRGB")
+  rgb_new <- rgb_new * 255
+  rgb_new[rgb_new > 255] <- 255  # Prevent color values from exceeding the maximum
+
+  # Convert adjusted RGB values back to hexadecimal format
+  apply(rgb_new, 1, function(x) grDevices::rgb(x[1], x[2], x[3], maxColorValue = 255))
+}
+
+
+
+
+
+
+
+
+
+#' Render a Spiral Plot Using Run-Length Encoding
+#'
+#' This function creates a spiral plot for visualizing sequential data in a compact and visually appealing way.
+#' It uses run-length encoding to represent the lengths and colors of sequences in the spiral.
+#'
+#' @param x A vector representing categories or segments.
+#' @param samples A vector indicating the sample each segment belongs to.
+#' @param values Numeric vector indicating the lengths of each segment.
+#' @param colors Character vector specifying the colors for each segment.
+#' @param labels Logical, whether to add labels to each segment.
+#' @importFrom grid gpar unit
+#' @importFrom spiralize spiral_rect spiral_text spiral_initialize spiral_track
+#' @export
+#' @return No return value, called for side effects. This function generates a spiral plot and optionally adds labels.
+#' @examples
+#' # Example: Creating a spiral plot using the spiral_newrle function
+#'
+#' # Define example data
+#' x <- c("A", "A", "B", "C")
+#' samples <- c("Sample1", "Sample1", "Sample2", "Sample2")
+#' values <- c(20, 30, 15, 35)
+#' colors <- c("red", "blue", "green", "purple")
+#' labels <- TRUE
+#'
+#' # Initialize the spiral plot, setting the x-axis range and scaling
+#' spiralize::spiral_initialize(xlim = c(0, sum(values)), scale_by = "curve_length",
+#'                  vp_param = list(x = grid::unit(0, "npc"), just = "left"))
+#'
+#' # Create a track for the spiral plot
+#' spiralize::spiral_track(height = 0.5)
+#'
+#' # Add segments to the spiral plot using run-length encoding
+#' spiral_newrle(x, samples, values, colors, labels)
+#'
+spiral_newrle <- function(x, samples, values, colors, labels = FALSE) {
+  x <- as.vector(x)  # Ensure x is a vector
+  samples <- as.vector(samples)  # Ensure samples is a vector
+  values <- as.numeric(values)  # Ensure values are numeric
+  position_start <- 0  # Initialize starting position
+  current_sample <- samples[1]  # Start with the first sample
+  cumulative_start <- position_start  # Initialize cumulative start for labels
+
+  # Loop through each value
+  for (i in seq_along(values)) {
+    position_end <- position_start + values[i]  # Calculate end position
+
+    # Use the specified color, defaulting to red if missing
+    color <- if (!is.na(colors[i])) colors[i] else "red"
+
+    # Draw the segment in the spiral
+    spiralize::spiral_rect(position_start, 0, position_end, 1, gp = grid::gpar(fill = color, col = NA))
+
+    # Check for sample change or last element
+    if (i == length(values) || samples[i + 1] != current_sample) {
+      if (labels) {
+        label_position <- (cumulative_start + position_end) / 2
+        spiralize::spiral_text(label_position, 0.5, current_sample, facing = "curved_inside", nice_facing = TRUE)
+      }
+      cumulative_start <- position_end  # Reset for next sample
+      if (i < length(values)) {
+        current_sample <- samples[i + 1]
+      }
+    }
+
+    position_start <- position_end  # Move to next start position
+  }
+}
+
+
+
+
+
+
+#' Create Spiral Plots with Legends Using 'spiralize' and 'ComplexHeatmap'
+#'
+#' This function initializes a spiral plot, adds tracks for pathways and samples,
+#' and generates legends based on the sample and pathway information in the provided data frame.
+#' It uses 'spiralize' for the spiral plot and 'ComplexHeatmap' for handling legends.
+#'
+#' @param results A data frame containing 'Pathway', 'Sample', 'Value', 'PathwayColor', and 'SampleColor' columns.
+#' @importFrom grid gpar
+#' @importFrom spiralize spiral_initialize spiral_track
+#' @importFrom ComplexHeatmap packLegend Legend draw
+#' @importFrom ggplot2 unit
+#' @export
+#' @return No return value, called for side effects. This function generates spiral plots and adds legends based on sample and pathway information.
+#' @examples
+#' # Example: Creating enrichment spiral plots with legends
+#'
+#' # Define the results data frame
+#' results <- data.frame(
+#'   Pathway = c("Pathway1", "Pathway1", "Pathway2", "Pathway2", "Pathway3"),
+#'   Sample = c("Sample1", "Sample1", "Sample2", "Sample2", "Sample3"),
+#'   Value = c(20, 30, 15, 35, 25),
+#'   PathwayColor = c("red", "red", "blue", "blue", "orange"),
+#'   SampleColor = c("green", "green", "purple", "purple", "cyan"),
+#'   stringsAsFactors = FALSE
+#' )
+#'
+#' # Create the enrichment spiral plots with legends
+#' enrichment_spiral_plots(results)
+#'
+enrichment_spiral_plots <- function(results) {
+  
+  if (!requireNamespace("systemfonts", quietly = TRUE)) {
+    stop("ggplot2 is required to use the function. Please install it.", call. = FALSE)
+  }
+
+  # Calculate the total value for setting the x-axis range
+  n <- sum(results$Value)
+
+  # Initialize the spiral plot
+  spiralize::spiral_initialize(xlim = c(0, n), scale_by = "curve_length",
+                               vp_param = list(x = ggplot2::unit(0, "npc"), just = "left"))
+
+  # Add a track for pathways
+  spiralize::spiral_track(height = 0.4)
+  spiral_newrle(results$Pathway, results$Sample, results$Value, results$PathwayColor, labels = FALSE)
+
+  # Add a track for samples
+  spiralize::spiral_track(height = 0.4)
+  spiral_newrle(results$Sample, results$Sample, results$Value, results$SampleColor, labels = TRUE)
+
+  # Generate legends based on sample, using unique pathway and color information
+  lgd_list <- tapply(1:nrow(results), results$Sample, function(ind) {
+    ComplexHeatmap::Legend(title = results$Sample[ind][1], at = unique(results$Pathway[ind]),
+                           legend_gp = grid::gpar(fill = unique(results$PathwayColor[ind])))
+  })
+
+  # Set the maximum height for the legends and draw them
+  lgd <- ComplexHeatmap::packLegend(list = lgd_list, max_height = ggplot2::unit(7, "inch"))
+  ComplexHeatmap::draw(lgd, x = ggplot2::unit(1, "npc") + ggplot2::unit(1, "mm"), just = "left")
+}
+
+
+
+