Skip to content

grid plot layout via theme_animint(rowspan, colspan, last_in_row)#153

Merged
tdhock merged 47 commits intomasterfrom
rowspan-colspan
Sep 9, 2025
Merged

grid plot layout via theme_animint(rowspan, colspan, last_in_row)#153
tdhock merged 47 commits intomasterfrom
rowspan-colspan

Conversation

@tdhock
Copy link
Copy Markdown
Collaborator

@tdhock tdhock commented Oct 8, 2024

closes #115

this proposal supersedes #139 which should be closed if this PR is sufficient.

The idea is to define three new plot attributes, to be specified inside theme_animint

  • rowspan=2 means plot takes up two rows (default=1)
  • colspan=2 means plot takes up two columns (default=1)
  • last_in_row=TRUE means this plot ends a row, HTML <tr> element. (default=FALSE)

the R code compiler needs to save these as attributes of the corresponding plot list.

For example

animint(
  ggplot()+theme_animint(rowspan=2)+ggtitle("first td in first tr, rowspan=2"),
  ggplot()+theme_animint(last_in_row=TRUE)+ggtitle("second td in first tr"),
  ggplot()+ggtitle("first td in second tr")
)

should make HTML like below
image

if any of these three attributes are specified in any of the ggplots, then the renderer JavaScript code puts the plot in the corresponding tr and td of the "outer table," according to the following rules:

  • we create a new <tr> before the first plot, and after every plot with last_in_row=TRUE
  • for every plot, we create a new <td> inside the current <tr>

There is no need for computing the total/max number of rows/columns.

@siddhesh195 please consider this PR and if you agree, close the other PR, and move any relevant code to this branch (compiler R code, tests, etc).

@tdhock tdhock mentioned this pull request Oct 8, 2024
@biplab-sutradhar
Copy link
Copy Markdown
Contributor

biplab-sutradhar commented Jun 2, 2025

Currently, animint renders plots sequentially without control over their positioning. Users need a way to specify row/column placement of plots.

My approach is to add three new theme_animint() parameters:

  • rowspan: Number of rows a plot should span (default=1)
  • colspan: Number of columns a plot should span (default=1)
  • last_in_row: Whether plot should end current row (default=FALSE)

Implementation:
R Compiler: Parse new theme attributes in theme_animint() Store attributes in plot JSON metadata

JavaScript Renderer: - Replace sequential rendering with a table-based grid

  • Create elements when:
    • Before the first plot
    • After plots with last_in_row=TRUE
  • Apply rowspan and colspan to elements

@biplab-sutradhar
Copy link
Copy Markdown
Contributor

@tdhock I am currently working on issue #115. It will take a little time to raise a pr. For gsoc should I document my progress daily or weekly? Also should I continue working on this branch or create a new one?

@tdhock
Copy link
Copy Markdown
Collaborator Author

tdhock commented Jun 3, 2025

for gsoc you should be writing code + pushing + writing in issues or prs every day.
blog every week with a summary is good too.

@tdhock tdhock mentioned this pull request Jun 3, 2025
…ed a new test for verifying rowspan functionality across multiple plots.
@biplab-sutradhar
Copy link
Copy Markdown
Contributor

biplab-sutradhar commented Jun 4, 2025

I tried implementing the rowspan and colspan layout feature it seems theme_animint(rowspan = 2) may not parsed properly by this code

 theme_attribute <- function(theme){
  options_list <- list()
  for(attributes in c("rowspan", "colspan", "last_in_row")) {
    arc <- paste0("animint.", attributes)
    options_list[[attributes]] <- if(arc %in% names(theme)){
      theme[[arc]]
    }
  }
  options_list
}

so it’s not getting added to the JSON or rendered in the browser as . So i thought to referred to siddhesh’s pr, but there also the row, col, rowspan, and colspan attributes aren’t appearing in the html output. So how did you test this implementation @siddhesh195 can you please provide suggestion?

and now instantly facing this issue

tests_init("chromote")
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()

Browse[1]> 
> tests_init()
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()

Browse[1]> 
> tests_exit()
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"

@tdhock can you please suggest what should I do?

Comment thread tests/testthat/test-renderer-sixplot.R Outdated
Comment thread tests/testthat/test-renderer-sixplot.R Outdated
Comment thread tests/testthat/test-renderer-sixplot.R Outdated
Comment thread tests/testthat/test-renderer-sixplot.R Outdated
@tdhock
Copy link
Copy Markdown
Collaborator Author

tdhock commented Jun 4, 2025

please undo addition of rds file

@biplab-sutradhar
Copy link
Copy Markdown
Contributor

biplab-sutradhar commented Jun 4, 2025

https://github.com/animint/animint2/blob/458071391e567ae39fb1cdcc49a18a229fd24b62/tests/testthat/test-renderer3-fiveplots.R
I was using this code from https://github.com/animint/animint2/tree/html-plot this branch here total visualization count expect_equal(length(all_plot_tables), 6) test passed but the other tests are failing either due to incorrect implementation or I might be testing them incorrectly.

now this error cames

tests_init("chromote")
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()
Browse[1]> 
> 
> tests_init()
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()

so manually added those function

> stop_servr <- animint2:::stop_servr
> start_servr <- animint2:::start_servr
> tests_init()

its working

@siddhesh195
Copy link
Copy Markdown
Contributor

I tried implementing the rowspan and colspan layout feature it seems theme_animint(rowspan = 2) may not parsed properly by this code

 theme_attribute <- function(theme){
  options_list <- list()
  for(attributes in c("rowspan", "colspan", "last_in_row")) {
    arc <- paste0("animint.", attributes)
    options_list[[attributes]] <- if(arc %in% names(theme)){
      theme[[arc]]
    }
  }
  options_list
}

