Skip to content

Enhance side connectors and improve alignment/spread features#78

Open
gforge wants to merge 5 commits into
masterfrom
develop
Open

Enhance side connectors and improve alignment/spread features#78
gforge wants to merge 5 commits into
masterfrom
develop

Conversation

@gforge

@gforge gforge commented Jun 20, 2026

Copy link
Copy Markdown
Owner

This pull request introduces several new features and enhancements to the Gmisc package, focusing on improving flowchart alignment, connector flexibility, and support for alternate flowchart shapes. The main changes include the addition of midpoint alignment using two references, enhanced spread and connector APIs, and improved handling of non-rectangular flowchart shapes for better visual alignment and connector placement.

Flowchart Alignment Improvements:

  • Added a new references argument to alignVertical(), alignHorizontal(), and the S3 align() wrapper, allowing alignment to the midpoint between two references. This is especially useful for centering side boxes (e.g., excluded patients) between main flowchart boxes. Supporting helpers and validation functions were also introduced. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]

Spread and Connector Enhancements:

  • Added exclude to spreadVertical(), spreadHorizontal(), and the S3 spread() wrapper, allowing side branches to be omitted from the main spread but retained for later operations. Improved span handling and support for deferred endpoints in spread().
  • Extended the S3 connect() API to support one-to-many grouped side fan-out and many-to-one grouped side fan-in, with new routing options (side_route, side_offset, side, end_side). Improved label placement for grouped side fan-out connectors. [1] [2]

Alternate Shape and Visual Improvements:

  • Added and expanded examples and helpers for alternate flowchart shapes (ellipse, database, document, documents, diamond, tape), ensuring proper text padding and visible bounds for connector anchoring. Non-rectangular shapes now expose their bounds for accurate label placement and connector routing. [1] [2] [3] [4] [5] [6] [7] [8]

Documentation and Build System:

  • Updated the .Rbuildignore file to exclude blog-posts and its contents from the build process.
  • Updated the NEWS file to document all new features, bug fixes, and improvements for this release.

These changes collectively enhance the flexibility, accuracy, and visual quality of flowchart creation in the Gmisc package.

gforge added 2 commits June 20, 2026 00:07
…unds

Side connectors (type = "side"):
- Add many-to-one grouped fan-in: connect(list("a","b"), "target", type="side")
  routes a shared return bus to the requested outer side instead of each line
  picking the closest side.
- Add one-to-many grouped fan-out, with optional connector labels centered on
  the offset bus.
- Fix one-to-one side connectors to honor the route/offset; previously the
  vertical segment hugged the box edge and the offset was ignored.
- Rename side_fan_in_route/side_fan_in_offset -> side_route/side_offset now that
  they apply to one-to-one, fan-out, and fan-in (params are unreleased 3.4.0, so
  no deprecation path needed).

Alignment / spread / move:
- align(): add `references` to center a box at the midpoint of two references.
- spread(): add `exclude` to keep side branches out of the main spread, and
  support deferred position() endpoints for from/to.
- move(): document edge-based `just` for absolute moves (right -> right border).

Shapes:
- Expose visible bounds (box_fn_bounds) and per-shape text padding for
  ellipse/database/document/tape so labels stay inside and connectors hit the
  visible edge; thread bounds through coords().
- fan_in_top trunks now terminate exactly on the target's top edge.

Docs/tests:
- Modernize the vignette to the define-then-spread/align/move style (phaseLabel
  example now spreads arms instead of absolute moves).
- Update NEWS for 3.4.0 and add tests covering side fan-in/fan-out/one-to-one
  offset, references, spread exclude, and shape bounds.
Copilot AI review requested due to automatic review settings June 20, 2026 10:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enhances Gmisc’s grid-based flowchart tooling by expanding alignment/spread capabilities, improving “side” connector routing/labeling, and adding better support for non-rectangular box shapes (padding + visible bounds) so visual alignment and connector anchoring are more accurate.

Changes:

  • Added midpoint alignment via references = list(ref1, ref2) to alignVertical() / alignHorizontal() (and updated examples/tests/docs).
  • Added exclude to spreadVertical() / spreadHorizontal() (and S3 spread()) to keep side branches out of the main spread while retaining them for later operations.
  • Expanded “side” connector behavior (grouped fan-out/fan-in + offset bus routing) and improved shape helpers to expose visible bounds for connector anchoring.

Reviewed changes

