Skip to content

Commit ebee26e

Browse files
committed
start proxy draft
1 parent 03f077c commit ebee26e

File tree

10 files changed

+205
-4
lines changed

10 files changed

+205
-4
lines changed

DESCRIPTION

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@ RoxygenNote: 7.3.2
1313
URL: https://github.com/cynkra/shinyG6
1414
BugReports: https://github.com/cynkra/shinyG6/issues
1515
Imports:
16-
htmlwidgets
16+
htmlwidgets,
17+
shiny
18+

NAMESPACE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export(g6Output)
2828
export(g6_behaviors)
2929
export(g6_options)
3030
export(g6_plugins)
31+
export(g6_proxy)
32+
export(g6_remove_nodes)
3133
export(grid_line)
3234
export(history)
3335
export(hover_activate)
@@ -46,3 +48,5 @@ export(toolbar)
4648
export(tooltip)
4749
export(watermark)
4850
export(zoom_canvas)
51+
import(htmlwidgets)
52+
importFrom(stats,setNames)

R/pkg.R

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#' @keywords internal
2+
"_PACKAGE"
3+
4+
#' @importFrom stats setNames
5+
#' @import htmlwidgets
6+
NULL

R/proxy.R

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#' Create a proxy object to modify an existing g6 graph instance
2+
#'
3+
#' This function creates a proxy object that can be used to update an existing g6 graph
4+
#' instance after it has been rendered in the UI. The proxy allows for server-side
5+
#' modifications of the graph without completely re-rendering it.
6+
#'
7+
#' @param id Character string matching the ID of the g6 graph instance to be modified.
8+
#' @param session The Shiny session object within which the graph exists.
9+
#' By default, this uses the current reactive domain.
10+
#'
11+
#' @return A proxy object of class "g6_proxy" that can be used with g6 proxy methods
12+
#' such as `g6_add_nodes()`, `g6_remove_nodes()`, etc.
13+
#'
14+
#' @details
15+
#' This function must be called from within a Shiny server function. The returned
16+
#' proxy object contains a reference to the session and the ID of the graph to be
17+
#' modified.
18+
#'
19+
#' @export
20+
g6_proxy <- function(id, session = shiny::getDefaultReactiveDomain()) {
21+
if (is.null(session)) {
22+
stop(
23+
"g6_proxy must be called from the server function of a Shiny app"
24+
)
25+
}
26+
27+
structure(
28+
list(id = id, session = session),
29+
class = "g6_proxy"
30+
)
31+
}
32+
33+
#' Remove nodes from a g6 graph via proxy
34+
#'
35+
#' This function removes one or more nodes from an existing g6 graph instance
36+
#' using a proxy object. This allows updating the graph without completely
37+
#' re-rendering it. When a node is removed, its connected edges are also removed.
38+
#'
39+
#' @param graph A g6_proxy object created with \code{\link{g6_proxy}}.
40+
#' @param ids Character vector or list containing the IDs of the nodes to be removed.
41+
#' If a single ID is provided, it will be converted to a list internally.
42+
#'
43+
#' @return The g6_proxy object (invisibly), allowing for method chaining.
44+
#'
45+
#' @details
46+
#' This function can only be used with a g6_proxy object within a Shiny application.
47+
#' It will not work with regular g6 objects outside of Shiny.
48+
#'
49+
#' Under the hood, this function uses the G6 removeNode method, which
50+
#' removes the specified node and all its related edges from the graph.
51+
#' See \url{https://g6.antv.antgroup.com/en/api/data#graphremovenodedata} for more details.
52+
#'
53+
#' @seealso \code{\link{g6_proxy}}
54+
#' @export
55+
g6_remove_nodes <- function(graph, ids) {
56+
if (!any(class(graph) %in% "g6_proxy")) {
57+
stop(
58+
"Can't use g6_remove_nodes with g6 object. Only within shiny & using g6_proxy"
59+
)
60+
}
61+
62+
if (!is.null(ids)) {
63+
if (length(ids) == 1) {
64+
ids <- list(ids)
65+
}
66+
}
67+
68+
graph$session$sendCustomMessage(sprintf("%s_g6-remove-nodes", graph$id), ids)
69+
graph
70+
}

inst/demo/app.R

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,31 @@ combos <- list(
7373
)
7474

7575
ui <- page_fluid(
76-
g6Output("graph")
76+
g6Output("graph"),
77+
actionButton("remove", "Remove nodes")
7778
)
7879

7980
server <- function(input, output, session) {
8081
output$graph <- renderG6({
81-
g6(nodes, edges, combos, options = list(theme = "dark"))
82+
g6(
83+
nodes,
84+
edges,
85+
combos,
86+
options = list(theme = "dark"),
87+
behaviors = g6_behaviors(
88+
zoom_canvas(),
89+
drag_element(),
90+
click_select(multiple = TRUE),
91+
brush_select(immediately = TRUE)
92+
),
93+
plugins = g6_plugins(
94+
minimap()
95+
)
96+
)
97+
})
98+
observeEvent(input$remove, {
99+
g6_proxy("graph") |>
100+
g6_remove_nodes("node1")
82101
})
83102

84103
observe({

inst/htmlwidgets/g6.js

Lines changed: 9 additions & 1 deletion
Large diffs are not rendered by default.

man/g6_proxy.Rd

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

man/g6_remove_nodes.Rd

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

man/shinyG6-package.Rd

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

srcjs/widgets/g6.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ HTMLWidgets.widget({
4444
// Modify node state
4545
Shiny.setInputValue(el.id + '-selected_edge', edgeData);
4646
})
47+
Shiny.addCustomMessageHandler(el.id + '_g6-remove-nodes', (m) => {
48+
try {
49+
graph.removeNodeData(m);
50+
graph.draw();
51+
} catch (error) {
52+
Shiny.notifications.show({ html: error, type: 'error' })
53+
}
54+
})
4755
}
4856

4957
graph.render();

0 commit comments

Comments
 (0)