so it’s not getting added to the JSON or rendered in the browser as . So i thought to referred to siddhesh’s pr, but there also the row, col, rowspan, and colspan attributes aren’t appearing in the html output. So how did you test this implementation @siddhesh195 can you please provide suggestion?

and now instantly facing this issue

tests_init("chromote")
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()

Browse[1]> 
> tests_init()
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()

Browse[1]> 
> tests_exit()
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"

@tdhock can you please suggest what should I do?

hello @biplab-sutradhar , please take a look at this commit 6999ac7 and see if it gives you some starting point of how to see row,col and span in html.

I had made that commit around a year ago during GSoC 2024 while working on the issue (#115 ) for which this PR exists,

also please paste the link of any PR you are referring instead of mentioning like "siddhesh’s pr".

thank you

Comment thread tests/testthat/test-renderer-sixplot.R Outdated
@siddhesh195
Copy link
Copy Markdown
Contributor

siddhesh195 commented Jun 6, 2025

I tried implementing the rowspan and colspan layout feature it seems theme_animint(rowspan = 2) may not parsed properly by this code

 theme_attribute <- function(theme){
  options_list <- list()
  for(attributes in c("rowspan", "colspan", "last_in_row")) {
    arc <- paste0("animint.", attributes)
    options_list[[attributes]] <- if(arc %in% names(theme)){
      theme[[arc]]
    }
  }
  options_list
}

so it’s not getting added to the JSON or rendered in the browser as . So i thought to referred to siddhesh’s pr, but there also the row, col, rowspan, and colspan attributes aren’t appearing in the html output. So how did you test this implementation @siddhesh195 can you please provide suggestion?

and now instantly facing this issue

tests_init("chromote")
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()

Browse[1]> 
> tests_init()
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"
Called from: tests_exit()

Browse[1]> 
> tests_exit()
Error in stop_servr(tmpPath = find_test_path()) : 
  could not find function "stop_servr"

@tdhock can you please suggest what should I do?

@biplab-sutradhar i see that you have already added a commit (2bb97e8) for trying to put parameters like row, col, rowspan etc. for each plot in the html. sorry for missing that.

your approach seems to be in the right direction. i need to see my PR (#139) again to know how I was able to put those parameters in html. also, since i was not following animint for some time, i need to ramp up on the new changes relevant to issue (#115), which this PR is trying to address

the simplest way you can check is just manually analyze the generated html in your browser using inspect. if your approach is right they should be there.

@biplab-sutradhar
Copy link
Copy Markdown
Contributor

biplab-sutradhar commented Jun 6, 2025

image
as per the code in td tag rowspan 2 should be there but it is not present possible that my testing process is wrong
image
@tdhock can you suggest what to do

@tdhock
Copy link
Copy Markdown
Collaborator Author

tdhock commented Jun 6, 2025

try using the Javascript debugger in your browser. click on the line of javascript code where you want to stop with a breakpoint, and inspect the variables there.

@biplab-sutradhar
Copy link
Copy Markdown
Contributor

@tdhock I have one question if I make new feature in animint.js file in \AppData\Local\R\win-library\4.4\animint2\htmljs\animint.js then I can test my changes directly in the browser.
But if I make changes to the R files in the package, how can I make animint2 use those updated R scripts?

@biplab-sutradhar
Copy link
Copy Markdown
Contributor

biplab-sutradhar commented Jun 6, 2025

image
rowspan and colspan attributes are not being included in the json mostly it should show in options key. When using console.log() for debugging, these values are showing as undefined

@tdhock
Copy link
Copy Markdown
Collaborator Author

tdhock commented Jun 6, 2025

good question! if you edit animint.js in the rendered data viz, you need to copy that to animint2/inst/htmljs/ and then re-install the package. (R CMD INSTALL animint2)

@biplab-sutradhar
Copy link
Copy Markdown
Contributor

image

If no rowspan, colspan, or last_in_row is set then rowspan, colspan is also not getting added, overall layout is changed because the rowspan and colspan attributes dont impact other tables, so the layout needed to be adjusted.

@tdhock
Copy link
Copy Markdown
Collaborator Author

tdhock commented Sep 2, 2025

now you have changed the code to render a table element as a parent of tr, which is good.

however the code is still creating a grid layout, even for a viz that has no rowspan/colspan/last_in_row defined in any ggplots.

For example the test-renderer1-hjust-text-anchor.R file defines several viz, none of which have rowspan/colspan/last_in_row defined.
in that case, there should be no grid layout table, but there is one renderered with the current code.
please change so that in this case, the code uses to the old layout method (add plots one after another, without adding table/tr elements).

Comment thread tests/testthat/test-renderer1-hjust-text-anchor.R Outdated
Comment thread R/z_animintHelpers.R Outdated
Comment thread R/z_animintHelpers.R Outdated
Comment thread R/z_animint.R Outdated
Comment thread inst/htmljs/animint.js Outdated
@biplab-sutradhar
Copy link
Copy Markdown
Contributor

My goal was to support two layout structures depending on whether the JSON file has rowspan, colspan, or last_in_row. To decide this early, I needed to load the JSON and set a flag called grid_layout before the rest of the code runs. At first, I tried using fetch, but since it is asynchronous, the flag was not ready in time. So I switched to synchronous file loading XMLHttpRequest(), which gave me the correct result immediately but also showed browser warnings Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

Comment thread inst/htmljs/animint.js Outdated
Comment thread inst/htmljs/animint.js Outdated
@tdhock tdhock merged commit edd494d into master Sep 9, 2025
5 checks passed
@tdhock
Copy link
Copy Markdown
Collaborator Author

tdhock commented Sep 9, 2025

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

layout ggplots in a table

3 participants