-
Notifications
You must be signed in to change notification settings - Fork 1
Refactor g2_col_cdn to constant, add record_print.g2, add CI workflows and examples #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
61b1bdd
a2c57d7
540ec20
a1d78a8
65d563f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,3 +6,4 @@ | |
| ^node_modules$ | ||
| ^package\.json$ | ||
| ^package-lock\.json$ | ||
| ^examples$ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,189 @@ | ||
| # gglite - Repository Instructions for Copilot | ||
|
|
||
| ## Repository Overview | ||
|
|
||
| This is an R package that provides a lightweight interface to the AntV G2 | ||
| JavaScript visualization library with a ggplot2-style API. It supports | ||
| rendering in R Markdown, litedown, Shiny, and standalone HTML previews. | ||
|
|
||
| **Project Type**: R package | ||
| **Languages**: R, JavaScript (via CDN) | ||
| **Size**: Small repository (~15 R source files) | ||
| **Target Runtime**: R (>= 3.5.0) | ||
|
|
||
| ## Build and Test Instructions | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| **Note**: R is automatically installed via `.github/copilot-setup-steps.yml` | ||
| when working with GitHub Copilot. For manual setup: | ||
| - R (>= 3.5.0) - available via `copilot-setup-steps.yml` | ||
| - R package dependencies (testit, roxygen2, xfun) - available via | ||
| `copilot-setup-steps.yml` | ||
|
|
||
| **For testing on Linux manually**: If not using Copilot's automated setup, | ||
| install the latest R from CRAN, not from Debian/Ubuntu official repositories. | ||
| Follow instructions at https://cran.r-project.org/bin/linux/ubuntu to ensure | ||
| you're testing with the most recent R version that users will have. | ||
|
|
||
| ### Bootstrap and Build Sequence | ||
|
|
||
| 1. **Build the R package**: | ||
| ```bash | ||
| R CMD build . | ||
| ``` | ||
|
|
||
| 2. **Install the package**: | ||
| ```bash | ||
| R CMD INSTALL gglite_*.tar.gz | ||
| ``` | ||
|
|
||
| 3. **Run tests**: | ||
| ```bash | ||
| R CMD check gglite_*.tar.gz --no-manual | ||
| ``` | ||
| or directly: | ||
| ```bash | ||
| Rscript tests/test-all.R | ||
| ``` | ||
| - Tests use the `testit` package | ||
| - All tests should pass without errors | ||
|
|
||
| ### Testing Conventions | ||
|
|
||
| - Tests are in `tests/testit/test-gglite.R` | ||
| - Use `testit` package for assertions | ||
| - Always wrap test conditions in `{}`: `assert('message', {})` | ||
| - Use `has_error()` instead of `tryCatch()` for error testing | ||
| - Load the package with `library(gglite)` before testing | ||
|
|
||
| ### Testing Plots in Headless Browsers | ||
|
|
||
| Since gglite generates HTML/JavaScript visualizations, **plots must be tested | ||
| in headless browsers** to make sure they can be rendered correctly and produce | ||
| no errors in the browser console. Use tools such as Puppeteer or Playwright to | ||
| open the generated HTML and verify that: | ||
|
|
||
| 1. The chart container element exists in the DOM. | ||
| 2. The G2 chart renders without JavaScript errors. | ||
| 3. No warnings or errors appear in the browser console. | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ### Key Files and Directories | ||
|
|
||
| **Root level**: | ||
| - `DESCRIPTION` - R package metadata | ||
| - `NAMESPACE` - R package namespace (auto-generated by roxygen2) | ||
| - `NEWS.md` - Changelog | ||
| - `README.md` - Package documentation | ||
| - `examples/` - Rmd example files for each chart component | ||
|
|
||
| **R code** (`R/`): | ||
| - `gglite.R` - Core: package doc, CDN URLs, `g2()`, `encode()`, | ||
| `annotate_df()` | ||
| - `mark.R` - All 35 mark (geometry) functions | ||
| - `scale.R` - `scale_of()` | ||
| - `coordinate.R` - `coordinate()`, `coord_transpose()` | ||
| - `interact.R` - `interact()` | ||
| - `theme.R` - `theme_of()` | ||
| - `transform.R` - `transform_of()` | ||
| - `facet.R` - `facet_rect()`, `facet_circle()` | ||
| - `animate.R` - `animate()` | ||
| - `component.R` - `axis_of()`, `legend_of()`, `title_of()`, `tooltip_of()`, | ||
| `labels_of()`, `style_mark()`, `slider_of()`, `scrollbar_of()` | ||
| - `render.R` - `build_config()`, `chart_html()`, `preview()`, `print.g2()`, | ||
| `knit_print.g2()`, `record_print.g2()`, `render_shiny()` | ||
|
|
||
| **Tests** (`tests/`): | ||
| - `test-all.R` - Entry point | ||
| - `testit/test-gglite.R` - All package tests using testit framework | ||
|
|
||
| ### CI/CD Configuration | ||
|
|
||
| **GitHub Actions** (`.github/workflows/`): | ||
| - `R-CMD-check.yaml` - Runs R CMD check on multiple platforms | ||
| - `copilot-setup-steps.yml` - Sets up the environment for Copilot | ||
| - `github-pages.yml` - Builds and deploys the package site via litedown | ||
|
|
||
| ## Validation Steps | ||
|
|
||
| Before submitting changes: | ||
|
|
||
| 1. Run `R CMD build .` to build the package | ||
| 2. Run `R CMD check gglite_*.tar.gz --no-manual` to validate | ||
| 3. Ensure all tests pass: `Rscript tests/test-all.R` | ||
| 4. Check GitHub Actions status for multi-platform validation | ||
| 5. Update `NEWS.md` to document your changes | ||
|
|
||
| ## Important Conventions | ||
|
|
||
| ### R Code Style | ||
|
|
||
| 1. **Assignment**: Use `=` instead of `<-` for assignment | ||
| 2. **Strings**: Use single quotes for strings (e.g., `'text'`) | ||
| 3. **Indentation**: Use 2 spaces (not 4 spaces or tabs) | ||
| 4. **Compact code**: Avoid `{}` for single-expression if statements; prefer | ||
| compact forms when possible | ||
| 5. **Roxygen documentation**: Don't use `@description` or `@details` | ||
| explicitly — just write the description text directly after the title. Don't | ||
| use `@title` either. | ||
| 6. **Examples**: Avoid `\dontrun{}` unless absolutely necessary. Prefer | ||
| runnable examples that can be tested automatically. | ||
| 7. **Function definitions**: For functions with many arguments, break the line | ||
| right after the opening `(`, indent arguments by 2 spaces, and try to wrap | ||
| them at 80-char width. | ||
| 8. **Re-wrap code**: Always re-wrap the code after making changes to maintain | ||
| consistent formatting and line length. | ||
| 9. **JavaScript in R**: Use `const` and arrow functions (`=>`) in JS, | ||
| `type="module"` for inline scripts, `defer` for external scripts. | ||
|
|
||
| ### Variables Are Character Strings | ||
|
|
||
| gglite does **NOT** use non-standard evaluation (NSE). Variables are specified | ||
| as character strings, e.g., `g2(mtcars, x = 'mpg', y = 'hp')`. | ||
|
|
||
| ### Testing Conventions | ||
|
|
||
| 1. **Use testit properly**: Write all test conditions in `()`, use `%==%` to | ||
| test for `identical()`, and test conditions can return vectors. | ||
| ```r | ||
| assert("test description", { | ||
| (length(result) %==% 3L) | ||
| (file.exists(result)) | ||
| }) | ||
| ``` | ||
|
|
||
| ### Build and Package Conventions | ||
|
|
||
| 1. **Always re-roxygenize**: Run `roxygen2::roxygenize()` after changing any | ||
| roxygen documentation to update man files | ||
| 2. **MANDATORY: R CMD check before EVERY commit**: You MUST run `R CMD check` | ||
| successfully before submitting ANY code changes. | ||
| 3. **MANDATORY: Wait for CI to be green**: After pushing code, you MUST wait | ||
| for GitHub Actions CI to complete successfully before claiming the task is | ||
| done. | ||
| 4. **Bump version in PRs**: Bump the patch version number in DESCRIPTION once | ||
| per PR (on the first commit or when you first make changes), not on every | ||
| commit to the PR | ||
| 5. **NEVER BREAK CI**: Breaking CI is completely unacceptable. If CI fails, you | ||
| must immediately fix it. | ||
| 6. **Never commit binary files**: Avoid version-controlling binary files, | ||
| especially automatically generated ones. | ||
| 7. **Testing**: Use testit assertions with proper error handling | ||
| 8. **Update NEWS.md**: When making changes, make sure to update `NEWS.md` | ||
| accordingly to document what changed. | ||
|
|
||
| ## Package API | ||
|
|
||
| The main entry point is `g2()` which creates a chart object, then pipe | ||
| operators (`|>`) chain mark, scale, coordinate, interaction, theme, and | ||
| component functions: | ||
|
|
||
| ```r | ||
| g2(mtcars, x = 'mpg', y = 'hp') |> | ||
| mark_point() |> | ||
| scale_of('x', type = 'log') |> | ||
| theme_of('dark') |> | ||
| title_of('Motor Trend Cars') | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| name: Copilot Setup Steps | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| push: | ||
| paths: | ||
| - .github/workflows/copilot-setup-steps.yml | ||
| pull_request: | ||
| paths: | ||
| - .github/workflows/copilot-setup-steps.yml | ||
|
|
||
| jobs: | ||
| copilot-setup-steps: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v5 | ||
|
|
||
| - name: Install R | ||
| uses: r-lib/actions/setup-r@HEAD | ||
| with: | ||
| use-public-rspm: true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| name: Build and deploy package site | ||
|
|
||
| on: | ||
| push: | ||
| branches: ["main"] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pages: write | ||
| id-token: write | ||
|
|
||
| jobs: | ||
| deploy: | ||
| environment: | ||
| name: github-pages | ||
| url: ${{ steps.deployment.outputs.page_url }} | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/configure-pages@v5 | ||
| with: | ||
| enablement: true | ||
|
|
||
| - uses: r-lib/actions/setup-r@HEAD | ||
| with: | ||
| use-public-rspm: true | ||
|
|
||
| - uses: r-lib/actions/setup-r-dependencies@HEAD | ||
|
|
||
| - uses: yihui/litedown/site@HEAD | ||
| with: | ||
| site-dir: 'site' | ||
|
|
||
| - uses: actions/upload-pages-artifact@v3 | ||
| with: | ||
| path: 'site' | ||
|
|
||
| - id: deployment | ||
| uses: actions/deploy-pages@v4 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # gglite 0.0.1 | ||
|
|
||
| - Changed `g2_col_cdn()` from a function to a constant `g2_col_cdn` since the | ||
| CDN URL is unlikely to change. | ||
|
|
||
| - Refactored the CDN `<script>` tags in `preview()` and `knit_print.g2()` into | ||
| a shared helper `cdn_scripts()` to reduce code repetition. | ||
|
|
||
| - Added `record_print.g2()` S3 method for `xfun::record_print()` so that | ||
| litedown can render gglite plots correctly in Rmd documents. | ||
|
|
||
| - Added `.github/copilot-instructions.md` for Copilot development guidance. | ||
|
|
||
| - Added `.github/workflows/copilot-setup-steps.yml` for Copilot environment | ||
| setup. | ||
|
|
||
| - Added `.github/workflows/github-pages.yml` for building the package site with | ||
| litedown. | ||
|
|
||
| - Added `examples/` directory with extensive Rmd examples for each gglite | ||
| component (marks, scales, coordinates, themes, transforms, interactions, | ||
| facets, animations, axes, legends, titles, tooltips, labels, styles, sliders, | ||
| and scrollbars). | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't mention trivial technical details that are worthless to end users for v0.1, just provide a summary of what this package does since everything is new
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in a1d78a8. NEWS.md now just summarizes what the package does for v0.1. |
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -88,6 +88,13 @@ chart_html = function(chart, id = NULL, width = NULL, height = NULL) { | |||||||||
| ) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| cdn_scripts = function() { | ||||||||||
| paste0( | ||||||||||
| '<script defer src="', g2_cdn(), '"></script>\n', | ||||||||||
| '<script defer src="', g2_col_cdn, '"></script>' | ||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. put defer at the end:
Suggested change
actually you should avoid repetition by a single sprintf() call that accepts a char vector of both g2 cdn and g2 col cdn and there's no need to concatenate HTML by
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in a1d78a8. |
||||||||||
| ) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| #' Preview a Chart in the Viewer or Browser | ||||||||||
| #' | ||||||||||
| #' @param chart A `g2` object. | ||||||||||
|
|
@@ -99,8 +106,7 @@ preview = function(chart, ...) { | |||||||||
| html = paste0( | ||||||||||
| '<!DOCTYPE html>\n<html>\n<head>\n', | ||||||||||
| '<meta charset="utf-8">\n', | ||||||||||
| '<script defer src="', g2_cdn(), '"></script>\n', | ||||||||||
| '<script defer src="', g2_col_cdn(), '"></script>\n', | ||||||||||
| cdn_scripts(), '\n', | ||||||||||
| '</head>\n<body>\n', | ||||||||||
| body, '\n', | ||||||||||
| '</body>\n</html>' | ||||||||||
|
|
@@ -125,20 +131,23 @@ print.g2 = function(x, ...) { | |||||||||
| #' @param ... Ignored. | ||||||||||
| #' @return A `knit_asis` character vector. | ||||||||||
| knit_print.g2 = function(x, ...) { | ||||||||||
| cdn = paste0( | ||||||||||
| '<script defer src="', g2_cdn(), '"></script>\n', | ||||||||||
| '<script defer src="', g2_col_cdn(), '"></script>' | ||||||||||
| ) | ||||||||||
| body = chart_html(x, ...) | ||||||||||
| out = paste0(cdn, '\n', body) | ||||||||||
| out = paste0(cdn_scripts(), '\n', chart_html(x, ...)) | ||||||||||
| structure(out, class = c('knit_asis', 'html')) | ||||||||||
| } | ||||||||||
|
|
||||||||||
| #' @export | ||||||||||
| record_print.g2 = function(x, ...) { | ||||||||||
| out = paste0(cdn_scripts(), '\n', chart_html(x, ...)) | ||||||||||
| xfun:::new_record(out, 'asis') | ||||||||||
| } | ||||||||||
|
|
||||||||||
| .onLoad = function(libname, pkgname) { | ||||||||||
| if (requireNamespace('knitr', quietly = TRUE)) { | ||||||||||
| registerS3method('knit_print', 'g2', knit_print.g2, | ||||||||||
| envir = asNamespace('knitr')) | ||||||||||
| } | ||||||||||
| registerS3method('record_print', 'g2', record_print.g2, | ||||||||||
| envir = asNamespace('xfun')) | ||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not necessary; method already exported
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already removed in 540ec20 (previous commit). |
||||||||||
| } | ||||||||||
|
|
||||||||||
| #' Render a Chart in Shiny | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the first heading in NEWS.md always represents the dev version and it should be of the form
# PKG x.ywhere PKG is the package name, and x.y is the next version to be released to CRAN (note it's x.y, not x.y.0); usually y is bumped from the current minor version, e.g., if the current dev version is 1.8.3, the next CRAN release is expected to be 1.9revise the version number and add this to copilot instructions accordingly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in a1d78a8. NEWS.md heading now uses
# gglite 0.1format. Added the convention to.github/copilot-instructions.mdunder Build and Package Conventions item 8.