Copilot reviewed 22 out of 28 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vignettes/Grid-based_flowcharts.Rmd Updates vignette examples to use spread(..., exclude=...) + midpoint alignment and new side connector args.
tests/testthat/test-flowchart-issue76-connectors.R Adds tests for new grouped/one-to-one side connector offset and routing behavior.
tests/testthat/test-connectGrob_fan_in_top.R Adds regression test that fan_in_top trunks terminate at the target top edge.
tests/testthat/test-boxShapes.R Adds tests asserting non-rectangular shapes expose visible bounds and padding affects sizing.
tests/testthat/test-boxGrob_spread.R Adds tests for spread(..., exclude=...) and for resolving deferred position() endpoints in subelement spreads.
tests/testthat/test-boxGrob_move.R Adds test clarifying that absolute moveBox(..., just=...) uses the requested edge as the target.
tests/testthat/test-align-pipeline.R Adds tests for midpoint alignment using references and validation errors.
R/boxGrobs_spread.R Implements exclude handling and resolves deferred position() endpoints before subelement spreads.
R/boxGrobs_s3_connect.R Renames side routing args and adds grouped side fan-out + many-to-one fan-in support in S3 connect().
R/boxGrobs_prCreateBoxCoordinates.R Adds box_fn_bounds support so coords can represent visible bounds of non-rectangular shapes.
R/boxGrobs_move.R Documentation update describing just semantics for absolute moves.
R/boxGrobs_connect.R Renames side routing args in connectGrob() and updates docs for grouped side fan-out labels.
R/boxGrobs_connect_strategies.R Wires side_route / side_offset through connector strategy dispatch.
R/boxGrobs_connect_pr_single_boxes.R Ensures one-to-one type="side" honors side_route / side_offset.
R/boxGrobs_connect_pr_many_to_one_fan_in_on_top_boxes.R Adjusts fan_in_top termination point to end exactly at the target top edge.
R/boxGrobs_boxShapes.R Adds per-shape padding and visible bounds metadata for several non-rectangular shapes.
R/boxGrobs_boxGrob.R Captures box_fn_bounds from shape grobs and passes it into coordinate generation.
R/boxGrobs_align.R Adds references midpoint alignment support and refactors subelement alignment to reuse common helpers.
R/boxGrobs_align_pr_helpers.R Adds helper functions for validating/resolving reference pairs and computing their midpoint coords.
NEWS.md Documents new alignment/spread/connect features and the shape/bounds improvements.
man/spread.Rd Documents the new exclude argument for spread.
man/prCreateBoxCoordinates.Rd Updates usage for the new box_fn_bounds parameter (but currently lacks argument docs).
man/moveBox.Rd Documents just semantics for absolute moves.
man/connect.Rd Updates docs to use side_route / side_offset and label support wording.
man/align.Rd Documents new references behavior and adds an example.
inst/examples/alignBox_ex.R Adds an example of midpoint alignment via references.
.Rbuildignore Excludes blog-posts/ from package builds.
.gitignore Ignores blog-posts/ directory.
Files not reviewed (5)
  • man/align.Rd: Generated file
  • man/connect.Rd: Generated file
  • man/moveBox.Rd: Generated file
  • man/prCreateBoxCoordinates.Rd: Generated file
  • man/spread.Rd: Generated file

Comment thread R/boxGrobs_boxGrob.R
Comment on lines +131 to 132
box_fn_bounds <- attr(rect, "box_fn_bounds")

Comment thread R/boxGrobs_s3_connect.R
Comment on lines 95 to 107
get_arg <- function(name, default) {
if (!is.null(args[[name]])) args[[name]] else default
}

lty_gp <- get_arg("lty_gp", getOption("connectGrob", default = gpar(fill = "black")))
arrow_obj <- get_arg("arrow_obj", getOption("connectGrobArrow", default = arrow(ends = "last", type = "closed")))
arrow_size <- get_arg("arrow_size", NULL)
side <- match.arg(get_arg("side", "auto"), c("auto", "left", "right"))
end_side <- match.arg(get_arg("end_side", "auto"), c("auto", "left", "right"))
side_fan_in_route <- match.arg(get_arg("side_fan_in_route", "outside"), c("outside", "edge"))
side_fan_in_offset <- get_arg("side_fan_in_offset", unit(5, "mm"))
side_route <- match.arg(get_arg("side_route", "outside"), c("outside", "edge"))
side_offset <- get_arg("side_offset", unit(5, "mm"))
smooth <- get_arg("smooth", FALSE)
corner_radius <- get_arg("corner_radius", unit(3, "mm"))
Comment thread R/boxGrobs_s3_connect.R
Comment on lines +194 to +207
get_arg <- function(name, default) {
if (!is.null(args[[name]])) args[[name]] else default
}

lty_gp <- get_arg("lty_gp", getOption("connectGrob", default = gpar(fill = "black")))
arrow_obj <- get_arg("arrow_obj", getOption("connectGrobArrow", default = arrow(ends = "last", type = "closed")))
arrow_size <- get_arg("arrow_size", NULL)
side <- match.arg(get_arg("side", "auto"), c("auto", "left", "right"))
end_side <- match.arg(get_arg("end_side", "auto"), c("auto", "left", "right"))
side_route <- match.arg(get_arg("side_route", "outside"), c("outside", "edge"))
side_offset <- get_arg("side_offset", unit(5, "mm"))
smooth <- get_arg("smooth", FALSE)
corner_radius <- get_arg("corner_radius", unit(3, "mm"))
label <- get_arg("label", NULL)
Comment thread R/boxGrobs_connect.R
Comment on lines +62 to +66
#' outgoing line.
#'
#' The label is drawn with a semi-transparent white background for readability.
#' Use `label_pad` to control padding around the text and `label_offset` to nudge
#' the label away from the connector when needed.
Comment on lines 3 to 7
#' @param viewport_data The arguments that will be used for generating the \code{viewport}
#' @param extra_coordinate_functions A list with named functions if we want additional
#' parameters
#' @return \code{list} of class \code{coords}
#' @importFrom checkmate assert_list
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.

2 participants