From e5a68034de5aa9a5d3e070cbf05b2683243cabfd Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 10 Jul 2024 00:05:51 -0400 Subject: [PATCH 01/69] Test to check for title of 3 plots Test to check for titles of 3 plots --- tests/testthat/test-renderer3-threeplots.R | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/testthat/test-renderer3-threeplots.R diff --git a/tests/testthat/test-renderer3-threeplots.R b/tests/testthat/test-renderer3-threeplots.R new file mode 100644 index 000000000..978502d07 --- /dev/null +++ b/tests/testthat/test-renderer3-threeplots.R @@ -0,0 +1,45 @@ + + +test_that("check if two plots exist", { + data1 <- data.frame( + x = c(1, 2, 3), # x-coordinates of the dots + y = c(1, 4, 9) # y-coordinates of the dots + ) + + plot1 <- ggplot(data1, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 3 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis") + + data2 <- data.frame( + x = c(1, 2), # x-coordinates of the dots + y = c(1, 4) # y-coordinates of the dots + ) + + plot2 <- ggplot(data2, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 2 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis") + + data3 <- data.frame( + x = c(2), # x-coordinates of the dots + y = c(2) # y-coordinates of the dots + ) + + plot3 <- ggplot(data3, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 1 Dot") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis") + + plot_list <- list( + plot1 = plot1, + plot2=plot2, + plot3=plot3 + ) + + info <-animint2HTML(plot_list) + titles <- getNodeSet(info$html, "//text[@class='plottitle']") + expect_match(xmlValue(titles[[1]]), "Plot of 3 Dots") + expect_match(xmlValue(titles[[2]]), "Plot of 2 Dots") + expect_match(xmlValue(titles[[3]]), "Plot of 1 Dot") +}) From d11bd6f6108cb92931d7ed2671a1d6cca3b3ab06 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Thu, 11 Jul 2024 20:25:35 -0400 Subject: [PATCH 02/69] added test to verify number of tables , their dimensions and number of points --- tests/testthat/test-renderer3-threeplots.R | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-renderer3-threeplots.R b/tests/testthat/test-renderer3-threeplots.R index 978502d07..93588f991 100644 --- a/tests/testthat/test-renderer3-threeplots.R +++ b/tests/testthat/test-renderer3-threeplots.R @@ -32,14 +32,37 @@ test_that("check if two plots exist", { xlab("X Axis") + ylab("Y Axis") plot_list <- list( - plot1 = plot1, + plot1=plot1, plot2=plot2, plot3=plot3 ) info <-animint2HTML(plot_list) titles <- getNodeSet(info$html, "//text[@class='plottitle']") + + points <- getNodeSet(info$html, "//circle[@class='geom']") + + number_of_points <- length(points) + tables <- getNodeSet(info$html, "//table[@style='display: inline-block;']") + svgs <- getNodeSet(info$html, "//svg[contains(@id,'')]") + number_of_tables<-length(tables) + + number_of_points <- length(points) + svg_dimensions <- lapply(svgs, function(svg) { + list( + height = as.numeric(xmlGetAttr(svg, "height")), + width = as.numeric(xmlGetAttr(svg, "width")) + ) + }) + for (dim in svg_dimensions) { + expect_equal(dim$height, 400) + expect_equal(dim$width, 400) + + } + expect_match(xmlValue(titles[[1]]), "Plot of 3 Dots") expect_match(xmlValue(titles[[2]]), "Plot of 2 Dots") expect_match(xmlValue(titles[[3]]), "Plot of 1 Dot") + expect_equal(number_of_points,6) + expect_equal(number_of_tables,3) }) From ae7bd35ef1135600c55c8603f38ff470bb34960e Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 16 Jul 2024 00:28:21 -0400 Subject: [PATCH 03/69] ramping up on animint.js ramping up on animint.js file by making temporary code changes and see how it changes the plots to understand how different functions in it work --- inst/htmljs/animint.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index d77109c3a..3568ca8bc 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -1065,7 +1065,8 @@ var animint = function (to_select, json_file) { get_stroke_width = get_attr("stroke"); }else{ get_stroke_width = function(d){ - return stroke_width; + //return stroke_width; + return 4 }; } From e516b9aef4b199ee5eab8e744a0d640484f163ec Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 16 Jul 2024 01:40:41 -0400 Subject: [PATCH 04/69] add all plots in single row add all plots in single row of a newly created outer table --- inst/htmljs/animint.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 3568ca8bc..224a94735 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -214,11 +214,21 @@ var animint = function (to_select, json_file) { // Save this geom and load it! update_geom(g_name, null); }; + var outer_table = d3.select("body").append("table") + .attr("id", "outerTable") + .style("width", "100%") + .style("border", "1px solid black"); + var row = outer_table.append("tr"); + // Add a cell to the row (1st row, 1st column) + var add_plot = function (p_name, p_info) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. - var plot_table = element.append("table").style("display", "inline-block"); + //var plot_table = element.append("table").style("display", "inline-block"); + var cell = row.append("td"); + var plot_table = cell.append("table") + .style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); var tdRight = plot_tr.append("td").attr("class", p_name+"_legend"); @@ -1065,8 +1075,8 @@ var animint = function (to_select, json_file) { get_stroke_width = get_attr("stroke"); }else{ get_stroke_width = function(d){ - //return stroke_width; - return 4 + return stroke_width; + }; } From 6ba7e6a0dc7e2c483be2fc323a7c5ccdc56eef0d Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 16 Jul 2024 19:46:26 -0400 Subject: [PATCH 05/69] used element variable used element variable which was not used earlier which led to failures locally. in this commit the plots are fixed in a single row of outer table, thus interactivity does not affect the relative positions of them. --- inst/htmljs/animint.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 224a94735..f77f303bb 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -214,10 +214,7 @@ var animint = function (to_select, json_file) { // Save this geom and load it! update_geom(g_name, null); }; - var outer_table = d3.select("body").append("table") - .attr("id", "outerTable") - .style("width", "100%") - .style("border", "1px solid black"); + var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); var row = outer_table.append("tr"); // Add a cell to the row (1st row, 1st column) @@ -227,8 +224,7 @@ var animint = function (to_select, json_file) { // columns: tdLeft and tdRight. //var plot_table = element.append("table").style("display", "inline-block"); var cell = row.append("td"); - var plot_table = cell.append("table") - .style("display", "inline-block"); + var plot_table = cell.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); var tdRight = plot_tr.append("td").attr("class", p_name+"_legend"); From 89c1e2f068bfb27cb3de22cfacc6a827bfd1cf73 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Thu, 18 Jul 2024 00:20:08 -0400 Subject: [PATCH 06/69] Update .gitignore knit-print fails for phantomjs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 815d6c977..2c60b1d28 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ *ANIMINT_TEST_FOO *pids.txt *~ +test-renderer1-knit-print.R From e53e7d91d1b1796858502b666b36021a974fb043 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 22 Jul 2024 11:51:35 -0400 Subject: [PATCH 07/69] put all plots in one column previously i put all plots in a single row of outer table, in this commit i put all plots in single column. i have also removed knit-print test because it had not passed on phantomjs and only passed for chromote in chromote testing branch --- inst/htmljs/animint.js | 23 ++- tests/testthat/test-renderer1-knit-print.R | 168 --------------------- 2 files changed, 17 insertions(+), 174 deletions(-) delete mode 100644 tests/testthat/test-renderer1-knit-print.R diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index f77f303bb..ffac67cf8 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -4,8 +4,9 @@ // var plot = new animint("#plot","path/to/plot.json"); // // Constructor for animint Object. -var animint = function (to_select, json_file) { +var animint = function (to_select, json_file) { + var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { @@ -214,15 +215,19 @@ var animint = function (to_select, json_file) { // Save this geom and load it! update_geom(g_name, null); }; - var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - var row = outer_table.append("tr"); - // Add a cell to the row (1st row, 1st column) - var add_plot = function (p_name, p_info) { + + //var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); + //var row = outer_table.append("tr"); + //Add a cell to the row (1st row, 1st column) + + + var add_plot = function (p_name, p_info,outer_table) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. //var plot_table = element.append("table").style("display", "inline-block"); + var row = outer_table.append("tr"); var cell = row.append("td"); var plot_table = cell.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); @@ -2026,8 +2031,14 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. + var construct_outer_table = function () { + var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); + //var row1 = outer_table1.append("tr"); + return outer_table; + } + var outer_table=construct_outer_table(); for (var p_name in response.plots) { - add_plot(p_name, response.plots[p_name]); + add_plot(p_name, response.plots[p_name],outer_table); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); diff --git a/tests/testthat/test-renderer1-knit-print.R b/tests/testthat/test-renderer1-knit-print.R deleted file mode 100644 index f69dcf27f..000000000 --- a/tests/testthat/test-renderer1-knit-print.R +++ /dev/null @@ -1,168 +0,0 @@ -acontext("knitting multiple animint plots in a single Rmd") - -knitr::knit_meta() #clear knitr 'metadata' -# Rmd.file <- "~/R/animint/inst/examples/test_knit_print.Rmd" ## Do we need this??? -Rmd.file <- system.file("examples", "test_knit_print.Rmd", - package = "animint2") -index.file <- file.path("animint-htmltest", "index.Rmd") - -file.copy(Rmd.file, index.file, overwrite=TRUE) -## https://github.com/rstudio/rmarkdown/issues/587#issuecomment-168437646 -## @yihui says "Do not use the output_dir argument of render()" -rmarkdown::render(index.file) -remDr$refresh() -Sys.sleep(1) -html <- getHTML() - -test_that("knit_print.animint renders five x axis titles", { - nodes <- getNodeSet(html, "//text[@class='xtitle']") - value.vec <- sapply(nodes, xmlValue) - expected.vec <- - c("first plot with color legend", - "second plot with color legend", - "non-interactive plot", - "position", - "segments") - expect_identical(value.vec, expected.vec) -}) - -test_that("segments and breakpoints are rendered", { - seg.list <- getNodeSet(html, "//g[@class='geom3_segment_signal']//line") - expect_equal(length(seg.list), 6) - break.list <- getNodeSet(html, "//g[@class='geom4_vline_signal']//line") - expect_equal(length(break.list), 5) -}) - -test_that("svg id property is unique", { - svg.list <- getNodeSet(html, "//svg") - attr.mat <- sapply(svg.list, xmlAttrs) - id.counts <- table(attr.mat["id",]) - expect_true(all(id.counts==1)) -}) - -all.list <- getNodeSet(html, "//*") -id.na.vec <- sapply(all.list, function(e){ - attr.vec.or.null <- xmlAttrs(e) - if("id" %in% names(attr.vec.or.null)){ - attr.vec.or.null[["id"]] - }else{ - NA - } -}) -## In HTML, all values are case-insensitive -## http://www.w3schools.com/tags/att_global_id.asp -lower.id.vec <- tolower(id.na.vec) -id.counts <- table(lower.id.vec) -(not.unique <- id.counts[1 < id.counts]) -test_that("id property is unique over entire page", { - expect_equal(length(not.unique), 0) -}) - -test_that("id must contain at least one character", { - expect_true(all(0 < nchar(names(id.counts)))) -}) - -test_that("id must not contain any space characters", { - expect_false(any(grepl(" ", names(id.counts)))) -}) - -## function to extract all circles from an HTML page -get_circles <- function(html=getHTML()) { - plot.names <- c("plot1top", "plot1bottom") - count.vec <- c() - for(i in seq_along(plot.names)){ - xpath <- sprintf("//div[@id='%s']//circle[@class='geom']", plot.names[[i]]) - circle.list <- getNodeSet(html, xpath) - count.vec[[i]] <- length(circle.list) - } - count.vec -} - -get_elements <- function(id){ - ##print("before div") - div <- remDr$findElement("id", id) - ## For debugging a NoSuchElement error I insert print statements. - ##print("before css selector") - tr.list <- div$findChildElements( - "css selector", "table.legend tr.label_variable") - a <- tr.list[[1]] - b <- tr.list[[2]] - ##print("before show_hide") - show_hide <- div$findChildElement("class name", "show_hide_selector_widgets") - ##print("before col_selector_widget") - widget <- div$findChildElement("class name", "label_variable_selector_widget") - list(a178=a, - b934=b, - show_hide=show_hide, - widget=widget) -} - -plot1top <- get_elements("plot1top") -plot1bottom <- get_elements("plot1bottom") - -# get_circles() returns a list of circles so comparing with list(expected, expected) - -test_that("clicking top legend adds/remove points", { - expect_equal(get_circles(), list(10, 10)) - - clickID("plot1top_q_label_variable_a178") - expect_equal(get_circles(), list(5, 10)) - - clickID("plot1top_q_label_variable_b934") - expect_equal(get_circles(), list(0, 10)) - - clickID("plot1top_q_label_variable_b934") - expect_equal(get_circles(), list(5, 10)) - - clickID("plot1top_q_label_variable_a178") - expect_equal(get_circles(), list(10, 10)) -}) - -test_that("clicking bottom legend adds/remove points", { - expect_equal(get_circles(), list(10, 10)) - - clickID("plot1bottom_q_label_variable_a178") - expect_equal(get_circles(), list(10, 5)) - - clickID("plot1bottom_q_label_variable_b934") - expect_equal(get_circles(), list(10, 0)) - - clickID("plot1bottom_q_label_variable_b934") - expect_equal(get_circles(), list(10, 5)) - - clickID("plot1bottom_q_label_variable_a178") - expect_equal(get_circles(), list(10, 10)) -}) - -plot1top$show_hide$clickElement() -s.div <- plot1top$widget$findChildElement("class name", "selectize-input") -s.div$clickElement() - -test_that("top widget adds/remove points", { - expect_equal(get_circles(), list(10, 10)) - remDr$sendKeysToActiveElement(list(key="backspace")) - expect_equal(get_circles(), list(5, 10)) - remDr$sendKeysToActiveElement(list(key="backspace")) - expect_equal(get_circles(), list(0, 10)) - remDr$sendKeysToActiveElement(list("a", key="enter")) - expect_equal(get_circles(), list(5, 10)) - remDr$sendKeysToActiveElement(list("b", key="enter")) - expect_equal(get_circles(), list(10, 10)) -}) - -plot1bottom$show_hide$clickElement() -s.div <- - plot1bottom$widget$findChildElement("class name", "selectize-input") -s.div$clickElement() - -test_that("bottom widget adds/remove points", { - expect_equal(get_circles(), list(10, 10)) - remDr$sendKeysToActiveElement(list(key="backspace")) - expect_equal(get_circles(), list(10, 5)) - remDr$sendKeysToActiveElement(list(key="backspace")) - expect_equal(get_circles(), list(10, 0)) - remDr$sendKeysToActiveElement(list("a", key="enter")) - expect_equal(get_circles(), list(10, 5)) - remDr$sendKeysToActiveElement(list("b", key="enter")) - expect_equal(get_circles(), list(10, 10)) -}) From 0ae75de88fb55b58b39ad98ac342326281f8068f Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 22 Jul 2024 15:04:12 -0400 Subject: [PATCH 08/69] add 2 plots per row and then make a new row in the newly created outer table, add 2 plots per row and then make a new row. this implementation will be built upon to complete if it is the suitable. --- helper-functions2.R | 19 +++++++++++++++++++ inst/htmljs/animint.js | 30 +++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 helper-functions2.R diff --git a/helper-functions2.R b/helper-functions2.R new file mode 100644 index 000000000..764126b15 --- /dev/null +++ b/helper-functions2.R @@ -0,0 +1,19 @@ +sendKey <- function(key, code, keyCode) { + remDr$Input$dispatchKeyEvent(type = "keyDown", key = key, code = code, windowsVirtualKeyCode = keyCode, nativeVirtualKeyCode = keyCode) + remDr$Input$dispatchKeyEvent(type = "keyUp", key = key, code = code, windowsVirtualKeyCode = keyCode, nativeVirtualKeyCode = keyCode) +} + +clickID <- function(...){ + v <- c(...) + stopifnot(length(v) == 1) + runtime_evaluate(script=sprintf("document.getElementById('%s').dispatchEvent(new CustomEvent('click'))", as.character(v))) +} + +runtime_evaluate <- function(script=NULL,return.value=FALSE){ + eval.result<- remDr$Runtime$evaluate(script,returnByValue = TRUE) + if (return.value){ + eval.result$result$value + }else{ + eval.result + } +} \ No newline at end of file diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index ffac67cf8..3cec6e623 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -6,7 +6,7 @@ // Constructor for animint Object. var animint = function (to_select, json_file) { - + console.log("hello") var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { @@ -222,14 +222,18 @@ var animint = function (to_select, json_file) { //Add a cell to the row (1st row, 1st column) - var add_plot = function (p_name, p_info,outer_table) { + var add_plot = function (p_name, p_info,outer_table,rowIdx=1,colIdx=1) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. //var plot_table = element.append("table").style("display", "inline-block"); - var row = outer_table.append("tr"); - var cell = row.append("td"); - var plot_table = cell.append("table").style("display", "inline-block"); + //var row = outer_table.append("tr"); + //var cell = row.append("td"); + //var cell = outer_table.select(`tr:nth-child(${rowIdx + 1})`).select(`td:nth-child(${colIdx + 1})`); + + //var plot_table = cell.append("table").style("display", "inline-block"); + //var outer_table = d3.select("#outerTable") + var plot_table = outer_table.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); var tdRight = plot_tr.append("td").attr("class", p_name+"_legend"); @@ -2033,16 +2037,28 @@ var animint = function (to_select, json_file) { // Add plots. var construct_outer_table = function () { var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row1 = outer_table1.append("tr"); + //var row = outer_table.append("tr"); + //var cell = row.append("td"); return outer_table; } var outer_table=construct_outer_table(); + var current_row=outer_table.append("tr") + var current_col=current_row.append("td") + var count=0; for (var p_name in response.plots) { - add_plot(p_name, response.plots[p_name],outer_table); + count=count+1 + if (count>2){ + count=1 + current_row=outer_table.append("tr") + current_col=current_row.append("td") + } + //console.log(count) + add_plot(p_name, response.plots[p_name],current_col); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); + current_col=current_row.append("td") } // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { From adf012b8e5ab500df52ed1ef4aa24ff4c6a02a2f Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Fri, 26 Jul 2024 16:16:53 -0400 Subject: [PATCH 09/69] table with 3 plots per row or user defined layout if the user has given input of row and column in theme animint, plots will be put in that location. but user needs to mention rows and columns for all plots. if the user does not want that option older functionality will work but with a new change of 3 plots per row and then a new row. --- R/theme-elements.r | 7 ++- R/z_animint.R | 11 ++-- inst/htmljs/animint.js | 111 ++++++++++++++++++++++++++++++----------- 3 files changed, 95 insertions(+), 34 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index d72b41507..76fbd069c 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -282,7 +282,10 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { plot.caption = el_def("element_text", "title"), plot.margin = el_def("margin"), - aspect.ratio = el_def("character") + aspect.ratio = el_def("character"), + + row = el_def("character"), + col = el_def("character") ) @@ -297,6 +300,8 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { # @param el an element # @param elname the name of the element validate_element <- function(el, elname) { + #print(el) + #print(elname) eldef <- .element_tree[[elname]] if (is.null(eldef)) { diff --git a/R/z_animint.R b/R/z_animint.R index b412bd454..cfdef8713 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -37,7 +37,7 @@ parsePlot <- function(meta, plot, plot.name){ ## Now ggplot specifies panel.margin in 'pt' instead of 'lines' plot.info$panel_margin_lines <- pt.to.lines(theme.pars$panel.margin) - ## No legend if theme(legend.postion="none"). + ## No legend if theme(legend.position="none"). plot.info$legend <- if(theme.pars$legend.position != "none"){ getLegendList(built) } @@ -103,7 +103,9 @@ parsePlot <- function(meta, plot, plot.name){ # extract minor grid lines plot.info$grid_minor <- get_grid(theme.pars$panel.grid.minor, theme.pars, plot.info, meta, built, major = F) - + theme <- plot_theme(built$plot) + plot.info$row <-theme$row + plot.info$col <-theme$col ## Flip labels if coords are flipped - transform does not take care ## of this. Do this BEFORE checking if it is blank or not, so that ## individual axes can be hidden appropriately, e.g. #1. @@ -249,6 +251,7 @@ storeLayer <- function(meta, g, g.data.varied){ animint2dir <- function(plot.list, out.dir = NULL, json.file = "plot.json", open.browser = interactive(), css.file = "") { + if(is.null(out.dir)){ out.dir <- tempfile() } @@ -359,6 +362,7 @@ animint2dir <- function(plot.list, out.dir = NULL, if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. + #print(parsed_info$plot.info) AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot ggplot.list[[list.name]]$built <- parsed_info$built @@ -638,7 +642,7 @@ animint2dir <- function(plot.list, out.dir = NULL, stop("missing first selector variable") } } - + meta$plots <- AllPlotsInfo meta$time <- AnimationInfo$time meta$timeValues <- AnimationInfo$timeValues @@ -690,6 +694,7 @@ getLegendList <- function(plistextra){ position <- theme$legend.position text <- theme$legend.text title <- theme$legend.title + #print(theme$row) # by default, guide boxes are vertically aligned if(is.null(theme$legend.box)) theme$legend.box <- "vertical" else theme$legend.box diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 3cec6e623..c36e8e2c4 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -6,7 +6,13 @@ // Constructor for animint Object. var animint = function (to_select, json_file) { - console.log("hello") + //console.log(json_file) + fetch(json_file) + .then(response => response.json()) + .then(data => { + console.log(data); // Prints the entire JSON data + }) + .catch(error => console.error('Error fetching the JSON file:', error)); var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { @@ -217,22 +223,11 @@ var animint = function (to_select, json_file) { }; - //var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row = outer_table.append("tr"); - //Add a cell to the row (1st row, 1st column) - - - var add_plot = function (p_name, p_info,outer_table,rowIdx=1,colIdx=1) { + var add_plot = function (p_name, p_info,outer_table) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. - //var plot_table = element.append("table").style("display", "inline-block"); - //var row = outer_table.append("tr"); - //var cell = row.append("td"); - //var cell = outer_table.select(`tr:nth-child(${rowIdx + 1})`).select(`td:nth-child(${colIdx + 1})`); - //var plot_table = cell.append("table").style("display", "inline-block"); - //var outer_table = d3.select("#outerTable") var plot_table = outer_table.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); @@ -2035,31 +2030,87 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - var construct_outer_table = function () { - var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row = outer_table.append("tr"); - //var cell = row.append("td"); + + var user_defined_layout= false + var count=0 + for (var p_name in response.plots) { + if (count>0){ + break; + } + if ('row' in response.plots[p_name]) { + user_defined_layout= true +} +count=count+1 +} + + console.log(user_defined_layout) + if(user_defined_layout){ + var maximum_row= 0 + var maximum_column= 0 + for (var p_name in response.plots) { + if (response.plots[p_name].row>maximum_row){ + maximum_row=response.plots[p_name].row + } + if (response.plots[p_name].col>maximum_column){ + maximum_column=response.plots[p_name].col + } + } + + var construct_outer_table = function () { + var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); + for (var i = 0; i <=maximum_row; i++) { + var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); + for (var j = 0; j <=maximum_column; j++){ + current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid white").style("width", "500px"); + } + } + return outer_table; } var outer_table=construct_outer_table(); - var current_row=outer_table.append("tr") - var current_col=current_row.append("td") - var count=0; - for (var p_name in response.plots) { - count=count+1 - if (count>2){ - count=1 - current_row=outer_table.append("tr") - current_col=current_row.append("td") - } - //console.log(count) - add_plot(p_name, response.plots[p_name],current_col); + + for (var p_name in response.plots) { + id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col + var cell= d3.select(id); + + add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); - current_col=current_row.append("td") } + }else{ + var construct_outer_table = function () { + var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); + //var row = outer_table.append("tr"); + //var cell = row.append("td"); + return outer_table; + } + var outer_table=construct_outer_table(); + var current_row=outer_table.append("tr") + var current_col=current_row.append("td") + var count=0; + for (var p_name in response.plots) { + count=count+1 + if (count>2){ + count=1 + current_row=outer_table.append("tr") + current_col=current_row.append("td") + } + //console.log(count) + add_plot(p_name, response.plots[p_name],current_col); + add_legend(p_name, response.plots[p_name]); + // Append style sheet to document head. + css.appendChild(document.createTextNode(styles.join(" "))); + document.head.appendChild(css); + current_col=current_row.append("td") + } + + } + + + + // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { add_selector(s_name, response.selectors[s_name]); From a2b8c0a15f9861660f802968333c1b5bb4d0a966 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Fri, 26 Jul 2024 16:30:43 -0400 Subject: [PATCH 10/69] test for putting plots in specific location of outer table test for putting plots in specific location of outer table by passing arguments of row and column in theme. i am working on making it compatible with theme as well --- tests/testthat/test-renderer3-fourplots.R | 83 +++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 tests/testthat/test-renderer3-fourplots.R diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R new file mode 100644 index 000000000..a1e4b5c89 --- /dev/null +++ b/tests/testthat/test-renderer3-fourplots.R @@ -0,0 +1,83 @@ + + +test_that("check if two plots exist", { + data1 <- data.frame( + x = c(1, 2, 3), # x-coordinates of the dots + y = c(1, 4, 9) # y-coordinates of the dots + ) + + plot1 <- ggplot(data1, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 3 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=0) + #theme(plot.title = element_text(color = "purple", size = 20, face = "bold")) + data2 <- data.frame( + x = c(1, 2), # x-coordinates of the dots + y = c(1, 4) # y-coordinates of the dots + ) + + plot2 <- ggplot(data2, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 2 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=2) + + data3 <- data.frame( + x = c(2), # x-coordinates of the dots + y = c(2) # y-coordinates of the dots + ) + + plot3 <- ggplot(data3, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 1 Dot") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) + plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + + geom_point() + + labs(title = "Car Weight vs. MPG") + + theme( + plot.title = element_text(color = "purple", size = 20, face = "bold"), + panel.background = element_rect(fill = "lightyellow"), + panel.grid.major = element_line(color = "gray", size = 0.8), + axis.title.x = element_text(color = "blue", size = 14), + axis.text.y = element_text(color = "red", size = 12), + legend.position = "bottom", + legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5), + row=1, + col=1 + ) + + plot_list <- list( + plot1=plot1, + plot2=plot2, + plot3=plot3, + plot4=plot4 + ) + + info <-animint2HTML(plot_list) + titles <- getNodeSet(info$html, "//text[@class='plottitle']") + + points <- getNodeSet(info$html, "//circle[@class='geom']") + + number_of_points <- length(points) + tables <- getNodeSet(info$html, "//table[@style='display: inline-block;']") + svgs <- getNodeSet(info$html, "//svg[contains(@id,'')]") + number_of_tables<-length(tables) + + number_of_points <- length(points) + svg_dimensions <- lapply(svgs, function(svg) { + list( + height = as.numeric(xmlGetAttr(svg, "height")), + width = as.numeric(xmlGetAttr(svg, "width")) + ) + }) + for (dim in svg_dimensions) { + expect_equal(dim$height, 400) + expect_equal(dim$width, 400) + + } + + #expect_match(xmlValue(titles[[1]]), "Plot of 3 Dots") + #expect_match(xmlValue(titles[[2]]), "Plot of 2 Dots") + #expect_match(xmlValue(titles[[3]]), "Plot of 1 Dot") + #expect_equal(number_of_points,6) + #expect_equal(number_of_tables,3) +}) From 45bbcf7705c26744267f2b679f39ca4d48a15dbe Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sun, 28 Jul 2024 00:32:19 -0400 Subject: [PATCH 11/69] check if svg element exists in a particular location of outer table check if svg element exists in a particular location of outer table. --- inst/htmljs/animint.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index c36e8e2c4..4502fc5c0 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2079,6 +2079,18 @@ count=count+1 css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); } + var parentElement1 = d3.select('#row1col1'); + var parentElement2 = d3.select('#row1col0'); + if (!parentElement1.select('svg').empty()) { + console.log("An element exists in #row1col1."); +} else { + console.log("No element found in #row1col1."); +} +if (!parentElement2.select('svg').empty()) { + console.log("An element exists in #row1col0."); +} else { + console.log("No element found in #row1col0."); +} }else{ var construct_outer_table = function () { var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); @@ -2105,7 +2117,6 @@ count=count+1 document.head.appendChild(css); current_col=current_row.append("td") } - } From 4951b0bebfadab18eb5e6b5e32cf29cc32fa18fd Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sun, 28 Jul 2024 01:45:25 -0400 Subject: [PATCH 12/69] error message if user forgets to add either row or column error message if user adds row and not column or vice versa --- inst/htmljs/animint.js | 15 +++++++++------ tests/testthat/test-renderer3-fourplots.R | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 4502fc5c0..75b175395 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2032,15 +2032,18 @@ var animint = function (to_select, json_file) { // Add plots. var user_defined_layout= false - var count=0 + //var count=0 for (var p_name in response.plots) { - if (count>0){ - break; - } - if ('row' in response.plots[p_name]) { + //console.log(response.plots[p_name].title) + if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { user_defined_layout= true } -count=count+1 +if ('row' in response.plots[p_name] && !('col' in response.plots[p_name])){ + throw new Error("You forgot to add column in "+response.plots[p_name].title+" plot."); +} +if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ + throw new Error("You forgot to add row in "+response.plots[p_name].title+" plot."); +} } console.log(user_defined_layout) diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index a1e4b5c89..84a79de17 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -29,7 +29,7 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) + xlab("X Axis") + ylab("Y Axis")+theme(row=0) plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + labs(title = "Car Weight vs. MPG") + From 96c5a458a161f5d058c08cbf3df47315d6193517 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 00:10:06 -0400 Subject: [PATCH 13/69] made function to check svg made a function to check if svg element exists at a specific location of the outer table. so this function will return true if plot exists at that location, false otherwise --- inst/htmljs/animint.js | 31 +++++++++++++---------- tests/testthat/test-renderer3-fourplots.R | 10 ++++---- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 75b175395..56efecfca 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2030,6 +2030,16 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. + + var check_svg = function (row_number,col_number) { + id="#row"+row_number+"col"+col_number + parentElement= d3.select(id) + if (!parentElement.select('svg').empty()) { + return true + }else{ + return false + } + } var user_defined_layout= false //var count=0 @@ -2046,7 +2056,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - console.log(user_defined_layout) + if(user_defined_layout){ var maximum_row= 0 var maximum_column= 0 @@ -2082,18 +2092,13 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); } - var parentElement1 = d3.select('#row1col1'); - var parentElement2 = d3.select('#row1col0'); - if (!parentElement1.select('svg').empty()) { - console.log("An element exists in #row1col1."); -} else { - console.log("No element found in #row1col1."); -} -if (!parentElement2.select('svg').empty()) { - console.log("An element exists in #row1col0."); -} else { - console.log("No element found in #row1col0."); -} + for (var i = 0; i <=maximum_row; i++) { + for (var j = 0; j <=maximum_column; j++){ + if (check_svg(i,j)){ + console.log("row"+i+" "+"col"+j) + } + } + } }else{ var construct_outer_table = function () { var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index 84a79de17..c06d6bb3e 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -9,7 +9,7 @@ test_that("check if two plots exist", { plot1 <- ggplot(data1, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 3 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=0) + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) #theme(plot.title = element_text(color = "purple", size = 20, face = "bold")) data2 <- data.frame( x = c(1, 2), # x-coordinates of the dots @@ -19,7 +19,7 @@ test_that("check if two plots exist", { plot2 <- ggplot(data2, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 2 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=2) + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) data3 <- data.frame( x = c(2), # x-coordinates of the dots @@ -29,7 +29,7 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0) + xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=0) plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + labs(title = "Car Weight vs. MPG") + @@ -41,8 +41,8 @@ test_that("check if two plots exist", { axis.text.y = element_text(color = "red", size = 12), legend.position = "bottom", legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5), - row=1, - col=1 + row=2, + col=2 ) plot_list <- list( From 0a78f92abc7abdcd18f26f70eedfe4eff4f06c14 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 11:46:09 -0400 Subject: [PATCH 14/69] put plots with fixed locations first, then put all other plots put plots with fixed locations first if the user has passed both row and column arguments in theme for that plot, then put all other plots in available empty locations. if user passes only row or column argument then give error message --- inst/htmljs/animint.js | 76 +++++++++++------------ tests/testthat/test-renderer3-fourplots.R | 11 ++-- 2 files changed, 42 insertions(+), 45 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 56efecfca..7b2e60c19 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2041,10 +2041,8 @@ var animint = function (to_select, json_file) { } } - var user_defined_layout= false - //var count=0 + for (var p_name in response.plots) { - //console.log(response.plots[p_name].title) if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { user_defined_layout= true } @@ -2054,13 +2052,15 @@ if ('row' in response.plots[p_name] && !('col' in response.plots[p_name])){ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ throw new Error("You forgot to add row in "+response.plots[p_name].title+" plot."); } -} - + } - if(user_defined_layout){ + + var maximum_row= 0 var maximum_column= 0 + var count=0 for (var p_name in response.plots) { + count=count+1 if (response.plots[p_name].row>maximum_row){ maximum_row=response.plots[p_name].row } @@ -2070,7 +2070,12 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } var construct_outer_table = function () { + var count_dimensions = Math.ceil(Math.sqrt(count))-1; var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); + maximum_row=Math.max(maximum_row,count_dimensions) + maximum_column=Math.max(maximum_column,count_dimensions) + console.log(maximum_row) + console.log(maximum_column) for (var i = 0; i <=maximum_row; i++) { var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); for (var j = 0; j <=maximum_column; j++){ @@ -2083,6 +2088,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ var outer_table=construct_outer_table(); for (var p_name in response.plots) { + if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col var cell= d3.select(id); @@ -2092,40 +2098,32 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); } - for (var i = 0; i <=maximum_row; i++) { - for (var j = 0; j <=maximum_column; j++){ - if (check_svg(i,j)){ - console.log("row"+i+" "+"col"+j) - } - } - } - }else{ - var construct_outer_table = function () { - var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row = outer_table.append("tr"); - //var cell = row.append("td"); - return outer_table; - } - var outer_table=construct_outer_table(); - var current_row=outer_table.append("tr") - var current_col=current_row.append("td") - var count=0; - for (var p_name in response.plots) { - count=count+1 - if (count>2){ - count=1 - current_row=outer_table.append("tr") - current_col=current_row.append("td") - } - //console.log(count) - add_plot(p_name, response.plots[p_name],current_col); - add_legend(p_name, response.plots[p_name]); - // Append style sheet to document head. - css.appendChild(document.createTextNode(styles.join(" "))); - document.head.appendChild(css); - current_col=current_row.append("td") - } } + pointer_row=0 + pointer_column=0 + for (var p_name in response.plots) { + if (!('row' in response.plots[p_name])){ + while (check_svg(pointer_row,pointer_column)) { + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 + } + } + id= "#row"+pointer_row+"col"+pointer_column + //console.log(id) + var cell= d3.select(id); + + add_plot(p_name, response.plots[p_name],cell); + add_legend(p_name, response.plots[p_name]); + // Append style sheet to document head. + css.appendChild(document.createTextNode(styles.join(" "))); + document.head.appendChild(css); + +} + } + + diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index c06d6bb3e..c2307113d 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -19,7 +19,7 @@ test_that("check if two plots exist", { plot2 <- ggplot(data2, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 2 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) + xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=1) data3 <- data.frame( x = c(2), # x-coordinates of the dots @@ -29,8 +29,9 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=0) - plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) + + plot4 <- ggplot(mtcars, aes(x = wt, y = mpg))+ geom_point() + labs(title = "Car Weight vs. MPG") + theme( @@ -40,9 +41,7 @@ test_that("check if two plots exist", { axis.title.x = element_text(color = "blue", size = 14), axis.text.y = element_text(color = "red", size = 12), legend.position = "bottom", - legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5), - row=2, - col=2 + legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5) ) plot_list <- list( From a692b3de664f2def0a6b03779ccdfbf10085a996 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 20:39:53 -0400 Subject: [PATCH 15/69] changed scope of implicitly global variables changed scope of implicitly global variables for global-varaibles test to pass. made the code more modular --- inst/htmljs/animint.js | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 7b2e60c19..5f9ce3631 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2030,10 +2030,11 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - + + var check_svg = function (row_number,col_number) { - id="#row"+row_number+"col"+col_number - parentElement= d3.select(id) + var id="#row"+row_number+"col"+col_number + var parentElement= d3.select(id) if (!parentElement.select('svg').empty()) { return true }else{ @@ -2054,11 +2055,14 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - - - var maximum_row= 0 - var maximum_column= 0 - var count=0 + var maximum_row= 0 + var maximum_column= 0 + var construct_outer_table = function () { + var count=0 + + var find_maximum_dimensions = function () { + + for (var p_name in response.plots) { count=count+1 if (response.plots[p_name].row>maximum_row){ @@ -2068,14 +2072,14 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ maximum_column=response.plots[p_name].col } } - - var construct_outer_table = function () { + } + find_maximum_dimensions() var count_dimensions = Math.ceil(Math.sqrt(count))-1; var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - console.log(maximum_row) - console.log(maximum_column) + //console.log(maximum_row) + //console.log(maximum_column) for (var i = 0; i <=maximum_row; i++) { var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); for (var j = 0; j <=maximum_column; j++){ @@ -2089,7 +2093,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ for (var p_name in response.plots) { if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { - id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col + var id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2099,8 +2103,8 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ document.head.appendChild(css); } } - pointer_row=0 - pointer_column=0 + var pointer_row=0 + var pointer_column=0 for (var p_name in response.plots) { if (!('row' in response.plots[p_name])){ while (check_svg(pointer_row,pointer_column)) { @@ -2110,7 +2114,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ pointer_row=pointer_row+1 } } - id= "#row"+pointer_row+"col"+pointer_column + var id= "#row"+pointer_row+"col"+pointer_column //console.log(id) var cell= d3.select(id); @@ -2122,8 +2126,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - - + From 95cd30f5ae8ea233a50d56daf81008708f53bcb4 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 23:55:26 -0400 Subject: [PATCH 16/69] Give error message if only row or col is added in theme Give error message in R session if only row or col is added in theme function. --- R/z_animint.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/R/z_animint.R b/R/z_animint.R index cfdef8713..4394d346e 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -362,7 +362,13 @@ animint2dir <- function(plot.list, out.dir = NULL, if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. - #print(parsed_info$plot.info) + #print(parsed_info$plot.info$title) + if (!is.null(parsed_info$plot.info$row) && is.null(parsed_info$plot.info$col)) { + stop("You forget to add col in ",parsed_info$plot.info$title) + } + if (!is.null(parsed_info$plot.info$col) && is.null(parsed_info$plot.info$row)) { + stop("You forget to add row in ",parsed_info$plot.info$title) + } AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot ggplot.list[[list.name]]$built <- parsed_info$built From 6999ac7b1d48fcf310a927b123d10769f3e65398 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 31 Jul 2024 15:00:07 -0400 Subject: [PATCH 17/69] theme_animint now accepts dimensions and not theme changed from theme to theme_animint for taking row and col arguments, removed the code to show browser side error if the user fails to add only row or col. because that is not necessary now because code to show error message in R session itself is there now. also changed theme function to theme_animint in the test i had wrote for passing row and col arguments --- R/theme-elements.r | 5 +---- R/theme.r | 11 +++++------ R/z_animint.R | 15 ++++++++------- R/z_animintHelpers.R | 10 ++++++++++ inst/htmljs/animint.js | 22 +++------------------- tests/testthat/test-renderer3-fourplots.R | 8 ++++---- 6 files changed, 31 insertions(+), 40 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index 76fbd069c..c616ad195 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -282,10 +282,7 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { plot.caption = el_def("element_text", "title"), plot.margin = el_def("margin"), - aspect.ratio = el_def("character"), - - row = el_def("character"), - col = el_def("character") + aspect.ratio = el_def("character") ) diff --git a/R/theme.r b/R/theme.r index 8730232d0..bffbc9e75 100644 --- a/R/theme.r +++ b/R/theme.r @@ -353,20 +353,19 @@ print.theme <- function(x, ...) utils::str(x) #' } theme <- function(..., complete = FALSE, validate = TRUE) { elements <- list(...) - + if (!is.null(elements$axis.ticks.margin)) { warning("`axis.ticks.margin` is deprecated. Please set `margin` property ", " of `axis.text` instead", call. = FALSE) elements$axis.ticks.margin <- NULL } - + # Check that all elements have the correct class (element_text, unit, etc) if (validate) { mapply(validate_element, elements, names(elements)) } - - structure(elements, class = c("theme", "gganimint"), - complete = complete, validate = validate) + + structure(elements, class = c("theme", "gganimint"),complete = complete, validate = validate) } @@ -494,7 +493,7 @@ update_theme <- function(oldtheme, newtheme) { # the default theme -- just replace everything with newtheme if (attr(newtheme, "complete")) return(newtheme) - + # These are elements in newtheme that aren't already set in oldtheme. # They will be pulled from the default theme. newitems <- !names(newtheme) %in% names(oldtheme) diff --git a/R/z_animint.R b/R/z_animint.R index 4394d346e..528a407e3 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -104,8 +104,6 @@ parsePlot <- function(meta, plot, plot.name){ plot.info$grid_minor <- get_grid(theme.pars$panel.grid.minor, theme.pars, plot.info, meta, built, major = F) theme <- plot_theme(built$plot) - plot.info$row <-theme$row - plot.info$col <-theme$col ## Flip labels if coords are flipped - transform does not take care ## of this. Do this BEFORE checking if it is blank or not, so that ## individual axes can be hidden appropriately, e.g. #1. @@ -202,7 +200,9 @@ parsePlot <- function(meta, plot, plot.name){ options_list <- getWidthAndHeight(plot$theme) options_list <- setUpdateAxes(plot$theme, options_list) plot.info$options <- options_list - + + plot.info$position <- getRowAndColumn(plot$theme) + list( plot.info=plot.info, ggplot=plot, @@ -361,13 +361,14 @@ animint2dir <- function(plot.list, out.dir = NULL, p <- plot.list[[list.name]] if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing + parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. #print(parsed_info$plot.info$title) - if (!is.null(parsed_info$plot.info$row) && is.null(parsed_info$plot.info$col)) { - stop("You forget to add col in ",parsed_info$plot.info$title) + if (!is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col)) { + stop("You passed row but not the col argument for ",parsed_info$plot.info$title) } - if (!is.null(parsed_info$plot.info$col) && is.null(parsed_info$plot.info$row)) { - stop("You forget to add row in ",parsed_info$plot.info$title) + if (!is.null(parsed_info$plot.info$position$col) && is.null(parsed_info$plot.info$position$row)) { + stop("You passed col but not the row argument for ",parsed_info$plot.info$title) } AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot diff --git a/R/z_animintHelpers.R b/R/z_animintHelpers.R index 1d9432a83..5aa87469b 100644 --- a/R/z_animintHelpers.R +++ b/R/z_animintHelpers.R @@ -147,6 +147,16 @@ getWidthAndHeight <- function(theme){ options_list } +getRowAndColumn <- function(theme){ + options_list <- list() + for(rc in c("row", "col")){ + arc <- paste0("animint.", rc) + options_list[[rc]] <- if(arc %in% names(theme)){ + theme[[arc]] + } + } + options_list +} setUpdateAxes <- function(theme, options_list){ update_axes <- "animint.update_axes" diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 5f9ce3631..fb0446f6e 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2043,18 +2043,6 @@ var animint = function (to_select, json_file) { } - for (var p_name in response.plots) { - if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { - user_defined_layout= true -} -if ('row' in response.plots[p_name] && !('col' in response.plots[p_name])){ - throw new Error("You forgot to add column in "+response.plots[p_name].title+" plot."); -} -if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ - throw new Error("You forgot to add row in "+response.plots[p_name].title+" plot."); -} - } - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2092,8 +2080,8 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ var outer_table=construct_outer_table(); for (var p_name in response.plots) { - if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { - var id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col + if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position) { + var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2106,7 +2094,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ var pointer_row=0 var pointer_column=0 for (var p_name in response.plots) { - if (!('row' in response.plots[p_name])){ + if (!('row' in response.plots[p_name].position)){ while (check_svg(pointer_row,pointer_column)) { pointer_column=pointer_column+1 if (pointer_column>maximum_column){ @@ -2127,10 +2115,6 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - - - - // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { add_selector(s_name, response.selectors[s_name]); diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index c2307113d..daf84c580 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -9,7 +9,7 @@ test_that("check if two plots exist", { plot1 <- ggplot(data1, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 3 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) + xlab("X Axis") + ylab("Y Axis") #theme(plot.title = element_text(color = "purple", size = 20, face = "bold")) data2 <- data.frame( x = c(1, 2), # x-coordinates of the dots @@ -19,7 +19,7 @@ test_that("check if two plots exist", { plot2 <- ggplot(data2, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 2 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=1) + xlab("X Axis") + ylab("Y Axis") data3 <- data.frame( x = c(2), # x-coordinates of the dots @@ -29,7 +29,7 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=1,col=1) plot4 <- ggplot(mtcars, aes(x = wt, y = mpg))+ geom_point() + @@ -42,7 +42,7 @@ test_that("check if two plots exist", { axis.text.y = element_text(color = "red", size = 12), legend.position = "bottom", legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5) - ) + )+theme_animint(row=0,col=1) plot_list <- list( plot1=plot1, From 91d0abb7ab14167e690f74ee87e02d96108dd2a0 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 6 Aug 2024 12:42:31 -0400 Subject: [PATCH 18/69] removed debugging line --- inst/htmljs/animint.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index fb0446f6e..356f8a4fa 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -6,13 +6,7 @@ // Constructor for animint Object. var animint = function (to_select, json_file) { - //console.log(json_file) - fetch(json_file) - .then(response => response.json()) - .then(data => { - console.log(data); // Prints the entire JSON data - }) - .catch(error => console.error('Error fetching the JSON file:', error)); + var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { From 5b05e8a7a2b484e9b23bfeeb1866cff2fe2d8c2c Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 6 Aug 2024 12:44:42 -0400 Subject: [PATCH 19/69] removed comments --- R/theme-elements.r | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index c616ad195..5450264da 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -297,8 +297,7 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { # @param el an element # @param elname the name of the element validate_element <- function(el, elname) { - #print(el) - #print(elname) + eldef <- .element_tree[[elname]] if (is.null(eldef)) { From 2e1a5f57ef8098a54ebabcb98b75b19387ecc500 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 7 Aug 2024 00:56:50 -0400 Subject: [PATCH 20/69] reverted to original style and indentation --- R/theme.r | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/theme.r b/R/theme.r index bffbc9e75..d00848790 100644 --- a/R/theme.r +++ b/R/theme.r @@ -365,7 +365,8 @@ theme <- function(..., complete = FALSE, validate = TRUE) { mapply(validate_element, elements, names(elements)) } - structure(elements, class = c("theme", "gganimint"),complete = complete, validate = validate) + structure(elements, class = c("theme", "gganimint"), + complete = complete, validate = validate) } From 9af1fe826374b2f8e9f68d59ebe7d7941bd9c673 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sat, 10 Aug 2024 14:42:18 -0400 Subject: [PATCH 21/69] made border transparent --- inst/htmljs/animint.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 356f8a4fa..9c654f1f0 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2057,15 +2057,15 @@ var animint = function (to_select, json_file) { } find_maximum_dimensions() var count_dimensions = Math.ceil(Math.sqrt(count))-1; - var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - //console.log(maximum_row) - //console.log(maximum_column) + table_width=(maximum_column+1)*500+"px" + var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid solid transparent"); + for (var i = 0; i <=maximum_row; i++) { - var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); + var current_row = outer_table.append("tr").style("border", "1px solid transparent").style("height", "500px"); for (var j = 0; j <=maximum_column; j++){ - current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid white").style("width", "500px"); + current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid solid transparent").style("width", "500px"); } } From a1735d25e91d54afa33b5c4fbdf12c7a947ea0d9 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sat, 10 Aug 2024 17:37:05 -0400 Subject: [PATCH 22/69] added var as prefix to make it local --- inst/htmljs/animint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 9c654f1f0..859a47db0 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2059,7 +2059,7 @@ var animint = function (to_select, json_file) { var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - table_width=(maximum_column+1)*500+"px" + var table_width=(maximum_column+1)*500+"px" var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid solid transparent"); for (var i = 0; i <=maximum_row; i++) { From 8698e18536dda1e9d39f51e607c58f8767bb2bb2 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 2 Sep 2024 19:44:46 -0400 Subject: [PATCH 23/69] plots save span plots save rowspan and colspan values as parameters which will be used later to implement the actual functionality --- R/z_animint.R | 2 ++ R/z_animintHelpers.R | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/R/z_animint.R b/R/z_animint.R index 528a407e3..9dbb80e35 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -203,6 +203,8 @@ parsePlot <- function(meta, plot, plot.name){ plot.info$position <- getRowAndColumn(plot$theme) + plot.info$span <- getRowspanAndColumnspan(plot$theme) + list( plot.info=plot.info, ggplot=plot, diff --git a/R/z_animintHelpers.R b/R/z_animintHelpers.R index 5aa87469b..d01c73dda 100644 --- a/R/z_animintHelpers.R +++ b/R/z_animintHelpers.R @@ -158,6 +158,17 @@ getRowAndColumn <- function(theme){ options_list } +getRowspanAndColumnspan <- function(theme){ + options_list <- list() + for(rscs in c("rowspan", "colspan")){ + arc <- paste0("animint.", rscs) + options_list[[rscs]] <- if(arc %in% names(theme)){ + theme[[arc]] + } + } + options_list +} + setUpdateAxes <- function(theme, options_list){ update_axes <- "animint.update_axes" if(update_axes %in% names(theme)){ From d4c90aa905bcd504259c3bcf66449ca612c6ef80 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 4 Sep 2024 00:03:11 -0400 Subject: [PATCH 24/69] rowspan is applied rowspan is applied assuming user has not put overlapping plots. code to show overlapping plots error will be added --- R/z_animint.R | 1 - inst/htmljs/animint.js | 33 +++++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/R/z_animint.R b/R/z_animint.R index 9dbb80e35..9367beba0 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -365,7 +365,6 @@ animint2dir <- function(plot.list, out.dir = NULL, ## If plot is correct, save to meta for further processing parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. - #print(parsed_info$plot.info$title) if (!is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col)) { stop("You passed row but not the col argument for ",parsed_info$plot.info$title) } diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 859a47db0..21e08cf0e 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2025,7 +2025,6 @@ var animint = function (to_select, json_file) { } // Add plots. - var check_svg = function (row_number,col_number) { var id="#row"+row_number+"col"+col_number var parentElement= d3.select(id) @@ -2036,7 +2035,6 @@ var animint = function (to_select, json_file) { } } - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2044,7 +2042,6 @@ var animint = function (to_select, json_file) { var find_maximum_dimensions = function () { - for (var p_name in response.plots) { count=count+1 if (response.plots[p_name].row>maximum_row){ @@ -2056,16 +2053,38 @@ var animint = function (to_select, json_file) { } } find_maximum_dimensions() + function generateKey(row, col) { + return `${row},${col}`; +} var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) var table_width=(maximum_column+1)*500+"px" - var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid solid transparent"); + var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); + let span_map = new Map(); + for (var p_name in response.plots) { + if (('rowspan' in response.plots[p_name].span)){ + + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + span_map.set(key,response.plots[p_name].span) + + } + } for (var i = 0; i <=maximum_row; i++) { - var current_row = outer_table.append("tr").style("border", "1px solid transparent").style("height", "500px"); + + var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); for (var j = 0; j <=maximum_column; j++){ - current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid solid transparent").style("width", "500px"); + + let key = generateKey(i,j); + if (span_map.has(key)){ + var rowspan=span_map.get(key).rowspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); + } + else{ + current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); + } + } } @@ -2077,7 +2096,6 @@ var animint = function (to_select, json_file) { if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position) { var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); - add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. @@ -2097,7 +2115,6 @@ var animint = function (to_select, json_file) { } } var id= "#row"+pointer_row+"col"+pointer_column - //console.log(id) var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); From 80943e63890ac875d79ad56bee312c037ef6667b Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 4 Sep 2024 23:12:23 -0400 Subject: [PATCH 25/69] colspan can now be applied colspan can now be applied --- inst/htmljs/animint.js | 103 +++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 21e08cf0e..589b94e2f 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2055,45 +2055,55 @@ var animint = function (to_select, json_file) { find_maximum_dimensions() function generateKey(row, col) { return `${row},${col}`; -} - var count_dimensions = Math.ceil(Math.sqrt(count))-1; - maximum_row=Math.max(maximum_row,count_dimensions) - maximum_column=Math.max(maximum_column,count_dimensions) - var table_width=(maximum_column+1)*500+"px" - var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); - let span_map = new Map(); - for (var p_name in response.plots) { - if (('rowspan' in response.plots[p_name].span)){ - - let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); - span_map.set(key,response.plots[p_name].span) - - } - } + } + var count_dimensions = Math.ceil(Math.sqrt(count))-1; + maximum_row=Math.max(maximum_row,count_dimensions) + maximum_column=Math.max(maximum_column,count_dimensions) + var table_width=(maximum_column+1)*500+"px" + var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); + let rowspan_map = new Map(); + let colspan_map = new Map(); + for (var p_name in response.plots) { + if (('rowspan' in response.plots[p_name].span)){ + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + rowspan_map.set(key,response.plots[p_name].span) + + } + if (('colspan' in response.plots[p_name].span)){ + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + colspan_map.set(key,response.plots[p_name].span) + + } + } for (var i = 0; i <=maximum_row; i++) { + var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); + for (var j = 0; j <=maximum_column; j++){ + let key = generateKey(i,j); + if (rowspan_map.has(key)){ + var rowspan=span_map.get(key).rowspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); - var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); - for (var j = 0; j <=maximum_column; j++){ - - let key = generateKey(i,j); - if (span_map.has(key)){ - var rowspan=span_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); - } - else{ - current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); - } - - } + } + else if(colspan_map.has(key)){ + var colspan=colspan_map.get(key).colspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan).style("height", "500px").style("border", "1px solid black"); + + } + else{ + current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); + + } + + } + } + return outer_table; - return outer_table; } var outer_table=construct_outer_table(); - for (var p_name in response.plots) { - if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position) { + if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position){ var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2103,17 +2113,19 @@ var animint = function (to_select, json_file) { document.head.appendChild(css); } } - var pointer_row=0 - var pointer_column=0 - for (var p_name in response.plots) { - if (!('row' in response.plots[p_name].position)){ - while (check_svg(pointer_row,pointer_column)) { - pointer_column=pointer_column+1 - if (pointer_column>maximum_column){ - pointer_column=0 - pointer_row=pointer_row+1 - } - } + var pointer_row=0 + var pointer_column=0 + for (var p_name in response.plots) { + if (!('row' in response.plots[p_name].position)){ + while (check_svg(pointer_row,pointer_column)) { + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 + + } + + } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); @@ -2122,9 +2134,10 @@ var animint = function (to_select, json_file) { // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); - -} - } + + } + + } // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { From 4ac29378a4f26c55f3ef3fb8aa0c4eb81fc84ff4 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sat, 7 Sep 2024 02:53:07 -0400 Subject: [PATCH 26/69] refactoring --- inst/htmljs/animint.js | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 589b94e2f..3cecdd36a 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2039,9 +2039,7 @@ var animint = function (to_select, json_file) { var maximum_column= 0 var construct_outer_table = function () { var count=0 - var find_maximum_dimensions = function () { - for (var p_name in response.plots) { count=count+1 if (response.plots[p_name].row>maximum_row){ @@ -2055,51 +2053,41 @@ var animint = function (to_select, json_file) { find_maximum_dimensions() function generateKey(row, col) { return `${row},${col}`; - } var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - var table_width=(maximum_column+1)*500+"px" - var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); + var outer_table = element.append("table").attr("id", "outerTable"); let rowspan_map = new Map(); let colspan_map = new Map(); for (var p_name in response.plots) { if (('rowspan' in response.plots[p_name].span)){ let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); rowspan_map.set(key,response.plots[p_name].span) - } if (('colspan' in response.plots[p_name].span)){ let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); colspan_map.set(key,response.plots[p_name].span) - } } for (var i = 0; i <=maximum_row; i++) { - var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); + var current_row = outer_table.append("tr"); for (var j = 0; j <=maximum_column; j++){ let key = generateKey(i,j); if (rowspan_map.has(key)){ var rowspan=span_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); - + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan); } else if(colspan_map.has(key)){ var colspan=colspan_map.get(key).colspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan).style("height", "500px").style("border", "1px solid black"); - + current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan); } else{ - current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); - + current_row.append("td").attr("id", "row"+i+"col"+j); } - } - } return outer_table; - } var outer_table=construct_outer_table(); for (var p_name in response.plots) { @@ -2122,9 +2110,7 @@ var animint = function (to_select, json_file) { if (pointer_column>maximum_column){ pointer_column=0 pointer_row=pointer_row+1 - } - } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); @@ -2134,9 +2120,7 @@ var animint = function (to_select, json_file) { // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); - } - } // Then add selectors and start downloading the first data subset. From 4a4d8ea5d2e91c20b35b4ce1284aca3415c1b149 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 16:46:18 -0400 Subject: [PATCH 27/69] corrected response.plots[p_name].row toresponse.plots[p_name].position.row corrected response.plots[p_name].row toresponse.plots[p_name].position.row, removed borders , removed hardcoded values of cell dimensions, added the left case where user has given both rowspan and colspan for a same plot --- inst/htmljs/animint.js | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 3cecdd36a..db59b79c1 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2042,13 +2042,13 @@ var animint = function (to_select, json_file) { var find_maximum_dimensions = function () { for (var p_name in response.plots) { count=count+1 - if (response.plots[p_name].row>maximum_row){ - maximum_row=response.plots[p_name].row - } - if (response.plots[p_name].col>maximum_column){ - maximum_column=response.plots[p_name].col + if (response.plots[p_name].position.row>maximum_row){ + maximum_row=response.plots[p_name].position.row + } + if (response.plots[p_name].position.col>maximum_column){ + maximum_column=response.plots[p_name].position.col + } } - } } find_maximum_dimensions() function generateKey(row, col) { @@ -2057,6 +2057,7 @@ var animint = function (to_select, json_file) { var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) + var maximum_dimensions=Math.max(maximum_column,maximum_row) var outer_table = element.append("table").attr("id", "outerTable"); let rowspan_map = new Map(); let colspan_map = new Map(); @@ -2070,18 +2071,23 @@ var animint = function (to_select, json_file) { colspan_map.set(key,response.plots[p_name].span) } } - for (var i = 0; i <=maximum_row; i++) { + for (var i = 0; i <=maximum_dimensions; i++) { var current_row = outer_table.append("tr"); - for (var j = 0; j <=maximum_column; j++){ + for (var j = 0; j <=maximum_dimensions; j++){ let key = generateKey(i,j); - if (rowspan_map.has(key)){ - var rowspan=span_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan); + if (rowspan_map.has(key) && (colspan_map.has(key))){ + var rowspan=rowspan_map.get(key).rowspan + var colspan=colspan_map.get(key).colspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).attr("colspan",colspan); } else if(colspan_map.has(key)){ var colspan=colspan_map.get(key).colspan current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan); } + else if(rowspan_map.has(key)){ + var rowspan=rowspan_map.get(key).rowspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan); + } else{ current_row.append("td").attr("id", "row"+i+"col"+j); } From 7fa9efe6d34b7a937b39d25a280304749e024398 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 17:14:55 -0400 Subject: [PATCH 28/69] throw error if user is incosistent is passing row and col throw error if user is incosistent is passing row and col arguments in plots, that is user passes them for some and not for others. --- R/z_animint.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/R/z_animint.R b/R/z_animint.R index 9367beba0..38df15b0c 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -359,11 +359,11 @@ animint2dir <- function(plot.list, out.dir = NULL, ## Call ggplot_build in parsPlot for all ggplots ggplot.list <- list() AllPlotsInfo <- list() + custom_layout <- FALSE for(list.name in names(plot.list)){ p <- plot.list[[list.name]] if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing - parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. if (!is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col)) { stop("You passed row but not the col argument for ",parsed_info$plot.info$title) @@ -371,6 +371,12 @@ animint2dir <- function(plot.list, out.dir = NULL, if (!is.null(parsed_info$plot.info$position$col) && is.null(parsed_info$plot.info$position$row)) { stop("You passed col but not the row argument for ",parsed_info$plot.info$title) } + if (!is.null(parsed_info$plot.info$position$row) && !is.null(parsed_info$plot.info$position$col)){ + custom_layout<- TRUE + } + if (is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col) && custom_layout){ + stop("You passed col and row for some plots and not for others, please pass for all or none") + } AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot ggplot.list[[list.name]]$built <- parsed_info$built From 3499fea541498f3264dda2b5bc537ff07e24829e Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 17:23:07 -0400 Subject: [PATCH 29/69] removed check_svg function check_svg function was for checking empty locations for rest of the plots when user puts rows and cols for some plots while not for others. this is no longer needed now because now the user has to select specific positions for all plots or for no plots at all --- inst/htmljs/animint.js | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index db59b79c1..2f0b328a5 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2025,16 +2025,6 @@ var animint = function (to_select, json_file) { } // Add plots. - var check_svg = function (row_number,col_number) { - var id="#row"+row_number+"col"+col_number - var parentElement= d3.select(id) - if (!parentElement.select('svg').empty()) { - return true - }else{ - return false - } - } - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2111,12 +2101,10 @@ var animint = function (to_select, json_file) { var pointer_column=0 for (var p_name in response.plots) { if (!('row' in response.plots[p_name].position)){ - while (check_svg(pointer_row,pointer_column)) { - pointer_column=pointer_column+1 - if (pointer_column>maximum_column){ - pointer_column=0 - pointer_row=pointer_row+1 - } + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); From 905feb338be9dd91781003945737850440c47dea Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 20:27:29 -0400 Subject: [PATCH 30/69] refactoring --- inst/htmljs/animint.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 2f0b328a5..bca903f6c 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2024,7 +2024,7 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - + var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2087,7 +2087,7 @@ var animint = function (to_select, json_file) { } var outer_table=construct_outer_table(); for (var p_name in response.plots) { - if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position){ + if ('row' in response.plots[p_name].position){ var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2136,7 +2136,6 @@ var animint = function (to_select, json_file) { } } } - //////////////////////////////////////////// // Widgets at bottom of page //////////////////////////////////////////// From 02870244065bab76b544c2946e61b217cec2f7cd Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 23:35:19 -0400 Subject: [PATCH 31/69] corrected code to properly traverse the outer table corrected the code to properly traverse the outer table to put the plots if the user choses not to use customized layout --- inst/htmljs/animint.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index bca903f6c..0776a55a3 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2024,7 +2024,6 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2101,14 +2100,13 @@ var animint = function (to_select, json_file) { var pointer_column=0 for (var p_name in response.plots) { if (!('row' in response.plots[p_name].position)){ - pointer_column=pointer_column+1 - if (pointer_column>maximum_column){ - pointer_column=0 - pointer_row=pointer_row+1 - } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); - + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 + } add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. From e46f73ca1c829dce5631b5f20f9809cc8656f2df Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 10 Jul 2024 00:05:51 -0400 Subject: [PATCH 32/69] Test to check for title of 3 plots Test to check for titles of 3 plots --- tests/testthat/test-renderer3-threeplots.R | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/testthat/test-renderer3-threeplots.R diff --git a/tests/testthat/test-renderer3-threeplots.R b/tests/testthat/test-renderer3-threeplots.R new file mode 100644 index 000000000..978502d07 --- /dev/null +++ b/tests/testthat/test-renderer3-threeplots.R @@ -0,0 +1,45 @@ + + +test_that("check if two plots exist", { + data1 <- data.frame( + x = c(1, 2, 3), # x-coordinates of the dots + y = c(1, 4, 9) # y-coordinates of the dots + ) + + plot1 <- ggplot(data1, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 3 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis") + + data2 <- data.frame( + x = c(1, 2), # x-coordinates of the dots + y = c(1, 4) # y-coordinates of the dots + ) + + plot2 <- ggplot(data2, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 2 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis") + + data3 <- data.frame( + x = c(2), # x-coordinates of the dots + y = c(2) # y-coordinates of the dots + ) + + plot3 <- ggplot(data3, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 1 Dot") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis") + + plot_list <- list( + plot1 = plot1, + plot2=plot2, + plot3=plot3 + ) + + info <-animint2HTML(plot_list) + titles <- getNodeSet(info$html, "//text[@class='plottitle']") + expect_match(xmlValue(titles[[1]]), "Plot of 3 Dots") + expect_match(xmlValue(titles[[2]]), "Plot of 2 Dots") + expect_match(xmlValue(titles[[3]]), "Plot of 1 Dot") +}) From 3cefb99c62303d01aa9a6366d1ea1579f8d27e0c Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Thu, 11 Jul 2024 20:25:35 -0400 Subject: [PATCH 33/69] added test to verify number of tables , their dimensions and number of points --- tests/testthat/test-renderer3-threeplots.R | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-renderer3-threeplots.R b/tests/testthat/test-renderer3-threeplots.R index 978502d07..93588f991 100644 --- a/tests/testthat/test-renderer3-threeplots.R +++ b/tests/testthat/test-renderer3-threeplots.R @@ -32,14 +32,37 @@ test_that("check if two plots exist", { xlab("X Axis") + ylab("Y Axis") plot_list <- list( - plot1 = plot1, + plot1=plot1, plot2=plot2, plot3=plot3 ) info <-animint2HTML(plot_list) titles <- getNodeSet(info$html, "//text[@class='plottitle']") + + points <- getNodeSet(info$html, "//circle[@class='geom']") + + number_of_points <- length(points) + tables <- getNodeSet(info$html, "//table[@style='display: inline-block;']") + svgs <- getNodeSet(info$html, "//svg[contains(@id,'')]") + number_of_tables<-length(tables) + + number_of_points <- length(points) + svg_dimensions <- lapply(svgs, function(svg) { + list( + height = as.numeric(xmlGetAttr(svg, "height")), + width = as.numeric(xmlGetAttr(svg, "width")) + ) + }) + for (dim in svg_dimensions) { + expect_equal(dim$height, 400) + expect_equal(dim$width, 400) + + } + expect_match(xmlValue(titles[[1]]), "Plot of 3 Dots") expect_match(xmlValue(titles[[2]]), "Plot of 2 Dots") expect_match(xmlValue(titles[[3]]), "Plot of 1 Dot") + expect_equal(number_of_points,6) + expect_equal(number_of_tables,3) }) From efcd2c5eb21496ac964b060198346e0e9fd81d7a Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 16 Jul 2024 00:28:21 -0400 Subject: [PATCH 34/69] ramping up on animint.js ramping up on animint.js file by making temporary code changes and see how it changes the plots to understand how different functions in it work --- inst/htmljs/animint.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index d77109c3a..3568ca8bc 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -1065,7 +1065,8 @@ var animint = function (to_select, json_file) { get_stroke_width = get_attr("stroke"); }else{ get_stroke_width = function(d){ - return stroke_width; + //return stroke_width; + return 4 }; } From 071eeb54ad857929147decc0d3b5fe6b48da72f9 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 16 Jul 2024 01:40:41 -0400 Subject: [PATCH 35/69] add all plots in single row add all plots in single row of a newly created outer table --- inst/htmljs/animint.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 3568ca8bc..224a94735 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -214,11 +214,21 @@ var animint = function (to_select, json_file) { // Save this geom and load it! update_geom(g_name, null); }; + var outer_table = d3.select("body").append("table") + .attr("id", "outerTable") + .style("width", "100%") + .style("border", "1px solid black"); + var row = outer_table.append("tr"); + // Add a cell to the row (1st row, 1st column) + var add_plot = function (p_name, p_info) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. - var plot_table = element.append("table").style("display", "inline-block"); + //var plot_table = element.append("table").style("display", "inline-block"); + var cell = row.append("td"); + var plot_table = cell.append("table") + .style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); var tdRight = plot_tr.append("td").attr("class", p_name+"_legend"); @@ -1065,8 +1075,8 @@ var animint = function (to_select, json_file) { get_stroke_width = get_attr("stroke"); }else{ get_stroke_width = function(d){ - //return stroke_width; - return 4 + return stroke_width; + }; } From 744a6389d7c1f59c162ebc50ca324fff42bee5bb Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 16 Jul 2024 19:46:26 -0400 Subject: [PATCH 36/69] used element variable used element variable which was not used earlier which led to failures locally. in this commit the plots are fixed in a single row of outer table, thus interactivity does not affect the relative positions of them. --- inst/htmljs/animint.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 224a94735..f77f303bb 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -214,10 +214,7 @@ var animint = function (to_select, json_file) { // Save this geom and load it! update_geom(g_name, null); }; - var outer_table = d3.select("body").append("table") - .attr("id", "outerTable") - .style("width", "100%") - .style("border", "1px solid black"); + var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); var row = outer_table.append("tr"); // Add a cell to the row (1st row, 1st column) @@ -227,8 +224,7 @@ var animint = function (to_select, json_file) { // columns: tdLeft and tdRight. //var plot_table = element.append("table").style("display", "inline-block"); var cell = row.append("td"); - var plot_table = cell.append("table") - .style("display", "inline-block"); + var plot_table = cell.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); var tdRight = plot_tr.append("td").attr("class", p_name+"_legend"); From 0fe67a8fee8a95cd94887b6cb8517d4505854a39 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Thu, 18 Jul 2024 00:20:08 -0400 Subject: [PATCH 37/69] Update .gitignore knit-print fails for phantomjs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 815d6c977..2c60b1d28 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ *ANIMINT_TEST_FOO *pids.txt *~ +test-renderer1-knit-print.R From 57d530b2efb5206a21e4ef587cd52b3e49b5b809 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 22 Jul 2024 11:51:35 -0400 Subject: [PATCH 38/69] put all plots in one column previously i put all plots in a single row of outer table, in this commit i put all plots in single column. i have also removed knit-print test because it had not passed on phantomjs and only passed for chromote in chromote testing branch --- inst/htmljs/animint.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index f77f303bb..ffac67cf8 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -4,8 +4,9 @@ // var plot = new animint("#plot","path/to/plot.json"); // // Constructor for animint Object. -var animint = function (to_select, json_file) { +var animint = function (to_select, json_file) { + var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { @@ -214,15 +215,19 @@ var animint = function (to_select, json_file) { // Save this geom and load it! update_geom(g_name, null); }; - var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - var row = outer_table.append("tr"); - // Add a cell to the row (1st row, 1st column) - var add_plot = function (p_name, p_info) { + + //var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); + //var row = outer_table.append("tr"); + //Add a cell to the row (1st row, 1st column) + + + var add_plot = function (p_name, p_info,outer_table) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. //var plot_table = element.append("table").style("display", "inline-block"); + var row = outer_table.append("tr"); var cell = row.append("td"); var plot_table = cell.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); @@ -2026,8 +2031,14 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. + var construct_outer_table = function () { + var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); + //var row1 = outer_table1.append("tr"); + return outer_table; + } + var outer_table=construct_outer_table(); for (var p_name in response.plots) { - add_plot(p_name, response.plots[p_name]); + add_plot(p_name, response.plots[p_name],outer_table); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); From c1fbe30877dedee442114c46c8d0481946381be7 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 22 Jul 2024 15:04:12 -0400 Subject: [PATCH 39/69] add 2 plots per row and then make a new row in the newly created outer table, add 2 plots per row and then make a new row. this implementation will be built upon to complete if it is the suitable. --- helper-functions2.R | 19 +++++++++++++++++++ inst/htmljs/animint.js | 30 +++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 helper-functions2.R diff --git a/helper-functions2.R b/helper-functions2.R new file mode 100644 index 000000000..764126b15 --- /dev/null +++ b/helper-functions2.R @@ -0,0 +1,19 @@ +sendKey <- function(key, code, keyCode) { + remDr$Input$dispatchKeyEvent(type = "keyDown", key = key, code = code, windowsVirtualKeyCode = keyCode, nativeVirtualKeyCode = keyCode) + remDr$Input$dispatchKeyEvent(type = "keyUp", key = key, code = code, windowsVirtualKeyCode = keyCode, nativeVirtualKeyCode = keyCode) +} + +clickID <- function(...){ + v <- c(...) + stopifnot(length(v) == 1) + runtime_evaluate(script=sprintf("document.getElementById('%s').dispatchEvent(new CustomEvent('click'))", as.character(v))) +} + +runtime_evaluate <- function(script=NULL,return.value=FALSE){ + eval.result<- remDr$Runtime$evaluate(script,returnByValue = TRUE) + if (return.value){ + eval.result$result$value + }else{ + eval.result + } +} \ No newline at end of file diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index ffac67cf8..3cec6e623 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -6,7 +6,7 @@ // Constructor for animint Object. var animint = function (to_select, json_file) { - + console.log("hello") var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { @@ -222,14 +222,18 @@ var animint = function (to_select, json_file) { //Add a cell to the row (1st row, 1st column) - var add_plot = function (p_name, p_info,outer_table) { + var add_plot = function (p_name, p_info,outer_table,rowIdx=1,colIdx=1) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. //var plot_table = element.append("table").style("display", "inline-block"); - var row = outer_table.append("tr"); - var cell = row.append("td"); - var plot_table = cell.append("table").style("display", "inline-block"); + //var row = outer_table.append("tr"); + //var cell = row.append("td"); + //var cell = outer_table.select(`tr:nth-child(${rowIdx + 1})`).select(`td:nth-child(${colIdx + 1})`); + + //var plot_table = cell.append("table").style("display", "inline-block"); + //var outer_table = d3.select("#outerTable") + var plot_table = outer_table.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); var tdRight = plot_tr.append("td").attr("class", p_name+"_legend"); @@ -2033,16 +2037,28 @@ var animint = function (to_select, json_file) { // Add plots. var construct_outer_table = function () { var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row1 = outer_table1.append("tr"); + //var row = outer_table.append("tr"); + //var cell = row.append("td"); return outer_table; } var outer_table=construct_outer_table(); + var current_row=outer_table.append("tr") + var current_col=current_row.append("td") + var count=0; for (var p_name in response.plots) { - add_plot(p_name, response.plots[p_name],outer_table); + count=count+1 + if (count>2){ + count=1 + current_row=outer_table.append("tr") + current_col=current_row.append("td") + } + //console.log(count) + add_plot(p_name, response.plots[p_name],current_col); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); + current_col=current_row.append("td") } // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { From 8da6e6c917b1a42bac00ee6843f993d1aed2d45a Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Fri, 26 Jul 2024 16:16:53 -0400 Subject: [PATCH 40/69] table with 3 plots per row or user defined layout if the user has given input of row and column in theme animint, plots will be put in that location. but user needs to mention rows and columns for all plots. if the user does not want that option older functionality will work but with a new change of 3 plots per row and then a new row. --- R/theme-elements.r | 7 ++- R/z_animint.R | 11 ++-- inst/htmljs/animint.js | 111 ++++++++++++++++++++++++++++++----------- 3 files changed, 95 insertions(+), 34 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index d72b41507..76fbd069c 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -282,7 +282,10 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { plot.caption = el_def("element_text", "title"), plot.margin = el_def("margin"), - aspect.ratio = el_def("character") + aspect.ratio = el_def("character"), + + row = el_def("character"), + col = el_def("character") ) @@ -297,6 +300,8 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { # @param el an element # @param elname the name of the element validate_element <- function(el, elname) { + #print(el) + #print(elname) eldef <- .element_tree[[elname]] if (is.null(eldef)) { diff --git a/R/z_animint.R b/R/z_animint.R index b412bd454..cfdef8713 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -37,7 +37,7 @@ parsePlot <- function(meta, plot, plot.name){ ## Now ggplot specifies panel.margin in 'pt' instead of 'lines' plot.info$panel_margin_lines <- pt.to.lines(theme.pars$panel.margin) - ## No legend if theme(legend.postion="none"). + ## No legend if theme(legend.position="none"). plot.info$legend <- if(theme.pars$legend.position != "none"){ getLegendList(built) } @@ -103,7 +103,9 @@ parsePlot <- function(meta, plot, plot.name){ # extract minor grid lines plot.info$grid_minor <- get_grid(theme.pars$panel.grid.minor, theme.pars, plot.info, meta, built, major = F) - + theme <- plot_theme(built$plot) + plot.info$row <-theme$row + plot.info$col <-theme$col ## Flip labels if coords are flipped - transform does not take care ## of this. Do this BEFORE checking if it is blank or not, so that ## individual axes can be hidden appropriately, e.g. #1. @@ -249,6 +251,7 @@ storeLayer <- function(meta, g, g.data.varied){ animint2dir <- function(plot.list, out.dir = NULL, json.file = "plot.json", open.browser = interactive(), css.file = "") { + if(is.null(out.dir)){ out.dir <- tempfile() } @@ -359,6 +362,7 @@ animint2dir <- function(plot.list, out.dir = NULL, if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. + #print(parsed_info$plot.info) AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot ggplot.list[[list.name]]$built <- parsed_info$built @@ -638,7 +642,7 @@ animint2dir <- function(plot.list, out.dir = NULL, stop("missing first selector variable") } } - + meta$plots <- AllPlotsInfo meta$time <- AnimationInfo$time meta$timeValues <- AnimationInfo$timeValues @@ -690,6 +694,7 @@ getLegendList <- function(plistextra){ position <- theme$legend.position text <- theme$legend.text title <- theme$legend.title + #print(theme$row) # by default, guide boxes are vertically aligned if(is.null(theme$legend.box)) theme$legend.box <- "vertical" else theme$legend.box diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 3cec6e623..c36e8e2c4 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -6,7 +6,13 @@ // Constructor for animint Object. var animint = function (to_select, json_file) { - console.log("hello") + //console.log(json_file) + fetch(json_file) + .then(response => response.json()) + .then(data => { + console.log(data); // Prints the entire JSON data + }) + .catch(error => console.error('Error fetching the JSON file:', error)); var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { @@ -217,22 +223,11 @@ var animint = function (to_select, json_file) { }; - //var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row = outer_table.append("tr"); - //Add a cell to the row (1st row, 1st column) - - - var add_plot = function (p_name, p_info,outer_table,rowIdx=1,colIdx=1) { + var add_plot = function (p_name, p_info,outer_table) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. - //var plot_table = element.append("table").style("display", "inline-block"); - //var row = outer_table.append("tr"); - //var cell = row.append("td"); - //var cell = outer_table.select(`tr:nth-child(${rowIdx + 1})`).select(`td:nth-child(${colIdx + 1})`); - //var plot_table = cell.append("table").style("display", "inline-block"); - //var outer_table = d3.select("#outerTable") var plot_table = outer_table.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); @@ -2035,31 +2030,87 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - var construct_outer_table = function () { - var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row = outer_table.append("tr"); - //var cell = row.append("td"); + + var user_defined_layout= false + var count=0 + for (var p_name in response.plots) { + if (count>0){ + break; + } + if ('row' in response.plots[p_name]) { + user_defined_layout= true +} +count=count+1 +} + + console.log(user_defined_layout) + if(user_defined_layout){ + var maximum_row= 0 + var maximum_column= 0 + for (var p_name in response.plots) { + if (response.plots[p_name].row>maximum_row){ + maximum_row=response.plots[p_name].row + } + if (response.plots[p_name].col>maximum_column){ + maximum_column=response.plots[p_name].col + } + } + + var construct_outer_table = function () { + var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); + for (var i = 0; i <=maximum_row; i++) { + var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); + for (var j = 0; j <=maximum_column; j++){ + current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid white").style("width", "500px"); + } + } + return outer_table; } var outer_table=construct_outer_table(); - var current_row=outer_table.append("tr") - var current_col=current_row.append("td") - var count=0; - for (var p_name in response.plots) { - count=count+1 - if (count>2){ - count=1 - current_row=outer_table.append("tr") - current_col=current_row.append("td") - } - //console.log(count) - add_plot(p_name, response.plots[p_name],current_col); + + for (var p_name in response.plots) { + id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col + var cell= d3.select(id); + + add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); - current_col=current_row.append("td") } + }else{ + var construct_outer_table = function () { + var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); + //var row = outer_table.append("tr"); + //var cell = row.append("td"); + return outer_table; + } + var outer_table=construct_outer_table(); + var current_row=outer_table.append("tr") + var current_col=current_row.append("td") + var count=0; + for (var p_name in response.plots) { + count=count+1 + if (count>2){ + count=1 + current_row=outer_table.append("tr") + current_col=current_row.append("td") + } + //console.log(count) + add_plot(p_name, response.plots[p_name],current_col); + add_legend(p_name, response.plots[p_name]); + // Append style sheet to document head. + css.appendChild(document.createTextNode(styles.join(" "))); + document.head.appendChild(css); + current_col=current_row.append("td") + } + + } + + + + // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { add_selector(s_name, response.selectors[s_name]); From dbbfcc7ae87d18ad86d72461f7c5307367eb1fbc Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Fri, 26 Jul 2024 16:30:43 -0400 Subject: [PATCH 41/69] test for putting plots in specific location of outer table test for putting plots in specific location of outer table by passing arguments of row and column in theme. i am working on making it compatible with theme as well --- tests/testthat/test-renderer3-fourplots.R | 83 +++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 tests/testthat/test-renderer3-fourplots.R diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R new file mode 100644 index 000000000..a1e4b5c89 --- /dev/null +++ b/tests/testthat/test-renderer3-fourplots.R @@ -0,0 +1,83 @@ + + +test_that("check if two plots exist", { + data1 <- data.frame( + x = c(1, 2, 3), # x-coordinates of the dots + y = c(1, 4, 9) # y-coordinates of the dots + ) + + plot1 <- ggplot(data1, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 3 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=0) + #theme(plot.title = element_text(color = "purple", size = 20, face = "bold")) + data2 <- data.frame( + x = c(1, 2), # x-coordinates of the dots + y = c(1, 4) # y-coordinates of the dots + ) + + plot2 <- ggplot(data2, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 2 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=2) + + data3 <- data.frame( + x = c(2), # x-coordinates of the dots + y = c(2) # y-coordinates of the dots + ) + + plot3 <- ggplot(data3, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 1 Dot") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) + plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + + geom_point() + + labs(title = "Car Weight vs. MPG") + + theme( + plot.title = element_text(color = "purple", size = 20, face = "bold"), + panel.background = element_rect(fill = "lightyellow"), + panel.grid.major = element_line(color = "gray", size = 0.8), + axis.title.x = element_text(color = "blue", size = 14), + axis.text.y = element_text(color = "red", size = 12), + legend.position = "bottom", + legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5), + row=1, + col=1 + ) + + plot_list <- list( + plot1=plot1, + plot2=plot2, + plot3=plot3, + plot4=plot4 + ) + + info <-animint2HTML(plot_list) + titles <- getNodeSet(info$html, "//text[@class='plottitle']") + + points <- getNodeSet(info$html, "//circle[@class='geom']") + + number_of_points <- length(points) + tables <- getNodeSet(info$html, "//table[@style='display: inline-block;']") + svgs <- getNodeSet(info$html, "//svg[contains(@id,'')]") + number_of_tables<-length(tables) + + number_of_points <- length(points) + svg_dimensions <- lapply(svgs, function(svg) { + list( + height = as.numeric(xmlGetAttr(svg, "height")), + width = as.numeric(xmlGetAttr(svg, "width")) + ) + }) + for (dim in svg_dimensions) { + expect_equal(dim$height, 400) + expect_equal(dim$width, 400) + + } + + #expect_match(xmlValue(titles[[1]]), "Plot of 3 Dots") + #expect_match(xmlValue(titles[[2]]), "Plot of 2 Dots") + #expect_match(xmlValue(titles[[3]]), "Plot of 1 Dot") + #expect_equal(number_of_points,6) + #expect_equal(number_of_tables,3) +}) From e671218b3dbeeec03bb462ed84dbf855eccfac76 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sun, 28 Jul 2024 00:32:19 -0400 Subject: [PATCH 42/69] check if svg element exists in a particular location of outer table check if svg element exists in a particular location of outer table. --- inst/htmljs/animint.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index c36e8e2c4..4502fc5c0 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2079,6 +2079,18 @@ count=count+1 css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); } + var parentElement1 = d3.select('#row1col1'); + var parentElement2 = d3.select('#row1col0'); + if (!parentElement1.select('svg').empty()) { + console.log("An element exists in #row1col1."); +} else { + console.log("No element found in #row1col1."); +} +if (!parentElement2.select('svg').empty()) { + console.log("An element exists in #row1col0."); +} else { + console.log("No element found in #row1col0."); +} }else{ var construct_outer_table = function () { var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); @@ -2105,7 +2117,6 @@ count=count+1 document.head.appendChild(css); current_col=current_row.append("td") } - } From 42eaf91aa011315cb9718adec75c98687718fbd4 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sun, 28 Jul 2024 01:45:25 -0400 Subject: [PATCH 43/69] error message if user forgets to add either row or column error message if user adds row and not column or vice versa --- inst/htmljs/animint.js | 15 +++++++++------ tests/testthat/test-renderer3-fourplots.R | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 4502fc5c0..75b175395 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2032,15 +2032,18 @@ var animint = function (to_select, json_file) { // Add plots. var user_defined_layout= false - var count=0 + //var count=0 for (var p_name in response.plots) { - if (count>0){ - break; - } - if ('row' in response.plots[p_name]) { + //console.log(response.plots[p_name].title) + if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { user_defined_layout= true } -count=count+1 +if ('row' in response.plots[p_name] && !('col' in response.plots[p_name])){ + throw new Error("You forgot to add column in "+response.plots[p_name].title+" plot."); +} +if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ + throw new Error("You forgot to add row in "+response.plots[p_name].title+" plot."); +} } console.log(user_defined_layout) diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index a1e4b5c89..84a79de17 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -29,7 +29,7 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) + xlab("X Axis") + ylab("Y Axis")+theme(row=0) plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + labs(title = "Car Weight vs. MPG") + From 3a3141bc2e381fa70738bce737c8bd9284311fe5 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 00:10:06 -0400 Subject: [PATCH 44/69] made function to check svg made a function to check if svg element exists at a specific location of the outer table. so this function will return true if plot exists at that location, false otherwise --- inst/htmljs/animint.js | 31 +++++++++++++---------- tests/testthat/test-renderer3-fourplots.R | 10 ++++---- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 75b175395..56efecfca 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2030,6 +2030,16 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. + + var check_svg = function (row_number,col_number) { + id="#row"+row_number+"col"+col_number + parentElement= d3.select(id) + if (!parentElement.select('svg').empty()) { + return true + }else{ + return false + } + } var user_defined_layout= false //var count=0 @@ -2046,7 +2056,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - console.log(user_defined_layout) + if(user_defined_layout){ var maximum_row= 0 var maximum_column= 0 @@ -2082,18 +2092,13 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); } - var parentElement1 = d3.select('#row1col1'); - var parentElement2 = d3.select('#row1col0'); - if (!parentElement1.select('svg').empty()) { - console.log("An element exists in #row1col1."); -} else { - console.log("No element found in #row1col1."); -} -if (!parentElement2.select('svg').empty()) { - console.log("An element exists in #row1col0."); -} else { - console.log("No element found in #row1col0."); -} + for (var i = 0; i <=maximum_row; i++) { + for (var j = 0; j <=maximum_column; j++){ + if (check_svg(i,j)){ + console.log("row"+i+" "+"col"+j) + } + } + } }else{ var construct_outer_table = function () { var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index 84a79de17..c06d6bb3e 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -9,7 +9,7 @@ test_that("check if two plots exist", { plot1 <- ggplot(data1, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 3 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=0) + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) #theme(plot.title = element_text(color = "purple", size = 20, face = "bold")) data2 <- data.frame( x = c(1, 2), # x-coordinates of the dots @@ -19,7 +19,7 @@ test_that("check if two plots exist", { plot2 <- ggplot(data2, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 2 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=2,col=2) + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) data3 <- data.frame( x = c(2), # x-coordinates of the dots @@ -29,7 +29,7 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0) + xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=0) plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + labs(title = "Car Weight vs. MPG") + @@ -41,8 +41,8 @@ test_that("check if two plots exist", { axis.text.y = element_text(color = "red", size = 12), legend.position = "bottom", legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5), - row=1, - col=1 + row=2, + col=2 ) plot_list <- list( From cb45b68ba4c3a987761781b7ac9337ca77a739cd Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 11:46:09 -0400 Subject: [PATCH 45/69] put plots with fixed locations first, then put all other plots put plots with fixed locations first if the user has passed both row and column arguments in theme for that plot, then put all other plots in available empty locations. if user passes only row or column argument then give error message --- inst/htmljs/animint.js | 76 +++++++++++------------ tests/testthat/test-renderer3-fourplots.R | 11 ++-- 2 files changed, 42 insertions(+), 45 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 56efecfca..7b2e60c19 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2041,10 +2041,8 @@ var animint = function (to_select, json_file) { } } - var user_defined_layout= false - //var count=0 + for (var p_name in response.plots) { - //console.log(response.plots[p_name].title) if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { user_defined_layout= true } @@ -2054,13 +2052,15 @@ if ('row' in response.plots[p_name] && !('col' in response.plots[p_name])){ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ throw new Error("You forgot to add row in "+response.plots[p_name].title+" plot."); } -} - + } - if(user_defined_layout){ + + var maximum_row= 0 var maximum_column= 0 + var count=0 for (var p_name in response.plots) { + count=count+1 if (response.plots[p_name].row>maximum_row){ maximum_row=response.plots[p_name].row } @@ -2070,7 +2070,12 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } var construct_outer_table = function () { + var count_dimensions = Math.ceil(Math.sqrt(count))-1; var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); + maximum_row=Math.max(maximum_row,count_dimensions) + maximum_column=Math.max(maximum_column,count_dimensions) + console.log(maximum_row) + console.log(maximum_column) for (var i = 0; i <=maximum_row; i++) { var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); for (var j = 0; j <=maximum_column; j++){ @@ -2083,6 +2088,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ var outer_table=construct_outer_table(); for (var p_name in response.plots) { + if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col var cell= d3.select(id); @@ -2092,40 +2098,32 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); } - for (var i = 0; i <=maximum_row; i++) { - for (var j = 0; j <=maximum_column; j++){ - if (check_svg(i,j)){ - console.log("row"+i+" "+"col"+j) - } - } - } - }else{ - var construct_outer_table = function () { - var outer_table = element.append("table").attr("id", "outerTable").style("width", "100%").style("border", "1px solid black"); - //var row = outer_table.append("tr"); - //var cell = row.append("td"); - return outer_table; - } - var outer_table=construct_outer_table(); - var current_row=outer_table.append("tr") - var current_col=current_row.append("td") - var count=0; - for (var p_name in response.plots) { - count=count+1 - if (count>2){ - count=1 - current_row=outer_table.append("tr") - current_col=current_row.append("td") - } - //console.log(count) - add_plot(p_name, response.plots[p_name],current_col); - add_legend(p_name, response.plots[p_name]); - // Append style sheet to document head. - css.appendChild(document.createTextNode(styles.join(" "))); - document.head.appendChild(css); - current_col=current_row.append("td") - } } + pointer_row=0 + pointer_column=0 + for (var p_name in response.plots) { + if (!('row' in response.plots[p_name])){ + while (check_svg(pointer_row,pointer_column)) { + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 + } + } + id= "#row"+pointer_row+"col"+pointer_column + //console.log(id) + var cell= d3.select(id); + + add_plot(p_name, response.plots[p_name],cell); + add_legend(p_name, response.plots[p_name]); + // Append style sheet to document head. + css.appendChild(document.createTextNode(styles.join(" "))); + document.head.appendChild(css); + +} + } + + diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index c06d6bb3e..c2307113d 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -19,7 +19,7 @@ test_that("check if two plots exist", { plot2 <- ggplot(data2, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 2 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) + xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=1) data3 <- data.frame( x = c(2), # x-coordinates of the dots @@ -29,8 +29,9 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=0) - plot4 <- ggplot(mtcars, aes(x = wt, y = mpg)) + + xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) + + plot4 <- ggplot(mtcars, aes(x = wt, y = mpg))+ geom_point() + labs(title = "Car Weight vs. MPG") + theme( @@ -40,9 +41,7 @@ test_that("check if two plots exist", { axis.title.x = element_text(color = "blue", size = 14), axis.text.y = element_text(color = "red", size = 12), legend.position = "bottom", - legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5), - row=2, - col=2 + legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5) ) plot_list <- list( From 06d5c1071ee28e98c509c046e3026e82887bd84a Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 20:39:53 -0400 Subject: [PATCH 46/69] changed scope of implicitly global variables changed scope of implicitly global variables for global-varaibles test to pass. made the code more modular --- inst/htmljs/animint.js | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 7b2e60c19..5f9ce3631 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2030,10 +2030,11 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - + + var check_svg = function (row_number,col_number) { - id="#row"+row_number+"col"+col_number - parentElement= d3.select(id) + var id="#row"+row_number+"col"+col_number + var parentElement= d3.select(id) if (!parentElement.select('svg').empty()) { return true }else{ @@ -2054,11 +2055,14 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - - - var maximum_row= 0 - var maximum_column= 0 - var count=0 + var maximum_row= 0 + var maximum_column= 0 + var construct_outer_table = function () { + var count=0 + + var find_maximum_dimensions = function () { + + for (var p_name in response.plots) { count=count+1 if (response.plots[p_name].row>maximum_row){ @@ -2068,14 +2072,14 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ maximum_column=response.plots[p_name].col } } - - var construct_outer_table = function () { + } + find_maximum_dimensions() var count_dimensions = Math.ceil(Math.sqrt(count))-1; var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - console.log(maximum_row) - console.log(maximum_column) + //console.log(maximum_row) + //console.log(maximum_column) for (var i = 0; i <=maximum_row; i++) { var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); for (var j = 0; j <=maximum_column; j++){ @@ -2089,7 +2093,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ for (var p_name in response.plots) { if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { - id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col + var id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2099,8 +2103,8 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ document.head.appendChild(css); } } - pointer_row=0 - pointer_column=0 + var pointer_row=0 + var pointer_column=0 for (var p_name in response.plots) { if (!('row' in response.plots[p_name])){ while (check_svg(pointer_row,pointer_column)) { @@ -2110,7 +2114,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ pointer_row=pointer_row+1 } } - id= "#row"+pointer_row+"col"+pointer_column + var id= "#row"+pointer_row+"col"+pointer_column //console.log(id) var cell= d3.select(id); @@ -2122,8 +2126,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - - + From 0368b858a05270665b082ad0704d174d4215d628 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 29 Jul 2024 23:55:26 -0400 Subject: [PATCH 47/69] Give error message if only row or col is added in theme Give error message in R session if only row or col is added in theme function. --- R/z_animint.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/R/z_animint.R b/R/z_animint.R index cfdef8713..4394d346e 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -362,7 +362,13 @@ animint2dir <- function(plot.list, out.dir = NULL, if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. - #print(parsed_info$plot.info) + #print(parsed_info$plot.info$title) + if (!is.null(parsed_info$plot.info$row) && is.null(parsed_info$plot.info$col)) { + stop("You forget to add col in ",parsed_info$plot.info$title) + } + if (!is.null(parsed_info$plot.info$col) && is.null(parsed_info$plot.info$row)) { + stop("You forget to add row in ",parsed_info$plot.info$title) + } AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot ggplot.list[[list.name]]$built <- parsed_info$built From 28f5cacec6e584df83797bd3f06cb0ec1fe4fdc2 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 31 Jul 2024 15:00:07 -0400 Subject: [PATCH 48/69] theme_animint now accepts dimensions and not theme changed from theme to theme_animint for taking row and col arguments, removed the code to show browser side error if the user fails to add only row or col. because that is not necessary now because code to show error message in R session itself is there now. also changed theme function to theme_animint in the test i had wrote for passing row and col arguments --- R/theme-elements.r | 5 +---- R/theme.r | 11 +++++------ R/z_animint.R | 15 ++++++++------- R/z_animintHelpers.R | 10 ++++++++++ inst/htmljs/animint.js | 22 +++------------------- tests/testthat/test-renderer3-fourplots.R | 8 ++++---- 6 files changed, 31 insertions(+), 40 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index 76fbd069c..c616ad195 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -282,10 +282,7 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { plot.caption = el_def("element_text", "title"), plot.margin = el_def("margin"), - aspect.ratio = el_def("character"), - - row = el_def("character"), - col = el_def("character") + aspect.ratio = el_def("character") ) diff --git a/R/theme.r b/R/theme.r index 8730232d0..bffbc9e75 100644 --- a/R/theme.r +++ b/R/theme.r @@ -353,20 +353,19 @@ print.theme <- function(x, ...) utils::str(x) #' } theme <- function(..., complete = FALSE, validate = TRUE) { elements <- list(...) - + if (!is.null(elements$axis.ticks.margin)) { warning("`axis.ticks.margin` is deprecated. Please set `margin` property ", " of `axis.text` instead", call. = FALSE) elements$axis.ticks.margin <- NULL } - + # Check that all elements have the correct class (element_text, unit, etc) if (validate) { mapply(validate_element, elements, names(elements)) } - - structure(elements, class = c("theme", "gganimint"), - complete = complete, validate = validate) + + structure(elements, class = c("theme", "gganimint"),complete = complete, validate = validate) } @@ -494,7 +493,7 @@ update_theme <- function(oldtheme, newtheme) { # the default theme -- just replace everything with newtheme if (attr(newtheme, "complete")) return(newtheme) - + # These are elements in newtheme that aren't already set in oldtheme. # They will be pulled from the default theme. newitems <- !names(newtheme) %in% names(oldtheme) diff --git a/R/z_animint.R b/R/z_animint.R index 4394d346e..528a407e3 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -104,8 +104,6 @@ parsePlot <- function(meta, plot, plot.name){ plot.info$grid_minor <- get_grid(theme.pars$panel.grid.minor, theme.pars, plot.info, meta, built, major = F) theme <- plot_theme(built$plot) - plot.info$row <-theme$row - plot.info$col <-theme$col ## Flip labels if coords are flipped - transform does not take care ## of this. Do this BEFORE checking if it is blank or not, so that ## individual axes can be hidden appropriately, e.g. #1. @@ -202,7 +200,9 @@ parsePlot <- function(meta, plot, plot.name){ options_list <- getWidthAndHeight(plot$theme) options_list <- setUpdateAxes(plot$theme, options_list) plot.info$options <- options_list - + + plot.info$position <- getRowAndColumn(plot$theme) + list( plot.info=plot.info, ggplot=plot, @@ -361,13 +361,14 @@ animint2dir <- function(plot.list, out.dir = NULL, p <- plot.list[[list.name]] if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing + parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. #print(parsed_info$plot.info$title) - if (!is.null(parsed_info$plot.info$row) && is.null(parsed_info$plot.info$col)) { - stop("You forget to add col in ",parsed_info$plot.info$title) + if (!is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col)) { + stop("You passed row but not the col argument for ",parsed_info$plot.info$title) } - if (!is.null(parsed_info$plot.info$col) && is.null(parsed_info$plot.info$row)) { - stop("You forget to add row in ",parsed_info$plot.info$title) + if (!is.null(parsed_info$plot.info$position$col) && is.null(parsed_info$plot.info$position$row)) { + stop("You passed col but not the row argument for ",parsed_info$plot.info$title) } AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot diff --git a/R/z_animintHelpers.R b/R/z_animintHelpers.R index 1d9432a83..5aa87469b 100644 --- a/R/z_animintHelpers.R +++ b/R/z_animintHelpers.R @@ -147,6 +147,16 @@ getWidthAndHeight <- function(theme){ options_list } +getRowAndColumn <- function(theme){ + options_list <- list() + for(rc in c("row", "col")){ + arc <- paste0("animint.", rc) + options_list[[rc]] <- if(arc %in% names(theme)){ + theme[[arc]] + } + } + options_list +} setUpdateAxes <- function(theme, options_list){ update_axes <- "animint.update_axes" diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 5f9ce3631..fb0446f6e 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2043,18 +2043,6 @@ var animint = function (to_select, json_file) { } - for (var p_name in response.plots) { - if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { - user_defined_layout= true -} -if ('row' in response.plots[p_name] && !('col' in response.plots[p_name])){ - throw new Error("You forgot to add column in "+response.plots[p_name].title+" plot."); -} -if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ - throw new Error("You forgot to add row in "+response.plots[p_name].title+" plot."); -} - } - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2092,8 +2080,8 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ var outer_table=construct_outer_table(); for (var p_name in response.plots) { - if ('row' in response.plots[p_name] && 'col' in response.plots[p_name]) { - var id= "#row"+response.plots[p_name].row+"col"+response.plots[p_name].col + if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position) { + var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2106,7 +2094,7 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ var pointer_row=0 var pointer_column=0 for (var p_name in response.plots) { - if (!('row' in response.plots[p_name])){ + if (!('row' in response.plots[p_name].position)){ while (check_svg(pointer_row,pointer_column)) { pointer_column=pointer_column+1 if (pointer_column>maximum_column){ @@ -2127,10 +2115,6 @@ if ('col' in response.plots[p_name] && !('row'in response.plots[p_name])){ } } - - - - // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { add_selector(s_name, response.selectors[s_name]); diff --git a/tests/testthat/test-renderer3-fourplots.R b/tests/testthat/test-renderer3-fourplots.R index c2307113d..daf84c580 100644 --- a/tests/testthat/test-renderer3-fourplots.R +++ b/tests/testthat/test-renderer3-fourplots.R @@ -9,7 +9,7 @@ test_that("check if two plots exist", { plot1 <- ggplot(data1, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 3 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=0) + xlab("X Axis") + ylab("Y Axis") #theme(plot.title = element_text(color = "purple", size = 20, face = "bold")) data2 <- data.frame( x = c(1, 2), # x-coordinates of the dots @@ -19,7 +19,7 @@ test_that("check if two plots exist", { plot2 <- ggplot(data2, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 2 Dots") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=1,col=1) + xlab("X Axis") + ylab("Y Axis") data3 <- data.frame( x = c(2), # x-coordinates of the dots @@ -29,7 +29,7 @@ test_that("check if two plots exist", { plot3 <- ggplot(data3, aes(x, y)) + geom_point(size = 2) + # Plot points with a specified size ggtitle("Plot of 1 Dot") + # Add a title to the plot - xlab("X Axis") + ylab("Y Axis")+theme(row=0,col=1) + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=1,col=1) plot4 <- ggplot(mtcars, aes(x = wt, y = mpg))+ geom_point() + @@ -42,7 +42,7 @@ test_that("check if two plots exist", { axis.text.y = element_text(color = "red", size = 12), legend.position = "bottom", legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5) - ) + )+theme_animint(row=0,col=1) plot_list <- list( plot1=plot1, From c5e4c8ca057f08929308dcb5e820cc5e8a7f67e6 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 6 Aug 2024 12:42:31 -0400 Subject: [PATCH 49/69] removed debugging line --- inst/htmljs/animint.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index fb0446f6e..356f8a4fa 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -6,13 +6,7 @@ // Constructor for animint Object. var animint = function (to_select, json_file) { - //console.log(json_file) - fetch(json_file) - .then(response => response.json()) - .then(data => { - console.log(data); // Prints the entire JSON data - }) - .catch(error => console.error('Error fetching the JSON file:', error)); + var default_axis_px = 16; function wait_until_then(timeout, condFun, readyFun) { From aa07dd9a6372cb5deae5cc298ba97f4b423a3bf2 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 6 Aug 2024 12:44:42 -0400 Subject: [PATCH 50/69] removed comments --- R/theme-elements.r | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index c616ad195..5450264da 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -297,8 +297,7 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { # @param el an element # @param elname the name of the element validate_element <- function(el, elname) { - #print(el) - #print(elname) + eldef <- .element_tree[[elname]] if (is.null(eldef)) { From 7b31296034b3bc2209945c4a2ab89281f5ed3f33 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 7 Aug 2024 00:56:50 -0400 Subject: [PATCH 51/69] reverted to original style and indentation --- R/theme.r | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/theme.r b/R/theme.r index bffbc9e75..d00848790 100644 --- a/R/theme.r +++ b/R/theme.r @@ -365,7 +365,8 @@ theme <- function(..., complete = FALSE, validate = TRUE) { mapply(validate_element, elements, names(elements)) } - structure(elements, class = c("theme", "gganimint"),complete = complete, validate = validate) + structure(elements, class = c("theme", "gganimint"), + complete = complete, validate = validate) } From 70d550d0b53ff638639db7b5add01f244a079156 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sat, 10 Aug 2024 14:42:18 -0400 Subject: [PATCH 52/69] made border transparent --- inst/htmljs/animint.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 356f8a4fa..9c654f1f0 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2057,15 +2057,15 @@ var animint = function (to_select, json_file) { } find_maximum_dimensions() var count_dimensions = Math.ceil(Math.sqrt(count))-1; - var outer_table = element.append("table").attr("id", "outerTable").style("width", "1500px").style("border", "1px solid white"); maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - //console.log(maximum_row) - //console.log(maximum_column) + table_width=(maximum_column+1)*500+"px" + var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid solid transparent"); + for (var i = 0; i <=maximum_row; i++) { - var current_row = outer_table.append("tr").style("border", "1px solid white").style("height", "500px"); + var current_row = outer_table.append("tr").style("border", "1px solid transparent").style("height", "500px"); for (var j = 0; j <=maximum_column; j++){ - current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid white").style("width", "500px"); + current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid solid transparent").style("width", "500px"); } } From d3e15b341e3e49d46f9060534fa26728a1814fab Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sat, 10 Aug 2024 17:37:05 -0400 Subject: [PATCH 53/69] added var as prefix to make it local --- inst/htmljs/animint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 9c654f1f0..859a47db0 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2059,7 +2059,7 @@ var animint = function (to_select, json_file) { var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - table_width=(maximum_column+1)*500+"px" + var table_width=(maximum_column+1)*500+"px" var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid solid transparent"); for (var i = 0; i <=maximum_row; i++) { From 731041f3653460153d497b6c33be673f0331c453 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Mon, 2 Sep 2024 19:44:46 -0400 Subject: [PATCH 54/69] plots save span plots save rowspan and colspan values as parameters which will be used later to implement the actual functionality --- R/z_animint.R | 2 ++ R/z_animintHelpers.R | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/R/z_animint.R b/R/z_animint.R index 528a407e3..9dbb80e35 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -203,6 +203,8 @@ parsePlot <- function(meta, plot, plot.name){ plot.info$position <- getRowAndColumn(plot$theme) + plot.info$span <- getRowspanAndColumnspan(plot$theme) + list( plot.info=plot.info, ggplot=plot, diff --git a/R/z_animintHelpers.R b/R/z_animintHelpers.R index 5aa87469b..d01c73dda 100644 --- a/R/z_animintHelpers.R +++ b/R/z_animintHelpers.R @@ -158,6 +158,17 @@ getRowAndColumn <- function(theme){ options_list } +getRowspanAndColumnspan <- function(theme){ + options_list <- list() + for(rscs in c("rowspan", "colspan")){ + arc <- paste0("animint.", rscs) + options_list[[rscs]] <- if(arc %in% names(theme)){ + theme[[arc]] + } + } + options_list +} + setUpdateAxes <- function(theme, options_list){ update_axes <- "animint.update_axes" if(update_axes %in% names(theme)){ From 06d02c864ea287010a6a4a1a59506efbad4e2818 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 4 Sep 2024 00:03:11 -0400 Subject: [PATCH 55/69] rowspan is applied rowspan is applied assuming user has not put overlapping plots. code to show overlapping plots error will be added --- R/z_animint.R | 1 - inst/htmljs/animint.js | 33 +++++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/R/z_animint.R b/R/z_animint.R index 9dbb80e35..9367beba0 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -365,7 +365,6 @@ animint2dir <- function(plot.list, out.dir = NULL, ## If plot is correct, save to meta for further processing parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. - #print(parsed_info$plot.info$title) if (!is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col)) { stop("You passed row but not the col argument for ",parsed_info$plot.info$title) } diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 859a47db0..21e08cf0e 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2025,7 +2025,6 @@ var animint = function (to_select, json_file) { } // Add plots. - var check_svg = function (row_number,col_number) { var id="#row"+row_number+"col"+col_number var parentElement= d3.select(id) @@ -2036,7 +2035,6 @@ var animint = function (to_select, json_file) { } } - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2044,7 +2042,6 @@ var animint = function (to_select, json_file) { var find_maximum_dimensions = function () { - for (var p_name in response.plots) { count=count+1 if (response.plots[p_name].row>maximum_row){ @@ -2056,16 +2053,38 @@ var animint = function (to_select, json_file) { } } find_maximum_dimensions() + function generateKey(row, col) { + return `${row},${col}`; +} var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) var table_width=(maximum_column+1)*500+"px" - var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid solid transparent"); + var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); + let span_map = new Map(); + for (var p_name in response.plots) { + if (('rowspan' in response.plots[p_name].span)){ + + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + span_map.set(key,response.plots[p_name].span) + + } + } for (var i = 0; i <=maximum_row; i++) { - var current_row = outer_table.append("tr").style("border", "1px solid transparent").style("height", "500px"); + + var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); for (var j = 0; j <=maximum_column; j++){ - current_row.append("td").attr("id", "row"+i+"col"+j).style("border", "1px solid solid transparent").style("width", "500px"); + + let key = generateKey(i,j); + if (span_map.has(key)){ + var rowspan=span_map.get(key).rowspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); + } + else{ + current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); + } + } } @@ -2077,7 +2096,6 @@ var animint = function (to_select, json_file) { if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position) { var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); - add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. @@ -2097,7 +2115,6 @@ var animint = function (to_select, json_file) { } } var id= "#row"+pointer_row+"col"+pointer_column - //console.log(id) var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); From 1eff5de8465c1e5e122e719a8af65c4e3cdb2b4f Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 4 Sep 2024 23:12:23 -0400 Subject: [PATCH 56/69] colspan can now be applied colspan can now be applied --- inst/htmljs/animint.js | 103 +++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 21e08cf0e..589b94e2f 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2055,45 +2055,55 @@ var animint = function (to_select, json_file) { find_maximum_dimensions() function generateKey(row, col) { return `${row},${col}`; -} - var count_dimensions = Math.ceil(Math.sqrt(count))-1; - maximum_row=Math.max(maximum_row,count_dimensions) - maximum_column=Math.max(maximum_column,count_dimensions) - var table_width=(maximum_column+1)*500+"px" - var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); - let span_map = new Map(); - for (var p_name in response.plots) { - if (('rowspan' in response.plots[p_name].span)){ - - let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); - span_map.set(key,response.plots[p_name].span) - - } - } + } + var count_dimensions = Math.ceil(Math.sqrt(count))-1; + maximum_row=Math.max(maximum_row,count_dimensions) + maximum_column=Math.max(maximum_column,count_dimensions) + var table_width=(maximum_column+1)*500+"px" + var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); + let rowspan_map = new Map(); + let colspan_map = new Map(); + for (var p_name in response.plots) { + if (('rowspan' in response.plots[p_name].span)){ + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + rowspan_map.set(key,response.plots[p_name].span) + + } + if (('colspan' in response.plots[p_name].span)){ + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + colspan_map.set(key,response.plots[p_name].span) + + } + } for (var i = 0; i <=maximum_row; i++) { + var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); + for (var j = 0; j <=maximum_column; j++){ + let key = generateKey(i,j); + if (rowspan_map.has(key)){ + var rowspan=span_map.get(key).rowspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); - var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); - for (var j = 0; j <=maximum_column; j++){ - - let key = generateKey(i,j); - if (span_map.has(key)){ - var rowspan=span_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); - } - else{ - current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); - } - - } + } + else if(colspan_map.has(key)){ + var colspan=colspan_map.get(key).colspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan).style("height", "500px").style("border", "1px solid black"); + + } + else{ + current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); + + } + + } + } + return outer_table; - return outer_table; } var outer_table=construct_outer_table(); - for (var p_name in response.plots) { - if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position) { + if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position){ var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2103,17 +2113,19 @@ var animint = function (to_select, json_file) { document.head.appendChild(css); } } - var pointer_row=0 - var pointer_column=0 - for (var p_name in response.plots) { - if (!('row' in response.plots[p_name].position)){ - while (check_svg(pointer_row,pointer_column)) { - pointer_column=pointer_column+1 - if (pointer_column>maximum_column){ - pointer_column=0 - pointer_row=pointer_row+1 - } - } + var pointer_row=0 + var pointer_column=0 + for (var p_name in response.plots) { + if (!('row' in response.plots[p_name].position)){ + while (check_svg(pointer_row,pointer_column)) { + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 + + } + + } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); @@ -2122,9 +2134,10 @@ var animint = function (to_select, json_file) { // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); - -} - } + + } + + } // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { From 0ecc99f0b7a14f825eda01dd31f853732c132e48 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sat, 7 Sep 2024 02:53:07 -0400 Subject: [PATCH 57/69] refactoring --- inst/htmljs/animint.js | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 589b94e2f..3cecdd36a 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2039,9 +2039,7 @@ var animint = function (to_select, json_file) { var maximum_column= 0 var construct_outer_table = function () { var count=0 - var find_maximum_dimensions = function () { - for (var p_name in response.plots) { count=count+1 if (response.plots[p_name].row>maximum_row){ @@ -2055,51 +2053,41 @@ var animint = function (to_select, json_file) { find_maximum_dimensions() function generateKey(row, col) { return `${row},${col}`; - } var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) - var table_width=(maximum_column+1)*500+"px" - var outer_table = element.append("table").attr("id", "outerTable").style("width", table_width).style("border", "1px solid black"); + var outer_table = element.append("table").attr("id", "outerTable"); let rowspan_map = new Map(); let colspan_map = new Map(); for (var p_name in response.plots) { if (('rowspan' in response.plots[p_name].span)){ let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); rowspan_map.set(key,response.plots[p_name].span) - } if (('colspan' in response.plots[p_name].span)){ let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); colspan_map.set(key,response.plots[p_name].span) - } } for (var i = 0; i <=maximum_row; i++) { - var current_row = outer_table.append("tr").style("height", "500px").style("border", "1px solid black"); + var current_row = outer_table.append("tr"); for (var j = 0; j <=maximum_column; j++){ let key = generateKey(i,j); if (rowspan_map.has(key)){ var rowspan=span_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("height", "500px").style("border", "1px solid black"); - + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan); } else if(colspan_map.has(key)){ var colspan=colspan_map.get(key).colspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan).style("height", "500px").style("border", "1px solid black"); - + current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan); } else{ - current_row.append("td").attr("id", "row"+i+"col"+j).style("height", "500px").style("border", "1px solid black"); - + current_row.append("td").attr("id", "row"+i+"col"+j); } - } - } return outer_table; - } var outer_table=construct_outer_table(); for (var p_name in response.plots) { @@ -2122,9 +2110,7 @@ var animint = function (to_select, json_file) { if (pointer_column>maximum_column){ pointer_column=0 pointer_row=pointer_row+1 - } - } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); @@ -2134,9 +2120,7 @@ var animint = function (to_select, json_file) { // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); - } - } // Then add selectors and start downloading the first data subset. From 54fcb779aac0677bef22c0a11d5dab1a9131b10e Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 16:46:18 -0400 Subject: [PATCH 58/69] corrected response.plots[p_name].row toresponse.plots[p_name].position.row corrected response.plots[p_name].row toresponse.plots[p_name].position.row, removed borders , removed hardcoded values of cell dimensions, added the left case where user has given both rowspan and colspan for a same plot --- inst/htmljs/animint.js | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 3cecdd36a..db59b79c1 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2042,13 +2042,13 @@ var animint = function (to_select, json_file) { var find_maximum_dimensions = function () { for (var p_name in response.plots) { count=count+1 - if (response.plots[p_name].row>maximum_row){ - maximum_row=response.plots[p_name].row - } - if (response.plots[p_name].col>maximum_column){ - maximum_column=response.plots[p_name].col + if (response.plots[p_name].position.row>maximum_row){ + maximum_row=response.plots[p_name].position.row + } + if (response.plots[p_name].position.col>maximum_column){ + maximum_column=response.plots[p_name].position.col + } } - } } find_maximum_dimensions() function generateKey(row, col) { @@ -2057,6 +2057,7 @@ var animint = function (to_select, json_file) { var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) + var maximum_dimensions=Math.max(maximum_column,maximum_row) var outer_table = element.append("table").attr("id", "outerTable"); let rowspan_map = new Map(); let colspan_map = new Map(); @@ -2070,18 +2071,23 @@ var animint = function (to_select, json_file) { colspan_map.set(key,response.plots[p_name].span) } } - for (var i = 0; i <=maximum_row; i++) { + for (var i = 0; i <=maximum_dimensions; i++) { var current_row = outer_table.append("tr"); - for (var j = 0; j <=maximum_column; j++){ + for (var j = 0; j <=maximum_dimensions; j++){ let key = generateKey(i,j); - if (rowspan_map.has(key)){ - var rowspan=span_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan); + if (rowspan_map.has(key) && (colspan_map.has(key))){ + var rowspan=rowspan_map.get(key).rowspan + var colspan=colspan_map.get(key).colspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).attr("colspan",colspan); } else if(colspan_map.has(key)){ var colspan=colspan_map.get(key).colspan current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan); } + else if(rowspan_map.has(key)){ + var rowspan=rowspan_map.get(key).rowspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan); + } else{ current_row.append("td").attr("id", "row"+i+"col"+j); } From 3a11c39a44dcbac9d9f1c9bf92c40c1768fd6cc3 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 17:14:55 -0400 Subject: [PATCH 59/69] throw error if user is incosistent is passing row and col throw error if user is incosistent is passing row and col arguments in plots, that is user passes them for some and not for others. --- R/z_animint.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/R/z_animint.R b/R/z_animint.R index 9367beba0..38df15b0c 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -359,11 +359,11 @@ animint2dir <- function(plot.list, out.dir = NULL, ## Call ggplot_build in parsPlot for all ggplots ggplot.list <- list() AllPlotsInfo <- list() + custom_layout <- FALSE for(list.name in names(plot.list)){ p <- plot.list[[list.name]] if(is.ggplot(p)){ ## If plot is correct, save to meta for further processing - parsed_info <- parsePlot(meta, p, list.name) # calls ggplot_build. if (!is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col)) { stop("You passed row but not the col argument for ",parsed_info$plot.info$title) @@ -371,6 +371,12 @@ animint2dir <- function(plot.list, out.dir = NULL, if (!is.null(parsed_info$plot.info$position$col) && is.null(parsed_info$plot.info$position$row)) { stop("You passed col but not the row argument for ",parsed_info$plot.info$title) } + if (!is.null(parsed_info$plot.info$position$row) && !is.null(parsed_info$plot.info$position$col)){ + custom_layout<- TRUE + } + if (is.null(parsed_info$plot.info$position$row) && is.null(parsed_info$plot.info$position$col) && custom_layout){ + stop("You passed col and row for some plots and not for others, please pass for all or none") + } AllPlotsInfo[[list.name]] <- parsed_info$plot.info ggplot.list[[list.name]]$ggplot <- parsed_info$ggplot ggplot.list[[list.name]]$built <- parsed_info$built From a21e13bd897409c7de20616f79be8e1a42f7355f Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 17:23:07 -0400 Subject: [PATCH 60/69] removed check_svg function check_svg function was for checking empty locations for rest of the plots when user puts rows and cols for some plots while not for others. this is no longer needed now because now the user has to select specific positions for all plots or for no plots at all --- inst/htmljs/animint.js | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index db59b79c1..2f0b328a5 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2025,16 +2025,6 @@ var animint = function (to_select, json_file) { } // Add plots. - var check_svg = function (row_number,col_number) { - var id="#row"+row_number+"col"+col_number - var parentElement= d3.select(id) - if (!parentElement.select('svg').empty()) { - return true - }else{ - return false - } - } - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2111,12 +2101,10 @@ var animint = function (to_select, json_file) { var pointer_column=0 for (var p_name in response.plots) { if (!('row' in response.plots[p_name].position)){ - while (check_svg(pointer_row,pointer_column)) { - pointer_column=pointer_column+1 - if (pointer_column>maximum_column){ - pointer_column=0 - pointer_row=pointer_row+1 - } + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); From 841c4ff60ea8cb1106f154cc16a2d3cb634eed6a Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 20:27:29 -0400 Subject: [PATCH 61/69] refactoring --- inst/htmljs/animint.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 2f0b328a5..bca903f6c 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2024,7 +2024,7 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - + var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2087,7 +2087,7 @@ var animint = function (to_select, json_file) { } var outer_table=construct_outer_table(); for (var p_name in response.plots) { - if ('row' in response.plots[p_name].position && 'col' in response.plots[p_name].position){ + if ('row' in response.plots[p_name].position){ var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); @@ -2136,7 +2136,6 @@ var animint = function (to_select, json_file) { } } } - //////////////////////////////////////////// // Widgets at bottom of page //////////////////////////////////////////// From 87ecfda76edbf3f111e40d7cf520e416b0627726 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 24 Sep 2024 23:35:19 -0400 Subject: [PATCH 62/69] corrected code to properly traverse the outer table corrected the code to properly traverse the outer table to put the plots if the user choses not to use customized layout --- inst/htmljs/animint.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index bca903f6c..0776a55a3 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2024,7 +2024,6 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - var maximum_row= 0 var maximum_column= 0 var construct_outer_table = function () { @@ -2101,14 +2100,13 @@ var animint = function (to_select, json_file) { var pointer_column=0 for (var p_name in response.plots) { if (!('row' in response.plots[p_name].position)){ - pointer_column=pointer_column+1 - if (pointer_column>maximum_column){ - pointer_column=0 - pointer_row=pointer_row+1 - } var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); - + pointer_column=pointer_column+1 + if (pointer_column>maximum_column){ + pointer_column=0 + pointer_row=pointer_row+1 + } add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); // Append style sheet to document head. From c66cdb022abbc5bbce0026730c08cf8e457f6483 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Fri, 27 Sep 2024 16:01:51 -0400 Subject: [PATCH 63/69] removed blank lines --- R/theme-elements.r | 1 - R/z_animint.R | 6 ------ inst/htmljs/animint.js | 6 ------ 3 files changed, 13 deletions(-) diff --git a/R/theme-elements.r b/R/theme-elements.r index 5450264da..d72b41507 100644 --- a/R/theme-elements.r +++ b/R/theme-elements.r @@ -297,7 +297,6 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) { # @param el an element # @param elname the name of the element validate_element <- function(el, elname) { - eldef <- .element_tree[[elname]] if (is.null(eldef)) { diff --git a/R/z_animint.R b/R/z_animint.R index 38df15b0c..860fcd554 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -200,9 +200,7 @@ parsePlot <- function(meta, plot, plot.name){ options_list <- getWidthAndHeight(plot$theme) options_list <- setUpdateAxes(plot$theme, options_list) plot.info$options <- options_list - plot.info$position <- getRowAndColumn(plot$theme) - plot.info$span <- getRowspanAndColumnspan(plot$theme) list( @@ -253,7 +251,6 @@ storeLayer <- function(meta, g, g.data.varied){ animint2dir <- function(plot.list, out.dir = NULL, json.file = "plot.json", open.browser = interactive(), css.file = "") { - if(is.null(out.dir)){ out.dir <- tempfile() } @@ -656,7 +653,6 @@ animint2dir <- function(plot.list, out.dir = NULL, stop("missing first selector variable") } } - meta$plots <- AllPlotsInfo meta$time <- AnimationInfo$time meta$timeValues <- AnimationInfo$timeValues @@ -708,10 +704,8 @@ getLegendList <- function(plistextra){ position <- theme$legend.position text <- theme$legend.text title <- theme$legend.title - #print(theme$row) # by default, guide boxes are vertically aligned if(is.null(theme$legend.box)) theme$legend.box <- "vertical" else theme$legend.box - # size of key (also used for bar in colorbar guide) if(is.null(theme$legend.key.width)) theme$legend.key.width <- theme$legend.key.size if(is.null(theme$legend.key.height)) theme$legend.key.height <- theme$legend.key.size diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 0776a55a3..8ad1c3668 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -4,7 +4,6 @@ // var plot = new animint("#plot","path/to/plot.json"); // // Constructor for animint Object. - var animint = function (to_select, json_file) { var default_axis_px = 16; @@ -215,13 +214,10 @@ var animint = function (to_select, json_file) { // Save this geom and load it! update_geom(g_name, null); }; - - var add_plot = function (p_name, p_info,outer_table) { // Each plot may have one or more legends. To make space for the // legends, we put each plot in a table with one row and two // columns: tdLeft and tdRight. - var plot_table = outer_table.append("table").style("display", "inline-block"); var plot_tr = plot_table.append("tr"); var tdLeft = plot_tr.append("td"); @@ -1070,7 +1066,6 @@ var animint = function (to_select, json_file) { }else{ get_stroke_width = function(d){ return stroke_width; - }; } @@ -2114,7 +2109,6 @@ var animint = function (to_select, json_file) { document.head.appendChild(css); } } - // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { add_selector(s_name, response.selectors[s_name]); From d9e0310e84a47b26e5a770cede7e27120029a840 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Tue, 1 Oct 2024 00:31:15 +0530 Subject: [PATCH 64/69] combined getRowAndColumn and getRowspanAndColumnspan functions --- R/z_animint.R | 3 +-- R/z_animintHelpers.R | 19 ++++--------------- inst/htmljs/animint.js | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/R/z_animint.R b/R/z_animint.R index 860fcd554..c3a0c9dcf 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -200,8 +200,7 @@ parsePlot <- function(meta, plot, plot.name){ options_list <- getWidthAndHeight(plot$theme) options_list <- setUpdateAxes(plot$theme, options_list) plot.info$options <- options_list - plot.info$position <- getRowAndColumn(plot$theme) - plot.info$span <- getRowspanAndColumnspan(plot$theme) + plot.info$attributes <- theme_attribute(plot$theme) list( plot.info=plot.info, diff --git a/R/z_animintHelpers.R b/R/z_animintHelpers.R index d01c73dda..bfc9b022f 100644 --- a/R/z_animintHelpers.R +++ b/R/z_animintHelpers.R @@ -147,22 +147,11 @@ getWidthAndHeight <- function(theme){ options_list } -getRowAndColumn <- function(theme){ +theme_attribute <- function(theme){ options_list <- list() - for(rc in c("row", "col")){ - arc <- paste0("animint.", rc) - options_list[[rc]] <- if(arc %in% names(theme)){ - theme[[arc]] - } - } - options_list -} - -getRowspanAndColumnspan <- function(theme){ - options_list <- list() - for(rscs in c("rowspan", "colspan")){ - arc <- paste0("animint.", rscs) - options_list[[rscs]] <- if(arc %in% names(theme)){ + for(attributes in c("rowspan", "colspan","row","col")){ + arc <- paste0("animint.", attributes) + options_list[[attributes]] <- if(arc %in% names(theme)){ theme[[arc]] } } diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 8ad1c3668..82c5c959b 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2026,11 +2026,11 @@ var animint = function (to_select, json_file) { var find_maximum_dimensions = function () { for (var p_name in response.plots) { count=count+1 - if (response.plots[p_name].position.row>maximum_row){ - maximum_row=response.plots[p_name].position.row + if (response.plots[p_name].attributes.row>maximum_row){ + maximum_row=response.plots[p_name].attributes.row } - if (response.plots[p_name].position.col>maximum_column){ - maximum_column=response.plots[p_name].position.col + if (response.plots[p_name].attributes.col>maximum_column){ + maximum_column=response.plots[p_name].attributes.col } } } @@ -2046,13 +2046,13 @@ var animint = function (to_select, json_file) { let rowspan_map = new Map(); let colspan_map = new Map(); for (var p_name in response.plots) { - if (('rowspan' in response.plots[p_name].span)){ - let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); - rowspan_map.set(key,response.plots[p_name].span) + if (('rowspan' in response.plots[p_name].attributes)){ + let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); + rowspan_map.set(key,response.plots[p_name].attributes) } - if (('colspan' in response.plots[p_name].span)){ - let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); - colspan_map.set(key,response.plots[p_name].span) + if (('colspan' in response.plots[p_name].attributes)){ + let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); + colspan_map.set(key,response.plots[p_name].attributes) } } for (var i = 0; i <=maximum_dimensions; i++) { From 446e549af93baca3a2e9378eeac0e8d951998022 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 2 Oct 2024 00:37:15 +0530 Subject: [PATCH 65/69] reverting changes for debugging --- R/z_animint.R | 3 ++- R/z_animintHelpers.R | 22 ++++++++++++++++++++++ inst/htmljs/animint.js | 20 ++++++++++---------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/R/z_animint.R b/R/z_animint.R index c3a0c9dcf..860fcd554 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -200,7 +200,8 @@ parsePlot <- function(meta, plot, plot.name){ options_list <- getWidthAndHeight(plot$theme) options_list <- setUpdateAxes(plot$theme, options_list) plot.info$options <- options_list - plot.info$attributes <- theme_attribute(plot$theme) + plot.info$position <- getRowAndColumn(plot$theme) + plot.info$span <- getRowspanAndColumnspan(plot$theme) list( plot.info=plot.info, diff --git a/R/z_animintHelpers.R b/R/z_animintHelpers.R index bfc9b022f..6f375fef9 100644 --- a/R/z_animintHelpers.R +++ b/R/z_animintHelpers.R @@ -158,6 +158,28 @@ theme_attribute <- function(theme){ options_list } +getRowAndColumn <- function(theme){ + options_list <- list() + for(rc in c("row", "col")){ + arc <- paste0("animint.", rc) + options_list[[rc]] <- if(arc %in% names(theme)){ + theme[[arc]] + } + } + options_list +} + +getRowspanAndColumnspan <- function(theme){ + options_list <- list() + for(rscs in c("rowspan", "colspan")){ + arc <- paste0("animint.", rscs) + options_list[[rscs]] <- if(arc %in% names(theme)){ + theme[[arc]] + } + } + options_list +} + setUpdateAxes <- function(theme, options_list){ update_axes <- "animint.update_axes" if(update_axes %in% names(theme)){ diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 82c5c959b..5d02354f4 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2026,11 +2026,11 @@ var animint = function (to_select, json_file) { var find_maximum_dimensions = function () { for (var p_name in response.plots) { count=count+1 - if (response.plots[p_name].attributes.row>maximum_row){ - maximum_row=response.plots[p_name].attributes.row + if (response.plots[p_name].position.row>maximum_row){ + maximum_row=response.plots[p_name].position.row } - if (response.plots[p_name].attributes.col>maximum_column){ - maximum_column=response.plots[p_name].attributes.col + if (response.plots[p_name].position.col>maximum_column){ + maximum_column=response.plots[p_name].position.col } } } @@ -2046,13 +2046,13 @@ var animint = function (to_select, json_file) { let rowspan_map = new Map(); let colspan_map = new Map(); for (var p_name in response.plots) { - if (('rowspan' in response.plots[p_name].attributes)){ - let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); - rowspan_map.set(key,response.plots[p_name].attributes) + if (('rowspan' in response.plots[p_name].span)){ + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + rowspan_map.set(key,response.plots[p_name].span) } - if (('colspan' in response.plots[p_name].attributes)){ - let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); - colspan_map.set(key,response.plots[p_name].attributes) + if (('colspan' in response.plots[p_name].position)){ + let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); + colspan_map.set(key,response.plots[p_name].span) } } for (var i = 0; i <=maximum_dimensions; i++) { From ff968115deeb488965c6e73d9c5c62dc44f6ac1e Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 2 Oct 2024 00:56:21 +0530 Subject: [PATCH 66/69] merged functions into attribute function --- R/z_animint.R | 3 +-- R/z_animintHelpers.R | 22 ---------------------- inst/htmljs/animint.js | 26 +++++++++++++------------- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/R/z_animint.R b/R/z_animint.R index 860fcd554..c3a0c9dcf 100644 --- a/R/z_animint.R +++ b/R/z_animint.R @@ -200,8 +200,7 @@ parsePlot <- function(meta, plot, plot.name){ options_list <- getWidthAndHeight(plot$theme) options_list <- setUpdateAxes(plot$theme, options_list) plot.info$options <- options_list - plot.info$position <- getRowAndColumn(plot$theme) - plot.info$span <- getRowspanAndColumnspan(plot$theme) + plot.info$attributes <- theme_attribute(plot$theme) list( plot.info=plot.info, diff --git a/R/z_animintHelpers.R b/R/z_animintHelpers.R index 6f375fef9..bfc9b022f 100644 --- a/R/z_animintHelpers.R +++ b/R/z_animintHelpers.R @@ -158,28 +158,6 @@ theme_attribute <- function(theme){ options_list } -getRowAndColumn <- function(theme){ - options_list <- list() - for(rc in c("row", "col")){ - arc <- paste0("animint.", rc) - options_list[[rc]] <- if(arc %in% names(theme)){ - theme[[arc]] - } - } - options_list -} - -getRowspanAndColumnspan <- function(theme){ - options_list <- list() - for(rscs in c("rowspan", "colspan")){ - arc <- paste0("animint.", rscs) - options_list[[rscs]] <- if(arc %in% names(theme)){ - theme[[arc]] - } - } - options_list -} - setUpdateAxes <- function(theme, options_list){ update_axes <- "animint.update_axes" if(update_axes %in% names(theme)){ diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 5d02354f4..47576ad98 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2026,11 +2026,11 @@ var animint = function (to_select, json_file) { var find_maximum_dimensions = function () { for (var p_name in response.plots) { count=count+1 - if (response.plots[p_name].position.row>maximum_row){ - maximum_row=response.plots[p_name].position.row + if (response.plots[p_name].attributes.row>maximum_row){ + maximum_row=response.plots[p_name].attributes.row } - if (response.plots[p_name].position.col>maximum_column){ - maximum_column=response.plots[p_name].position.col + if (response.plots[p_name].attributes.col>maximum_column){ + maximum_column=response.plots[p_name].attributes.col } } } @@ -2046,13 +2046,13 @@ var animint = function (to_select, json_file) { let rowspan_map = new Map(); let colspan_map = new Map(); for (var p_name in response.plots) { - if (('rowspan' in response.plots[p_name].span)){ - let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); - rowspan_map.set(key,response.plots[p_name].span) + if (('rowspan' in response.plots[p_name].attributes)){ + let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); + rowspan_map.set(key,response.plots[p_name].attributes) } - if (('colspan' in response.plots[p_name].position)){ - let key = generateKey(response.plots[p_name].position.row, response.plots[p_name].position.col); - colspan_map.set(key,response.plots[p_name].span) + if (('colspan' in response.plots[p_name].attributes)){ + let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); + colspan_map.set(key,response.plots[p_name].attributes) } } for (var i = 0; i <=maximum_dimensions; i++) { @@ -2081,8 +2081,8 @@ var animint = function (to_select, json_file) { } var outer_table=construct_outer_table(); for (var p_name in response.plots) { - if ('row' in response.plots[p_name].position){ - var id= "#row"+response.plots[p_name].position.row+"col"+response.plots[p_name].position.col + if ('row' in response.plots[p_name].attributes){ + var id= "#row"+response.plots[p_name].attributes.row+"col"+response.plots[p_name].attributes.col var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); @@ -2094,7 +2094,7 @@ var animint = function (to_select, json_file) { var pointer_row=0 var pointer_column=0 for (var p_name in response.plots) { - if (!('row' in response.plots[p_name].position)){ + if (!('row' in response.plots[p_name].attributes)){ var id= "#row"+pointer_row+"col"+pointer_column var cell= d3.select(id); pointer_column=pointer_column+1 From 9624583341d23be090819b137de173412571a964 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Wed, 2 Oct 2024 06:08:20 +0530 Subject: [PATCH 67/69] code for handling rowspan updated the code for handling rowspan without creating extra columns and pushing right cells further right as it did earlier. --- inst/htmljs/animint.js | 75 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 47576ad98..9770dcbe5 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2021,7 +2021,6 @@ var animint = function (to_select, json_file) { // Add plots. var maximum_row= 0 var maximum_column= 0 - var construct_outer_table = function () { var count=0 var find_maximum_dimensions = function () { for (var p_name in response.plots) { @@ -2034,10 +2033,43 @@ var animint = function (to_select, json_file) { } } } + find_maximum_dimensions() + var rowspan_count_map = new Map(); + + var create_grid = function () { + let array2D = new Array(maximum_row); + for (let i = 0; i <= maximum_row; i++){ + array2D[i] = new Array(maximum_column+1).fill(0); // Fill each row with 0s + } + return array2D + } + var span_grid=create_grid() + + var update_rowspan_values = function (start_row,col,rowspan) { + var current_row=start_row + while (current_row< start_row+rowspan-1) { + span_grid[current_row][col]=1 + current_row=current_row+1 + } + } + + var update_rowspan_prefix = function () { + for (var current_row=0;current_row<=maximum_row;current_row=current_row+1){ + for (var current_col=1;current_col<=maximum_column;current_col=current_col+1){ + + span_grid[current_row][current_col]=span_grid[current_row][current_col]+span_grid[current_row][current_col-1] + } + } + } + + var construct_outer_table = function () { + function generateKey(row, col) { return `${row},${col}`; } + + var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) @@ -2049,40 +2081,64 @@ var animint = function (to_select, json_file) { if (('rowspan' in response.plots[p_name].attributes)){ let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); rowspan_map.set(key,response.plots[p_name].attributes) - } + var rowspan_value=response.plots[p_name].attributes.rowspan + if (rowspan_value>1){ + var start_row=response.plots[p_name].attributes.row+1 + update_rowspan_values(start_row,response.plots[p_name].attributes.col,response.plots[p_name].attributes.rowspan) + + } + } + if (('colspan' in response.plots[p_name].attributes)){ let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); colspan_map.set(key,response.plots[p_name].attributes) } } + for (var i = 0; i <=maximum_dimensions; i++) { - var current_row = outer_table.append("tr"); + var current_row = outer_table.append("tr").style("border","1px solid white"); for (var j = 0; j <=maximum_dimensions; j++){ let key = generateKey(i,j); if (rowspan_map.has(key) && (colspan_map.has(key))){ var rowspan=rowspan_map.get(key).rowspan var colspan=colspan_map.get(key).colspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).attr("colspan",colspan); + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).attr("colspan",colspan).style("border","1px solid white"); } else if(colspan_map.has(key)){ var colspan=colspan_map.get(key).colspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan); + current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan).style("border","1px solid white"); } else if(rowspan_map.has(key)){ var rowspan=rowspan_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan); + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("border","1px solid white"); } else{ - current_row.append("td").attr("id", "row"+i+"col"+j); + current_row.append("td").attr("id", "row"+i+"col"+j).style("border","1px solid white"); } } } return outer_table; - } + } + var outer_table=construct_outer_table(); + + if((span_grid[0].length>1)){ + update_rowspan_prefix(); + } + for (var p_name in response.plots) { if ('row' in response.plots[p_name].attributes){ - var id= "#row"+response.plots[p_name].attributes.row+"col"+response.plots[p_name].attributes.col + var row=response.plots[p_name].attributes.row + var column=response.plots[p_name].attributes.col + if(column>0){ + decrease=span_grid[row][column-1] + + } + else{ + decrease=0 + } + + var id= "#row"+response.plots[p_name].attributes.row+"col"+(response.plots[p_name].attributes.col-decrease) var cell= d3.select(id); add_plot(p_name, response.plots[p_name],cell); add_legend(p_name, response.plots[p_name]); @@ -2091,6 +2147,7 @@ var animint = function (to_select, json_file) { document.head.appendChild(css); } } + var pointer_row=0 var pointer_column=0 for (var p_name in response.plots) { From 399620296ea2b9f5d685ab07196e10513fe8017b Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Thu, 3 Oct 2024 17:52:43 +0530 Subject: [PATCH 68/69] removed unnecessary lines and added test removed unnecessary lines and added test to plot 9 plots, some with rowspans --- inst/htmljs/animint.js | 4 +- tests/testthat/test1-renderer3-rowspan.R | 127 +++++++++++++++++++++++ 2 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 tests/testthat/test1-renderer3-rowspan.R diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index 9770dcbe5..a8b75e367 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2035,7 +2035,6 @@ var animint = function (to_select, json_file) { } find_maximum_dimensions() - var rowspan_count_map = new Map(); var create_grid = function () { let array2D = new Array(maximum_row); @@ -2044,6 +2043,7 @@ var animint = function (to_select, json_file) { } return array2D } + var span_grid=create_grid() var update_rowspan_values = function (start_row,col,rowspan) { @@ -2069,7 +2069,6 @@ var animint = function (to_select, json_file) { return `${row},${col}`; } - var count_dimensions = Math.ceil(Math.sqrt(count))-1; maximum_row=Math.max(maximum_row,count_dimensions) maximum_column=Math.max(maximum_column,count_dimensions) @@ -2132,7 +2131,6 @@ var animint = function (to_select, json_file) { var column=response.plots[p_name].attributes.col if(column>0){ decrease=span_grid[row][column-1] - } else{ decrease=0 diff --git a/tests/testthat/test1-renderer3-rowspan.R b/tests/testthat/test1-renderer3-rowspan.R new file mode 100644 index 000000000..ae6968a40 --- /dev/null +++ b/tests/testthat/test1-renderer3-rowspan.R @@ -0,0 +1,127 @@ + + +test_that("check rowspan", { + plot_of_3_dots_data <- data.frame( + x = c(1, 2, 3), # x-coordinates of the dots + y = c(1, 4, 9) # y-coordinates of the dots + ) + + plot_of_3_dots <- ggplot(plot_of_3_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 3 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=0,col=0,rowspan=2) + + plot_of_2_dots_data <- data.frame( + x = c(1, 2), # x-coordinates of the dots + y = c(1, 4) # y-coordinates of the dots + ) + + plot_of_2_dots <- ggplot(plot_of_2_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 2 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=0,col=1) + + + plot_of_1_dot_data <- data.frame( + x = c(2), # x-coordinates of the dots + y = c(2) # y-coordinates of the dots + ) + + plot_of_1_dot <- ggplot(plot_of_1_dot_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 1 Dot") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=0,col=2,rowspan=2) + + car_weight_mpg <- ggplot(mtcars, aes(x = wt, y = mpg))+ + geom_point() + + labs(title = "Car Weight vs. MPG") + + theme( + plot.title = element_text(color = "purple", size = 20, face = "bold"), + panel.background = element_rect(fill = "lightyellow"), + panel.grid.major = element_line(color = "gray", size = 0.8), + axis.title.x = element_text(color = "blue", size = 14), + axis.text.y = element_text(color = "red", size = 12), + legend.position = "bottom", + legend.background = element_rect(fill = "lightblue", color = "black", size = 0.5) + )+theme_animint(row=0,col=3) + + plot_of_4_dots_data <- data.frame( + x = c(1, 2, 3,6), # x-coordinates of the dots + y = c(1, 4, 9,13) # y-coordinates of the dots + ) + + plot_of_4_dots <- ggplot(plot_of_4_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 4 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=2,col=2) + + plot_of_4_dots_copy <- ggplot(plot_of_4_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 4 Dots Copy") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=2,col=3) + + + plot_of_5_dots_data <- data.frame( + x = c(1, 2, 3,6,9), # x-coordinates of the dots + y = c(1, 4, 9,13,16) # y-coordinates of the dots + ) + + plot_of_5_dots <- ggplot(plot_of_5_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 5 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=1,col=1) + + plot_of_6_dots_data <- data.frame( + x = c(1, 2, 3,6,9,11), # x-coordinates of the dots + y = c(1, 4, 9,13,16,18) # y-coordinates of the dots + ) + + plot_of_6_dots <- ggplot(plot_of_6_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 6 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=2,col=0) + + + plot_of_7_dots_data <- data.frame( + x = c(1, 2, 3,6,9,11,12), # x-coordinates of the dots + y = c(1, 4, 9,13,16,18,19) # y-coordinates of the dots + ) + + plot_of_7_dots <- ggplot(plot_of_7_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 7 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=2,col=1) + + plot_of_8_dots_data <- data.frame( + x = c(1, 2, 3,6,9,11,12,13), # x-coordinates of the dots + y = c(1, 4, 9,13,16,18,19,21) # y-coordinates of the dots + ) + + plot_of_8_dots <- ggplot(plot_of_8_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 8 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=1,col=3,rowspan=2) + + + + + plot_list <- list( + plot1=plot_of_3_dots, + plot2=plot_of_2_dots, + plot3=plot_of_1_dot, + plot4=car_weight_mpg, + plot5=plot_of_4_dots, + plot6=plot_of_5_dots, + plot7=plot_of_6_dots, + plot8=plot_of_7_dots, + plot9=plot_of_8_dots + ) + + info <-animint2HTML(plot_list) + + tables <- getNodeSet(info$html, "//table[@style='display: inline-block;']") + + number_of_tables<-length(tables) + + expect_equal(number_of_tables,9) +}) \ No newline at end of file From 700f1d9fa72fdaf7f7d7e6d608b002fb60e540e4 Mon Sep 17 00:00:00 2001 From: siddhesh195 Date: Sun, 6 Oct 2024 03:23:27 +0530 Subject: [PATCH 69/69] refactored code, added test refactored the code to make clear distinction between the code of customized plot layout and non customized plot layout. added one test --- inst/htmljs/animint.js | 163 ++++++++++++---------- tests/testthat/test-renderer3-fiveplots.R | 87 ++++++++++++ 2 files changed, 177 insertions(+), 73 deletions(-) create mode 100644 tests/testthat/test-renderer3-fiveplots.R diff --git a/inst/htmljs/animint.js b/inst/htmljs/animint.js index a8b75e367..ba6785d62 100644 --- a/inst/htmljs/animint.js +++ b/inst/htmljs/animint.js @@ -2019,10 +2019,21 @@ var animint = function (to_select, json_file) { d3.select("title").text(response.title); } // Add plots. - var maximum_row= 0 - var maximum_column= 0 - var count=0 - var find_maximum_dimensions = function () { + + + var check_customized_layout = function () { + for (var p_name in response.plots) { + if ("row" in response.plots[p_name].attributes){ + return true + } + return false + } + } + var layout_customized=check_customized_layout() + if (layout_customized){ + var maximum_row= 0 + var maximum_column= 0 + var find_maximum_dimensions = function () { for (var p_name in response.plots) { count=count+1 if (response.plots[p_name].attributes.row>maximum_row){ @@ -2033,19 +2044,16 @@ var animint = function (to_select, json_file) { } } } - - find_maximum_dimensions() - - var create_grid = function () { - let array2D = new Array(maximum_row); - for (let i = 0; i <= maximum_row; i++){ - array2D[i] = new Array(maximum_column+1).fill(0); // Fill each row with 0s + find_maximum_dimensions() + var create_grid = function () { + let array2D = new Array(maximum_row); + for (let i = 0; i <= maximum_row; i++){ + array2D[i] = new Array(maximum_column+1).fill(0); // Fill each row with 0s } return array2D - } + } var span_grid=create_grid() - var update_rowspan_values = function (start_row,col,rowspan) { var current_row=start_row while (current_row< start_row+rowspan-1) { @@ -2057,76 +2065,67 @@ var animint = function (to_select, json_file) { var update_rowspan_prefix = function () { for (var current_row=0;current_row<=maximum_row;current_row=current_row+1){ for (var current_col=1;current_col<=maximum_column;current_col=current_col+1){ - span_grid[current_row][current_col]=span_grid[current_row][current_col]+span_grid[current_row][current_col-1] + } - } + } - var construct_outer_table = function () { - - function generateKey(row, col) { - return `${row},${col}`; } - - var count_dimensions = Math.ceil(Math.sqrt(count))-1; - maximum_row=Math.max(maximum_row,count_dimensions) - maximum_column=Math.max(maximum_column,count_dimensions) - var maximum_dimensions=Math.max(maximum_column,maximum_row) - var outer_table = element.append("table").attr("id", "outerTable"); - let rowspan_map = new Map(); - let colspan_map = new Map(); - for (var p_name in response.plots) { - if (('rowspan' in response.plots[p_name].attributes)){ + var construct_outer_table = function () { + function generateKey(row, col) { + return `${row},${col}`; + + } + var maximum_dimensions=Math.max(maximum_column,maximum_row) + var outer_table = element.append("table").attr("id", "outerTable"); + let rowspan_map = new Map(); + let colspan_map = new Map(); + for (var p_name in response.plots) { + if (('rowspan' in response.plots[p_name].attributes)){ let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); rowspan_map.set(key,response.plots[p_name].attributes) var rowspan_value=response.plots[p_name].attributes.rowspan if (rowspan_value>1){ var start_row=response.plots[p_name].attributes.row+1 update_rowspan_values(start_row,response.plots[p_name].attributes.col,response.plots[p_name].attributes.rowspan) - + } } - if (('colspan' in response.plots[p_name].attributes)){ let key = generateKey(response.plots[p_name].attributes.row, response.plots[p_name].attributes.col); colspan_map.set(key,response.plots[p_name].attributes) } + } - for (var i = 0; i <=maximum_dimensions; i++) { var current_row = outer_table.append("tr").style("border","1px solid white"); for (var j = 0; j <=maximum_dimensions; j++){ - let key = generateKey(i,j); - if (rowspan_map.has(key) && (colspan_map.has(key))){ - var rowspan=rowspan_map.get(key).rowspan - var colspan=colspan_map.get(key).colspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).attr("colspan",colspan).style("border","1px solid white"); - } - else if(colspan_map.has(key)){ - var colspan=colspan_map.get(key).colspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan).style("border","1px solid white"); - } - else if(rowspan_map.has(key)){ - var rowspan=rowspan_map.get(key).rowspan - current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("border","1px solid white"); - } - else{ - current_row.append("td").attr("id", "row"+i+"col"+j).style("border","1px solid white"); - } + let key = generateKey(i,j); + if (rowspan_map.has(key) && (colspan_map.has(key))){ + var rowspan=rowspan_map.get(key).rowspan + var colspan=colspan_map.get(key).colspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).attr("colspan",colspan).style("border","1px solid white"); + + } + else if(colspan_map.has(key)){ + var colspan=colspan_map.get(key).colspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("colspan",colspan).style("border","1px solid white"); + } + else if(rowspan_map.has(key)){ + var rowspan=rowspan_map.get(key).rowspan + current_row.append("td").attr("id", "row"+i+"col"+j).attr("rowspan",rowspan).style("border","1px solid white"); + } + else{ + current_row.append("td").attr("id", "row"+i+"col"+j).style("border","1px solid white"); + } } } return outer_table; - } - - var outer_table=construct_outer_table(); - - if((span_grid[0].length>1)){ + } + var outer_table=construct_outer_table(); update_rowspan_prefix(); - } - - for (var p_name in response.plots) { - if ('row' in response.plots[p_name].attributes){ + for (var p_name in response.plots) { var row=response.plots[p_name].attributes.row var column=response.plots[p_name].attributes.col if(column>0){ @@ -2143,27 +2142,45 @@ var animint = function (to_select, json_file) { // Append style sheet to document head. css.appendChild(document.createTextNode(styles.join(" "))); document.head.appendChild(css); + } - } + }else{ + var count=0 + for (var p_name in response.plots){ + count=count+1 + } + var maximum_dimensions = Math.ceil(Math.sqrt(count))-1; + var construct_outer_table = function () { + + var outer_table = element.append("table").attr("id", "outerTable"); + for (var i = 0; i <=maximum_dimensions; i++) { + var current_row = outer_table.append("tr").style("border","1px solid white"); + for (var j = 0; j <=maximum_dimensions; j++){ + current_row.append("td").attr("id", "row"+i+"col"+j).style("border","1px solid white"); + } + } + return outer_table; + } + var outer_table=construct_outer_table(); var pointer_row=0 var pointer_column=0 for (var p_name in response.plots) { - if (!('row' in response.plots[p_name].attributes)){ - var id= "#row"+pointer_row+"col"+pointer_column - var cell= d3.select(id); - pointer_column=pointer_column+1 - if (pointer_column>maximum_column){ - pointer_column=0 - pointer_row=pointer_row+1 - } - add_plot(p_name, response.plots[p_name],cell); - add_legend(p_name, response.plots[p_name]); - // Append style sheet to document head. - css.appendChild(document.createTextNode(styles.join(" "))); - document.head.appendChild(css); - } + var id= "#row"+pointer_row+"col"+pointer_column + var cell= d3.select(id); + pointer_column=pointer_column+1 + if (pointer_column>maximum_dimensions){ + pointer_column=0 + pointer_row=pointer_row+1 + } + add_plot(p_name, response.plots[p_name],cell); + add_legend(p_name, response.plots[p_name]); + // Append style sheet to document head. + css.appendChild(document.createTextNode(styles.join(" "))); + document.head.appendChild(css); } + } + // Then add selectors and start downloading the first data subset. for (var s_name in response.selectors) { add_selector(s_name, response.selectors[s_name]); diff --git a/tests/testthat/test-renderer3-fiveplots.R b/tests/testthat/test-renderer3-fiveplots.R new file mode 100644 index 000000000..5d3196270 --- /dev/null +++ b/tests/testthat/test-renderer3-fiveplots.R @@ -0,0 +1,87 @@ + +test_that("check rowspan, all plots in single row", { + plot_of_3_dots_data <- data.frame( + x = c(1, 2, 3), # x-coordinates of the dots + y = c(1, 4, 9) # y-coordinates of the dots + ) + + plot_of_3_dots <- ggplot(plot_of_3_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 3 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=0,col=2,rowspan=2) + + plot_of_2_dots_data <- data.frame( + x = c(1, 2), # x-coordinates of the dots + y = c(1, 4) # y-coordinates of the dots + ) + + plot_of_2_dots <- ggplot(plot_of_2_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 2 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=0,col=1) + + + plot_of_1_dot_data <- data.frame( + x = c(2), # x-coordinates of the dots + y = c(2) # y-coordinates of the dots + ) + + plot_of_1_dot <- ggplot(plot_of_1_dot_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 1 Dot") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=0,col=0,rowspan=2) + + + plot_of_4_dots_data <- data.frame( + x = c(1, 2, 3,6), # x-coordinates of the dots + y = c(1, 4, 9,13) # y-coordinates of the dots + ) + + plot_of_4_dots <- ggplot(plot_of_4_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 4 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=0,col=3) + + plot_of_4_dots_copy <- ggplot(plot_of_4_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 4 Dots Copy") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=2,col=3) + + + plot_of_5_dots_data <- data.frame( + x = c(1, 2, 3,6,9), # x-coordinates of the dots + y = c(1, 4, 9,13,16) # y-coordinates of the dots + ) + + plot_of_5_dots <- ggplot(plot_of_5_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 5 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=1,col=1) + + plot_of_6_dots_data <- data.frame( + x = c(1, 2, 3,6,9,11), # x-coordinates of the dots + y = c(1, 4, 9,13,16,18) # y-coordinates of the dots + ) + + plot_of_6_dots <- ggplot(plot_of_6_dots_data, aes(x, y)) + + geom_point(size = 2) + # Plot points with a specified size + ggtitle("Plot of 6 Dots") + # Add a title to the plot + xlab("X Axis") + ylab("Y Axis")+theme_animint(row=1,col=3) + + plot_list <- list( + plot1=plot_of_1_dot, + plot2=plot_of_2_dots, + plot3=plot_of_3_dots, + plot4=plot_of_4_dots, + plot5=plot_of_5_dots, + plot6=plot_of_6_dots + ) + + info <-animint2HTML(plot_list) + + tables <- getNodeSet(info$html, "//table[@style='display: inline-block;']") + + number_of_tables<-length(tables) + + expect_equal(number_of_tables,6) +}) \ No newline at end of file