Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# Changes in version 2025.10.31 (PR#272)

- Download status table now displays three new columns: `total_MB` (total disk space used by all downloaded chunks), `mean_MB` (average chunk size), and `rows` (total number of data rows). Chunk sizes are calculated in R using `file.size()` and exported via plot.json for efficient display updates after each chunk download.

# Changes in version 2025.10.31 (PR#271)

- `geom_point()` now warns when shape parameter is set to a value other than 21, since animint2 web rendering only supports shape=21 for proper display of both color and fill aesthetics.


# Changes in version 2025.10.27 (PR#269)

- `geom_point()` default shape changed from 19 to 21 to enable both color and fill aesthetics for more consistent static rendering.
Expand Down
8 changes: 8 additions & 0 deletions R/geom-.r
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,14 @@ Geom <- gganimintproto("Geom",
data.table::fwrite(
data.or.null$common, file = tsv.path,
row.names = FALSE, sep = "\t")
# Track common chunk size and rows
if(!exists("chunk_info", envir=meta)) {
meta$chunk_info <- list()
}
meta$chunk_info[[tsv.name]] <- list(
bytes = file.size(tsv.path),
rows = nrow(data.or.null$common)
)
data.or.null$varied
}
list(g=g, g.data.varied=g.data.varied, timeValues=AnimationInfo$timeValues)
Expand Down
13 changes: 13 additions & 0 deletions R/z_animint.R
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,21 @@ storeLayer <- function(meta, g, g.data.varied){
## Save each variable chunk to a separate tsv file.
meta$chunk.i <- 1L
meta$g <- g
# Initialize chunk_info only if it doesn't exist (common chunk may have been saved)
if(!exists("chunk_info", envir=meta)) {
meta$chunk_info <- list()
}
g$chunks <- saveChunks(g.data.varied, meta)
g$total <- length(unlist(g$chunks))

## Add chunk size information to geom - filter to only this geom's chunks
g$chunk_info <- list()
geom_prefix <- paste0(g$classed, "_chunk")
for(chunk_name in names(meta$chunk_info)) {
if(startsWith(chunk_name, geom_prefix)) {
g$chunk_info[[chunk_name]] <- meta$chunk_info[[chunk_name]]
}
}

## Finally save to the master geom list.
meta$geoms[[g$classed]] <- g
Expand Down
14 changes: 13 additions & 1 deletion R/z_animintHelpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,21 @@ saveChunks <- function(x, meta){
# fwrite defaults ensure fields are quoted so that embedded
# newlines or tabs in string fields do not break the TSV format
# when read by d3.tsv.
csv.path <- file.path(meta$out.dir, csv.name)
data.table::fwrite(
na.omit(x), file.path(meta$out.dir, csv.name),
na.omit(x), csv.path,
row.names=FALSE, sep="\t")
# Calculate chunk size and row count
chunk_bytes <- file.size(csv.path)
chunk_rows <- nrow(na.omit(x))
# Store chunk info
if(!exists("chunk_info", envir=meta)) {
meta$chunk_info <- list()
}
meta$chunk_info[[csv.name]] <- list(
bytes = chunk_bytes,
rows = chunk_rows
)
meta$chunk.i <- meta$chunk.i + 1L
this.i
}else if(is.list(x)){
Expand Down
73 changes: 63 additions & 10 deletions inst/htmljs/animint.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,31 @@ var animint = function (to_select, json_file) {
// Add a row to the loading table.
g_info.tr = Widgets["loading"].append("tr");
g_info.tr.append("td").text(g_name);
g_info.tr.append("td").attr("class", "chunk");
g_info.tr.append("td").attr("class", "downloaded").text(0);
g_info.tr.append("td").text(g_info.total);
g_info.tr.append("td").attr("class", "status").text("initialized");
g_info.td_files = g_info.tr.append("td").attr("class", "files").style("text-align", "right");
g_info.td_MB = g_info.tr.append("td").attr("class", "MB").style("text-align", "right");
g_info.td_rows = g_info.tr.append("td").attr("class", "rows").style("text-align", "right");

// Initialize size tracking
g_info.total_bytes = 0;
g_info.total_rows = 0;
g_info.downloaded_chunks = 0;

// Calculate total possible bytes and rows from chunk_info
g_info.possible_bytes = 0;
g_info.possible_rows = 0;
g_info.total_possible_chunks = g_info.total;
if(g_info.chunk_info){
var tsv_count = 0;
for(var chunk_name in g_info.chunk_info){
if(chunk_name.endsWith('.tsv')){
g_info.possible_bytes += g_info.chunk_info[chunk_name].bytes;
g_info.possible_rows += g_info.chunk_info[chunk_name].rows;
tsv_count++;
}
}
// chunk_info includes the common chunk, so total_possible_chunks should include it
g_info.total_possible_chunks = tsv_count;
}

// load chunk tsv
g_info.data = {};
Expand All @@ -243,6 +264,21 @@ var animint = function (to_select, json_file) {
d3.tsv(common_path, function (error, response) {
var converted = convert_R_types(response, g_info.types);
g_info.data[common_tsv] = nest_by_group.map(converted);
// Track common chunk download for size information
if(g_info.chunk_info && g_info.chunk_info[common_tsv]){
var info = g_info.chunk_info[common_tsv];
g_info.total_bytes += info.bytes;
g_info.total_rows += info.rows;
g_info.downloaded_chunks += 1;
// Update display
var downloaded_count = g_info.downloaded_chunks;
var total_count = g_info.total_possible_chunks;
var downloaded_MB = (g_info.total_bytes / 1048576).toFixed(2);
var possible_MB = (g_info.possible_bytes / 1048576).toFixed(2);
g_info.td_files.text(downloaded_count + " / " + total_count);
g_info.td_MB.text(downloaded_MB + " / " + possible_MB);
g_info.td_rows.text(g_info.total_rows + " / " + g_info.possible_rows);
}
});
} else {
g_info.common_tsv = null;
Expand Down Expand Up @@ -997,8 +1033,27 @@ var animint = function (to_select, json_file) {
});
var chunk = nest.map(response);
g_info.data[tsv_name] = chunk;
g_info.tr.select("td.downloaded").text(d3.keys(g_info.data).length);
g_info.download_status[tsv_name] = "saved";

// Update size information after download
if(g_info.chunk_info && g_info.chunk_info[tsv_name]){
var info = g_info.chunk_info[tsv_name];
g_info.total_bytes += info.bytes;
g_info.total_rows += info.rows;
g_info.downloaded_chunks += 1;

// Update display with "downloaded / total" format
var downloaded_count = g_info.downloaded_chunks;
var total_count = g_info.total_possible_chunks;
g_info.td_files.text(downloaded_count + " / " + total_count);

var downloaded_MB = (g_info.total_bytes / 1048576).toFixed(2);
var possible_MB = (g_info.possible_bytes / 1048576).toFixed(2);
g_info.td_MB.text(downloaded_MB + " / " + possible_MB);

g_info.td_rows.text(g_info.total_rows + " / " + g_info.possible_rows);
}

funAfter(chunk);
});
});
Expand All @@ -1007,7 +1062,6 @@ var animint = function (to_select, json_file) {
// update_geom is responsible for obtaining a chunk of downloaded
// data, and then calling draw_geom to actually draw it.
var draw_geom = function(g_info, chunk, selector_name, PANEL){
g_info.tr.select("td.status").text("displayed");
var svg = SVGs[g_info.classed];
// derive the plot name from the geometry name
var g_names = g_info.classed.split("_");
Expand Down Expand Up @@ -2372,10 +2426,9 @@ var animint = function (to_select, json_file) {
Widgets["loading"] = loading;
var tr = loading.append("tr");
tr.append("th").text("geom");
tr.append("th").attr("class", "chunk").text("selected chunk");
tr.append("th").attr("class", "downloaded").text("downloaded");
tr.append("th").attr("class", "total").text("total");
tr.append("th").attr("class", "status").text("status");
tr.append("th").attr("class", "files").style("text-align", "right").text("files");
tr.append("th").attr("class", "MB").style("text-align", "right").text("MB");
tr.append("th").attr("class", "rows").style("text-align", "right").text("rows");

// Add geoms and construct nest operators.
for (var g_name in response.geoms) {
Expand Down
10 changes: 10 additions & 0 deletions tests/testthat/test-download-status-table.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
test_that("download status table should show file sizes", {
js_file = system.file("htmljs", "animint.js", package="animint2")
js_text = paste(readLines(js_file), collapse=" ")
mb_column = grep('attr\\("class", "MB"\\)', js_text)
expect_gt(length(mb_column), 0)
files_column = grep('attr\\("class", "files"\\)', js_text)
expect_gt(length(files_column), 0)
rows_column = grep('attr\\("class", "rows"\\)', js_text)
expect_gt(length(rows_column), 0)
})
Loading