Skip to content

Commit 1ac9b1f

Browse files
feat(plot): add JGD graphics device integration
Embed the JGD (JSON Graphics Device) VS Code extension directly into vscode-R so users only need the `jgd` R package for interactive, Canvas2D-rendered plots with history, navigation, and PNG/SVG export. Add `r.plot.backend` enum setting (auto/standard/httpgd/jgd) with backward compatibility for existing `r.plot.useHttpgd` configurations. The JGD socket server starts eagerly on activation when the backend is set to "jgd", passing JGD_SOCKET to R terminals via env vars. Closes #1679 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e2974f6 commit 1ac9b1f

19 files changed

Lines changed: 1961 additions & 13 deletions

R/profile.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ local({
2525
})
2626

2727
if (requireNamespace("sess", quietly = TRUE)) {
28+
plot_backend <- Sys.getenv("SESS_PLOT_BACKEND", "standard")
2829
sess::connect(
2930
use_rstudioapi = as.logical(Sys.getenv("SESS_RSTUDIOAPI", "TRUE")),
30-
use_httpgd = as.logical(Sys.getenv("SESS_USE_HTTPGD", "TRUE"))
31+
use_httpgd = (plot_backend == "httpgd"),
32+
use_jgd = (plot_backend == "jgd")
3133
)
3234
}

package.json

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,45 @@
18411841
"r.plot.useHttpgd": {
18421842
"type": "boolean",
18431843
"default": false,
1844-
"markdownDescription": "Use the httpgd-based plot viewer instead of the base VSCode-R plot viewer.\n\nRequires the `httpgd` R package version 1.2.0 or later."
1844+
"markdownDescription": "Use the httpgd-based plot viewer instead of the base VSCode-R plot viewer.\n\nRequires the `httpgd` R package version 1.2.0 or later.",
1845+
"markdownDeprecationMessage": "Use `#r.plot.backend#` instead."
1846+
},
1847+
"r.plot.backend": {
1848+
"type": "string",
1849+
"default": "auto",
1850+
"enum": [
1851+
"auto",
1852+
"standard",
1853+
"httpgd",
1854+
"jgd"
1855+
],
1856+
"markdownEnumDescriptions": [
1857+
"Automatic: uses httpgd if `#r.plot.useHttpgd#` is true, otherwise standard",
1858+
"Standard static plot viewer (PNG/SVG)",
1859+
"httpgd-based interactive plot viewer (requires `httpgd` R package)",
1860+
"JGD-based interactive plot viewer (requires `jgd` R package)"
1861+
],
1862+
"markdownDescription": "Select the plot backend.\n\nWhen set to `auto`, the backend is determined by the legacy `#r.plot.useHttpgd#` setting."
1863+
},
1864+
"r.plot.jgd.historyLimit": {
1865+
"type": "number",
1866+
"default": 50,
1867+
"description": "Maximum number of plots retained in JGD history per session."
1868+
},
1869+
"r.plot.jgd.exportWidth": {
1870+
"type": "number",
1871+
"default": 7,
1872+
"description": "Default export width in inches for JGD plots."
1873+
},
1874+
"r.plot.jgd.exportHeight": {
1875+
"type": "number",
1876+
"default": 7,
1877+
"description": "Default export height in inches for JGD plots."
1878+
},
1879+
"r.plot.jgd.exportDpi": {
1880+
"type": "number",
1881+
"default": 150,
1882+
"description": "Default export DPI for JGD plots."
18451883
},
18461884
"r.plot.format": {
18471885
"type": "string",

sess/DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ Imports:
1717
rstudioapi,
1818
svglite
1919
Suggests:
20+
jgd,
2021
testthat (>= 3.0.0)
2122
Config/roxygen2/version: 8.0.0

sess/R/hooks.R

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
#'
33
#' @param use_rstudioapi Logical. Enable rstudioapi emulation.
44
#' @param use_httpgd Logical. Enable httpgd plot device if available.
5+
#' @param use_jgd Logical. Enable jgd plot device if available.
56
#' @export
6-
register_hooks <- function(use_rstudioapi = TRUE, use_httpgd = TRUE) {
7+
register_hooks <- function(use_rstudioapi = TRUE, use_httpgd = TRUE, use_jgd = FALSE) {
78
# 1. Override View() to serve table data via paged RPC.
89
show_dataview <- function(x, title = deparse(substitute(x))) {
910
# make sure title is computed.
@@ -112,8 +113,12 @@ register_hooks <- function(use_rstudioapi = TRUE, use_httpgd = TRUE) {
112113
invisible(x)
113114
}
114115

115-
# 4. httpgd or Static Plot Hook
116-
if (use_httpgd && requireNamespace("httpgd", quietly = TRUE)) {
116+
# 4. Plot device: JGD > httpgd > Standard
117+
if (use_jgd && nzchar(Sys.getenv("JGD_SOCKET")) && requireNamespace("jgd", quietly = TRUE)) {
118+
options(device = function(...) {
119+
jgd::jgd()
120+
})
121+
} else if (use_httpgd && requireNamespace("httpgd", quietly = TRUE)) {
117122
options(device = function(...) {
118123
httpgd::hgd(silent = TRUE)
119124
notify_client("httpgd", list(url = httpgd::hgd_url()))

sess/R/server.R

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
#' session JSON file written by the extension.
66
#' @param use_rstudioapi Logical. Enable rstudioapi emulation. Defaults to TRUE.
77
#' @param use_httpgd Logical. Use httpgd for plotting if available. Defaults to TRUE.
8+
#' @param use_jgd Logical. Use jgd for plotting if available. Defaults to FALSE.
89
#' @export
9-
connect <- function(pipe_path = NULL, use_rstudioapi = TRUE, use_httpgd = TRUE) {
10+
connect <- function(pipe_path = NULL, use_rstudioapi = TRUE, use_httpgd = TRUE, use_jgd = FALSE) {
1011
.sess_env$con <- NULL
1112
.sess_env$pending_responses <- list()
1213
.sess_env$read_buffer <- ""
@@ -90,7 +91,8 @@ connect <- function(pipe_path = NULL, use_rstudioapi = TRUE, use_httpgd = TRUE)
9091

9192
if (is.na(use_rstudioapi)) use_rstudioapi <- TRUE
9293
if (is.na(use_httpgd)) use_httpgd <- TRUE
93-
register_hooks(use_rstudioapi = use_rstudioapi, use_httpgd = use_httpgd)
94+
if (is.na(use_jgd)) use_jgd <- FALSE
95+
register_hooks(use_rstudioapi = use_rstudioapi, use_httpgd = use_httpgd, use_jgd = use_jgd)
9496

9597
invisible(NULL)
9698
}

sess/man/connect.Rd

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sess/man/dispatch_message.Rd

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sess/man/ipc_write.Rd

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sess/man/notify_client.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sess/man/poll_connection.Rd

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)