Compare commits

...

193 Commits

Author SHA1 Message Date
pvictor 85708897b0 v0.4.3 2024-05-15 11:23:59 +02:00
pvictor 9200d918ad fix news and version number 2024-05-15 11:07:42 +02:00
pvictor 58723475cb updated slope chart height 2024-05-13 11:52:39 +02:00
pvictor b313b45989 added slope charts 2024-05-13 11:20:25 +02:00
pvictor 7e4189366e updated ApexCharts.js to 3.49.1 2024-05-13 11:18:20 +02:00
pvictor 3a3a10369f updated life_expec data + long format 2024-05-13 11:17:46 +02:00
pvictor d0fac7c1ee Updated ApexCharts.js to 3.48.0 2024-03-20 10:25:34 +01:00
pvictor 1ac176f30c maj pkgdown + doc 2024-03-11 11:29:42 +01:00
pvictor 624ab8b901 update pkgdown 2024-03-09 12:00:13 +01:00
pvictor 57733add33 Updated ApexCharts.js to 3.47.0 2024-03-09 11:48:29 +01:00
pvictor c1560fc9c5 Updated ApexCharts.js to 3.46.0 2024-02-21 11:50:04 +01:00
dependabot[bot] e68f20930c
Bump postcss from 8.3.11 to 8.4.31 (#73)
Bumps [postcss](https://github.com/postcss/postcss) from 8.3.11 to 8.4.31.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.3.11...8.4.31)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-20 11:07:15 +01:00
pvictor 6cff8a9f67 updated apexcharts.js to 3.45.0 2023-12-20 11:06:46 +01:00
pvictor 1d94f9d4a6 Updated ApexCharts.js to 3.44.0 2023-10-20 10:14:59 +02:00
pvictor eb228597d8 Updated ApexCharts.js to 3.43.0 2023-10-03 09:20:13 +02:00
pvictor bbda86de93 fix heatmap xaxis (force character) 2023-08-23 10:42:59 +02:00
pvictor 467be227fc Updated ApexCharts.js to 3.41.1 2023-08-23 10:13:17 +02:00
pvictor 11d244e992 prepare for cran 2023-06-14 14:05:06 +02:00
pvictor 5587cdbef4 added dumbbell example in vignette + area charts 2023-06-14 11:40:27 +02:00
pvictor be187e37f1 added example data 2023-06-14 11:40:03 +02:00
Victor Perrier 34aee9bc96
updated test-coverage github action 2023-06-13 18:36:14 +02:00
Victor Perrier 44ead44178
apex(): support for dumbbell charts 2023-06-13 18:02:54 +02:00
Victor Perrier 9baa753c3f
added parse_dumbbell_data() 2023-06-13 18:01:21 +02:00
pvictor 24c552ea68 Updated ApexCharts.js to 3.41.0 2023-06-12 09:51:06 +02:00
pvictor b7ed86e556 added ax_forecast_data_points() 2023-05-17 15:49:28 +02:00
pvictor 7705b91e88 Updated ApexCharts.js to 3.40.0 2023-05-05 10:04:44 +02:00
pvictor 70204162f4 Updated ApexCharts.js to 3.37.3 2023-04-05 11:08:55 +02:00
dependabot[bot] 11c6938935
Bump webpack from 5.64.4 to 5.76.0 (#69)
Bumps [webpack](https://github.com/webpack/webpack) from 5.64.4 to 5.76.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.64.4...v5.76.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 16:30:51 +01:00
pvictor f83cb879a8 apex(): update bar config 2023-02-22 10:52:04 +01:00
pvictor de477fec66 fix rcmdcheck 2023-02-22 10:49:40 +01:00
pvictor 896998074e added support for boxplot in apex() 2023-02-22 10:45:29 +01:00
pvictor b69b7b7b4d updated apexcharts to 3.37.0 2023-02-08 09:23:23 +01:00
pvictor 1b6a57df3a prepare for cran 2023-01-08 19:23:11 +01:00
pvictor 34d73e81ee updated github actions 2023-01-08 18:45:39 +01:00
pvictor 7d32381a65 CRAN status badge 2022-12-09 09:50:30 +01:00
pvictor 2174c8b238 New cran checks badge URL, fix #64 2022-12-09 09:48:13 +01:00
Victor Perrier 1fe6e97eee
Facets y2 (#65)
* decompose set scale

* set scale yaxis 2

* get global chart serie for fixed yaxis
2022-12-09 09:36:32 +01:00
pvictor cacfcde3ce bump version 2022-12-01 15:45:47 +01:00
pvictor 4ef564e605 facets: added grid_width arg 2022-12-01 15:38:15 +01:00
Victor Perrier 23dbb5e869
Merge pull request #59 from dreamRs/dependabot/npm_and_yarn/terser-5.14.2
Bump terser from 5.10.0 to 5.14.2
2022-12-01 15:25:28 +01:00
pvictor 4cbf760e29 facets: fix add_line usage 2022-12-01 15:24:57 +01:00
pvictor 1e3ad8fcc8 gh action pkgdown 2022-12-01 14:26:40 +01:00
pvictor 162b7874d6 gh actions pkgdown 2022-12-01 12:49:48 +01:00
pvictor ef470d1889 gh action pkgdown 2022-12-01 12:36:08 +01:00
pvictor 69a343fca0 updated pkgdown gh action 2022-12-01 12:26:15 +01:00
pvictor e848debf0a facets: manage yaxis2 correctly 2022-12-01 11:51:52 +01:00
pvictor f50e0064c2 updated apexcharts to 3.36.3 2022-11-09 09:51:05 +01:00
pvictor d0d234baee basic support for rangeArea charts 2022-10-25 22:20:14 +02:00
pvictor a9914aa702 updated Apexcharts to 3.36.0 2022-10-25 18:11:22 +02:00
dependabot[bot] f45efa78fd
Bump terser from 5.10.0 to 5.14.2
Bumps [terser](https://github.com/terser/terser) from 5.10.0 to 5.14.2.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-20 10:04:33 +00:00
pvictor bc22af7e0c
Updated ApexCharts.js to 3.35.0 2022-04-02 18:34:43 +02:00
pvictor 7a959cb461
prepare for CRAN 2022-02-27 18:22:58 +01:00
pvictor ea4abf2779
Updated ApexCharts.js to 3.33.1 2022-02-27 18:22:42 +01:00
Victor Perrier aa6d74a38d
Merge pull request #56 from dreamRs/dependabot/npm_and_yarn/nanoid-3.2.0
Bump nanoid from 3.1.30 to 3.2.0
2022-02-27 17:19:18 +01:00
dependabot[bot] eb2a82746e
Bump nanoid from 3.1.30 to 3.2.0
Bumps [nanoid](https://github.com/ai/nanoid) from 3.1.30 to 3.2.0.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.1.30...3.2.0)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-22 06:47:26 +00:00
pvictor 50fac13d51 Updated ApexCharts.js to 3.33.0 2022-01-11 16:35:30 +01:00
pvictor 3f1bb5048e updated pkgdown 2021-12-11 18:54:39 +01:00
pvictor 036244b981 added ApexCharts to export to fix brush chart in markdown 2021-12-10 18:39:38 +01:00
pvictor f7de6805db updated pkgdown action 2021-12-10 17:12:56 +01:00
pvictor 64ca1925c1 updated pkgdown action 2021-12-10 16:41:44 +01:00
pvictor 50926f0570 pkgdown via github action 2021-12-10 16:35:48 +01:00
pvictor 67a97cdf5f updated pkgdown 2021-12-10 16:33:17 +01:00
pvictor 314baa5cd9 removed docs folder 2021-12-10 16:33:03 +01:00
pvictor dddd472c1f removed unhcr_popstats_2017 dataset because of annoying note 2021-11-29 20:04:50 +01:00
pvictor 4f4142211b updated docs 2021-11-29 18:58:47 +01:00
pvictor f4215fdf37 updated ApexCharts.js to 3.31.0 2021-11-29 18:53:59 +01:00
pvictor 301051c297 minimal htmlwidgets version required 2021-11-23 16:56:30 +01:00
pvictor 45f29fca2e
updated pkgdown 2021-11-17 12:22:49 +01:00
pvictor c717358068
updated facets documentation 2021-11-17 12:13:25 +01:00
pvictor 0f7ec49342
use %||% from rlang 2021-11-17 11:45:05 +01:00
pvictor fe45564f6a
added roxygen template for common documentation (ax) 2021-11-17 11:41:10 +01:00
pvictor 647f4ab9c8 Updated ApexCharts.js to 3.30.0 2021-11-16 20:30:31 +01:00
pvictor ace2508e89
prepare for cran 2021-10-21 14:36:25 +02:00
pvictor a0d0616009
locales files: removed non ascii characters 2021-10-21 14:36:08 +02:00
pvictor 47381fcfda
updated github actions 2021-10-21 11:59:06 +02:00
pvictor d14e36d22b
updated vignettes titles 2021-10-21 11:55:32 +02:00
pvictor 14484602f7
updated pkgdown site 2021-10-20 18:23:29 +02:00
pvictor 017b84f35c
reorganized vignettes 2021-10-20 18:18:06 +02:00
pvictor 05494785ae
updated ApexCharts to 3.29.0 2021-10-20 18:17:27 +02:00
Victor Perrier c0672ba655
Merge pull request #53 from dreamRs/packer
Packer
2021-09-17 15:33:27 +02:00
pvictor 8bda434fa0 removed dev folder 2021-09-17 15:19:33 +02:00
pvictor 01c1c8ed2d maj readme and news 2021-09-17 11:24:35 +02:00
pvictor 090f3d2d37 export d3.format as format 2021-09-17 11:17:43 +02:00
pvictor 7b9df92ee7 updated Apexcharts to 3.28.3 2021-09-17 10:42:39 +02:00
pvictor f670771a22 some tests 2021-09-05 18:56:38 +02:00
pvictor 027c5bc16f
use packer 2021-08-20 16:53:55 +02:00
pvictor 4178c633de
vignette advanced: changed title level 2021-08-20 15:57:57 +02:00
pvictor 705f9f971a
updated pkgdown 2021-07-23 11:19:23 +02:00
pvictor 3c861bec58
removed docs 2021-07-23 10:38:18 +02:00
pvictor 251df70b2b
updated apexcharts to 3.27.3 2021-07-23 10:35:05 +02:00
pvictor cefba791f7
updated documentation (point and marker crosslink) 2021-07-23 10:19:43 +02:00
pvictor dfd9bb07af
updated Apexcharts to 3.26.3 2021-05-19 10:04:34 +02:00
pvictor ea494e899d
rebuild pkgdown site 2021-05-19 09:57:07 +02:00
pvictor a05d2db20d
prepare for cran 2021-05-11 14:40:27 +02:00
pvictor 56ce243b0f
updated pkgdown 2021-05-11 11:54:06 +02:00
pvictor 2c18c1b329
updated vignette 2021-05-11 11:45:41 +02:00
pvictor 8fa55a9f53
moved examples files in inst/ 2021-05-11 10:18:08 +02:00
pvictor 28931d2887
moved js files 2021-05-11 10:06:51 +02:00
pvictor 36a537a79b
updated Apexcharts to 3.26.2 2021-05-10 14:11:18 +02:00
pvictor 1e42e587af
fixed typo and updated examples 2021-04-28 09:01:33 +02:00
pvictor e3efecf7f8
updated pkgdown site 2021-04-19 10:31:12 +02:00
pvictor e2af5eee09
updated pkgdown site 2021-04-19 10:30:44 +02:00
pvictor 4352d95f97
Updated ApexCharts.js to 3.26.1 2021-04-19 10:16:24 +02:00
pvictor 14b2a2cc74 rebuilt pkgdown 2021-03-15 21:56:19 +01:00
pvictor bfc50ca080 updated ApexCharts to 3.26.0 2021-03-15 21:55:04 +01:00
pvictor 1d54804e04 update apexcharts to 3.25.0 (custom build) 2021-03-12 21:05:12 +01:00
pvictor 9efca10228 fixed passing JS func from proxy 2021-02-11 21:52:55 +01:00
pvictor 3e85bd477a remove dplyr from suggests 2021-01-15 10:53:51 +01:00
pvictor 63db3566fb facets column fixed: fixed bug complete data x order 2021-01-12 17:35:53 +01:00
pvictor 552675f0a2 rebuild pkgdown 2021-01-08 15:51:12 +01:00
pvictor 318690ff06 test facets axis title + others 2021-01-08 15:02:44 +01:00
pvictor e76a129702 facets: x & y axis title 2021-01-08 14:17:17 +01:00
pvictor 83d6926fe6 facet title: vignette and tests 2021-01-08 11:33:13 +01:00
pvictor 67680c48f3 facets: title and subtitle 2021-01-08 10:12:23 +01:00
pvictor f91a6c69c6 updated build_grid method 2021-01-07 20:17:06 +01:00
pvictor 2d9b9ff631 removed travis and added coverage 2021-01-07 09:52:06 +01:00
pvictor 1e74d6857e mores tests bis 2021-01-06 17:13:05 +01:00
pvictor 5ac0087461 more tests 2021-01-06 14:47:34 +01:00
pvictor cf81488f56 tests facets 2021-01-06 12:04:03 +01:00
pvictor 1aac748555 facet shiny examples 2021-01-06 11:34:27 +01:00
pvictor 3d55188a00 clean and rebuild pkgdown site 2021-01-06 10:49:04 +01:00
pvictor 5dc9271701 updated vignette sync charts 2021-01-06 10:29:34 +01:00
Victor Perrier 4b82ddb922
Merge pull request #39 from dreamRs/facet-grid
Facet grid
2021-01-06 10:18:27 +01:00
pvictor 55e19f60c4 added facet grid to vignette 2021-01-06 10:05:37 +01:00
pvictor 5679b7cdba facets: better range fixed x axis 2021-01-06 09:52:25 +01:00
pvictor 175271d01a bug scales + examples 2021-01-05 15:08:13 +01:00
pvictor 730d6651a0 facet_grid: labeller 2021-01-05 12:14:48 +01:00
pvictor bdf6e19597 facets: change scales only if not already provided 2021-01-05 11:11:24 +01:00
pvictor 3c252c9f20 added apex_facet_grid() 2021-01-04 17:10:29 +01:00
pvictor 90aac1901b grid: shiny & markdown method 2021-01-04 12:02:48 +01:00
pvictor 901e67494d compute count if no y aesthetic 2020-12-31 09:46:32 +01:00
pvictor 88f926b788 added apex_grid() 2020-12-30 16:16:53 +01:00
pvictor b17ad7b046 removed old js 2020-12-30 11:12:46 +01:00
pvictor 69104bb6a9 facets: colors manual fix + floating title 2020-12-30 11:12:28 +01:00
pvictor 12c02b5336 updated ApexCharts to 3.23.1 2020-12-30 10:01:36 +01:00
pvictor 9a1c257977 Upgraded ApexCharts to 3.23.0 2020-12-16 14:42:16 +01:00
pvictor dea01b7e8d fixed timeline charts 2020-12-16 14:39:10 +01:00
Victor Perrier 5e3be7068a
Merge pull request #38 from dreamRs/mixed-candlestick
Mixed candlestick
2020-12-16 14:31:01 +01:00
pvictor 9a56de4d4e candlestick: fixed timestamps issues 2020-12-16 14:12:57 +01:00
pvictor 898ff0f729 add line to candlestick chart 2020-12-15 19:14:25 +01:00
pvictor c7fcaab4bd rebuild pkgdown 2020-12-15 11:14:28 +01:00
Victor Perrier 35472372cd
Merge pull request #36 from dreamRs/facets
Adding facets with ax_facet_wrap()
2020-12-15 10:54:08 +01:00
pvictor 7131c8fd00 facets vignette 2020-12-14 17:41:35 +01:00
pvictor 0bd9dda5a7 facet: bar charts 2020-12-14 17:20:32 +01:00
pvictor 47ef3d1b3e fixed r cmd check 2020-12-08 16:22:24 +01:00
pvictor 88956c582b shiny render func 2020-12-08 14:49:16 +01:00
pvictor 19d25ee1fd updated Apexcharts to 3.22.3 2020-12-08 10:51:41 +01:00
pvictor c27a0feba5 facet_wrap: arg facets + accept characters 2020-12-04 18:00:04 +01:00
pvictor 7091f5da01 facet: hide yaxis 2020-12-04 14:02:52 +01:00
pvictor eb01583f51 small changes for scatter axis tick values 2020-12-04 11:56:02 +01:00
pvictor 639450cb7d facet_wrap: added scales arg 2020-12-03 17:31:04 +01:00
pvictor 585cbd0bfd knitre print method 2020-12-03 11:03:59 +01:00
pvictor 971388c4f1 simplify build_facets 2020-12-03 10:46:01 +01:00
pvictor 1bca00e544 examples facet_wrap 2020-12-03 10:33:33 +01:00
pvictor ff7b5ba7d9 unlist facet label 2020-12-03 10:33:20 +01:00
pvictor 70eb611091 export label_value 2020-12-03 10:32:50 +01:00
pvictor de3d9c1a9f export vars 2020-12-03 10:24:43 +01:00
pvictor 0cadab8b51 facet: css for grid responsive 2020-12-03 10:15:00 +01:00
pvictor 716e96b16c facet: added labeller 2020-12-03 10:11:40 +01:00
pvictor 4470756c38 facet_wrap implementation test 2020-12-02 15:50:03 +01:00
pvictor 67f09cd048 rebuild pkgdown 2020-11-18 10:43:05 +01:00
pvictor ffefe8d394 updated ApexCharts to 3.22.2 2020-11-18 10:38:58 +01:00
pvictor 2a261e1a91 bump version 2020-11-11 10:25:32 +01:00
pvictor 727c9ed3fe fixed bad JS namespace 2020-11-11 10:21:28 +01:00
pvictor 5560ae0b31 fixed bug with numeric and groups (values dropped) 2020-11-02 11:31:48 +01:00
pvictor 805e441499 fixed examples with run_demo_* 2020-11-02 11:30:44 +01:00
pvictor 9fb6a7b341 prepare for cran 2020-10-16 14:26:55 +02:00
pvictor 02560a95a0 added polarArea to apex() 2020-10-06 09:50:27 +02:00
pvictor 315001e883 updated revdep check 2020-10-05 09:45:02 +02:00
pvictor 11a5037276 updated ApexCharts to 3.22.0 2020-10-05 09:44:44 +02:00
pvictor be7b3d4061 fixed typos 2020-10-05 09:44:14 +02:00
pvictor c7d037eea8 added ax_colors_manual() 2020-10-02 09:51:39 +02:00
pvictor c06574ba3b JS: width&height from page + removed updateOption promise 2020-10-02 08:46:49 +02:00
pvictor 6b23a4a9ab test proxy toggle 2020-10-01 14:13:03 +02:00
pvictor dbeb316074 updated Apexcharts to 3.21.0 + treemap example 2020-09-28 16:42:42 +02:00
pvictor 7e64d25710 revdep check 2020-09-09 15:47:09 +02:00
pvictor cd38b5c5e5 broken link & license 2020-09-09 14:07:59 +02:00
pvictor abad2b837c rebuild pkgdown 2020-09-09 12:43:08 +02:00
pvictor 74512ce454 updated apexcharts.js to 3.20.1 2020-09-09 12:39:38 +02:00
pvictor af5670a0b0 apex: remove NAs in scatter chart (bis) 2020-08-11 09:41:53 +02:00
pvictor 53e7addd8b apex(): remove NAs in scatter chart 2020-08-11 09:41:30 +02:00
pvictor eecfb61154 updated pkgdown 2020-08-03 10:08:02 +02:00
pvictor 3bd31007f5 updated Apexcharts to 3.20.0 2020-08-03 10:07:15 +02:00
pvictor 7a20be6e20 bump + update NEWS 2020-07-27 18:55:44 +02:00
pvictor faa07879ef shiny: export base4 dataURI 2020-07-27 18:55:31 +02:00
pvictor 9481c21d43 renamed run_demo_*() funs 2020-07-27 09:26:28 +02:00
pvictor 5aff3524a2 added add_smooth_line() 2020-07-26 18:38:18 +02:00
pvictor b487e92b70 brush examples 2020-07-26 10:46:29 +02:00
pvictor 5be96dcd77 added add_line() 2020-07-26 10:46:18 +02:00
pvictor d44581dc2a update ApexCharts to 3.19.2 2020-07-26 10:45:46 +02:00
pvictor 53cc0cdb32 new dataset: climate_paris 2020-07-26 10:45:25 +02:00
pvictor 145c48f3b7 bump version 2020-07-26 10:45:00 +02:00
pvictor bd179f978b rebuild pkgdown 2020-07-01 10:51:05 +02:00
1087 changed files with 10098 additions and 69902 deletions

View File

@ -3,10 +3,22 @@
^apexcharter\.Rproj$
^\.Rproj\.user$
^dev$
^img$
^revdep
^_pkgdown\.yml$
^docs$
^cran-comments\.md$
^CRAN-RELEASE$
^examples$
^man-roxygen$
^\.github$
^LICENSE\.md$
^codecov\.yml$
^pkgdown$
^srcjs$
^node_modules$
^package\.json$
^package-lock\.json$
^webpack\.dev\.js$
^webpack\.prod\.js$
^webpack\.common\.js$
^CRAN-SUBMISSION$

49
.github/workflows/R-CMD-check.yaml vendored Normal file
View File

@ -0,0 +1,49 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: R-CMD-check
jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
strategy:
fail-fast: false
matrix:
config:
- {os: macos-latest, r: 'release'}
- {os: windows-latest, r: 'release'}
- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
- {os: ubuntu-latest, r: 'release'}
- {os: ubuntu-latest, r: 'oldrel-1'}
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes
steps:
- uses: actions/checkout@v3
- uses: r-lib/actions/setup-pandoc@v2
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check
- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true

View File

@ -1,80 +0,0 @@
on:
push:
branches:
- master
pull_request:
branches:
- master
name: R-CMD-check
jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
strategy:
fail-fast: false
matrix:
config:
- {os: windows-latest, r: 'release'}
- {os: macOS-latest, r: 'release'}
- {os: macOS-latest, r: 'devel'}
- {os: ubuntu-16.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
env:
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
RSPM: ${{ matrix.config.rspm }}
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-r@master
with:
r-version: ${{ matrix.config.r }}
- uses: r-lib/actions/setup-pandoc@master
- name: Query dependencies
run: |
install.packages('remotes')
saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
shell: Rscript {0}
- name: Cache R packages
if: runner.os != 'Windows'
uses: actions/cache@v1
with:
path: ${{ env.R_LIBS_USER }}
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-
- name: Install system dependencies
if: runner.os == 'Linux'
env:
RHUB_PLATFORM: linux-x86_64-ubuntu-gcc
run: |
Rscript -e "remotes::install_github('r-hub/sysreqs')"
sysreqs=$(Rscript -e "cat(sysreqs::sysreq_commands('DESCRIPTION'))")
sudo -s eval "$sysreqs"
- name: Install dependencies
run: |
remotes::install_deps(dependencies = TRUE)
remotes::install_cran("rcmdcheck")
shell: Rscript {0}
- name: Check
env:
_R_CHECK_CRAN_INCOMING_REMOTE_: false
run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
shell: Rscript {0}
- name: Upload check results
if: failure()
uses: actions/upload-artifact@master
with:
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
path: check

47
.github/workflows/pkgdown.yaml vendored Normal file
View File

@ -0,0 +1,47 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
release:
types: [published]
workflow_dispatch:
name: pkgdown
jobs:
pkgdown:
runs-on: ubuntu-latest
# Only restrict concurrency for non-PR jobs
concurrency:
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
- uses: r-lib/actions/setup-pandoc@v2
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::pkgdown, local::., any::dplyr, any::highcharter, any::gapminder
needs: website
pak-version: devel
- name: Build site
run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
shell: Rscript {0}
- name: Deploy to GitHub pages 🚀
if: github.event_name != 'pull_request'
uses: JamesIves/github-pages-deploy-action@v4.4.1
with:
clean: false
branch: gh-pages
folder: docs

50
.github/workflows/test-coverage.yaml vendored Normal file
View File

@ -0,0 +1,50 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: test-coverage
jobs:
test-coverage:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::covr
needs: coverage
- name: Test coverage
run: |
covr::codecov(
quiet = FALSE,
clean = FALSE,
install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package")
)
shell: Rscript {0}
- name: Show testthat output
if: always()
run: |
## --------------------------------------------------------------------
find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true
shell: bash
- name: Upload test results
if: failure()
uses: actions/upload-artifact@v3
with:
name: coverage-test-failures
path: ${{ runner.temp }}/package

3
.gitignore vendored
View File

@ -4,3 +4,6 @@ inst/doc
.RData
*.Rproj
data-raw/*.csv
node_modules
docs
data-raw/inputs/

View File

@ -1,11 +0,0 @@
# R for travis: see documentation at https://docs.travis-ci.com/user/languages/r
language: R
sudo: false
cache: packages
#before_cache: Rscript -e 'remotes::install_cran("pkgdown")'
#deploy:
# provider: script
# script: Rscript -e 'pkgdown::deploy_site_github()'
# skip_cleanup: true

View File

@ -1,5 +1,5 @@
Package: apexcharter
Version: 0.1.5
Version: 0.4.3
Title: Create Interactive Chart with the JavaScript 'ApexCharts' Library
Description: Provides an 'htmlwidgets' interface to 'apexcharts.js'.
'Apexcharts' is a modern JavaScript charting library to build interactive charts and visualizations with simple API.
@ -15,7 +15,8 @@ LazyData: true
ByteCompile: true
Depends: R (>= 2.10)
Imports:
htmlwidgets,
htmltools,
htmlwidgets (>= 1.5.3),
magrittr,
rlang,
ggplot2,
@ -23,12 +24,12 @@ Imports:
shiny (>= 1.1.0)
Suggests:
testthat,
dplyr,
knitr,
scales,
rmarkdown
RoxygenNote: 7.1.0
rmarkdown,
covr
RoxygenNote: 7.3.1
Roxygen: list(markdown = TRUE)
URL: https://github.com/dreamRs/apexcharter, https://dreamrs.github.io/apexcharter
URL: https://github.com/dreamRs/apexcharter, https://dreamrs.github.io/apexcharter/
BugReports: https://github.com/dreamRs/apexcharter/issues
VignetteBuilder: knitr

View File

@ -1,2 +1,2 @@
YEAR: 2019
YEAR: 2020
COPYRIGHT HOLDER: Victor Perrier

View File

@ -1,9 +1,6 @@
ApexCharts.js
=============
# MIT License
The MIT License (MIT)
Copyright (c) 2018 ApexCharts
Copyright (c) 2020 Victor Perrier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -12,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,24 +1,35 @@
# Generated by roxygen2: do not edit by hand
S3method(print,apex_facet)
S3method(print,apex_grid)
export("%>%")
export(JS)
export(add_event)
export(add_event_marker)
export(add_hline)
export(add_line)
export(add_point)
export(add_shade)
export(add_shade_weekend)
export(add_smooth_line)
export(add_vline)
export(aes)
export(apex)
export(apex_grid)
export(apexchart)
export(apexchartOutput)
export(apexchartProxy)
export(apexfacetOutput)
export(apexgridOutput)
export(ax_annotations)
export(ax_chart)
export(ax_colors)
export(ax_colors_manual)
export(ax_dataLabels)
export(ax_facet_grid)
export(ax_facet_wrap)
export(ax_fill)
export(ax_forecast_data_points)
export(ax_grid)
export(ax_labels)
export(ax_labels2)
@ -42,6 +53,7 @@ export(ax_xaxis)
export(ax_yaxis)
export(ax_yaxis2)
export(bar_opts)
export(boxplot_opts)
export(bubble_opts)
export(config_update)
export(events_opts)
@ -49,33 +61,66 @@ export(format_date)
export(format_num)
export(heatmap_opts)
export(label)
export(label_value)
export(parse_df)
export(pie_opts)
export(radialBar_opts)
export(renderApexchart)
export(renderApexfacet)
export(renderApexgrid)
export(renderSparkBox)
export(run_input_demo)
export(run_sparkbox_demo)
export(run_sync_demo)
export(run_demo_input)
export(run_demo_sparkbox)
export(run_demo_sync)
export(set_input_click)
export(set_input_export)
export(set_input_selection)
export(set_input_zoom)
export(set_tooltip_fixed)
export(sparkBoxOutput)
export(spark_box)
export(vars)
importFrom(ggplot2,aes)
importFrom(ggplot2,label_value)
importFrom(ggplot2,vars)
importFrom(graphics,boxplot)
importFrom(htmltools,css)
importFrom(htmltools,renderTags)
importFrom(htmltools,resolveDependencies)
importFrom(htmltools,tagList)
importFrom(htmltools,tags)
importFrom(htmltools,validateCssUnit)
importFrom(htmlwidgets,JS)
importFrom(htmlwidgets,JSEvals)
importFrom(htmlwidgets,createWidget)
importFrom(htmlwidgets,getDependency)
importFrom(htmlwidgets,shinyRenderWidget)
importFrom(htmlwidgets,shinyWidgetOutput)
importFrom(htmlwidgets,sizingPolicy)
importFrom(jsonlite,fromJSON)
importFrom(magrittr,"%>%")
importFrom(rlang,"!!")
importFrom(rlang,"%||%")
importFrom(rlang,as_label)
importFrom(rlang,eval_tidy)
importFrom(rlang,is_function)
importFrom(rlang,is_list)
importFrom(rlang,is_named)
importFrom(rlang,is_null)
importFrom(rlang,quo)
importFrom(rlang,quos)
importFrom(rlang,sym)
importFrom(rlang,syms)
importFrom(shiny,createRenderFunction)
importFrom(shiny,createWebDependency)
importFrom(shiny,exprToFunction)
importFrom(shiny,getDefaultReactiveDomain)
importFrom(shiny,registerInputHandler)
importFrom(shiny,shinyAppFile)
importFrom(shiny,uiOutput)
importFrom(stats,complete.cases)
importFrom(stats,lm)
importFrom(stats,loess)
importFrom(stats,predict)
importFrom(stats,setNames)
importFrom(utils,modifyList)

92
NEWS.md
View File

@ -1,3 +1,93 @@
apexcharter 0.4.3
==================
* Updated ApexCharts.js to 3.49.1 (see https://github.com/apexcharts/apexcharts.js/releases).
* New chart type : slope charts.
apexcharter 0.4.2
==================
* Updated ApexCharts.js to 3.46.0 (see https://github.com/apexcharts/apexcharts.js/releases).
apexcharter 0.4.1
==================
* Updated ApexCharts.js to 3.41.0 (new charts type: dumbbell chart and funnel chart).
* `apex()` : added support for boxplot.
* New function `ax_forecast_data_points()` to mark points as forecasted values.
apexcharter 0.4.0
==================
* Updated ApexCharts.js to 3.36.3.
* New chart type : range area charts.
* Facets: correctly manage secondary y axis.
apexcharter 0.3.1
==================
* Updated ApexCharts.js to 3.33.1
* Minimal {htmlwidgets} version required >= 1.5.3
apexcharter 0.3.0
==================
* Updated ApexCharts.js to 3.29.0
* Internal: use [{packer}](https://github.com/JohnCoene/packer) to manage JavaScript assets.
* `d3.format` JavaScript functions are now available in browser under `format()` and `formatLocale()`.
apexcharter 0.2.0
==================
* Updated ApexCharts.js to 3.26.2
* New functions `ax_facet_wrap()` and `ax_facet_grid()` to create faceting charts.
* New function `apex_grid()` to combine several charts in a grid.
apexcharter 0.1.8
==================
* Updated ApexCharts.js to 3.22.2
## Bugfixes
* Fixed bad JavaScript namespace
* Fixed bug in groups with scatter chart
apexcharter 0.1.7
==================
* Updated ApexCharts.js to 3.22.0
* New chart type: treemap, see vignette for example.
* New function `ax_colors_manual()` to set color mapping manually.
* `apex()` now accept `polarArea` as type of chart.
apexcharter 0.1.6
==================
* Updated ApexCharts.js to 3.20.1
* New functions `add_line()` and `add_smooth_line()` to add simple or trend line on charts (scatter & bars).
* New Shiny input: export, to retrieve chart's base64 dataURI.
apexcharter 0.1.5
==================
@ -10,7 +100,7 @@ apexcharter 0.1.5
## New functions
* `spark_box` to create boxes with sparkline, see corresponding vignette for more details.
* `add_shade()`, `add_shade_weekend()`, `add_event()` to add annotations on timeries charts.
* `add_shade()`, `add_shade_weekend()`, `add_event()` to add annotations on time-series charts.
* `add_hline()`, `add_vline()`, `add_point()` to add annotations on charts.
* `set_tooltip_fixed()` to fix tooltip in specific position.

View File

@ -96,7 +96,8 @@ add_annotation <- function(ax, type_annotation = c("xaxis", "yaxis", "points"),
#' @param cssClass A custom Css Class to give to the annotation label elements.
#' @param padding Padding for the label: top, right, bottom, left.
#'
#' @return A \code{list} that can be used in \code{\link{add_shade}}.
#' @return A \code{list} that can be used in \code{\link{add_shade}}, \code{\link{add_point}},
#' \code{\link{add_event}}, \code{\link{add_event_marker}}.
#' @export
#'
label <- function(text = NULL,
@ -181,7 +182,7 @@ marker <- function(size = NULL,
#' @description \code{add_shade()} allow to add a shaded area on specified range,
#' \code{add_shade_weekend()} add a shadow on every week-end.
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param from Vector of position to start shadow.
#' @param to Vector of position to end shadow.
#' @param color Color of the shadow.
@ -194,7 +195,7 @@ marker <- function(size = NULL,
#' @note \code{add_shade_weekend} only works if variable
#' used for x-axis is of class \code{Date} or \code{POSIXt}.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @name add-shade
@ -258,7 +259,7 @@ add_shade_weekend <- function(ax, color = "#848484", opacity = 0.2, label = NULL
#'
#' @description Add a vertical line to mark a special event on a chart.
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param when Vector of position to place the event.
#' @param color Color of the line.
#' @param dash Creates dashes in borders of SVG path.
@ -269,8 +270,10 @@ add_shade_weekend <- function(ax, color = "#848484", opacity = 0.2, label = NULL
#' @param ... Additional arguments, see
#' \url{https://apexcharts.com/docs/options/annotations/} for possible options.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @seealso \code{\link{add_event_marker}} to add a point.
#'
#' @example examples/add_event.R
add_event <- function(ax, when, color = "#E41A1C", dash = 4, label = NULL, ...) {
@ -287,13 +290,17 @@ add_event <- function(ax, when, color = "#E41A1C", dash = 4, label = NULL, ...)
}
#' Add an event marker to a chart
#' @title Add an event marker to a chart
#'
#' @description Add a point with a label based on a datetime.
#'
#' @param when Vector of position to place the event.
#' @inheritParams add_point
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @return An [apexchart()] `htmlwidget` object.
#' @export
#'
#' @seealso \code{\link{add_event}} to add a vertical line.
#'
#' @example examples/add_event_marker.R
add_event_marker <- function(ax, when, y,
@ -331,7 +338,7 @@ add_event_marker <- function(ax, when, y,
#' Add horizontal or vertical line
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param value Vector of position for the line(s).
#' @param color Color(s) of the line(s).
#' @param dash Creates dashes in borders of SVG path.
@ -342,10 +349,10 @@ add_event_marker <- function(ax, when, y,
#' @param ... Additional arguments, see
#' \url{https://apexcharts.com/docs/options/annotations/} for possible options.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @name add-lines
#' @name add-vh-lines
#'
#' @example examples/add-lines.R
add_hline <- function(ax, value, color = "#000", dash = 0, label = NULL, ...) {
@ -362,7 +369,7 @@ add_hline <- function(ax, value, color = "#000", dash = 0, label = NULL, ...) {
)
}
#' @export
#' @rdname add-lines
#' @rdname add-vh-lines
add_vline <- function(ax, value, color = "#000", dash = 0, label = NULL, ...) {
add_annotation(
ax = ax,
@ -381,7 +388,7 @@ add_vline <- function(ax, value, color = "#000", dash = 0, label = NULL, ...) {
#' Add an annotation point
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param x Coordinate(s) on the x-axis.
#' @param y Coordinate(s) on the y-axis.
#' @param size Size of the marker.
@ -395,8 +402,10 @@ add_vline <- function(ax, value, color = "#000", dash = 0, label = NULL, ...) {
#' @param ... Additional arguments, see
#' \url{https://apexcharts.com/docs/options/annotations/} for possible options.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @seealso \code{\link{add_event_marker}} to add a point when x-axis is a datetime.
#'
#' @example examples/add_point.R
add_point <- function(ax, x, y,
@ -411,7 +420,7 @@ add_point <- function(ax, x, y,
ax = ax,
type_annotation = "points",
position = "front",
as_date = FALSE,
as_date = inherits(x, c("Date", "POSIXct")),
x = x, y = y,
marker = marker(
size = size,

View File

@ -115,7 +115,7 @@ events_opts <- function(click = NULL,
#' @title Bar options
#'
#' @description Use these options in \code{\link{ax_plotOptions}}.
#' @description Use these options in [ax_plotOptions()].
#'
#' @param horizontal Logical. This option will turn a column chart into a horizontal bar chart.
#' @param endingShape Available Options: \code{"flat"} or \code{"rounded"}.
@ -128,16 +128,15 @@ events_opts <- function(click = NULL,
#'
#' @note See \url{https://apexcharts.com/docs/options/plotoptions/bar/}.
#'
#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}.
#' @return A \code{list} of options that can be used in [ax_plotOptions()].
#'
#' @export
#'
#' @examples
#'
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' apex(count(mpg, manufacturer), aes(manufacturer, n)) %>%
#' apex(mpg, aes(manufacturer)) %>%
#' ax_plotOptions(
#' bar = bar_opts(
#' endingShape = "rounded",
@ -171,7 +170,7 @@ bar_opts <- function(horizontal = NULL,
#' @title Heatmap options
#'
#' @description Use these options in \code{\link{ax_plotOptions}}.
#' @description Use these options in [ax_plotOptions()].
#'
#' @param radius Numeric. Radius of the rectangle inside heatmap.
#' @param enableShades Logical. Enable different shades of color depending on the value
@ -181,7 +180,7 @@ bar_opts <- function(horizontal = NULL,
#'
#' @note See \url{https://apexcharts.com/docs/options/plotoptions/heatmap/}.
#'
#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}.
#' @return A \code{list} of options that can be used in [ax_plotOptions()].
#'
#' @export
#'
@ -229,7 +228,7 @@ heatmap_opts <- function(radius = NULL,
#' @title Radial bar options
#'
#' @description Use these options in \code{\link{ax_plotOptions}}.
#' @description Use these options in [ax_plotOptions()].
#'
#' @param size Numeric. Manual size of the radialBars instead of calculating automatically from default height / width.
#' @param inverseOrder Logical. Whether to make the first value of series innermost or outermost.
@ -244,7 +243,7 @@ heatmap_opts <- function(radius = NULL,
#'
#' @note See \url{https://apexcharts.com/docs/options/plotoptions/radialbar/}.
#'
#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}.
#' @return A \code{list} of options that can be used in [ax_plotOptions()].
#'
#' @export
#'
@ -302,7 +301,7 @@ radialBar_opts <- function(size = NULL,
#' @title Pie options
#'
#' @description Use these options in \code{\link{ax_plotOptions}}.
#' @description Use these options in [ax_plotOptions()].
#'
#' @param size Numeric. Custom size of the pie which will override the default size calculations.
#' @param donut List with two fields \code{size} (Donut / ring size in percentage relative to the total pie area.)
@ -315,16 +314,14 @@ radialBar_opts <- function(size = NULL,
#'
#' @note See \url{https://apexcharts.com/docs/options/plotoptions/pie/}.
#'
#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}.
#' @return A \code{list} of options that can be used in [ax_plotOptions()].
#'
#' @export
#'
#' @examples
#'
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' apex(count(mpg, cyl), aes(cyl, n), type = "donut") %>%
#' apex(mpg, aes(cyl), type = "donut") %>%
#' ax_plotOptions(
#' pie = pie_opts(
#' donut = list(size = "90%", background = "#BABABA")
@ -354,7 +351,7 @@ pie_opts <- function(size = NULL,
#' @title Bubble options
#'
#' @description Use these options in \code{\link{ax_plotOptions}}.
#' @description Use these options in [ax_plotOptions()].
#'
#' @param minBubbleRadius Minimum radius size of a bubble.
#' If a bubble value is too small to be displayed, this size will be used.
@ -364,7 +361,7 @@ pie_opts <- function(size = NULL,
#'
#' @note See \url{https://apexcharts.com/docs/options/plotoptions/bubble/}.
#'
#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}.
#' @return A \code{list} of options that can be used in [ax_plotOptions()].
#' @export
#'
#' @examples
@ -389,3 +386,36 @@ bubble_opts <- function(minBubbleRadius, maxBubbleRadius, ...) {
)
}
#' @title Boxplot options
#'
#' @description Use these options in [ax_plotOptions()].
#'
#' @param color.upper Color for the upper quartile (Q3 to median) of the box plot.
#' @param color.lower Color for the lower quartile (median to Q1) of the box plot.
#' @param ... Additional parameters.
#'
#' @note See \url{https://apexcharts.com/docs/options/plotoptions/boxplot/}.
#'
#' @return A \code{list} of options that can be used in [ax_plotOptions()].
#' @export
#'
#' @examples
#' data("mpg", package = "ggplot2")
#' apex(mpg, aes(class, hwy), "boxplot") %>%
#' ax_plotOptions(
#' boxPlot = boxplot_opts(color.upper = "#848484", color.lower = "#848484" )
#' )
boxplot_opts <- function(color.upper, color.lower, ...) {
dropNulls(
list(
colors = dropNulls(list(
upper = color.upper,
lower = color.lower
)),
...
)
)
}

View File

@ -4,7 +4,7 @@
#' Annotations properties
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param position Whether to put the annotations behind the charts or in front of it. Available Options: \code{"front"} or \code{"back"}.
#' @param yaxis List of lists.
#' @param xaxis List of lists.
@ -13,7 +13,6 @@
#'
#' @note See \url{https://apexcharts.com/docs/options/annotations/}.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @examples
@ -126,7 +125,7 @@ ax_annotations <- function(ax,
#' Chart parameters
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param type Specify the chart type. Available Options: \code{"bar"}, \code{"column"}, \code{"line"},
#' \code{"pie"}, \code{"donut"}, \code{"radialBar"}, \code{"scatter"}, \code{"bubble"}, \code{"heatmap"}.
#' @param stacked Logical. Enables stacked option for axis charts.
@ -154,7 +153,6 @@ ax_annotations <- function(ax,
#' @param height Height of the chart.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @example examples/ax_chart.R
@ -186,25 +184,25 @@ ax_chart <- function(ax,
#' Specific options for chart
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @param bar See \code{\link{bar_opts}}.
#' @param heatmap See \code{\link{heatmap_opts}}.
#' @param radialBar See \code{\link{radialBar_opts}}.
#' @param pie See \code{\link{pie_opts}}.
#' @param bubble See \code{\link{bubble_opts}}.
#' @template ax-default
#' @param bar See [bar_opts()].
#' @param heatmap See [heatmap_opts()].
#' @param radialBar See [radialBar_opts()].
#' @param pie See [pie_opts()].
#' @param bubble See [bubble_opts()].
#' @param boxPlot See [boxplot_opts()].
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @examples
#' library(dplyr)
#' data("diamonds", package = "ggplot2")
#'
#' # Stack bar type
#' apex(
#' data = count(diamonds, cut),
#' mapping = aes(x = cut, y = n)
#' data = diamonds,
#' mapping = aes(x = cut)
#' ) %>%
#' ax_plotOptions(
#' bar = bar_opts(endingShape = "rounded", columnWidth = "10%")
@ -212,8 +210,8 @@ ax_chart <- function(ax,
#'
#' # Pie
#' apex(
#' data = count(diamonds, cut),
#' mapping = aes(x = cut, y = n),
#' data = diamonds,
#' mapping = aes(x = cut),
#' type = "pie"
#' ) %>%
#' ax_plotOptions(
@ -237,6 +235,7 @@ ax_plotOptions <- function(ax,
radialBar = NULL,
pie = NULL,
bubble = NULL,
boxPlot = NULL,
...) {
params <- c(as.list(environment()), list(...))[-1]
.ax_opt2(ax, "plotOptions", l = dropNulls(params))
@ -245,31 +244,29 @@ ax_plotOptions <- function(ax,
#' Colors
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param ... Colors for the chart's series. When all colors are used, it starts from the beginning.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/colors/}
#'
#' @examples
#'
#' library(dplyr)
#' data("diamonds", package = "ggplot2")
#'
#' # Change default color(s)
#' apex(
#' data = count(diamonds, cut),
#' mapping = aes(x = cut, y = n)
#' data = diamonds,
#' mapping = aes(x = cut)
#' ) %>%
#' ax_colors("#F7D358")
#'
#'
#' library(scales)
#' apex(
#' data = count(diamonds, cut, color),
#' mapping = aes(x = cut, y = n, fill = color)
#' data = diamonds,
#' mapping = aes(x = cut, fill = color)
#' ) %>%
#' ax_colors(brewer_pal(palette = "Set2")(7))
ax_colors <- function(ax, ...) {
@ -283,7 +280,7 @@ ax_colors <- function(ax, ...) {
#' Labels on data
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param enabled To determine whether to show dataLabels or not.
#' @param textAnchor The alignment of text relative to dataLabel's drawing position.
#' Accepted values \code{"start"}, \code{"middle"} or \code{"end"}.
@ -294,19 +291,18 @@ ax_colors <- function(ax, ...) {
#' @param formatter The formatter function takes in a single value and allows you to format the value before displaying
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/datalabels/}
#'
#' @examples
#' library(dplyr)
#' data("diamonds", package = "ggplot2")
#'
#' # Add data labels
#' apex(
#' data = count(diamonds, cut),
#' mapping = aes(x = cut, y = n)
#' data = diamonds,
#' mapping = aes(x = cut)
#' ) %>%
#' ax_dataLabels(enabled = TRUE)
ax_dataLabels <- function(ax,
@ -325,7 +321,7 @@ ax_dataLabels <- function(ax,
#' Fill property
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param type Whether to fill the paths with solid colors or gradient.
#' Available options: \code{"solid"}, \code{"gradient"}, \code{"pattern"} or \code{"image"}.
#' @param colors Colors to fill the svg paths..
@ -335,19 +331,18 @@ ax_dataLabels <- function(ax,
#' @param pattern A list of parameters.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/fill/}
#'
#' @examples
#' library(dplyr)
#' data("diamonds", package = "ggplot2")
#'
#' # Use a pattern to fill bars
#' apex(
#' data = count(diamonds, cut, color),
#' mapping = aes(x = color, y = n, fill = cut)
#' data = diamonds,
#' mapping = aes(x = color, fill = cut)
#' ) %>%
#' ax_fill(
#' type = "pattern",
@ -389,7 +384,7 @@ ax_fill <- function(ax,
#' Add grids on chart
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param show Logical. To show or hide grid area (including xaxis / yaxis)
#' @param borderColor Colors of grid borders / lines.
#' @param strokeDashArray Creates dashes in borders of svg path. Higher number creates more space between dashes in the border.
@ -401,26 +396,25 @@ ax_fill <- function(ax,
#' @param padding A list of parameters.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/grid/}
#'
#' @examples
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' # Hide Y-axis and gridelines
#' apex(
#' data = count(mpg, manufacturer),
#' mapping = aes(x = manufacturer, y = n)
#' data = mpg,
#' mapping = aes(x = manufacturer)
#' ) %>%
#' ax_grid(show = FALSE)
#'
#' # just grid lines
#' apex(
#' data = count(mpg, manufacturer),
#' mapping = aes(x = manufacturer, y = n)
#' data = mpg,
#' mapping = aes(x = manufacturer)
#' ) %>%
#' ax_grid(yaxis = list(lines = list(show = FALSE)))
#'
@ -454,12 +448,12 @@ ax_grid <- function(ax,
#' Alternative axis labels
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param labels A vector to use as labels.
#' @param ... Vector. In Axis Charts (line / column), labels can be set instead of setting xaxis categories
#' option. While, in pie/donut charts, each label corresponds to value in series array.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @name ax_labels
@ -490,7 +484,7 @@ ax_labels2 <- function(ax, labels) {
#' Legend properties
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param show Logical. Whether to show or hide the legend container.
#' @param position Available position options for legend: \code{"top"}, \code{"right"}, \code{"bottom"}, \code{"left"}.
#' @param showForSingleSeries Show legend even if there is just 1 series.
@ -516,26 +510,25 @@ ax_labels2 <- function(ax, labels) {
#' @param floating Logical. The floating option will take out the legend from the chart area and make it float above the chart.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/legend/}
#'
#' @examples
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' # Legend position
#' apex(
#' data = count(mpg, manufacturer, year),
#' mapping = aes(x = manufacturer, y = n, fill = year)
#' data = mpg,
#' mapping = aes(x = manufacturer, fill = year)
#' ) %>%
#' ax_legend(position = "right")
#'
#' # hide legend
#' apex(
#' data = count(mpg, manufacturer, year),
#' mapping = aes(x = manufacturer, y = n, fill = year)
#' data = mpg,
#' mapping = aes(x = manufacturer, fill = year)
#' ) %>%
#' ax_legend(show = FALSE)
ax_legend <- function(ax,
@ -565,7 +558,7 @@ ax_legend <- function(ax,
#' Markers properties
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param size Numeric. Size of the marker point.
#' @param colors Sets the fill color(s) of the marker point.
#' @param strokeColor Stroke Color of the marker.
@ -579,7 +572,7 @@ ax_legend <- function(ax,
#' @param hover List with item \code{size} (Size of the marker when it is active).
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/markers/}
@ -614,7 +607,7 @@ ax_markers <- function(ax,
#' No data specification
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param text
#' @param align
#' @param verticalAlign
@ -623,7 +616,7 @@ ax_markers <- function(ax,
#' @param style
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @noRd
#'
ax_noData <- function(ax,
@ -641,22 +634,21 @@ ax_noData <- function(ax,
#' Responsive options
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/responsive/}
#'
#' @examples
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' # Open in browser and resize window
#' apex(
#' data = count(mpg, manufacturer, year),
#' mapping = aes(x = manufacturer, y = n, fill = year),
#' data = mpg,
#' mapping = aes(x = manufacturer, fill = year),
#' type = "bar"
#' ) %>%
#' ax_legend(position = "right") %>%
@ -682,10 +674,10 @@ ax_responsive <- function(ax, ...) {
#' Add data to a chart
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param ... Lists containing data to plot, typically list with two items: \code{name} and \code{data}.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @name ax-series
@ -725,25 +717,24 @@ ax_series2 <- function(ax, l) {
#' Charts' states
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param normal A list of parameters.
#' @param hover A list of parameters.
#' @param active A list of parameters.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/states/}
#'
#' @examples
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' # Inverse effect on hover
#' apex(
#' data = count(mpg, manufacturer),
#' mapping = aes(x = manufacturer, y = n),
#' data = mpg,
#' mapping = aes(x = manufacturer),
#' type = "bar"
#' ) %>%
#' ax_states(
@ -765,7 +756,7 @@ ax_states <- function(ax,
#' Chart's title
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param text Text to display as a title of chart.
#' @param align Alignment of subtitle relative to chart area. Possible Options: \code{"left"}, \code{"center"} and \code{"right"}.
#' @param margin Numeric. Vertical spacing around the title text.
@ -775,7 +766,7 @@ ax_states <- function(ax,
#' @param style List with two items: \code{fontSize} (Font Size of the title text) and \code{color} (Fore color of the title text).
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/title/}
@ -806,7 +797,7 @@ ax_title <- function(ax,
#' Chart's subtitle
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param text Text to display as a subtitle of chart.
#' @param align Alignment of subtitle relative to chart area. Possible Options: \code{"left"}, \code{"center"} and \code{"right"}.
#' @param margin Numeric. Vertical spacing around the subtitle text.
@ -816,7 +807,7 @@ ax_title <- function(ax,
#' @param style List with two items: \code{fontSize} (Font Size of the subtitle text) and \code{color} (Fore color of the subtitle text).
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/subtitle/}
@ -850,7 +841,7 @@ ax_subtitle <- function(ax,
#' Stroke properties
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param show Logical. To show or hide path-stroke / line
#' @param curve In line / area charts, whether to draw smooth lines or straight lines.
#' Available Options: \code{"smooth"} (connects the points in a curve fashion. Also known as spline)
@ -864,7 +855,7 @@ ax_subtitle <- function(ax,
#' @param dashArray Creates dashes in borders of svg path. Higher number creates more space between dashes in the border.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/stroke/}
@ -906,7 +897,7 @@ ax_stroke <- function(ax,
#' Tooltip options
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param enabled Logical. Show tooltip when user hovers over chart area.
#' @param shared Logical. When having multiple series, show a shared tooltip.
#' @param followCursor Logical. Follow user's cursor position instead of putting tooltip on actual data points.
@ -924,26 +915,25 @@ ax_stroke <- function(ax,
#' @param fixed A list of parameters.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/tooltip/}
#'
#' @examples
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' # Hide tooltip
#' apex(
#' data = count(mpg, manufacturer, year),
#' mapping = aes(x = manufacturer, y = n, fill = year)
#' data = mpg,
#' mapping = aes(x = manufacturer, fill = year)
#' ) %>%
#' ax_tooltip(enabled = FALSE)
#'
#' # Share between series
#' apex(
#' data = count(mpg, manufacturer, year),
#' mapping = aes(x = manufacturer, y = n, fill = year)
#' data = mpg,
#' mapping = aes(x = manufacturer, fill = year)
#' ) %>%
#' ax_tooltip(shared = TRUE)
#'
@ -981,7 +971,7 @@ ax_tooltip <- function(ax,
#' X-axis options
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param type Character. Available Options : \code{"categories"} and \code{"datetime"}.
#' @param categories Categories are labels which are displayed on the x-axis.
#' @param labels A list of parameters.
@ -1000,33 +990,32 @@ ax_tooltip <- function(ax,
#' @param tooltip A list of parameters.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/xaxis/}
#'
#' @examples
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#'
#' # X axis title
#' apex(
#' data = count(mpg, manufacturer),
#' mapping = aes(x = manufacturer, y = n)
#' data = mpg,
#' mapping = aes(x = manufacturer)
#' ) %>%
#' ax_xaxis(title = list(text = "Car's manufacturer"))
#'
#' # force labels to rotate and increase height
#' apex(
#' data = count(mpg, manufacturer),
#' mapping = aes(x = manufacturer, y = n)
#' data = mpg,
#' mapping = aes(x = manufacturer)
#' ) %>%
#' ax_xaxis(labels = list(rotateAlways = TRUE, maxHeight = 180))
#'
#' # force to not rotate
#' apex(
#' data = count(mpg, manufacturer),
#' mapping = aes(x = manufacturer, y = n)
#' data = mpg,
#' mapping = aes(x = manufacturer)
#' ) %>%
#' ax_xaxis(labels = list(rotate = 0, trim = FALSE))
#'
@ -1087,7 +1076,7 @@ ax_xaxis <- function(ax,
#' Y-axis options
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param opposite Logical. When enabled, will draw the yaxis on the right side of the chart.
#' @param tickAmount Number of Tick Intervals to show.
#' @param max Lowest number to be set for the y-axis. The graph drawing beyond this number will be clipped off.
@ -1102,7 +1091,7 @@ ax_xaxis <- function(ax,
#' @param crosshairs A list of parameters.
#' @param ... Additional parameters.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/yaxis/}
@ -1156,10 +1145,10 @@ ax_yaxis <- function(ax,
#' Secondary Y-axis options
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param ... See arguments from \code{\link{ax_yaxis}}.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @export
#'
#' @example examples/ax_yaxis2.R
@ -1181,40 +1170,38 @@ ax_yaxis2 <- function(ax, ...) {
#' Theme for charts
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param mode use light or dark theme.
#' @param palette Character. Available palettes: \code{"palette1"} to \code{"palette10"}.
#' @param monochrome A list of parameters.
#' @param ... Additional parameters.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @note See \url{https://apexcharts.com/docs/options/theme/}
#'
#' @examples
#' library(dplyr)
#' data("mpg", package = "ggplot2")
#' data("diamonds", package = "ggplot2")
#'
#' # Dark mode
#' apex(
#' data = count(mpg, manufacturer),
#' mapping = aes(x = manufacturer, y = n)
#' data = mpg,
#' mapping = aes(x = manufacturer)
#' ) %>%
#' ax_theme(mode = "dark")
#'
#' # Use predefined palette (1 to 10)
#' apex(
#' data = count(diamonds, cut, color),
#' mapping = aes(x = color, y = n, fill = cut)
#' data = diamonds,
#' mapping = aes(x = color, fill = cut)
#' ) %>%
#' ax_theme(palette = "palette2")
#'
#' # monochrome palette
#' apex(
#' data = count(diamonds, cut, color),
#' mapping = aes(x = color, y = n, fill = cut)
#' data = diamonds,
#' mapping = aes(x = color, fill = cut)
#' ) %>%
#' ax_theme(monochrome = list(enabled = TRUE, color = "#0B6121"))
ax_theme <- function(ax,
@ -1238,7 +1225,7 @@ ax_theme <- function(ax,
#' Configuration for charts with no data
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param text The text to display when no-data is available.
#' @param align Horizontal alignment: \code{"left"}, \code{"center"} or \code{"right"}.
#' @param verticalAlign Vertical alignment: \code{"top"}, \code{"middle"} or \code{"bottom"}.
@ -1247,7 +1234,6 @@ ax_theme <- function(ax,
#' @param fontFamily FontFamily of the text.
#' @param offsetX,offsetY Text offset.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @examples
@ -1287,9 +1273,44 @@ ax_nodata <- function(ax,
#' Forecast data points
#'
#' @template ax-default
#' @param count Number of ending data-points you want to indicate as a forecast or prediction values.
#' The ending line/bar will result into a dashed border with a distinct look to differentiate from the rest of the data-points.
#' @param fillOpacity Opacity of the fill attribute.
#' @param strokeWidth Sets the width of the points.
#' @param dashArray Creates dashes in borders of svg path. Higher number creates more space between dashes in the border.
#' @param ... Additional arguments (not used).
#'
#' @export
#'
#' @examples
#' # add 5 predictions to data then plot it
#' data.frame(
#' time = seq_len(53),
#' lh = c(
#' as.vector(lh),
#' as.vector(predict(arima(lh, order = c(1,0,1)), 5)$pred)
#' )
#' ) %>%
#' apex(aes(time, lh), type = "line") %>%
#' ax_xaxis(type = "numeric") %>%
#' ax_forecast_data_points(count = 5)
ax_forecast_data_points <- function(ax,
count = NULL,
fillOpacity = NULL,
strokeWidth = NULL,
dashArray = NULL,
...) {
params <- list(
count = count,
fillOpacity = fillOpacity,
strokeWidth = strokeWidth,
dashArray = dashArray
)
.ax_opt2(ax, "forecastDataPoints", l = dropNulls(params))
}

240
R/apex.R
View File

@ -1,64 +1,79 @@
#' @title Quick ApexChart
#'
#' @title Quick ApexCharts
#'
#' @description Initialize a chart with three main parameters :
#' data, mapping and type of chart.
#'
#' @param data Default dataset to use for chart. If not already
#' a \code{data.frame}, it will be coerced to with \code{as.data.frame}.
#' a `data.frame`, it will be coerced to with `as.data.frame`.
#' @param mapping Default list of aesthetic mappings to use for chart
#' @param type Specify the chart type. Available options:
#' \code{"column"}, \code{"bar"},
#' \code{"line"}, \code{"step"}, \code{"spline"},
#' \code{"area"}, \code{"area-step"}, \code{"area-spline"},
#' \code{"pie"}, \code{"donut"},
#' \code{"radialBar"}, \code{"radar"}, \code{"scatter"}, \code{"heatmap"},
#' \code{"timeline"}.
#' `"column"`, `"bar"`,
#' `"line"`, `"step"`, `"spline"`,
#' `"area"`, `"area-step"`, `"area-spline"`,
#' `"pie"`, `"donut"`,
#' `"radialBar"`, `"radar"`, `"scatter"`,
#' `"heatmap"`, `"treemap"`,
#' `"timeline"`, `"dumbbell"` and `"slope"`.
#' @param ... Other arguments passed on to methods. Not currently used.
#' @param auto_update In Shiny application, update existing chart
#' rather than generating new one. Can be \code{TRUE}/\code{FALSE} or
#' use \code{\link{config_update}} for more control.
#' @param synchronize Give a common id to charts to synchronize them (tooltip and zoom).
#' @param serie_name Name for the serie displayed in tooltip,
#' only used for single serie.
#' @param width A numeric input in pixels.
#' @param height A numeric input in pixels.
#' @param elementId Use an explicit element ID for the widget.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#' @inheritParams apexchart
#'
#' @return An [apexchart()] `htmlwidget` object.
#'
#' @export
#'
#'
#' @importFrom rlang eval_tidy as_label
#' @importFrom utils modifyList
#' @importFrom stats complete.cases
#'
#' @example examples/apex.R
apex <- function(data, mapping, type = "column", ...,
apex <- function(data, mapping,
type = "column",
...,
auto_update = TRUE,
synchronize = NULL,
serie_name = NULL,
width = NULL,
height = NULL,
height = NULL,
elementId = NULL) {
type <- match.arg(
arg = type,
arg = type,
choices = c(
"column", "bar", "line", "area", "spline", "step",
"area-spline", "area-step",
"pie", "donut", "radialBar", "radar",
"scatter", "heatmap",
"timeline", "candlestick"
"column", "bar",
"rangeBar", "dumbbell",
"line", "spline", "step", "slope",
"area", "area-spline", "area-step",
"rangeArea",
"pie", "donut",
"radialBar",
"radar",
"polarArea",
"scatter", "bubble",
"heatmap",
"treemap",
"timeline",
"candlestick",
"boxplot"
)
)
data <- as.data.frame(data)
if (identical(type, "heatmap")) {
mapping <- rename_aes_heatmap(mapping)
} else {
mapping <- rename_aes(mapping)
}
if (identical(type, "scatter") & is_sized(mapping)) {
type <- "bubble"
}
mapdata <- lapply(mapping, rlang::eval_tidy, data = data)
if (type %in% c("pie", "donut", "radialBar")) {
type_no_compute <- c("candlestick", "boxplot", "timeline", "heatmap", "rangeArea", "rangeBar", "dumbbell", "slope")
if (is.null(mapdata$y) & !type %in% type_no_compute) {
mapdata <- compute_count(mapdata)
}
if (type %in% c("pie", "donut", "radialBar", "polarArea")) {
opts <- list(
chart = list(type = correct_type(type)),
series = list1(mapdata$y),
@ -67,7 +82,7 @@ apex <- function(data, mapping, type = "column", ...,
} else {
opts <- list(
chart = dropNulls(list(
type = correct_type(type),
type = correct_type(type),
group = synchronize
)),
series = make_series(mapdata, mapping, type, serie_name)
@ -82,10 +97,10 @@ apex <- function(data, mapping, type = "column", ...,
opts$xaxis$labels$style$colors <- "#848484"
}
ax <- apexchart(
ax_opts = opts,
width = width,
ax_opts = opts,
width = width,
height = height,
elementId = elementId,
elementId = elementId,
auto_update = auto_update
)
if (inherits(mapdata$x, c("character", "Date", "POSIXt", "numeric", "integer")) & length(mapdata$x) > 0) {
@ -94,46 +109,77 @@ apex <- function(data, mapping, type = "column", ...,
max = max(mapdata$x, na.rm = TRUE)
)
}
ax$x$data <- data
ax$x$mapping <- mapping
ax$x$type <- type
ax$x$serie_name <- serie_name
class(ax) <- c(class(ax), "apex")
return(ax)
}
# Construct series
make_series <- function(mapdata, mapping, type = NULL, serie_name = NULL) {
if (identical(type, "candlestick")) {
#' @importFrom rlang %||%
make_series <- function(mapdata, mapping, type = NULL, serie_name = NULL, force_datetime_names = FALSE) {
if (identical(type, "boxplot")) {
series <- parse_boxplot_data(mapdata, serie_name = serie_name)
} else if (identical(type, "candlestick")) {
if (!all(c("x", "open", "high", "low", "close") %in% names(mapping)))
stop("For candlestick charts 'x', 'open', 'high', 'low', and 'close' aesthetics must be provided.", call. = FALSE)
if (!is.null(mapdata$group))
warning("'group' aesthetic in candlestick chart is not supported", call. = FALSE)
mapdata$group <- NULL
series <- parse_candlestick_data(mapdata)
} else if (identical(type, "rangeBar")) {
} else if (isTRUE(type %in% c("rangeBar", "timeline"))) {
if (!all(c("x", "start", "end") %in% names(mapping)))
stop("For timeline charts 'x', 'start', and 'end' aesthetics must be provided.", call. = FALSE)
if (is.null(mapdata$group))
mapdata$group <- serie_name %||% rlang::as_label(mapping$x)
series <- parse_timeline_data(mapdata)
} else if (isTRUE(type %in% c("dumbbell"))) {
if (!all(c("y", "x", "xend") %in% names(mapping)))
stop("For dumbbell charts 'x', 'xend', and 'y' aesthetics must be provided.", call. = FALSE)
if (is.null(mapdata$group))
mapdata$group <- serie_name %||% rlang::as_label(mapping$x)
series <- parse_dumbbell_data(mapdata)
} else {
mapdata <- as.data.frame(mapdata, stringsAsFactors = FALSE)
if (all(rlang::has_name(mapdata, c("ymin", "ymax")))) {
mapdata$y <- lapply(
X = seq_len(nrow(mapdata)),
FUN = function(i) {
list(mapdata$ymin[i], mapdata$ymax[i])
}
)
mapdata$ymin <- mapdata$ymax <- NULL
}
if (isTRUE(type %in% c("scatter", "bubble"))) {
complete <- complete.cases(mapdata[c("x", "y")])
n_missing <- sum(!complete)
if (n_missing > 0) {
mapdata <- mapdata[complete, ]
warning(sprintf("apex: Removed %s rows containing missing values", n_missing), call. = FALSE)
}
}
if (is.character(mapdata$x))
mapdata$x[is.na(mapdata$x)] <- "NA"
x_order <- unique(mapdata$x)
if (is_x_datetime(mapdata)) {
add_names <- FALSE
if (is_x_datetime(mapdata) & !identical(type, "rangeArea")) {
add_names <- force_datetime_names
x_order <- sort(x_order)
} else {
add_names <- names(mapping)
add_names <- names(mapdata)
}
if (is.null(serie_name) & !is.null(mapping$y))
serie_name <- rlang::as_label(mapping$y)
series <- list(dropNulls(list(
name = serie_name,
name = as.character(serie_name),
type = multi_type(type),
data = parse_df(mapdata, add_names = add_names)
)))
if (is_grouped(mapping)) {
mapdata <- rename_aes(mapdata)
len_grp <- tapply(mapdata$group, mapdata$group, length)
len_grp <- tapply(as.character(mapdata$group), as.character(mapdata$group), length)
if (length(unique(len_grp)) > 1 & !isTRUE(type %in% c("scatter", "bubble"))) {
warning("apex: all groups must have same length! You can use `tidyr::complete` for this.")
}
@ -142,12 +188,12 @@ make_series <- function(mapdata, mapping, type = NULL, serie_name = NULL) {
FUN = function(x) {
data <- mapdata[mapdata$group %in% x, ]
data <- data[, setdiff(names(data), "group"), drop = FALSE]
data <- data[match(x = x_order, table = data$x, nomatch = 0L), , drop = FALSE]
data <- data[order(match(x = data[["x"]], table = x_order, nomatch = 0L)), , drop = FALSE]
dropNulls(list(
name = x,
name = as.character(x),
type = multi_type(type),
data = parse_df(
data = data,
data = data,
add_names = add_names
)
))
@ -166,8 +212,11 @@ is_sized <- function(x) {
any(c("size", "z") %in% names(x))
}
#' @importFrom rlang quo
rename_aes_heatmap <- function(mapping) {
if (is.null(mapping["x"]))
stop("apex(..., type = 'heatmap') must have an 'x' aesthetic", call. = FALSE)
mapping[["x"]] <- quo(as.character(!!mapping[["x"]]))
n_mapping <- names(mapping)
n_mapping[n_mapping == "y"] <- "group"
if ("fill" %in% n_mapping) {
@ -207,23 +256,25 @@ list1 <- function(x) {
# Change type of charts for helpers type
correct_type <- function(type) {
if (identical(type, "column")) {
if (isTRUE(type %in% c("column"))) {
"bar"
} else if (isTRUE(type %in% c("spline", "step"))) {
} else if (isTRUE(type %in% c("spline", "step", "slope"))) {
"line"
} else if (isTRUE(type %in% c("area-spline", "area-step"))) {
"area"
} else if (identical(type, "timeline")) {
} else if (isTRUE(type %in% c("timeline", "dumbbell"))) {
"rangeBar"
} else if (identical(type, "boxplot")) {
"boxPlot"
} else {
type
}
}
multi_type <- function(x) {
multis <- c("column", "area", "line",
"spline", "step", "scatter",
"bubble")
multis <- c("column", "area", "line",
"spline", "step", "scatter",
"bubble", "rangeArea")
if (isTRUE(x %in% multis)) {
correct_type(x)
} else {
@ -233,26 +284,57 @@ multi_type <- function(x) {
range_num <- function(x) {
if (is.numeric(x) & length(x) > 0) {
range(pretty(x))
p <- pretty(x)
list(
values = p,
n = length(p) - 1,
range = range(p)
)
} else {
NULL
}
}
#' @importFrom rlang %||%
compute_count <- function(mapdata) {
if (!is_grouped(mapdata)) {
x <- mapdata$x
weight <- mapdata$weight %||% rep(1, length(x))
count <- tapply(weight, x, sum, na.rm = TRUE, simplify = FALSE)
mapdata$x <- names(count)
mapdata$y <- as.numeric(count)
} else {
weight <- mapdata$weight %||% rep(1, length(mapdata$x))
count <- tapply(weight, mapdata[c("x", "group")], sum, na.rm = TRUE, simplify = FALSE)
mapdata$x <- rep(rownames(count), ncol(count))
mapdata$y <- unlist(count, use.names = FALSE)
mapdata$group <- rep(colnames(count), each = nrow(count))
}
mapdata$y[is.na(mapdata$y)] <- 0
return(mapdata)
}
# Configs ----
# Switch between auto configs according to type & mapping
choose_config <- function(type, mapdata) {
datetime <- is_x_datetime(mapdata)
range_x <- range_num(mapdata$x)
range_y <- range_num(mapdata$y)
if (identical(type, "boxplot")) {
box_horiz <- !is.numeric(mapdata$y) & is.numeric(mapdata$x)
}
switch(
type,
type,
"bar" = config_bar(horizontal = TRUE),
"dumbbell" = config_bar(horizontal = TRUE, isDumbbell = TRUE),
"column" = config_bar(horizontal = FALSE, datetime = datetime),
"line" = config_line(datetime = datetime),
"area" = config_line(datetime = datetime),
"rangeArea" = config_line(datetime = datetime),
"spline" = config_line(curve = "smooth", datetime = datetime),
"step" = config_line(curve = "stepline", datetime = datetime),
"area-spline" = config_line(curve = "smooth", datetime = datetime),
@ -261,33 +343,33 @@ choose_config <- function(type, mapdata) {
"bubble" = config_scatter(range_x = range_x, range_y = range_y, datetime = datetime),
"timeline" = config_timeline(),
"candlestick" = config_candlestick(),
"boxplot" = config_boxplot(horizontal = box_horiz),
"slope" = config_slope(),
list()
)
}
# Config for column & bar charts
config_bar <- function(horizontal = FALSE, datetime = FALSE) {
config_bar <- function(horizontal = FALSE, datetime = FALSE, isDumbbell = FALSE) {
config <- list(
dataLabels = list(enabled = FALSE),
plotOptions = list(
bar = list(
horizontal = horizontal
horizontal = horizontal,
isDumbbell = isDumbbell
)
),
tooltip = list(
shared = TRUE,
shared = TRUE,
intersect = FALSE,
followCursor = TRUE
),
grid = list(
yaxis = list(lines = list(show = !isTRUE(horizontal))),
xaxis = list(lines = list(show = isTRUE(horizontal)))
)
)
if (isTRUE(horizontal)) {
config <- c(config, list(
grid = list(
yaxis = list(lines = list(show = FALSE)),
xaxis = list(lines = list(show = TRUE))
)
))
}
if (isTRUE(datetime)) {
config$xaxis$type <- "datetime"
}
@ -301,7 +383,7 @@ config_line <- function(curve = "straight", datetime = FALSE) {
stroke = list(
curve = curve,
width = 2
),
),
yaxis = list(
decimalsInFloat = 2
)
@ -320,17 +402,20 @@ config_scatter <- function(range_x, range_y, datetime = FALSE) {
dataLabels = list(enabled = FALSE),
xaxis = list(
type = "numeric",
min = range_x[1],
max = range_x[2],
min = range_x$range[1],
max = range_x$range[2],
tickAmount = range_x$n,
# labels = list(formatter = format_num("~r")),
crosshairs = list(
show = TRUE,
stroke = list(dashArray = 0)
)
),
yaxis = list(
min = range_y[1],
max = range_y[2],
decimalsInFloat = 3,
min = range_y$range[1],
max = range_y$range[2],
tickAmount = range_y$n,
labels = list(formatter = format_num("~r")),
tooltip = list(
enabled = TRUE
)
@ -370,3 +455,22 @@ config_candlestick <- function() {
)
}
config_boxplot <- function(horizontal = FALSE) {
list(
plotOptions = list(
bar = list(
horizontal = horizontal
)
)
)
}
config_slope <- function() {
list(
plotOptions = list(
line = list(
isSlopeChart = TRUE
)
)
)
}

View File

@ -5,9 +5,8 @@
#' to create interactive and modern SVG charts.
#'
#' @name apexcharter-package
#' @docType package
#' @author Victor Perrier (@@dreamRs_fr)
NULL
"_PACKAGE"
#' apexcharter exported operators and S3 methods
#'
@ -30,6 +29,18 @@ NULL
#' @rdname apexcharter-exports
NULL
#' @importFrom ggplot2 vars
#' @name vars
#' @export
#' @rdname apexcharter-exports
NULL
#' @importFrom ggplot2 label_value
#' @name label_value
#' @export
#' @rdname apexcharter-exports
NULL
#' @importFrom htmlwidgets JS
#' @name JS
#' @export

View File

@ -1,22 +1,26 @@
#' Create an apexcharts.js widget
#' Create an ApexCharts widget
#'
#' @param ax_opts A \code{list} in JSON format with chart parameters.
#' @param ax_opts A `list` in JSON format with chart parameters.
#' @param auto_update In Shiny application, update existing chart
#' rather than generating new one. Can be \code{TRUE}/\code{FALSE} or
#' use \code{\link{config_update}} for more control.
#' @param width A numeric input in pixels.
#' @param height A numeric input in pixels.
#' rather than generating new one. Can be `TRUE`/`FALSE` or
#' use [config_update()] for more control.
#' @param width,height A numeric input in pixels.
#' @param elementId Use an explicit element ID for the widget.
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#' @return An [apexchart()] `htmlwidget` object.
#' @seealso For quickly create a chart, see [apex()].
#' @export
#'
#' @importFrom htmlwidgets createWidget sizingPolicy
#'
#' @example examples/apexchart.R
apexchart <- function(ax_opts = list(), auto_update = TRUE, width = NULL, height = NULL, elementId = NULL) {
apexchart <- function(ax_opts = list(),
auto_update = TRUE,
width = NULL,
height = NULL,
elementId = NULL) {
if (isTRUE(auto_update)) {
auto_update <- config_update()
}
@ -35,7 +39,12 @@ apexchart <- function(ax_opts = list(), auto_update = TRUE, width = NULL, height
height = height,
package = "apexcharter",
elementId = elementId,
preRenderHook = add_locale_apex,
preRenderHook = function(widget) {
widget$x$data <- NULL
widget$x$mapping <- NULL
widget$x$add_line <- NULL
add_locale_apex(widget)
},
sizingPolicy = htmlwidgets::sizingPolicy(
defaultWidth = "100%",
defaultHeight = "100%",
@ -52,15 +61,17 @@ apexchart <- function(ax_opts = list(), auto_update = TRUE, width = NULL, height
)
}
# dput(tools::file_path_sans_ext(list.files("inst/apexcharts-locale/")))
#' @importFrom jsonlite fromJSON
add_locale_apex <- function(widget) {
if (!is.null(widget$x$ax_opts$chart$defaultLocale)) {
defaultLocale <- widget$x$ax_opts$chart$defaultLocale
defaultLocale <- match.arg(
arg = defaultLocale,
choices = c("ca", "cs", "de", "el", "en", "es", "fi", "fr", "he", "hi",
"hr", "hy", "id", "it", "ko", "lt", "nb", "nl", "pl", "pt-br",
"pt", "ru", "se", "sk", "sl", "th", "tr", "ua")
choices = c("ca", "cs", "de", "el", "en", "es", "fi", "fr", "he", "hi",
"hr", "hu", "hy", "id", "it", "ja", "ka", "ko", "lt", "nb", "nl",
"pl", "pt-br", "pt", "rs", "ru", "se", "sk", "sl", "sq", "th",
"tr", "ua", "zh-cn")
)
if (!is.null(widget$x$ax_opts$chart$locales)) {
warning(
@ -69,7 +80,7 @@ add_locale_apex <- function(widget) {
)
} else {
path <- system.file(
file.path("htmlwidgets/lib/apexcharts-locales", paste0(defaultLocale, ".json")),
file.path("apexcharts-locale", paste0(defaultLocale, ".json")),
package = "apexcharter"
)
locale <- jsonlite::fromJSON(txt = path)
@ -87,22 +98,22 @@ add_locale_apex <- function(widget) {
#' @param update_options Update or not global options for chart.
#' @param options_animate Should the chart animate on re-rendering.
#' @param options_redrawPaths When the chart is re-rendered,
#' should it draw from the existing paths or completely redraw
#' the chart paths from the beginning. By default, the chart
#' should it draw from the existing paths or completely redraw
#' the chart paths from the beginning. By default, the chart
#' is re-rendered from the existing paths.
#' @param update_synced_charts All the charts in a group should
#' also update when one chart in a group is updated.
#'
#'
#' @export
config_update <- function(series_animate = TRUE,
update_options = FALSE,
options_animate = TRUE,
config_update <- function(series_animate = TRUE,
update_options = FALSE,
options_animate = TRUE,
options_redrawPaths = TRUE,
update_synced_charts = FALSE) {
list(
series_animate = series_animate,
update_options = update_options,
options_animate = options_animate,
series_animate = series_animate,
update_options = update_options,
options_animate = options_animate,
options_redrawPaths = options_redrawPaths,
update_synced_charts = update_synced_charts
)
@ -114,31 +125,34 @@ config_update <- function(series_animate = TRUE,
#' @description Output and render functions for using apexcharter within Shiny
#' applications and interactive Rmd documents.
#'
#' @param outputId output variable to read from
#' @param width,height Must be a valid CSS unit (like \code{'100\%'},
#' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a
#' string and have \code{'px'} appended.
#' @param expr An expression that generates a apexcharter
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This
#' @param outputId Output variable to read from.
#' @param width,height Must be a valid CSS unit (like `100%`,
#' `400px`, `auto`) or a number, which will be coerced to a
#' string and have `px` appended.
#' @param expr An expression that generates a calendar
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' is useful if you want to save an expression in a variable.
#'
#' @return An Apexchart output that can be included in the application UI.
#'
#' @return Output element that can be included in UI. Render function to create output in server.
#'
#' @note To render a chart with facets (using [ax_facet_wrap()] or [ax_facet_grid()]) in Shiny,
#' see [apexfacetOutput()] (in UI) and [renderApexfacet()] (in Server).
#'
#' @name apexcharter-shiny
#'
#' @export
#'
#' @importFrom htmlwidgets shinyWidgetOutput shinyRenderWidget
#'
#'
#' @example examples/apexcharter-shiny.R
apexchartOutput <- function(outputId, width = "100%", height = "400px"){
apexchartOutput <- function(outputId, width = "100%", height = "400px") { # nocov start
htmlwidgets::shinyWidgetOutput(outputId, "apexcharter", width, height, package = "apexcharter")
}
} # nocov end
#' @rdname apexcharter-shiny
#' @export
renderApexchart <- function(expr, env = parent.frame(), quoted = FALSE) {
renderApexchart <- function(expr, env = parent.frame(), quoted = FALSE) { # nocov start
if (!quoted) { expr <- substitute(expr) } # force quoted
htmlwidgets::shinyRenderWidget(expr, apexchartOutput, env, quoted = TRUE)
}
} # nocov end

47
R/colors.R Normal file
View File

@ -0,0 +1,47 @@
#' Set specific color's series
#'
#' @template ax-default
#' @param values Named list, names represent data series, values colors to use.
#'
#' @export
#'
#' @example examples/colors.R
ax_colors_manual <- function(ax, values) {
if (!inherits(ax, "apexcharter"))
stop("ax_colors_manual: ax must be an apexcharter object", call. = FALSE)
ax$x$colors_manual <- values
ax$x$ax_opts$colors <- NULL
groups <- get_groups(ax)
values <- validate_values(values, groups)
ax_colors(ax = ax, values$val)
}
#' @importFrom rlang is_named
validate_values <- function(values, groups) {
if (!rlang::is_named(values))
stop("values must be a named list or vector")
nm <- names(values)
val <- unname(unlist(values))
nm_check <- setdiff(groups, nm)
if (length(nm_check) > 0) {
warning("Some groups doesn't have a corresponding color value")
}
list(
nm = intersect(groups, nm),
val = val[match(x = groups, table = nm, nomatch = 0L)]
)
}
get_groups <- function(ax) {
if (!inherits(ax, "apexcharter"))
stop("ax must be an apexcharter htmlwidget")
if (is.null(ax$x$ax_opts$series))
stop("ax must have a serie of data")
groups <- lapply(ax$x$ax_opts$series, `[[`, "name")
groups <- unlist(groups)
as.character(groups)
}

View File

@ -1,20 +1,3 @@
#' UNHCR data for 2017
#'
#' The dataset contains data about UNHCR's populations of concern for the year 2017.
#'
#' @format A data frame with 11237 observations and the following 6 variables:
#' \describe{
#' \item{\code{country_origin}}{Country of origin of population}
#' \item{\code{country_residence}}{Country / territory of asylum/residence of population}
#' \item{\code{population_type}}{Populations of concern : Refugees, Asylum-seekers, Internally displaced persons (IDPs), Returned refugees,
#' Returned IDPs, Stateless persons, Others of concern.}
#' \item{\code{value}}{Number of people concerned}
#' \item{\code{continent_residence}}{Continent of origin of population}
#' \item{\code{continent_origin}}{Continent of residence of population}
#' }
#' @source UNHCR (The UN Refugee Agency) (\url{https://www.unhcr.org/})
"unhcr_popstats_2017"
#' UNHCR data by continent of origin
#'
@ -24,11 +7,11 @@
#' \describe{
#' \item{\code{year}}{Year concerned.}
#' \item{\code{population_type}}{Populations of concern : Refugees, Asylum-seekers, Internally displaced persons (IDPs), Returned refugees,
#' Returned IDPs, Stateless persons, Others of concern.}
#' Returned IDPs, Stateless persons, Others of concern.}
#' \item{\code{continent_origin}}{Continent of residence of population.}
#' \item{\code{n}}{Number of people concerned.}
#' }
#' @source UNHCR (The UN Refugee Agency) (\url{https://www.unhcr.org/})
#' @source UNHCR (The UN Refugee Agency) (\url{https://data.unhcr.org/})
"unhcr_ts"
@ -40,7 +23,7 @@
#' @format A data frame with 120 observations and the following 3 variables:
#' \describe{
#' \item{\code{date}}{date.}
#' \item{\code{type}}{Type of data : realised or forecast.}
#' \item{\code{type}}{Type of data : realized or forecast.}
#' \item{\code{value}}{Value in giga-watt per hour.}
#' }
#' @source Rte (Electricity Transmission Network in France) (\url{https://data.rte-france.com/})
@ -53,7 +36,7 @@
#' @format A data frame with 60 observations and the following 5 variables:
#' \describe{
#' \item{\code{datetime}}{Timestamp.}
#' \item{\code{open}}{Open value.}
#' \item{\code{open}}{Open value.}
#' \item{\code{high}}{Highest value.}
#' \item{\code{low}}{Lowest value.}
#' \item{\code{close}}{Close value.}
@ -62,3 +45,56 @@
"candles"
#' @title Paris Climate
#'
#' @description Average temperature and precipitation in Paris for the period 1971-2000.
#'
#'
#' @format A data frame with 12 observations and the following 3 variables:
#' \describe{
#' \item{\code{month}}{Month}
#' \item{\code{temperature}}{Temperature (in degree celsius).}
#' \item{\code{precipitation}}{Precipitation (in mm).}
#' }
#' @source Wikipedia (\url{https://fr.wikipedia.org/wiki/Climat_de_Paris})
"climate_paris"
#' @title eco2mix data
#'
#' @description The dataset contains data about electricity consumption and production in France between 2012 and 2022.
#'
#' @format A data frame with 3,033 observations and 3 variables.
#'
#' @source Rte (Réseau et transport d'électricité) (\url{https://www.rte-france.com/eco2mix} and \url{https://opendata.reseaux-energies.fr/})
"eco2mix"
#' @title Temperature data
#'
#' @description The dataset contains data about temperatures in France between 2018 and 2022.
#'
#' @format A data frame with 365 observations and 6 variables.
#'
#' @source Enedis (\url{https://data.enedis.fr/explore/dataset/donnees-de-temperature-et-de-pseudo-rayonnement/})
"temperatures"
#' @title Life expectancy data
#'
#' @description The dataset contains data about life expectancy in 1972 and 2007 for 10 countries.
#'
#' @format A data frame with 10 observations and 4 variables.
#'
#' @source gapminder package (\url{https://jennybc.github.io/gapminder/} and \url{https://www.gapminder.org/data/})
"life_expec"
#' @title Life expectancy data (long format)
#'
#' @description The dataset contains data about life expectancy in 1972 and 2007 for 10 countries.
#'
#' @format A data frame with 20 observations and 3 variables.
#'
#' @source gapminder package (\url{https://jennybc.github.io/gapminder/} and \url{https://www.gapminder.org/data/})
"life_expec_long"

180
R/facets-utils.R Normal file
View File

@ -0,0 +1,180 @@
#' @importFrom rlang eval_tidy
get_facets <- function(data, rows, cols, type = c("wrap", "grid")) {
type <- match.arg(type)
byrows <- lapply(X = rows, FUN = eval_tidy, data = data)
bycols <- lapply(X = cols, FUN = eval_tidy, data = data)
facets <- split(x = data, f = c(bycols, byrows), sep = "|__|")
facets <- lapply(
X = seq_along(facets),
FUN = function(i) {
facet <- facets[[i]]
attr(facet, "keys") <- strsplit(
x = names(facets)[i],
split = "|__|", fixed = TRUE
)[[1]]
facet
}
)
label_row <- lapply(byrows, unique)
label_row <- lapply(label_row, sort)
label_row <- apply(expand.grid(label_row), 1, paste, collapse = "*")
label_col <- lapply(bycols, unique)
label_col <- lapply(label_col, sort)
label_col <- apply(expand.grid(label_col), 1, paste, collapse = "*")
list(
facets = facets,
nrow = if (identical(type, "grid")) n_facet(byrows) else NULL,
ncol = if (identical(type, "grid")) n_facet(bycols) else NULL,
label_row = label_row,
label_col = label_col
)
}
n_facet <- function(l) {
l <- lapply(l, function(x) {
length(unique(x))
})
Reduce(`*`, l)
}
#' @importFrom rlang %||% is_list is_named
set_scale <- function(ax, values, scales = c("fixed", "free", "free_y", "free_x"), axis = c("x", "y", "y2")) {
if (is.null(scales))
return(ax)
scales <- match.arg(scales)
axis <- match.arg(axis)
if (identical(axis, "y2")) {
axis <- "y"
wyaxis <- 2
} else {
wyaxis <- 1
}
if (is.null(values))
return(ax)
if (inherits(values, c("numeric", "integer", "Date", "POSIXt"))) {
range_vals <- range(pretty(values, n = 10), na.rm = TRUE)
} else {
range_vals <- NULL
}
waxis <- switch(
axis,
"x" = "xaxis",
"y" = "yaxis"
)
this_axis <- ax$x$ax_opts[[waxis]]
if (inherits(this_axis, "yaxis2")) {
ax$x$ax_opts[[waxis]][[wyaxis]] <- set_scale_axis(
this_axis[[wyaxis]],
range_vals = range_vals,
scales = scales,
axis = axis
)
# ax$x$ax_opts[[waxis]][[2]] <- set_scale_axis(
# this_axis[[2]],
# range_vals = range_vals,
# scales = scales,
# axis = axis
# )
} else {
ax$x$ax_opts[[waxis]] <- set_scale_axis(
this_axis,
range_vals = range_vals,
scales = scales,
axis = axis
)
}
return(ax)
}
scale_fmt <- function(x, time = inherits(x, c("Date", "POSIXt"))) {
if (is.null(x))
return(NULL)
if (time)
x <- format_date(x)
x
}
set_scale_axis <- function(this_axis,
range_vals,
scales = c("fixed", "free", "free_y", "free_x"),
axis = c("x", "y")) {
scales <- match.arg(scales)
axis <- match.arg(axis)
if (scales == "fixed") {
this_axis$min <- this_axis$min %||% scale_fmt(range_vals[1])
this_axis$max <- this_axis$max %||% scale_fmt(range_vals[2])
} else if (scales == "free") {
this_axis$min <- NULL
this_axis$max <- NULL
} else if (scales == "free_x") {
if (axis == "y") {
this_axis$min <- this_axis$min %||% scale_fmt(range_vals[1])
this_axis$max <- this_axis$max %||% scale_fmt(range_vals[2])
} else {
this_axis$min <- NULL
this_axis$max <- NULL
}
} else if (scales == "free_y") {
if (axis == "x") {
this_axis$min <- this_axis$min %||% scale_fmt(range_vals[1])
this_axis$max <- this_axis$max %||% scale_fmt(range_vals[2])
} else {
this_axis$min <- NULL
this_axis$max <- NULL
}
}
return(this_axis)
}
get_option <- function(ax, opt1, opt2 = NULL) {
if (is.null(opt2)) {
ax$x$ax_opts[[opt1]]
} else {
ax$x$ax_opts[[opt1]][[opt2]]
}
}
remove_option <- function(ax, opt1, opt2 = NULL) {
if (is.null(opt2)) {
ax$x$ax_opts[[opt1]] <- NULL
} else {
ax$x$ax_opts[[opt1]][[opt2]] <- NULL
}
ax
}
get_yaxis_serie <- function(ax, which = 1) {
series <- ax$x$ax_opts$series
yaxis <- ax$x$ax_opts$yaxis
if (inherits(yaxis, c("yaxis", "yaxis2"))) {
yaxis <- yaxis[[which]]
name <- yaxis$serieName
if (!is.null(name)) {
series_names <- vapply(series, FUN = `[[`, "name", FUN.VALUE = character(1))
indice <- which(name == series_names)
} else {
indice <- which
}
unlist(lapply(series[[indice]]$data, FUN = `[[`, "y"))
} else {
unlist(lapply(
X = seq_along(series),
FUN = function(indice) {
unlist(lapply(series[[indice]]$data, FUN = `[[`, "y"))
}
))
}
}
has_yaxis2 <- function(ax) {
inherits(ax$x$ax_opts$yaxis, "yaxis2")
}

498
R/facets.R Normal file
View File

@ -0,0 +1,498 @@
#' @importFrom rlang eval_tidy is_null is_function
build_facets <- function(chart) {
data <- chart$x$data
mapall <- lapply(chart$x$mapping, eval_tidy, data = data)
labeller <- chart$x$facet$labeller
title <- get_option(chart, "title")
chart <- remove_option(chart, "title")
subtitle <- get_option(chart, "subtitle")
chart <- remove_option(chart, "subtitle")
xaxis_title <- get_option(chart, "xaxis", "title")
chart <- remove_option(chart, "xaxis", "title")
yaxis_title <- get_option(chart, "yaxis", "title")
chart <- remove_option(chart, "yaxis", "title")
facets_list <- get_facets(
data = data,
rows = chart$x$facet$facets_row,
cols = chart$x$facet$facets_col,
type = chart$x$facet$type
)
facets_data <- facets_list$facets
nrow_ <- facets_list$nrow %||% chart$x$facet$nrow
ncol_ <- facets_list$ncol %||% chart$x$facet$ncol
nums <- seq_along(facets_data)
dims <- get_grid_dims(nums, nrow = nrow_, ncol = ncol_)
grid <- matrix(
data = c(
nums,
rep(NA, times = (dims$nrow * dims$ncol) - length(nums))
),
nrow = dims$nrow,
ncol = dims$ncol,
byrow = TRUE
)
lrow <- get_last_row(grid)
facet_data_add_line <- if (!is.null(chart$x$add_line)) {
get_facets(
data = chart$x$add_line$data,
rows = chart$x$facet$facets_row,
cols = chart$x$facet$facets_col,
type = chart$x$facet$type
)$facets
}
facets <- lapply(
X = nums,
FUN = function(i) {
new <- chart
facet <- facets_data[[i]]
if (identical(chart$x$facet$type, "wrap") && !is_null(labeller) && is_function(labeller)) {
keys <- attr(facet, "keys")
text <- labeller(keys)
new <- ax_title(new, text = text, margin = 0, floating = length(text) <= 1)
}
mapdata <- lapply(chart$x$mapping, eval_tidy, data = facet)
if (chart$x$facet$scales %in% c("fixed", "free_y") & chart$x$type %in% c("bar")) {
mapdata <- complete_mapdata(mapdata, mapall)
}
if (chart$x$facet$scales %in% c("fixed", "free_x") & chart$x$type %in% c("column")) {
mapdata <- complete_mapdata(mapdata, mapall)
}
new$x$ax_opts$series <- make_series(mapdata, chart$x$mapping, chart$x$type, chart$x$serie_name)
new <- set_scale(new, mapall$x, scales = chart$x$facet$scales, axis = "x")
new <- set_scale(new, mapall$y, scales = chart$x$facet$scales, axis = "y")
if (chart$x$facet$scales %in% c("fixed", "free_x")) {
new <- ax_yaxis(new, show = i %in% grid[, 1])
}
# if (chart$x$facet$scales %in% c("fixed", "free_y")) {
# new <- ax_xaxis(new, labels = list(show = i %in% lrow), axisTicks = list(show = TRUE))
# }
if (chart$x$facet$scales %in% c("fixed", "free_y") & chart$x$type %in% c("bar", "column")) {
new <- ax_xaxis(new, labels = list(show = i %in% lrow))
}
if (!is.null(new$x$colors_manual)) {
new <- ax_colors_manual(ax = new, values = new$x$colors_manual)
}
if (!is.null(facet_data_add_line)) {
maplinedata <- lapply(chart$x$add_line$mapping, eval_tidy, data = facet_data_add_line[[i]])
if (chart$x$facet$scales %in% c("fixed", "free_y") & chart$x$type %in% c("bar")) {
maplinedata <- complete_mapdata(maplinedata, mapall)
}
if (chart$x$facet$scales %in% c("fixed", "free_x") & chart$x$type %in% c("column")) {
maplinedata <- complete_mapdata(maplinedata, mapall)
}
new$x$ax_opts$series <- c(
new$x$ax_opts$series,
make_series(
mapdata = maplinedata,
mapping = chart$x$add_line$mapping,
type = chart$x$add_line$type,
serie_name = chart$x$add_line$serie_name,
force_datetime_names = c("x", "y")
)
)
# new <- add_line(
# ax = new,
# mapping = chart$x$add_line$mapping,
# data = facet_data_add_line[[i]],
# type = chart$x$add_line$type,
# serie_name = chart$x$add_line$serie_name
# )
}
if (has_yaxis2(new)) {
values <- get_yaxis_serie(chart, 2)
new <- set_scale(new, values, scales = chart$x$facet$scales, axis = "y2")
}
new$height <- chart$height %||% chart$x$facet$chart_height
new$x$facet <- NULL
class(new) <- setdiff(class(new), "apex_facet")
return(new)
}
)
list(
facets = facets,
type = chart$x$facet$type,
nrow = facets_list$nrow,
ncol = facets_list$ncol,
label_row = facets_list$label_row,
label_col = facets_list$label_col,
title = title,
subtitle = subtitle,
xaxis_title = xaxis_title,
yaxis_title = yaxis_title
)
}
get_last_row <- function(mat) {
apply(X = mat, MARGIN = 2, FUN = function(x) {
x <- x[!is.na(x)]
x[length(x)]
})
}
#' @title Facets for ApexCharts
#'
#' @description Create matrix of charts by row and column faceting variable (`ax_facet_grid`),
#' or by specified number of row and column for faceting variable(s) (`ax_facet_wrap`).
#'
#' @param ax An [apexchart()] `htmlwidget` object.
#' @param facets Variable(s) to use for facetting, wrapped in `vars(...)`.
#' @param nrow,ncol Number of row and column in output matrix.
#' @param scales Should scales be fixed (`"fixed"`, the default),
#' free (`"free"`), or free in one dimension (`"free_x"`, `"free_y"`)?
#' @param labeller A function with one argument containing for each facet the value of the faceting variable.
#' @param chart_height Individual chart height, ignored if an height is defined in `apex()` or `apexcharter()`.
#' @param grid_width Total width for the grid, regardless of the number of column.
#'
#' @return An [apexchart()] `htmlwidget` object with an additionnal class `"apex_facet"`.
#'
#' @details # Warning
#' To properly render in Shiny applications, use [apexfacetOutput()] (in UI) and [renderApexfacet()] (in Server).
#'
#' @export
#'
#' @name apex-facets
#'
#' @importFrom rlang quos syms
#'
#' @example examples/facet_wrap.R
ax_facet_wrap <- function(ax,
facets,
nrow = NULL,
ncol = NULL,
scales = c("fixed", "free", "free_y", "free_x"),
labeller = label_value,
chart_height = "300px",
grid_width = "100%") {
if (!inherits(ax, "apex"))
stop("ax_facet_wrap only works with charts generated with apex()", call. = FALSE)
scales <- match.arg(scales)
if (is.character(facets))
facets <- quos(!!!syms(facets))
ax$x$facet <- list(
facets_row = facets,
nrow = nrow,
ncol = ncol,
scales = scales,
labeller = labeller,
chart_height = chart_height,
grid_width = grid_width,
type = "wrap"
)
class(ax) <- c("apex_facet", class(ax))
return(ax)
}
#' @param rows,cols A set of variables or expressions quoted by `vars()`
#' and defining faceting groups on the rows or columns dimension.
#' @export
#'
#' @rdname apex-facets
#'
#' @example examples/facet_grid.R
ax_facet_grid <- function(ax,
rows = NULL,
cols = NULL,
scales = c("fixed", "free", "free_y", "free_x"),
labeller = label_value,
chart_height = "300px",
grid_width = "100%") {
if (!inherits(ax, "apex"))
stop("ax_facet_wrap only works with charts generated with apex()", call. = FALSE)
scales <- match.arg(scales)
if (!is.null(rows) && is.character(rows))
rows <- quos(!!!syms(rows))
if (!is.null(cols) && is.character(cols))
cols <- quos(!!!syms(cols))
ax$x$facet <- list(
facets_row = rows,
facets_col = cols,
nrow = NULL,
ncol = NULL,
scales = scales,
labeller = labeller,
chart_height = chart_height,
grid_width = grid_width,
type = "grid"
)
class(ax) <- c("apex_facet", class(ax))
return(ax)
}
# Tag ---------------------------------------------------------------------
#' @importFrom rlang %||%
#' @importFrom htmltools tags css validateCssUnit
build_facet_tag <- function(x) {
facets <- build_facets(x)
content <- facets$facets
d <- get_grid_dims(content, x$x$facet$nrow, x$x$facet$ncol)
row_after <- col_before <- NULL
if (!is.null(facets$xaxis_title)) {
if (identical(facets$type, "wrap")) {
area <- paste(
d$nrow + 1,
1,
d$nrow + 1,
d$ncol + 2,
sep = " / "
)
} else {
area <- paste(
(facets$nrow %||% 1) + 1 + !is.null(facets$ncol),
1,
(facets$nrow %||% 1) + 1 + !is.null(facets$ncol),
(facets$ncol %||% 1) + 2,
sep = " / "
)
}
TAGX <- tags$div(
class = "apexcharter-facet-xaxis-title",
facets$xaxis_title$text,
style = make_styles(facets$xaxis_title$style),
style = paste("grid-area:", area, ";")
)
content <- c(content, list(TAGX))
row_after <- "30px"
}
if (!is.null(facets$yaxis_title)) {
if (identical(facets$type, "wrap")) {
area <- paste(
1,
1,
d$nrow + 1,
2,
sep = " / "
)
} else {
area <- paste(
1,
1,
(facets$nrow %||% 1) + 1 + !is.null(facets$ncol),
2,
sep = " / "
)
}
TAGY <- tags$div(
class = "apexcharter-facet-yaxis-title apexcharter-facet-rotate180",
facets$yaxis_title$text,
style = make_styles(facets$yaxis_title$style),
style = paste("grid-area:", area, ";")
)
content <- c(content, list(TAGY))
col_before <- "30px"
}
if (identical(facets$type, "wrap")) {
TAG <- build_grid(
content = content,
nrow = d$nrow,
ncol = d$ncol,
row_after = row_after,
col_before = col_before
)
} else if (identical(facets$type, "grid")) {
if (!is.null(facets$nrow)) {
for (i in seq_along(facets$label_row)) {
content <- append(
x = content,
values = tagList(tags$div(
class = "apexcharter-facet-row-label",
x$x$facet$labeller(facets$label_row[i])
)),
after = ((facets$ncol %||% 1 + 1) * i) - 1
)
}
}
if (!is.null(facets$ncol)) {
content <- tagList(
lapply(
X = facets$label_col,
FUN = function(label_col) {
tags$div(x$x$facet$labeller(label_col), class = "apexcharter-facet-col-label")
}
),
if (!is.null(facets$nrow)) tags$div(),
content
)
}
TAG <- build_grid(
content,
nrow = facets$nrow %||% 1,
ncol = facets$ncol %||% 1,
row_before = if (!is.null(facets$ncol)) "30px",
col_after = if (!is.null(facets$nrow)) "30px",
row_gap = "3px",
col_gap = "3px",
row_after = row_after,
col_before = col_before
)
} else {
stop("Facetting must be wrap or grid", call. = FALSE)
}
if (!is.null(facets$subtitle)) {
TAG <- tagList(
tags$div(
class = "apexcharter-facet-subtitle",
facets$subtitle$text,
style = make_styles(facets$subtitle$style)
),
TAG
)
}
if (!is.null(facets$title)) {
TAG <- tagList(
tags$div(
class = "apexcharter-facet-title",
facets$title$text,
style = make_styles(facets$title$style)
),
TAG
)
}
TAG <- tags$div(
style = css(width = validateCssUnit(x$x$facet$grid_width)),
class = "apexcharter-facet",
TAG
)
return(TAG)
}
# Shiny -------------------------------------------------------------------
#' @title Shiny bindings for faceting with apexcharter
#'
#' @description Output and render functions for using apexcharter faceting within Shiny
#' applications and interactive Rmd documents.
#'
#' @param outputId output variable to read from
#'
#' @return An Apexcharts output that can be included in the application UI.
#' @export
#'
#' @name apexcharter-shiny-facets
#'
#' @importFrom htmltools tagList
#' @importFrom shiny uiOutput
#' @importFrom htmlwidgets getDependency
#'
#' @example examples/facet-wrap-shiny.R
apexfacetOutput <- function(outputId) {
tagList(
uiOutput(outputId = outputId),
getDependency(name = "apexcharter", package = "apexcharter")
)
}
#' @param expr An expression that generates a apexcharter facet with [ax_facet_wrap()] or [ax_facet_grid()].
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' is useful if you want to save an expression in a variable.
#'
#' @seealso [ax_facet_wrap()], [ax_facet_grid()]
#'
#' @export
#'
#' @rdname apexcharter-shiny-facets
#'
#' @importFrom shiny exprToFunction createRenderFunction createWebDependency
#' @importFrom htmltools renderTags resolveDependencies
renderApexfacet <- function(expr, env = parent.frame(), quoted = FALSE) { # nocov start
func <- exprToFunction(expr, env, quoted)
createRenderFunction(
func = func,
transform = function(result, shinysession, name, ...) {
if (is.null(result) || length(result) == 0)
return(NULL)
if (!inherits(result, "apex_facet")) {
stop(
"renderApexfacet: 'expr' must return an apexcharter facet object.",
call. = FALSE
)
}
TAG <- build_facet_tag(result)
rendered <- renderTags(TAG)
deps <- lapply(
X = resolveDependencies(rendered$dependencies),
FUN = createWebDependency
)
list(
html = rendered$html,
deps = deps
)
}, apexfacetOutput, list()
)
} # nocov end
# Print methods -----------------------------------------------------------
#' @export
print.apex_facet <- function(x, ...) { # nocov start
TAG <- build_facet_tag(x)
print(htmltools::browsable(TAG))
} # nocov end
knit_print.apex_facet <- function(x, ..., options = NULL) { # nocov start
TAG <- build_facet_tag(x)
knitr::knit_print(htmltools::browsable(TAG), options = options, ...)
} # nocov end
# Complete ----------------------------------------------------------------
complete_mapdata <- function(mapdata, mapall) {
data <- as.data.frame(mapdata)
full_x <- unique(mapall$x)
full_data <- data.frame(
xorder = seq_along(full_x),
x = full_x,
stringsAsFactors = FALSE
)
full_data <- merge(
x = full_data,
y = data,
by = "x",
all.x = TRUE,
sort = FALSE
)
full_data <- full_data[order(full_data$xorder), ]
full_data$xorder <- NULL
full_data$y[is.na(full_data$y)] <- 0
return(as.list(full_data))
}
complete_data <- function(data, vars, fill_var, fill_value = 0) {
full_data <- expand.grid(lapply(
X = data[, vars],
FUN = unique
))
full_data <- merge(
x = full_data,
y = data,
by = vars,
all.x = TRUE,
sort = FALSE
)
full_data[[fill_var]][is.na(full_data[[fill_var]])] <- fill_value
return(full_data)
}

View File

@ -10,25 +10,25 @@
#'
#' @return a \code{JS} function
#' @export
#'
#'
#' @importFrom htmlwidgets JS
#'
#' @example examples/format.R
format_num <- function(format, prefix = "", suffix = "", locale = "en-US") {
check_locale_d3(locale)
path <- system.file(file.path("htmlwidgets/lib/d3-format/locale", paste0(locale, ".json")), package = "apexcharter")
path <- system.file(file.path("d3-format-locale", paste0(locale, ".json")), package = "apexcharter")
if (path != "") {
locale <- paste(readLines(con = path, encoding = "UTF-8"), collapse = "")
}
JS(sprintf(
"function(value) {var locale = d3.formatLocale(JSON.parse('%s')); return '%s' + locale.format('%s')(value) + '%s';}",
"function(value) {var locale = formatLocale(JSON.parse('%s')); return '%s' + locale.format('%s')(value) + '%s';}",
locale, prefix, format, suffix
))
}
check_locale_d3 <- function(x) {
json <- list.files(system.file("htmlwidgets/lib/d3-format/locale", package = "apexcharter"))
json <- list.files(system.file("d3-format-locale", package = "apexcharter"))
njson <- gsub("\\.json", "", json)
if (!x %in% njson) {
stop(paste(

221
R/grid.R Normal file
View File

@ -0,0 +1,221 @@
get_grid_dims <- function(content, nrow = NULL, ncol = NULL) {
n <- length(content)
if (is.null(nrow) & !is.null(ncol))
nrow <- ceiling(n / ncol)
if (!is.null(nrow) & is.null(ncol))
ncol <- ceiling(n / nrow)
if (is.null(nrow) & is.null(ncol)) {
if (n %% 3 < 1) {
ncol <- 3
nrow <- ceiling(n / ncol)
} else {
ncol <- 2
nrow <- ceiling(n / ncol)
}
}
list(nrow = nrow, ncol = ncol)
}
#' @importFrom htmltools tags
build_grid <- function(content,
nrow = NULL,
ncol = NULL,
row_gap = "5px",
col_gap = "0px",
row_before = NULL,
row_after = NULL,
col_before = NULL,
col_after = NULL,
height = NULL,
width = NULL) {
d <- get_grid_dims(content, nrow, ncol)
col_style <- paste("grid-template-columns:", col_before, sprintf("repeat(%s, 1fr)", d$ncol), col_after, ";")
row_style <- paste("grid-template-rows:", row_before, sprintf("repeat(%s, 1fr)", d$nrow), row_after, ";")
tags$div(
class = "apexcharter-grid-container",
style = if (!is.null(height)) paste0("height:", height, ";"),
style = if (!is.null(width)) paste0("width:", width, ";"),
style = "display: grid;",
style = col_style,
style = row_style,
style = sprintf("grid-column-gap: %s;", col_gap),
style = sprintf("grid-row-gap: %s;", row_gap),
content
)
}
#' Create a grid of ApexCharts
#'
#' @param ... Several \code{apexcharts} \code{htmlwidget} objects.
#' @param nrow,ncol Number of rows and columns.
#' @param row_gap,col_gap Gap between rows and columns.
#' @param grid_area Custom grid area to make elements take more than a single
#' cell in grid, see \url{https://cssgrid-generator.netlify.app/} for examples.
#' @param height,width Height and width of the main grid.
#' @param .list A list of \code{apexcharts} \code{htmlwidget} objects.
#'
#' @return Custom \code{apex_grid} object.
#'
#' @note You have to provide either height for the grid or individual chart height to make it work.
#'
#' @export
#'
#' @importFrom htmltools tags
#'
#' @example examples/apex_grid.R
apex_grid <- function(...,
nrow = NULL,
ncol = NULL,
row_gap = "10px",
col_gap = "0px",
grid_area = NULL,
height = NULL,
width = NULL,
.list = NULL) {
content <- c(list(...), .list)
if (!is.null(grid_area)) {
stopifnot(length(grid_area) == length(content))
content <- lapply(
X = seq_along(content),
FUN = function(i) {
tags$div(
style = paste0("grid-area:", grid_area[i]),
content[i]
)
}
)
}
grid <- list(
content = content,
nrow = nrow,
ncol = ncol,
col_gap = col_gap,
row_gap = row_gap,
height = height,
width = width
)
class(grid) <- c("apex_grid", class(grid))
return(grid)
}
# Shiny -------------------------------------------------------------------
#' @title Shiny bindings for grid with apexcharter
#'
#' @description Output and render functions for using apexcharter grid within Shiny
#' applications and interactive Rmd documents.
#'
#' @param outputId output variable to read from
#'
#' @return An Apexcharts output that can be included in the application UI.
#' @export
#'
#' @name apexcharter-shiny-grid
#'
#' @importFrom htmltools tagList
#' @importFrom shiny uiOutput
#' @importFrom htmlwidgets getDependency
#'
#' @example examples/grid-shiny.R
apexgridOutput <- function(outputId) {
tagList(
uiOutput(outputId = outputId),
getDependency(name = "apexcharter", package = "apexcharter")
)
}
#' @param expr An expression that generates a apexcharter grid.
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This
#' is useful if you want to save an expression in a variable.
#'
#' @export
#'
#' @rdname apexcharter-shiny-grid
#'
#' @importFrom shiny exprToFunction createRenderFunction createWebDependency
#' @importFrom htmltools renderTags resolveDependencies
renderApexgrid <- function(expr, env = parent.frame(), quoted = FALSE) { # nocov start
func <- exprToFunction(expr, env, quoted)
createRenderFunction(
func = func,
transform = function(result, shinysession, name, ...) {
if (is.null(result) || length(result) == 0)
return(NULL)
if (!inherits(result, "apex_grid")) {
stop(
"renderApexgrid: 'expr' must return an apexcharter grid object.",
call. = FALSE
)
}
TAG <- build_grid(
result$content,
nrow = result$nrow,
ncol = result$ncol,
col_gap = result$col_gap,
row_gap = result$row_gap,
height = result$height,
width = result$width
)
rendered <- renderTags(TAG)
deps <- lapply(
X = resolveDependencies(rendered$dependencies),
FUN = createWebDependency
)
list(
html = rendered$html,
deps = deps
)
}, apexgridOutput, list()
)
} # nocov end
# Print methods -----------------------------------------------------------
# nocov start
#' @export
print.apex_grid <- function(x, ...) {
TAG <- build_grid(
x$content,
nrow = x$nrow,
ncol = x$ncol,
col_gap = x$col_gap,
row_gap = x$row_gap,
height = x$height,
width = x$width
)
print(htmltools::browsable(TAG))
}
knit_print.apex_grid <- function(x, ..., options = NULL) {
TAG <- build_grid(
x$content,
nrow = x$nrow,
ncol = x$ncol,
col_gap = x$col_gap,
row_gap = x$row_gap,
height = x$height,
width = x$width
)
knitr::knit_print(htmltools::browsable(TAG), options = options, ...)
}
# nocov end

View File

@ -1,7 +1,7 @@
#' Modify axis, legend, and chart labels
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param title Text for the title.
#' @param subtitle Text for the subtitle.
#' @param x Text for the x-axis label.

138
R/mixed-charts.R Normal file
View File

@ -0,0 +1,138 @@
#' @title Add a line to a chart
#'
#' @description Add a line to an existing chart (bar, scatter and line types supported).
#' On scatter charts you can also add a smooth line.
#'
#' @template ax-default
#' @param mapping Default list of aesthetic mappings to use for chart.
#' @param data A \code{data.frame} to use to add a line, if \code{NULL} (default),
#' the \code{data.frame} provided in \code{apex()} will be used.
#' @param type Type of line.
#' @param serie_name Name for the serie displayed in tooltip and legend.
#'
#' @export
#'
#' @name add-line
#'
#' @example examples/mixed-charts.R
add_line <- function(ax,
mapping,
data = NULL,
type = c("line", "spline"),
serie_name = NULL) {
type <- match.arg(type)
if (!inherits(ax, "apex"))
stop("add_line: ax must have been created with apex() function.", call. = FALSE)
if (is.null(ax$x$mixed_type)) {
apex_type <- ax$x$ax_opts$chart$type
ax$x$mixed_type <- apex_type
} else {
apex_type <- ax$x$mixed_type
}
if (!isTRUE(apex_type %in% c("line", "bar", "scatter", "candlestick", "rangeArea")))
stop("add_line: apex() must be a column, scatter or candlestick chart.", call. = FALSE)
if (!identical(apex_type, "rangeArea"))
ax$x$ax_opts$chart$type <- "line"
if (is.null(data))
data <- ax$x$data
data <- as.data.frame(data)
mapdata <- lapply(mapping, rlang::eval_tidy, data = data)
ax$x$ax_opts$series <- c(
ax$x$ax_opts$series,
make_series(mapdata, mapping, type, serie_name, force_datetime_names = c("x", "y"))
)
ax$x$add_line <- list(
data = data,
mapping = mapping,
type = type,
serie_name = serie_name
)
if (identical(apex_type, "scatter")) {
if (is.null(ax$x$ax_opts$markers$size)) {
ax$x$ax_opts$markers$size <- c(6, 0)
} else {
ax$x$ax_opts$markers$size <- c(ax$x$ax_opts$markers$size, 0)
}
}
if (identical(apex_type, "bar")) {
if (is.null(ax$x$ax_opts$stroke$width)) {
ax$x$ax_opts$stroke$width <- c(0, 4)
} else {
ax$x$ax_opts$stroke$width <- c(ax$x$ax_opts$stroke$width, 4)
}
}
if (identical(apex_type, "candlestick")) {
if (is.null(ax$x$ax_opts$stroke$width)) {
ax$x$ax_opts$stroke$width <- c(1, 4)
} else {
ax$x$ax_opts$stroke$width <- c(ax$x$ax_opts$stroke$width, 4)
}
}
if (identical(type, "line")) {
ax$x$ax_opts$stroke$curve <- "straight"
} else if (identical(type, "spline")) {
ax$x$ax_opts$stroke$curve <- "smooth"
}
return(ax)
}
#' @param formula Formula passed to the \code{method}, default to \code{y ~ x} from main aesthetics.
#' @param model Model to use between \code{\link{lm}} or \code{\link{loess}}.
#' @param n Number of points used for predictions.
#' @param ... Arguments passed to \code{model}.
#'
#' @export
#'
#' @importFrom stats lm loess predict
#' @importFrom rlang !! sym
#'
#' @name add-line
add_smooth_line <- function(ax,
formula = y ~ x,
model = c("lm", "loess"),
n = 100,
...,
type = c("line", "spline"),
serie_name = NULL) {
model <- match.arg(model)
type <- match.arg(type)
if (!inherits(ax, "apex"))
stop("add_smooth_line: ax must have been created with apex() function.", call. = FALSE)
if (is.null(ax$x$mixed_type)) {
apex_type <- ax$x$ax_opts$chart$type
ax$x$mixed_type <- apex_type
} else {
apex_type <- ax$x$mixed_type
}
if (!isTRUE(apex_type %in% c("scatter")))
stop("add_smooth_line: apex() must be a scatter chart.", call. = FALSE)
ax$x$ax_opts$chart$type <- "line"
data <- as.data.frame(ax$x$data)
mapping <- ax$x$mapping
mapdata <- lapply(mapping, rlang::eval_tidy, data = data)
if (identical(model, "lm")) {
model_results <- lm(formula = formula, data = mapdata, ...)
} else if (identical(model, "loess")) {
model_results <- loess(formula = formula, data = mapdata, ...)
}
new_data <- data.frame(x = seq(
from = min(mapdata$x, na.rm = TRUE),
to = max(mapdata$x, na.rm = TRUE),
length.out = n
))
new_data$smooth <- predict(model_results, new_data)
add_line(
ax = ax,
mapping = aes(x = `!!`(sym("x")), y = `!!`(sym("smooth"))),
data = new_data,
type = type,
serie_name = serie_name
)
}

View File

@ -1,6 +1,6 @@
#' @importFrom shiny registerInputHandler
.onLoad <- function(...) {
.onLoad <- function(...) { # nocov start
shiny::registerInputHandler("apex_click", function(data, ...) {
if (is.null(data)) {
NULL
@ -15,7 +15,7 @@
}
return(value)
}
})
}, force = TRUE)
shiny::registerInputHandler("apex_datetime", function(data, ...) {
if (is.null(data)) {
NULL
@ -35,4 +35,6 @@
}
}
}, force = TRUE)
}
register_s3_method("knitr", "knit_print", "apex_facet")
register_s3_method("knitr", "knit_print", "apex_grid")
} # nocov end

View File

@ -31,10 +31,10 @@ parse_df <- function(data, add_names = FALSE) {
X = data[],
FUN = function(x) {
if (inherits(x, "Date")) {
# as.numeric(x) * 86400000
# format(x)
js_date(x)
# js_date(x)
as.numeric(x) * 1000 * 60*60*24
} else if (inherits(x, "POSIXt")) {
# js_date(x)
as.numeric(x) * 1000
} else if (inherits(x, "factor")) {
as.character(x)
@ -110,14 +110,54 @@ parse_timeline_data <- function(.list) {
}
parse_dumbbell_data <- function(.list) {
if (is.null(.list$group)) {
lapply(
X = seq_len(length(.list[[1]])),
FUN = function(i) {
val <- lapply(.list, `[[`, i)
l <- list(
x = as.character(val$y),
y = list(val$x, val$xend)
)
if (!is.null(val$fill)) {
l$fillColor <- val$fill
}
l
}
)
} else {
grouped <- as.data.frame(.list, stringsAsFactors = FALSE)
grouped$group <- NULL
grouped <- split(
x = grouped,
f = .list$group
)
grouped <- lapply(grouped, as.list)
lapply(
X = names(grouped),
FUN = function(name) {
list(
name = name,
data = parse_dumbbell_data(grouped[[name]])
)
}
)
}
}
parse_candlestick_data <- function(.list) {
list(list(
type = "candlestick",
data = lapply(
X = seq_len(length(.list[[1]])),
FUN = function(i) {
val <- lapply(.list, `[[`, i)
list(
x = js_date(val$x)[[1]],
# x = js_date(val$x)[[1]],
x = as.numeric(val$x) * 1000,
y = c(val$open, val$high, val$low, val$close)
)
}
@ -125,3 +165,30 @@ parse_candlestick_data <- function(.list) {
))
}
#' @importFrom graphics boxplot
parse_boxplot_data <- function(.list, serie_name = NULL) {
if (!is.numeric(.list$y) & is.numeric(.list$x)) {
.list[c("x", "y")] <- .list[c("y", "x")]
}
boxed <- boxplot(y ~ x, data = .list, plot = FALSE)
list(dropNulls(list(
serie_name = serie_name,
type = "boxPlot",
data = lapply(
X = seq_along(boxed$names),
FUN = function(i) {
list(
x = boxed$names[i],
y = c(
boxed$stats[1, i],
boxed$stats[2, i],
boxed$stats[3, i],
boxed$stats[4, i],
boxed$stats[5, i]
)
)
}
)
)))
}

102
R/proxy.R
View File

@ -1,28 +1,28 @@
#' @title Proxy for \code{apexchart}
#'
#'
#' @description Allow to update a chart in Shiny application.
#'
#' @param shinyId single-element character vector indicating the output ID of the
#' chart to modify (if invoked from a Shiny module, the namespace will be added
#' automatically)
#' @param session the Shiny session object to which the chart belongs; usually the
#' default value will suffice
#' default value will suffice
#'
#' @export
#'
#'
#' @importFrom shiny getDefaultReactiveDomain
#'
apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain()) {
if (is.null(session)) {
stop("apexchartProxy must be called from the server function of a Shiny app")
}
if (!is.null(session$ns) && nzchar(session$ns(NULL)) && substring(shinyId, 1, nchar(session$ns(""))) != session$ns("")) {
shinyId <- session$ns(shinyId)
}
structure(
list(
session = session,
@ -43,7 +43,7 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' @return A \code{apexchartProxy} \code{htmlwidget} object.
#' @noRd
.ax_proxy <- function(proxy, name, ...) {
if (!"apexchart_Proxy" %in% class(proxy))
if (!"apexchart_Proxy" %in% class(proxy))
stop("This function must be used with a apexchartProxy object", call. = FALSE)
proxy$session$sendCustomMessage(
type = sprintf("update-apexchart-%s", name),
@ -52,7 +52,7 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
proxy
}
.ax_proxy2 <- function(proxy, name, l) {
if (!"apexchart_Proxy" %in% class(proxy))
if (!"apexchart_Proxy" %in% class(proxy))
stop("This function must be used with a apexchartProxy object", call. = FALSE)
proxy$session$sendCustomMessage(
type = sprintf("update-apexchart-%s", name),
@ -64,9 +64,9 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' @title Proxy for updating series.
#'
#' @description Allows you to update the series array overriding the existing one.
#' @title Proxy for updating series.
#'
#' @description Allows you to update the series array overriding the existing one.
#'
#' @param proxy A \code{apexchartProxy} \code{htmlwidget} object.
#' @param newSeries The series array to override the existing one.
@ -75,10 +75,10 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' @export
#'
#' @examples
#'
#'
#' if (interactive()) {
#' library(shiny)
#'
#'
#' ui <- fluidPage(
#' fluidRow(
#' column(
@ -88,15 +88,15 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' )
#' )
#' )
#'
#'
#' server <- function(input, output, session) {
#'
#'
#' rv <- reactiveValues()
#' rv$df <- data.frame(
#' date = Sys.Date() + 1:20,
#' values = sample(10:90, 20, TRUE)
#' )
#'
#'
#' observe({
#' invalidateLater(1000, session)
#' df <- isolate(rv$df)
@ -109,17 +109,17 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' )
#' rv$df <- df
#' })
#'
#'
#' output$chart <- renderApexchart({
#' # Generate chart once
#' apex(isolate(rv$df), aes(date, values), "spline") %>%
#' apex(isolate(rv$df), aes(date, values), "spline") %>%
#' ax_xaxis(
#' range = 10 * 24 * 60 * 60 * 1000
#' # Fixed range for x-axis : 10 days
#' # days*hours*minutes*seconds*milliseconds
#' )
#' })
#'
#'
#' observe({
#' # Update chart to add new data
#' apexchartProxy("chart") %>%
@ -128,24 +128,24 @@ apexchartProxy <- function(shinyId, session = shiny::getDefaultReactiveDomain())
#' T
#' )
#' })
#'
#'
#' }
#'
#'
#' shinyApp(ui, server)
#' }
#'
#'
ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
.ax_proxy2(
proxy = proxy,
name = "series",
proxy = proxy,
name = "series",
l = list(newSeries = newSeries, animate = animate)
)
}
#' @title Proxy for updating options
#'
#' @title Proxy for updating options
#'
#' @description Allows you to update the configuration object.
#'
#' @param proxy A \code{apexchartProxy} \code{htmlwidget} object.
@ -153,11 +153,13 @@ ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
#'
#' @export
#'
#' @importFrom htmlwidgets JSEvals
#'
#' @examples
#'
#'
#' if (interactive()) {
#' library(shiny)
#'
#'
#' ui <- fluidPage(
#' fluidRow(
#' column(
@ -176,20 +178,20 @@ ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
#' )
#' )
#' server <- function(input, output, session) {
#'
#'
#' output$chart <- renderApexchart({
#' apexchart() %>%
#' ax_chart(type = "bar") %>%
#' ax_chart(type = "bar") %>%
#' ax_series(list(
#' name = "Example",
#' data = c(23, 43, 76, 31)
#' )) %>%
#' )) %>%
#' ax_xaxis(
#' categories = c("Label A", "Label B",
#' "Label C", "Label D")
#' )
#' })
#'
#'
#' observe({
#' apexchartProxy("chart") %>%
#' ax_proxy_options(list(
@ -201,19 +203,43 @@ ax_proxy_series <- function(proxy, newSeries, animate = TRUE) {
#' )
#' ))
#' })
#'
#'
#' }
#'
#'
#' shinyApp(ui, server)
#' }
#'
#'
ax_proxy_options <- function(proxy, options) {
.ax_proxy2(
proxy = proxy,
name = "options",
l = list(options = options)
proxy = proxy,
name = "options",
l = list(options = options, evals = JSEvals(options))
)
}
#' @title Toggle series with proxy
#'
#' @description This method allows you to toggle the visibility of series programmatically.
#' Useful when you have a custom legend.
#'
#' @param proxy A \code{apexchartProxy} \code{htmlwidget} object.
#' @param series_name The series name which you want to toggle visibility for.
#'
#' @noRd
#'
#' @example examples/proxy-toggle.R
ax_proxy_toggle_series <- function(proxy, series_name) {
.ax_proxy2(
proxy = proxy,
name = "toggle-series",
l = list(seriesName = list1(series_name))
)
}

View File

@ -8,7 +8,7 @@
#' with size > 0 and set tooltip's options `intersect = TRUE` and `shared = FALSE`.
#' * **scatter:** retrieve XY coordinates.
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param inputId The id that will be used server-side for retrieving click.
#' @param multiple Allow multiple selection: \code{TRUE} or \code{FALSE} (default).
#' @param effect_type Type of effect for selected element, default is to use lightly darken color.
@ -17,7 +17,6 @@
#'
#' @note If x-axis is of type datetime, value retrieved is of class \code{POSIXct}.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @importFrom shiny getDefaultReactiveDomain
@ -38,7 +37,7 @@
#' # Interactive examples:
#' if (interactive()) {
#'
#' run_input_demo("click")
#' run_demo_input("click")
#'
#' }
set_input_click <- function(ax, inputId, multiple = FALSE,
@ -67,13 +66,12 @@ set_input_click <- function(ax, inputId, multiple = FALSE,
#' Retrieve zoom information in Shiny
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param inputId The id that will be used server-side for retrieving zoom.
#' @param session The Shiny session.
#'
#' @note If x-axis is of type datetime, value retrieved is of class \code{POSIXct}.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @importFrom shiny getDefaultReactiveDomain
@ -81,7 +79,7 @@ set_input_click <- function(ax, inputId, multiple = FALSE,
#' @examples
#' if (interactive()) {
#'
#' run_input_demo("zoom")
#' run_demo_input("zoom")
#'
#' }
set_input_zoom <- function(ax, inputId,
@ -97,7 +95,7 @@ set_input_zoom <- function(ax, inputId,
#' Retrieve selection information in Shiny
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param inputId The id that will be used server-side for retrieving selection.
#' @param type Allow selection either on x-axis, y-axis or on both axis.
#' @param fill_color Background color of the selection rect which is drawn when user drags on the chart.
@ -111,7 +109,6 @@ set_input_zoom <- function(ax, inputId,
#' @param ymin,ymax Start value of y-axis. Both \code{min} and \code{max} must be provided.
#' @param session The Shiny session.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @examples
@ -131,11 +128,19 @@ set_input_zoom <- function(ax, inputId,
#' xmin = format_date("1980-01-01"),
#' xmax = format_date("1985-01-01")
#' )
set_input_selection <- function(ax, inputId, type = c("x", "xy", "y"),
fill_color = "#24292e", fill_opacity = 0.1,
stroke_width = 1, stroke_dasharray = 3,
stroke_color = "#24292e", stroke_opacity = 0.4,
xmin = NULL, xmax = NULL, ymin = NULL, ymax = NULL,
set_input_selection <- function(ax,
inputId,
type = c("x", "xy", "y"),
fill_color = "#24292e",
fill_opacity = 0.1,
stroke_width = 1,
stroke_dasharray = 3,
stroke_color = "#24292e",
stroke_opacity = 0.4,
xmin = NULL,
xmax = NULL,
ymin = NULL,
ymax = NULL,
session = shiny::getDefaultReactiveDomain()) {
type <- match.arg(type)
if (is.null(session))
@ -169,6 +174,34 @@ set_input_selection <- function(ax, inputId, type = c("x", "xy", "y"),
#' Retrieve chart's base64 dataURI.
#'
#' @template ax-default
#' @param inputId The id that will be used server-side for retrieving data.
#' @param session The Shiny session.
#'
#' @export
#'
#' @example examples/export-2.R
set_input_export <- function(ax, inputId,
session = shiny::getDefaultReactiveDomain()) { # nocov start
if (is.null(session))
session <- list(ns = identity)
ax$x$shinyEvents$export <- list(
inputId = session$ns(inputId)
)
ax
} # nocov end
# Demo --------------------------------------------------------------------
# nocov start
#' Run Shiny input events examples
#'
#' @param example Name of the example.
@ -180,15 +213,15 @@ set_input_selection <- function(ax, inputId, type = c("x", "xy", "y"),
#' @examples
#' if (interactive()) {
#'
#' run_input_demo("click")
#' run_input_demo("zoom")
#' run_input_demo("selection")
#' run_demo_input("click")
#' run_demo_input("zoom")
#' run_demo_input("selection")
#'
#' }
run_input_demo <- function(example = c("click", "zoom", "selection")) {
run_demo_input <- function(example = c("click", "zoom", "selection")) {
example <- match.arg(example)
shiny::shinyAppFile(
appFile = system.file("examples-input", example, "app.R", package = "apexcharter"),
appFile = system.file("examples/input", example, "app.R", package = "apexcharter"),
options = list("display.mode" = "showcase")
)
}
@ -205,12 +238,12 @@ run_input_demo <- function(example = c("click", "zoom", "selection")) {
#' @examples
#' if (interactive()) {
#'
#' run_sync_demo()
#' run_demo_sync()
#'
#' }
run_sync_demo <- function() {
run_demo_sync <- function() {
shiny::shinyAppFile(
appFile = system.file("example-sync", "app.R", package = "apexcharter"),
appFile = system.file("examples/sync", "app.R", package = "apexcharter"),
options = list("display.mode" = "showcase")
)
}
@ -225,13 +258,14 @@ run_sync_demo <- function() {
#' @examples
#' if (interactive()) {
#'
#' run_sparkbox_demo()
#' run_demo_sparkbox()
#'
#' }
run_sparkbox_demo <- function() {
run_demo_sparkbox <- function() {
shiny::shinyAppFile(
appFile = system.file("example-spark", "app.R", package = "apexcharter"),
appFile = system.file("examples/spark", "app.R", package = "apexcharter"),
options = list("display.mode" = "showcase")
)
}
# nocov end

View File

@ -103,14 +103,14 @@ spark_box <- function(data,
#' @rdname apexcharter-shiny
#' @export
sparkBoxOutput <- function(outputId, width = "100%", height = "160px"){
sparkBoxOutput <- function(outputId, width = "100%", height = "160px") { # nocov start
htmlwidgets::shinyWidgetOutput(outputId, "apexcharter", width, height, package = "apexcharter")
}
} # nocov end
#' @rdname apexcharter-shiny
#' @export
renderSparkBox <- function(expr, env = parent.frame(), quoted = FALSE) {
renderSparkBox <- function(expr, env = parent.frame(), quoted = FALSE) { # nocov start
if (!quoted) { expr <- substitute(expr) } # force quoted
htmlwidgets::shinyRenderWidget(expr, apexchartOutput, env, quoted = TRUE)
}
} # nocov end

View File

@ -1,13 +1,12 @@
#' Fix tooltip
#' Fixed tooltip
#'
#' @param ax An \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param position Predefined position: \code{"topLeft"}, \code{"topRight"},
#' \code{"bottomLeft"} or \code{"bottomRight"}.
#' @param offsetX Sets the left offset for the tooltip container in fixed position.
#' @param offsetY Sets the top offset for the tooltip container in fixed position.
#'
#' @return An \code{apexcharts} \code{htmlwidget} object.
#' @export
#'
#' @example examples/set_tooltip_fixed.R

View File

@ -5,17 +5,16 @@ null_or_empty <- function(x) {
dropNullsOrEmpty <- function(x) {
x[!vapply(x, null_or_empty, FUN.VALUE = logical(1))]
clss <- class(x)
x <- x[!vapply(x, null_or_empty, FUN.VALUE = logical(1))]
class(x) <- clss
return(x)
}
dropNulls <- function(x) {
x[!vapply(x, is.null, FUN.VALUE = logical(1))]
}
`%||%` <- function(x, y) {
if (!is.null(x)) x else y
}
formatNoSci <- function(x) {
if (is.null(x)) return(NULL)
format(x, scientific = FALSE, digits = 15)
@ -42,54 +41,65 @@ to_posix <- function(x) {
}
to_hyphen <- function(x) {
tolower(gsub("([A-Z])", "-\\1", x))
}
make_styles <- function(styles) {
styles <- dropNulls(styles)
if (length(styles) < 1)
return(NULL)
styles <- sprintf("%s: %s;", to_hyphen(names(styles)), unlist(styles, use.names = FALSE))
paste(styles, collapse = " ")
}
#' Utility function to create ApexChart parameters JSON
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param name Slot's name to edit
#' @param ... Arguments for the slot
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#'
#' @importFrom utils modifyList
#'
#' @noRd
.ax_opt <- function(ax, name, ...) {
if (is.null(ax$x$ax_opts[[name]])) {
ax$x$ax_opts[[name]] <- list(...)
} else {
ax$x$ax_opts[[name]] <- utils::modifyList(
x = ax$x$ax_opts[[name]],
val = list(...),
ax$x$ax_opts[[name]] <- modifyList(
x = ax$x$ax_opts[[name]],
val = list(...),
keep.null = TRUE
)
}
ax$x$ax_opts[[name]] <- dropNullsOrEmpty(ax$x$ax_opts[[name]])
return(ax)
}
#' Utility function to create ApexChart parameters JSON
#'
#' @param ax A \code{apexcharts} \code{htmlwidget} object.
#' @template ax-default
#' @param name Slot's name to edit
#' @param l List of arguments for the slot
#'
#' @return A \code{apexcharts} \code{htmlwidget} object.
#' @importFrom utils modifyList
#'
#' @noRd
.ax_opt2 <- function(ax, name, l) {
if (is.null(ax$x$ax_opts[[name]])) {
ax$x$ax_opts[[name]] <- l
} else {
ax$x$ax_opts[[name]] <- utils::modifyList(
x = ax$x$ax_opts[[name]],
val = l,
ax$x$ax_opts[[name]] <- modifyList(
x = ax$x$ax_opts[[name]],
val = l,
keep.null = TRUE
)
}
ax$x$ax_opts[[name]] <- dropNullsOrEmpty(ax$x$ax_opts[[name]])
return(ax)
}
@ -100,4 +110,29 @@ to_posix <- function(x) {
# From vignette('knit_print', package = 'knitr')
# and https://github.com/rstudio/htmltools/pull/108/files
register_s3_method <- function(pkg, generic, class, fun = NULL) { # nocov start
stopifnot(is.character(pkg), length(pkg) == 1)
stopifnot(is.character(generic), length(generic) == 1)
stopifnot(is.character(class), length(class) == 1)
if (is.null(fun)) {
fun <- get(paste0(generic, ".", class), envir = parent.frame())
} else {
stopifnot(is.function(fun))
}
if (pkg %in% loadedNamespaces()) {
registerS3method(generic, class, fun, envir = asNamespace(pkg))
}
# Always register hook in case package is later unloaded & reloaded
setHook(
packageEvent(pkg, "onLoad"),
function(...) {
registerS3method(generic, class, fun, envir = asNamespace(pkg))
}
)
} # nocov end

View File

@ -1,33 +1,28 @@
# apexcharter
> Htmlwidget for [apexcharts.js](https://github.com/apexcharts/apexcharts.js) : A modern JavaScript charting library to build interactive charts and visualizations with simple API. See the [online demo](https://dreamrs.github.io/apexcharter) for examples.
> Htmlwidget for [apexcharts.js](https://github.com/apexcharts/apexcharts.js) : A modern JavaScript charting library to build interactive charts and visualizations with simple API. See the [online documentation](https://dreamrs.github.io/apexcharter/) for examples.
<!-- badges: start -->
[![version](http://www.r-pkg.org/badges/version/apexcharter)](https://CRAN.R-project.org/package=apexcharter)
[![cran checks](https://cranchecks.info/badges/worst/apexcharter)](https://cranchecks.info/pkgs/apexcharter)
[![Travis build status](https://travis-ci.org/dreamRs/apexcharter.svg?branch=master)](https://travis-ci.org/dreamRs/apexcharter)
[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://www.tidyverse.org/lifecycle/#maturing)
[![R build status](https://github.com/dreamRs/apexcharter/workflows/R-CMD-check/badge.svg)](https://github.com/dreamRs/apexcharter/actions)
[![CRAN status](https://www.r-pkg.org/badges/version/apexcharter)](https://CRAN.R-project.org/package=apexcharter)
[![cran checks](https://badges.cranchecks.info/worst/apexcharter.svg)](https://cran.r-project.org/web/checks/check_results_apexcharter.html)
[![Codecov test coverage](https://codecov.io/gh/dreamRs/apexcharter/branch/master/graph/badge.svg)](https://app.codecov.io/gh/dreamRs/apexcharter?branch=master)
[![R-CMD-check](https://github.com/dreamRs/apexcharter/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/dreamRs/apexcharter/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->
:warning: Use RStudio >= 1.2 to properly display charts
## Installation
Install from CRAN with:
Install from [CRAN](https://CRAN.R-project.org/package=apexcharter) with:
```r
install.packages("apexcharter")
```
Or install the development version from [GitHub](https://github.com/) with:
Or install the development version from [GitHub](https://github.com/dreamRs/apexcharter) with:
``` r
# install.packages("devtools")
devtools::install_github("dreamRs/apexcharter")
```r
# install.packages("remotes")
remotes::install_github("dreamRs/apexcharter")
```
@ -39,11 +34,8 @@ Use `apex` function to quickly create visualizations :
```r
library(apexcharter)
data("mpg", package = "ggplot2")
n_manufac <- dplyr::count(mpg, manufacturer)
apex(data = n_manufac, type = "bar", mapping = aes(x = manufacturer, y = n))
apex(data = mpg, type = "bar", mapping = aes(manufacturer))
```
![](man/figures/apex-bar.png)
@ -65,7 +57,6 @@ All methods from ApexCharts are available with function like `ax_*` compatible w
```r
library(apexcharter)
data(mpg, package = "ggplot2")
n_manufac <- dplyr::count(mpg, manufacturer)
apexchart() %>%
ax_chart(type = "bar") %>%
@ -84,10 +75,10 @@ apexchart() %>%
) %>%
ax_series(list(
name = "Count",
data = n_manufac$n
data = tapply(mpg$manufacturer, mpg$manufacturer, length)
)) %>%
ax_colors("#112446") %>%
ax_xaxis(categories = n_manufac$manufacturer) %>%
ax_xaxis(categories = unique(mpg$manufacturer)) %>%
ax_title(text = "Number of models") %>%
ax_subtitle(text = "Data from ggplot2")
```
@ -146,3 +137,27 @@ apexchart(ax_opts = list(
![](man/figures/raw-api.png)
## Development
This package use [{packer}](https://github.com/JohnCoene/packer) to manage JavaScript assets, see packer's [documentation](https://packer.john-coene.com/#/) for more.
Install nodes modules with:
```r
packer::npm_install()
```
Modify `srcjs/widgets/apexcharter.js`, then run:
```r
packer::bundle()
```
Re-install R package and try `apexcharter()` or `apex()` functions.

View File

@ -1,9 +1,17 @@
url: https://dreamrs.github.io/apexcharter/
template:
package: dreamRs
toc:
depth: 3
bootstrap: 5
bootswatch: zephyr
bslib:
base_font: {google: "Poppins"}
primary: "#112446"
navbar-dark-color: "#FFFFFF"
secondary: "#DFDFDF"
navbar-dark-active-color: "#DFDFDF"
navbar:
bg: primary
authors:
Victor Perrier:

14
codecov.yml Normal file
View File

@ -0,0 +1,14 @@
comment: false
coverage:
status:
project:
default:
target: auto
threshold: 1%
informational: true
patch:
default:
target: auto
threshold: 1%
informational: true

View File

@ -1,14 +1,13 @@
## Test environments
* local OS Widows 10 install, R 3.6.3
* ubuntu 14.04 (on travis-ci), R 3.6.3
* local Ubuntu 22.04 install, R 4.2.2
* ubuntu 22.04, Windows 10, macOS (on GitHub Actions), R 4.2.2
* win-builder (devel and release)
## R CMD check results
0 errors | 0 warnings | 0 note
* New features and updated javascript dependencies
Updated JavaScript dependencies and new features.
Thank you!
Victor

119
data-raw/climate-paris.R Normal file
View File

@ -0,0 +1,119 @@
# ------------------------------------------------------------------------
#
# Title : Paris climate
# By : Victor
# Date : 2020-07-24
#
# ------------------------------------------------------------------------
# Packages ----------------------------------------------------------------
library(rvest)
library(data.table)
library(janitor)
# Data --------------------------------------------------------------------
tables_list <- read_html(x = "https://fr.wikipedia.org/wiki/Climat_de_Paris") %>%
html_table(fill = TRUE)
# Temperature
temperature <- tables_list[[1]]
setDT(temperature)
setnames(temperature, make_clean_names)
temperature <- temperature[periode == "1971-2000" & mois == "Température moyenne (°C)"]
temperature[, periode := NULL]
temperature[, annee := NULL]
temperature[, mois := NULL]
setnames(temperature, month.abb)
t_data <- melt(
data = temperature,
measure.vars = names(temperature),
variable.name = "month",
value.name = "temperature",
variable.factor = FALSE
)
t_data[, temperature := type.convert(temperature, dec = ",")]
t_data
# Precipitation
precipitation <- tables_list[[3]]
setDT(precipitation)
setnames(precipitation, make_clean_names)
precipitation <- precipitation[periode == "1971-2000" & mois == "Précipitations (mm)"]
precipitation[, periode := NULL]
precipitation[, annee := NULL]
precipitation[, mois := NULL]
setnames(precipitation, month.abb)
p_data <- melt(
data = precipitation,
measure.vars = names(precipitation),
variable.name = "month",
value.name = "precipitation",
variable.factor = FALSE
)
p_data[, precipitation := type.convert(precipitation, dec = ",")]
p_data
climate_paris <- merge(t_data, p_data, by = "month", sort = FALSE)
climate_paris
climate_paris <- as.data.frame(climate_paris)
usethis::use_data(climate_paris, overwrite = TRUE)
# Test chart --------------------------------------------------------------
library(apexcharter)
ax <- apex(climate_paris, aes(month, precipitation), type = "column", serie_name = "Precipitation")
ax$x$ax_opts$series <- c(
ax$x$ax_opts$series,
list(list(
name = "Temperature",
type = "line",
data = parse_df(climate_paris[, list(month, temperature)], add_names = c("x", "y"))
))
)
ax %>%
ax_chart(type = "line") %>%
ax_markers(size = c(6, 0)) %>%
ax_stroke(width = c(0, 4)) %>%
ax_yaxis(
title = list(text = "Precipitation (in mm)")
) %>%
ax_yaxis2(
opposite = TRUE,
decimalsInFloat = 0,
title = list(text = "Temperature (in degree celsius)")
) %>%
ax_dataLabels(
enabled = TRUE, enabledOnSeries = list(1)
)
apex(climate_paris, aes(month, precipitation), type = "column", serie_name = "Precipitation") %>%
add_line(aes(month, temperature), serie_name = "Temperature")
apex(climate_paris, aes(month, precipitation), type = "column", serie_name = "Precipitation") %>%
add_line(aes(month, temperature), data = climate_paris, serie_name = "Temperature") %>%
add_line(aes(month, temperature + 5), data = climate_paris, serie_name = "Temperature 2")

131
data-raw/eco2mix.R Normal file
View File

@ -0,0 +1,131 @@
# ------------------------------------------------------------------------
#
# eCO2mix data
# https://www.rte-france.com/eco2mix
#
# ------------------------------------------------------------------------
# Packages ----------------------------------------------------------------
library(data.table)
library(fasttime)
complete <- function(data, vars, fill = list()) {
data <- data[do.call(CJ, c(
lapply(
X = mget(vars),
FUN = function(var) {
if (inherits(var, "factor")) {
if (anyNA(var)) {
factor(c(levels(var), NA_character_), levels = levels(var), ordered = is.ordered(var))
} else {
factor(levels(var), levels = levels(var), ordered = is.ordered(var))
}
} else {
unique(var)
}
}
),
list(sorted = FALSE)
)), on = vars]
if (length(fill) > 0 && all(nzchar(names(fill)))) {
for (fillvar in names(fill)) {
data[is.na(get(fillvar)), (fillvar) := fill[[fillvar]]]
}
}
data[]
}
# Download data -----------------------------------------------------------
# Source: https://odre.opendatasoft.com/explore/dataset/eco2mix-national-cons-def/
# and https://odre.opendatasoft.com/explore/dataset/eco2mix-national-tr
# Read & transform data ---------------------------------------------------
# eco2mix <- fread(file = "data-raw/inputs/eco2mix-national-cons-def.csv")
# eco2mix <- eco2mix[, c(5, 6, 9:17)]
# setnames(eco2mix, c("datetime", "consumption", "fuel", "coal", "gas", "nuclear", "wind", "solar", "hydraulic", "pumping", "bioenergies"))
eco2mix_tr <- fread(file = "data-raw/inputs/eco2mix-national-tr.csv")
eco2mix_tr <- eco2mix_tr[, c(5, 6, 9:17)]
setnames(eco2mix_tr, c("datetime", "consumption", "fuel", "coal", "gas", "nuclear", "wind", "solar", "hydraulic", "pumping", "bioenergies"))
eco2mix <- copy(eco2mix_tr)
# eco2mix <- rbind(eco2mix, eco2mix_tr)
eco2mix <- eco2mix[!is.na(consumption)]
eco2mix[, consumption := NULL]
# eco2mix[, date := as.Date(format(datetime, format = "%Y-%m-%d"))]
# eco2mix[, datetime := NULL]
# setcolorder(eco2mix, "date")
eco2mix <- eco2mix[minute(datetime) != 15]
eco2mix <- eco2mix[minute(datetime) != 45]
eco2mix <- eco2mix[datetime >= (max(datetime) - 24*60*60*7)]
eco2mix <- melt(
data = eco2mix,
id.vars = 1,
variable.name = "source",
value.name = "production",
na.rm = TRUE,
variable.factor = FALSE
)
eco2mix <- eco2mix[, list(production = round(mean(production))), by = list(datetime, source)]
eco2mix[, source := factor(
x = source,
levels = c("pumping", "wind", "solar", "nuclear", "hydraulic", "gas", "coal", "fuel", "bioenergies"),
ordered = TRUE
)]
eco2mix <- complete(eco2mix, c("datetime", "source"), list(production = 0))
setorder(eco2mix, source, datetime)
eco2mix[]
# Use data ----------------------------------------------------------------
setDF(eco2mix)
usethis::use_data(eco2mix, internal = FALSE, overwrite = TRUE, compress = "xz")
# Test example ------------------------------------------------------------
apex(eco2mix[source == "consumption"], aes(date, production), type = "line")
# data("eco2mix", package = "apexcharter")
apex(eco2mix, aes(datetime, production, fill = source), type = "area") %>%
ax_chart(animations = list(enabled = FALSE), stacked = TRUE) %>%
ax_stroke(width = 1) %>%
ax_fill(opacity = 1, type = "solid") %>%
ax_tooltip(x = list(format = "dd MMM, HH:mm")) %>%
ax_yaxis(labels = list(formatter = format_num("~", suffix = "MW"))) %>%
ax_colors_manual(
list(
"bioenergies" = "#156956",
"fuel" = "#80549f",
"coal" = "#a68832",
"solar" = "#d66b0d",
"gas" = "#f20809",
"wind" = "#72cbb7",
"hydraulic" = "#2672b0",
"nuclear" = "#e4a701",
"pumping" = "#0e4269"
)
) %>%
ax_labs(
title = "Electricity generation by sector in France",
subtitle = "Data from \u00e9CO\u2082mix"
)

View File

@ -0,0 +1,68 @@
# Package -----------------------------------------------------------------
library(data.table)
library(gapminder)
# Data --------------------------------------------------------------------
life_expec_long <- as.data.table(gapminder::gapminder)
life_expec_long <- life_expec_long[year %in% c(1972, 2007), list(country, year, lifeExp)]
# life_expec <- life_expec[country %in% sample(unique(country), 10)]
life_expec_long <- life_expec_long[country %in% c("Botswana", "Ghana", "Iran", "Liberia", "Malaysia", "Mexico",
"Nigeria", "Pakistan", "Philippines", "Zambia")]
life_expec_long[, country := as.character(country)]
life_expec <- dcast(life_expec_long, country ~ year, value.var = "lifeExp")
life_expec[, type := fifelse(`1972` > `2007`, "decreased", "increased")]
# Use data ----------------------------------------------------------------
setDF(life_expec)
usethis::use_data(life_expec, internal = FALSE, overwrite = TRUE, compress = "xz")
setDF(life_expec_long)
usethis::use_data(life_expec_long, internal = FALSE, overwrite = TRUE, compress = "xz")
# Test example ------------------------------------------------------------
pkgload::load_all()
apex(life_expec, aes(country, x = `1972`, xend = `2007`), type = "dumbbell") %>%
ax_plotOptions(
bar = bar_opts(
dumbbellColors = list(list("#3d85c6", "#fb6003"))
)
) %>%
ax_colors("#BABABA") %>%
ax_labs(
title = "Life expectancy : 1972 vs. 2007",
subtitle = "Data from Gapminder dataset",
x = "Life expectancy at birth, in years"
)
apex(life_expec, aes(country, x = `1972`, xend = `2007`, group = type), type = "dumbbell") %>%
ax_xaxis(type = "category", categories = unique(life_expec$country)) %>%
ax_plotOptions(
bar = bar_opts(
dumbbellColors = list(list("#3d85c6", "#fb6003"), list("#3d85c6", "#fb6003"))
)
) %>%
ax_colors(c("#3d85c6", "#fb6003")) %>%
ax_labs(
title = "Life expectancy : 1972 vs. 2007",
subtitle = "Data from Gapminder dataset",
x = "Life expectancy at birth, in years"
)

63
data-raw/temperature.R Normal file
View File

@ -0,0 +1,63 @@
# ------------------------------------------------------------------------
#
# temperature data for France
# https://data.enedis.fr/explore/dataset/donnees-de-temperature-et-de-pseudo-rayonnement
#
# ------------------------------------------------------------------------
# Packages ----------------------------------------------------------------
library(data.table)
library(fasttime)
# Data --------------------------------------------------------------------
temperatures <- fread(file = "data-raw/inputs/donnees-de-temperature-et-de-pseudo-rayonnement.csv")
temperatures <- temperatures[, c(6, 7, 8, 2)]
setnames(temperatures, c("year", "month", "day", "temperature"))
temperatures <- temperatures[year > 2017]
temperatures <- temperatures[, list(temperature = round(mean(temperature, na.rm = TRUE), 1)), by = c("year", "month", "day")]
temperatures <- dcast(data = temperatures, formula = month + day ~ year, value.var = "temperature")
temperatures <- temperatures[!(month == 2 & day == 29)]
temperatures[, low := do.call(pmin, c(as.list(.SD), na.rm = TRUE)), .SDcols = as.character(2018:2021)]
temperatures[, high := do.call(pmax, c(as.list(.SD), na.rm = TRUE)), .SDcols = as.character(2018:2021)]
temperatures[, average := rowMeans(.SD, na.rm = TRUE), .SDcols = as.character(2018:2021)]
temperatures[, (as.character(2018:2021)) := NULL]
# setnames(temperatures, "2022", "temperature")
temperatures[, date := as.Date("2022-01-01") + (seq_len(.N) - 1)]
temperatures[, (c("month", "day")) := NULL]
setcolorder(temperatures, "date")
temperatures[]
# Save --------------------------------------------------------------------
setDF(temperatures)
usethis::use_data(temperatures, internal = FALSE, overwrite = TRUE, compress = "xz")
# Test example ------------------------------------------------------------
pkgload::load_all()
apex(temperatures, aes(x = date, ymin = low, ymax = high), type = "rangeArea", serie_name = "Low/High (2018-2021)") %>%
add_line(aes(date, `2023`)) %>%
ax_chart(animations = list(enabled = FALSE)) %>%
ax_yaxis(tickAmount = 7, labels = list(formatter = format_num("~", suffix = "°C"))) %>%
ax_colors(c("#8485854D", "#FF0000")) %>%
ax_stroke(width = c(1, 2)) %>%
ax_fill(opacity = 1, type = "solid") %>%
ax_labs(
title = "Temperatures in 2023 with range from 2018 to 2021",
subtitle = "Data from ENEDIS"
)

BIN
data/climate_paris.rda Normal file

Binary file not shown.

BIN
data/eco2mix.rda Normal file

Binary file not shown.

BIN
data/life_expec.rda Normal file

Binary file not shown.

BIN
data/life_expec_long.rda Normal file

Binary file not shown.

BIN
data/temperatures.rda Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,120 +0,0 @@
# Parsing options ---------------------------------------------------------
cx <- V8::v8()
cx$source(file = "inst/htmlwidgets/lib/apexcharts-1.0.4/Options.js")
ApexOpts <- cx$get("Options")
names(ApexOpts)
str(ApexOpts$chart, max.level = 1)
str(ApexOpts$chart$animations, max.level = 1)
# Utils -------------------------------------------------------------------
make_fun <- function(opts, name, file = "") {
args <- names(opts[[name]])
if (is.null(args)) {
args <- "..."
} else {
args <- sprintf("%s = NULL", args)
args <- paste(args, collapse = ",\n")
args <- paste0(args, ", ...")
}
body <- paste(
"\nparams <- c(as.list(environment()), list(...))[-1]",
paste0(".ax_opt2(ax, \"", name, "\", l = dropNulls(params))\n"),
sep = "\n"
)
res <- paste0("ax_", name, " <- function(ax, ", args, ") {", body, "}\n\n\n")
cat(res, file = file, append = TRUE)
return(invisible(res))
}
make_opts <- function(opts, name, file = "") {
args <- names(opts[[name]])
if (is.null(args)) {
args <- "..."
body <- "list(...)"
} else {
body <- sprintf("%s = %s", args, args)
body <- paste(body, collapse = ",\n")
body <- paste0("c(list(", body, "), list(...))")
args <- sprintf("%s = NULL", args)
args <- paste(args, collapse = ",\n")
args <- paste0(args, ", ...")
}
body <- paste0("dropNulls(", body, ")")
res <- paste0(name, "Opts", " <- function(", args, ") {", body, "}\n\n\n")
cat(res, file = file, append = TRUE)
return(invisible(res))
}
# chart -------------------------------------------------------------------
make_fun(ApexOpts, "chart")
# plotOptions -------------------------------------------------------------
make_fun(ApexOpts, "plotOptions")
# ALL ---------------------------------------------------------------------
lapply(
X = names(ApexOpts),
FUN = make_fun, opts = ApexOpts, file = "R/apex-utils.R"
)
# Options -----------------------------------------------------------------
# scroller
str(ApexOpts$chart$scroller)
make_opts(ApexOpts$chart, "scroller")
# plotOptions -- bar
make_opts(ApexOpts$plotOptions, "bar")
### write funs
# chart
str(ApexOpts$chart, max.level = 1)
make_opts(ApexOpts$chart, "scroller", file = "R/apex-options.R")
make_opts(ApexOpts$chart, "events", file = "R/apex-options.R")
make_opts(ApexOpts$chart, "selection", file = "R/apex-options.R")
# plotOptions
str(ApexOpts$plotOptions, max.level = 1)
make_opts(ApexOpts$plotOptions, "bar", file = "R/apex-options.R")
make_opts(ApexOpts$plotOptions, "heatmap", file = "R/apex-options.R")
make_opts(ApexOpts$plotOptions, "radialBar", file = "R/apex-options.R")
make_opts(ApexOpts$plotOptions, "pie", file = "R/apex-options.R")

View File

@ -1,96 +0,0 @@
# apexcharts.js raw api ---------------------------------------------------
library(apexcharter)
library(ggplot2) # for data
library(dplyr)
# bar ----
data(mpg)
dat <- count(mpg, manufacturer)
apexchart(ax_opts = list(
chart = list(type = "bar"),
plotOptions = list(
bar = list(
horizontal = FALSE,
endingShape = "flat",
columnWidth = "70%",
dataLabels = list(
position = "top"
)
)
),
colors = list("#112446"),
grid = list(
show = TRUE,
position = "front"
),
series = list(list(
name = "Count",
data = dat$n
)),
xaxis = list(categories = dat$manufacturer)
))
# line ----
# recreating (mostly): https://apexcharts.com/javascript-chart-demos/line-charts/data-labels/
apexchart(ax_opts = list(
chart = list(
type = "line"
),
stroke = list(
curve = "smooth"
),
grid = list(
borderColor = "#e7e7e7",
row = list(
colors = c("#f3f3f3", "transparent"),
opacity = 0.5
)
),
dataLabels = list(
enabled = TRUE
),
markers = list(style = "inverted", size = 6),
series = list(
list(
name = "High",
data = c(28, 29, 33, 36, 32, 32, 33)
),
list(
name = "Low",
data = c(12, 11, 14, 18, 17, 13, 13)
)
),
title = list(
text = "Average High & Low Temperature",
align = "left"
),
xaxis = list(
categories = month.abb[1:7]
),
yaxis = list(
title = list(text = "Temperature"),
labels = list(
formatter = htmlwidgets::JS("function(value) {return value + \'\u00b0C\';}")
)
)
))

View File

@ -1,259 +0,0 @@
<!-- Generated by pkgdown: do not edit by hand -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page not found (404) • apexcharter</title>
<!-- jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<!-- Bootstrap -->
<link href="css/theme.css" rel="stylesheet">
<style>
#pkgdown-sidebar {
z-index: 100;
background: #FFF;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-nuL8/2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL+1ev4=" crossorigin="anonymous"></script>
<!-- Font -->
<link href="css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- bootstrap-toc -->
<link rel="stylesheet" href="bootstrap-toc.css">
<script src="bootstrap-toc.js"></script>
<!-- Font Awesome icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous" />
<!-- clipboard.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script>
<!-- headroom.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script>
<!-- pkgdown -->
<link href="pkgdown.css" rel="stylesheet">
<script src="pkgdown.js"></script>
<!-- Particles -->
<script src="js/particles.min.js"></script>
<style>
html,
body {
margin: 0;
padding: 0;
}
.contents {
opacity: 1;
background-color: #FFF;
z-index: 1;
}
#sidebar {
opacity: 1;
background-color: #FFF;
z-index: 1;
}
footer {
z-index: 1;
}
#particles {
position: fixed;
display: block;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 0;
}
.background {
position: absolute;
display: block;
top: 0;
left: 0;
z-index: 0;
}
</style>
<!-- Font Awesome icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css" integrity="sha256-nAmazAk6vS34Xqo0BSrTb+abbtFlgsFK7NKSi6o7Y78=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/v4-shims.min.css" integrity="sha256-6qHlizsOWFskGlwVOKuns+D1nB6ssZrHQrNj1wGplHc=" crossorigin="anonymous" />
<!-- clipboard.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.4/clipboard.min.js" integrity="sha256-FiZwavyI2V6+EXO1U+xzLG3IKldpiTFf3153ea9zikQ=" crossorigin="anonymous"></script>
<!-- headroom.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.4/headroom.min.js" integrity="sha256-DJFC1kqIhelURkuza0AvYal5RxMtpzLjFhsnVIeuk+U=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.4/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script>
<!-- pkgdown -->
<link href="pkgdown.css" rel="stylesheet">
<script src="pkgdown.js"></script>
<meta property="og:title" content="Page not found (404)" />
<!-- mathjax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body id="body">
<div class="container template-title-body">
<header>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand hidden-xs hidden-sm" style="padding: 10px 15px !important;">
<img src="https://github.com/dreamRs.png" class="hidden-xs hidden-sm" style="height: 50px;display: inline;vertical-align: middle;">
<a class="navbar-link" href="index.html">apexcharter</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Released version">0.1.4.960</span>
</span>
<span class="navbar-brand hidden-md hidden-lg">
<a class="navbar-link" href="index.html">apexcharter</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Released version">0.1.4.960</span>
</span>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>
<a href="index.html">
<span class="fas fa fas fa-home fa-lg"></span>
</a>
</li>
<li>
<a href="articles/apexcharter.html">Get started</a>
</li>
<li>
<a href="reference/index.html">Reference</a>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
Articles
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="articles/articles/advanced-configuration.html">Advanced configuration examples</a>
</li>
<li>
<a href="articles/chart-options.html">Chart options</a>
</li>
<li>
<a href="articles/shiny-integration.html">Shiny integration</a>
</li>
<li>
<a href="articles/spark-box.html">Spark boxes</a>
</li>
<li>
<a href="articles/sync-charts.html">Syncing charts</a>
</li>
</ul>
</li>
<li>
<a href="news/index.html">Changelog</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://github.com/dreamRs/apexcharter/">
<span class="fab fa fab fa-github fa-lg"></span>
</a>
</li>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container -->
</div><!--/.navbar -->
</header>
<div class="row">
<div class="contents col-md-9">
<div class="page-header">
<h1>Page not found (404)</h1>
</div>
Content not found. Please use links in the navbar.
</div>
</div>
<footer>
<div class="copyright">
<p>Developed by <a href='https://twitter.com/_pvictorr'><img src="https://pbs.twimg.com/profile_images/844237339404722177/E1U61aM8_normal.jpg"/> Victor Perrier</a>, <a href='https://twitter.com/_mfaan'><img src="https://pbs.twimg.com/profile_images/912313931326218240/o1-wvA18_normal.jpg" /> Fanny Meyer</a>.</p>
</div>
<div class="pkgdown">
<p>Site built with <a href="https://pkgdown.r-lib.org/">pkgdown</a> 1.5.1.9000.</p>
</div>
</footer>
</div>
<div id="particles"></div>
<script>
window.onload = function() {
var config = {"particles":{"number":{"value":90,"density":{"enable":true,"value_area":1200}},"color":{"value":"#112446"},"shape":{"type":"circle","stroke":{"width":0,"color":"#000000"},"polygon":{"nb_sides":5},"image":{"src":"img/github.svg","width":100,"height":100}},"opacity":{"value":0.8,"random":false,"anim":{"enable":false,"speed":1,"opacity_min":0.1,"sync":false}},"size":{"value":3,"random":true,"anim":{"enable":false,"speed":40,"size_min":0.1,"sync":false}},"line_linked":{"enable":true,"distance":150,"color":"#112446","opacity":0.6,"width":1},"move":{"enable":true,"speed":5,"direction":"none","random":false,"straight":false,"out_mode":"out","bounce":false,"attract":{"enable":false,"rotateX":600,"rotateY":1200}}},"interactivity":{"detect_on":"canvas","events":{"onhover":{"enable":true,"mode":"repulse"},"onclick":{"enable":true,"mode":"push"},"resize":true}},"modes":{"grab":{"distance":400,"line_linked":{"opacity":1}},"bubble":{"distance":400,"size":40,"duration":2,"opacity":8,"speed":3},"repulse":{"distance":200,"duration":0.4},"push":{"particles_nb":4},"remove":{"particles_nb":2}},"retina_detect":true} ;
particlesJS("particles", config);
};
</script>
</body>
</html>

View File

@ -1,261 +0,0 @@
<!-- Generated by pkgdown: do not edit by hand -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>License • apexcharter</title>
<!-- jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<!-- Bootstrap -->
<link href="css/theme.css" rel="stylesheet">
<style>
#pkgdown-sidebar {
z-index: 100;
background: #FFF;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-nuL8/2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL+1ev4=" crossorigin="anonymous"></script>
<!-- Font -->
<link href="css/montserrat.css" rel="stylesheet">
<style>body {font-family: 'Montserrat', sans-serif;}</style>
<!-- bootstrap-toc -->
<link rel="stylesheet" href="bootstrap-toc.css">
<script src="bootstrap-toc.js"></script>
<!-- Font Awesome icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous" />
<!-- clipboard.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script>
<!-- headroom.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script>
<!-- pkgdown -->
<link href="pkgdown.css" rel="stylesheet">
<script src="pkgdown.js"></script>
<!-- Particles -->
<script src="js/particles.min.js"></script>
<style>
html,
body {
margin: 0;
padding: 0;
}
.contents {
opacity: 1;
background-color: #FFF;
z-index: 1;
}
#sidebar {
opacity: 1;
background-color: #FFF;
z-index: 1;
}
footer {
z-index: 1;
}
#particles {
position: fixed;
display: block;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 0;
}
.background {
position: absolute;
display: block;
top: 0;
left: 0;
z-index: 0;
}
</style>
<!-- Font Awesome icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css" integrity="sha256-nAmazAk6vS34Xqo0BSrTb+abbtFlgsFK7NKSi6o7Y78=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/v4-shims.min.css" integrity="sha256-6qHlizsOWFskGlwVOKuns+D1nB6ssZrHQrNj1wGplHc=" crossorigin="anonymous" />
<!-- clipboard.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.4/clipboard.min.js" integrity="sha256-FiZwavyI2V6+EXO1U+xzLG3IKldpiTFf3153ea9zikQ=" crossorigin="anonymous"></script>
<!-- headroom.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.4/headroom.min.js" integrity="sha256-DJFC1kqIhelURkuza0AvYal5RxMtpzLjFhsnVIeuk+U=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.4/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script>
<!-- pkgdown -->
<link href="pkgdown.css" rel="stylesheet">
<script src="pkgdown.js"></script>
<meta property="og:title" content="License" />
<!-- mathjax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body id="body">
<div class="container template-title-body">
<header>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand hidden-xs hidden-sm" style="padding: 10px 15px !important;">
<img src="https://github.com/dreamRs.png" class="hidden-xs hidden-sm" style="height: 50px;display: inline;vertical-align: middle;">
<a class="navbar-link" href="index.html">apexcharter</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Released version">0.1.4.960</span>
</span>
<span class="navbar-brand hidden-md hidden-lg">
<a class="navbar-link" href="index.html">apexcharter</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Released version">0.1.4.960</span>
</span>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>
<a href="index.html">
<span class="fas fa fas fa-home fa-lg"></span>
</a>
</li>
<li>
<a href="articles/apexcharter.html">Get started</a>
</li>
<li>
<a href="reference/index.html">Reference</a>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
Articles
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="articles/articles/advanced-configuration.html">Advanced configuration examples</a>
</li>
<li>
<a href="articles/chart-options.html">Chart options</a>
</li>
<li>
<a href="articles/shiny-integration.html">Shiny integration</a>
</li>
<li>
<a href="articles/spark-box.html">Spark boxes</a>
</li>
<li>
<a href="articles/sync-charts.html">Syncing charts</a>
</li>
</ul>
</li>
<li>
<a href="news/index.html">Changelog</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://github.com/dreamRs/apexcharter/">
<span class="fab fa fab fa-github fa-lg"></span>
</a>
</li>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container -->
</div><!--/.navbar -->
</header>
<div class="row">
<div class="contents col-md-9">
<div class="page-header">
<h1>License</h1>
</div>
<pre>YEAR: 2019
COPYRIGHT HOLDER: Victor Perrier
</pre>
</div>
</div>
<footer>
<div class="copyright">
<p>Developed by <a href='https://twitter.com/_pvictorr'><img src="https://pbs.twimg.com/profile_images/844237339404722177/E1U61aM8_normal.jpg"/> Victor Perrier</a>, <a href='https://twitter.com/_mfaan'><img src="https://pbs.twimg.com/profile_images/912313931326218240/o1-wvA18_normal.jpg" /> Fanny Meyer</a>.</p>
</div>
<div class="pkgdown">
<p>Site built with <a href="https://pkgdown.r-lib.org/">pkgdown</a> 1.5.1.9000.</p>
</div>
</footer>
</div>
<div id="particles"></div>
<script>
window.onload = function() {
var config = {"particles":{"number":{"value":90,"density":{"enable":true,"value_area":1200}},"color":{"value":"#112446"},"shape":{"type":"circle","stroke":{"width":0,"color":"#000000"},"polygon":{"nb_sides":5},"image":{"src":"img/github.svg","width":100,"height":100}},"opacity":{"value":0.8,"random":false,"anim":{"enable":false,"speed":1,"opacity_min":0.1,"sync":false}},"size":{"value":3,"random":true,"anim":{"enable":false,"speed":40,"size_min":0.1,"sync":false}},"line_linked":{"enable":true,"distance":150,"color":"#112446","opacity":0.6,"width":1},"move":{"enable":true,"speed":5,"direction":"none","random":false,"straight":false,"out_mode":"out","bounce":false,"attract":{"enable":false,"rotateX":600,"rotateY":1200}}},"interactivity":{"detect_on":"canvas","events":{"onhover":{"enable":true,"mode":"repulse"},"onclick":{"enable":true,"mode":"push"},"resize":true}},"modes":{"grab":{"distance":400,"line_linked":{"opacity":1}},"bubble":{"distance":400,"size":40,"duration":2,"opacity":8,"speed":3},"repulse":{"distance":200,"duration":0.4},"push":{"particles_nb":4},"remove":{"particles_nb":2}},"retina_detect":true} ;
particlesJS("particles", config);
};
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,285 +0,0 @@
/*!
*
* htmlwidgets bindings for ApexCharts
* https://github.com/dreamRs/apexcharter
*
*/
/// Functions
// From Friss tuto (https://github.com/FrissAnalytics/shinyJsTutorials/blob/master/tutorials/tutorial_03.Rmd)
function get_widget(id) {
var htmlWidgetsObj = HTMLWidgets.find("#" + id);
var widgetObj;
if (typeof htmlWidgetsObj !== "undefined") {
widgetObj = htmlWidgetsObj.getChart();
}
return widgetObj;
}
function is_single(options) {
var typeLabels = ["pie", "radialBar", "donut"];
var lab = typeLabels.indexOf(options.w.config.chart.type) > -1;
var single = options.w.config.series.length === 1;
return lab | single;
}
function is_datetime(chartContext) {
if (
chartContext.hasOwnProperty("w") &&
chartContext.w.hasOwnProperty("config") &&
chartContext.w.config.hasOwnProperty("xaxis") &&
chartContext.w.config.xaxis.hasOwnProperty("type")
) {
return chartContext.w.config.xaxis.type == "datetime";
} else {
return false;
}
}
function getSelection(chartContext, selectedDataPoints, serieIndex) {
var typeLabels = ["pie", "radialBar", "donut"];
var typeXY = ["scatter", "bubble"];
var selected;
if (typeLabels.indexOf(chartContext.opts.chart.type) > -1) {
var labels = chartContext.opts.labels;
selected = selectedDataPoints[serieIndex].map(function(index) {
return labels[index];
});
} else {
var data = chartContext.opts.series[serieIndex].data;
selected = selectedDataPoints[serieIndex].map(function(index) {
var val = data[index];
if (typeXY.indexOf(chartContext.opts.chart.type) < 0) {
if (val.hasOwnProperty("x")) {
val = val.x;
} else {
val = val[0];
}
}
return val;
});
}
//console.log(selected);
if (typeXY.indexOf(chartContext.opts.chart.type) > -1) {
selected = {
x: selected.map(function(obj) {
return obj.x;
}),
y: selected.map(function(obj) {
return obj.y;
})
};
}
if (typeof selected == "undefined") {
selected = null;
}
return selected;
}
function getYaxis(axis) {
var yzoom = { min: null, max: null };
if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) {
var y_axis;
if (axis.yaxis.hasOwnProperty("min")) {
y_axis = axis.yaxis;
} else {
y_axis = axis.yaxis[0];
}
if (y_axis.hasOwnProperty("min") && typeof y_axis.min !== "undefined") {
yzoom.min = y_axis.min;
}
if (y_axis.hasOwnProperty("max") && typeof y_axis.max !== "undefined") {
yzoom.max = y_axis.max;
}
}
return yzoom;
}
function getXaxis(axis) {
var xzoom = { min: null, max: null };
if (typeof axis.xaxis !== "undefined") {
var x_axis = axis.xaxis;
if (x_axis.hasOwnProperty("min") && typeof x_axis.min !== "undefined") {
xzoom.min = x_axis.min;
}
if (x_axis.hasOwnProperty("max") && typeof x_axis.max !== "undefined") {
xzoom.max = x_axis.max;
}
}
return xzoom;
}
/// Widget
HTMLWidgets.widget({
name: "apexcharter",
type: "output",
factory: function(el, width, height) {
var axOpts;
var apexchart = null;
return {
renderValue: function(x) {
// Global options
axOpts = x.ax_opts;
// Sizing
if (typeof axOpts.chart === "undefined") {
axOpts.chart = {};
}
axOpts.chart.width = width;
axOpts.chart.height = height;
if (!axOpts.chart.hasOwnProperty("parentHeightOffset")) {
axOpts.chart.parentHeightOffset = 0;
}
if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) {
if (!axOpts.hasOwnProperty("chart")) {
axOpts.chart = {};
}
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (x.shinyEvents.hasOwnProperty("click")) {
axOpts.chart.events.dataPointSelection = function(
event,
chartContext,
opts
) {
var options = opts;
var nonEmpty = opts.selectedDataPoints.filter(function(el) {
return el !== null && el.length > 0;
});
if (nonEmpty.length > 0) {
var select = {};
for (var i = 0; i < opts.selectedDataPoints.length; i++) {
if (typeof opts.selectedDataPoints[i] === "undefined") {
continue;
}
var selection = getSelection(
chartContext,
options.selectedDataPoints,
i
);
if (selection !== null) {
if (opts.w.config.series[i].hasOwnProperty("name")) {
var name = opts.w.config.series[i].name;
select[name] = selection;
} else {
select[i] = selection;
}
}
}
if (is_single(options)) {
select = select[Object.keys(select)[0]];
}
Shiny.setInputValue(
x.shinyEvents.click.inputId + ":apex_click",
{ value: select, datetime: is_datetime(chartContext) }
);
} else {
Shiny.setInputValue(x.shinyEvents.click.inputId, null);
}
};
}
if (x.shinyEvents.hasOwnProperty("zoomed")) {
axOpts.chart.events.zoomed = function(chartContext, xaxis, yaxis) {
var id = x.shinyEvents.zoomed.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
Shiny.setInputValue(id, {
x: getXaxis(xaxis),
y: getYaxis(xaxis)
});
};
}
if (x.shinyEvents.hasOwnProperty("selection")) {
axOpts.chart.events.selection = function(
chartContext,
xaxis,
yaxis
) {
var id = x.shinyEvents.selection.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
var selectionValue;
if (x.shinyEvents.selection.type === "x") {
selectionValue = { x: xaxis.xaxis };
} else if (x.shinyEvents.selection.type === "xy") {
selectionValue = { x: xaxis.xaxis, y: getYaxis(xaxis) };
} else if (x.shinyEvents.selection.type === "y") {
selectionValue = { y: getYaxis(xaxis) };
}
Shiny.setInputValue(id, selectionValue);
};
}
}
// Generate or update chart
if (apexchart === null) {
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
} else {
if (x.auto_update) {
apexchart.updateSeries(axOpts.series, x.auto_update.series_animate);
if (x.auto_update.update_options) {
apexchart.updateOptions(
axOpts,
x.auto_update.options_redrawPaths,
x.auto_update.options_animate
);
}
} else {
apexchart.destroy();
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
}
}
},
getChart: function() {
return apexchart;
},
resize: function(width, height) {
apexchart.updateOptions({
chart: {
width: width,
height: height
}
});
}
};
}
});
if (HTMLWidgets.shinyMode) {
// update serie
Shiny.addCustomMessageHandler("update-apexchart-series", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateSeries(
[
{
data: obj.data.newSeries
}
],
obj.data.animate
);
}
});
// update options
Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateOptions(obj.data.options);
}
});
}

View File

@ -1,285 +0,0 @@
/*!
*
* htmlwidgets bindings for ApexCharts
* https://github.com/dreamRs/apexcharter
*
*/
/// Functions
// From Friss tuto (https://github.com/FrissAnalytics/shinyJsTutorials/blob/master/tutorials/tutorial_03.Rmd)
function get_widget(id) {
var htmlWidgetsObj = HTMLWidgets.find("#" + id);
var widgetObj;
if (typeof htmlWidgetsObj !== "undefined") {
widgetObj = htmlWidgetsObj.getChart();
}
return widgetObj;
}
function is_single(options) {
var typeLabels = ["pie", "radialBar", "donut"];
var lab = typeLabels.indexOf(options.w.config.chart.type) > -1;
var single = options.w.config.series.length === 1;
return lab | single;
}
function is_datetime(chartContext) {
if (
chartContext.hasOwnProperty("w") &&
chartContext.w.hasOwnProperty("config") &&
chartContext.w.config.hasOwnProperty("xaxis") &&
chartContext.w.config.xaxis.hasOwnProperty("type")
) {
return chartContext.w.config.xaxis.type == "datetime";
} else {
return false;
}
}
function getSelection(chartContext, selectedDataPoints, serieIndex) {
var typeLabels = ["pie", "radialBar", "donut"];
var typeXY = ["scatter", "bubble"];
var selected;
if (typeLabels.indexOf(chartContext.opts.chart.type) > -1) {
var labels = chartContext.opts.labels;
selected = selectedDataPoints[serieIndex].map(function(index) {
return labels[index];
});
} else {
var data = chartContext.opts.series[serieIndex].data;
selected = selectedDataPoints[serieIndex].map(function(index) {
var val = data[index];
if (typeXY.indexOf(chartContext.opts.chart.type) < 0) {
if (val.hasOwnProperty("x")) {
val = val.x;
} else {
val = val[0];
}
}
return val;
});
}
//console.log(selected);
if (typeXY.indexOf(chartContext.opts.chart.type) > -1) {
selected = {
x: selected.map(function(obj) {
return obj.x;
}),
y: selected.map(function(obj) {
return obj.y;
})
};
}
if (typeof selected == "undefined") {
selected = null;
}
return selected;
}
function getYaxis(axis) {
var yzoom = { min: null, max: null };
if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) {
var y_axis;
if (axis.yaxis.hasOwnProperty("min")) {
y_axis = axis.yaxis;
} else {
y_axis = axis.yaxis[0];
}
if (y_axis.hasOwnProperty("min") && typeof y_axis.min !== "undefined") {
yzoom.min = y_axis.min;
}
if (y_axis.hasOwnProperty("max") && typeof y_axis.max !== "undefined") {
yzoom.max = y_axis.max;
}
}
return yzoom;
}
function getXaxis(axis) {
var xzoom = { min: null, max: null };
if (typeof axis.xaxis !== "undefined") {
var x_axis = axis.xaxis;
if (x_axis.hasOwnProperty("min") && typeof x_axis.min !== "undefined") {
xzoom.min = x_axis.min;
}
if (x_axis.hasOwnProperty("max") && typeof x_axis.max !== "undefined") {
xzoom.max = x_axis.max;
}
}
return xzoom;
}
/// Widget
HTMLWidgets.widget({
name: "apexcharter",
type: "output",
factory: function(el, width, height) {
var axOpts;
var apexchart = null;
return {
renderValue: function(x) {
// Global options
axOpts = x.ax_opts;
// Sizing
if (typeof axOpts.chart === "undefined") {
axOpts.chart = {};
}
axOpts.chart.width = width;
axOpts.chart.height = height;
if (!axOpts.chart.hasOwnProperty("parentHeightOffset")) {
axOpts.chart.parentHeightOffset = 0;
}
if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) {
if (!axOpts.hasOwnProperty("chart")) {
axOpts.chart = {};
}
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (x.shinyEvents.hasOwnProperty("click")) {
axOpts.chart.events.dataPointSelection = function(
event,
chartContext,
opts
) {
var options = opts;
var nonEmpty = opts.selectedDataPoints.filter(function(el) {
return el !== null && el.length > 0;
});
if (nonEmpty.length > 0) {
var select = {};
for (var i = 0; i < opts.selectedDataPoints.length; i++) {
if (typeof opts.selectedDataPoints[i] === "undefined") {
continue;
}
var selection = getSelection(
chartContext,
options.selectedDataPoints,
i
);
if (selection !== null) {
if (opts.w.config.series[i].hasOwnProperty("name")) {
var name = opts.w.config.series[i].name;
select[name] = selection;
} else {
select[i] = selection;
}
}
}
if (is_single(options)) {
select = select[Object.keys(select)[0]];
}
Shiny.setInputValue(
x.shinyEvents.click.inputId + ":apex_click",
{ value: select, datetime: is_datetime(chartContext) }
);
} else {
Shiny.setInputValue(x.shinyEvents.click.inputId, null);
}
};
}
if (x.shinyEvents.hasOwnProperty("zoomed")) {
axOpts.chart.events.zoomed = function(chartContext, xaxis, yaxis) {
var id = x.shinyEvents.zoomed.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
Shiny.setInputValue(id, {
x: getXaxis(xaxis),
y: getYaxis(xaxis)
});
};
}
if (x.shinyEvents.hasOwnProperty("selection")) {
axOpts.chart.events.selection = function(
chartContext,
xaxis,
yaxis
) {
var id = x.shinyEvents.selection.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
var selectionValue;
if (x.shinyEvents.selection.type === "x") {
selectionValue = { x: xaxis.xaxis };
} else if (x.shinyEvents.selection.type === "xy") {
selectionValue = { x: xaxis.xaxis, y: getYaxis(xaxis) };
} else if (x.shinyEvents.selection.type === "y") {
selectionValue = { y: getYaxis(xaxis) };
}
Shiny.setInputValue(id, selectionValue);
};
}
}
// Generate or update chart
if (apexchart === null) {
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
} else {
if (x.auto_update) {
apexchart.updateSeries(axOpts.series, x.auto_update.series_animate);
if (x.auto_update.update_options) {
apexchart.updateOptions(
axOpts,
x.auto_update.options_redrawPaths,
x.auto_update.options_animate
);
}
} else {
apexchart.destroy();
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
}
}
},
getChart: function() {
return apexchart;
},
resize: function(width, height) {
apexchart.updateOptions({
chart: {
width: width,
height: height
}
});
}
};
}
});
if (HTMLWidgets.shinyMode) {
// update serie
Shiny.addCustomMessageHandler("update-apexchart-series", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateSeries(
[
{
data: obj.data.newSeries
}
],
obj.data.animate
);
}
});
// update options
Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateOptions(obj.data.options);
}
});
}

View File

@ -1,315 +0,0 @@
/*!
*
* htmlwidgets bindings for ApexCharts
* https://github.com/dreamRs/apexcharter
*
*/
/// Functions
// From Friss tuto (https://github.com/FrissAnalytics/shinyJsTutorials/blob/master/tutorials/tutorial_03.Rmd)
function get_widget(id) {
var htmlWidgetsObj = HTMLWidgets.find("#" + id);
var widgetObj;
if (typeof htmlWidgetsObj !== "undefined") {
widgetObj = htmlWidgetsObj.getChart();
}
return widgetObj;
}
function is_single(options) {
var typeLabels = ["pie", "radialBar", "donut"];
var lab = typeLabels.indexOf(options.w.config.chart.type) > -1;
var single = options.w.config.series.length === 1;
return lab | single;
}
function is_datetime(chartContext) {
if (
chartContext.hasOwnProperty("w") &&
chartContext.w.hasOwnProperty("config") &&
chartContext.w.config.hasOwnProperty("xaxis") &&
chartContext.w.config.xaxis.hasOwnProperty("type")
) {
return chartContext.w.config.xaxis.type == "datetime";
} else {
return false;
}
}
function getSelection(chartContext, selectedDataPoints, serieIndex) {
var typeLabels = ["pie", "radialBar", "donut"];
var typeXY = ["scatter", "bubble"];
var selected;
if (typeLabels.indexOf(chartContext.opts.chart.type) > -1) {
var labels = chartContext.opts.labels;
selected = selectedDataPoints[serieIndex].map(function(index) {
return labels[index];
});
} else {
var data = chartContext.opts.series[serieIndex].data;
selected = selectedDataPoints[serieIndex].map(function(index) {
var val = data[index];
if (typeXY.indexOf(chartContext.opts.chart.type) < 0) {
if (val.hasOwnProperty("x")) {
val = val.x;
} else {
val = val[0];
}
}
return val;
});
}
//console.log(selected);
if (typeXY.indexOf(chartContext.opts.chart.type) > -1) {
selected = {
x: selected.map(function(obj) {
return obj.x;
}),
y: selected.map(function(obj) {
return obj.y;
})
};
}
if (typeof selected == "undefined") {
selected = null;
}
return selected;
}
function getYaxis(axis) {
var yzoom = { min: null, max: null };
if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) {
var y_axis;
if (axis.yaxis.hasOwnProperty("min")) {
y_axis = axis.yaxis;
} else {
y_axis = axis.yaxis[0];
}
if (y_axis.hasOwnProperty("min") && typeof y_axis.min !== "undefined") {
yzoom.min = y_axis.min;
}
if (y_axis.hasOwnProperty("max") && typeof y_axis.max !== "undefined") {
yzoom.max = y_axis.max;
}
}
return yzoom;
}
function getXaxis(axis) {
var xzoom = { min: null, max: null };
if (typeof axis.xaxis !== "undefined") {
var x_axis = axis.xaxis;
if (x_axis.hasOwnProperty("min") && typeof x_axis.min !== "undefined") {
xzoom.min = x_axis.min;
}
if (x_axis.hasOwnProperty("max") && typeof x_axis.max !== "undefined") {
xzoom.max = x_axis.max;
}
}
return xzoom;
}
/// Widget
HTMLWidgets.widget({
name: "apexcharter",
type: "output",
factory: function(el, width, height) {
var axOpts;
var apexchart = null;
return {
renderValue: function(x) {
// Global options
axOpts = x.ax_opts;
if (x.sparkbox) {
el.style.padding = "3px 0 0 0";
el.style.boxShadow = "0px 1px 22px -12px #607D8B";
el.style.background = x.sparkbox.background;
el.classList.add("apexcharter-spark-box");
}
// Sizing
if (typeof axOpts.chart === "undefined") {
axOpts.chart = {};
}
axOpts.chart.width = width;
axOpts.chart.height = height;
if (!axOpts.chart.hasOwnProperty("id")) {
axOpts.chart.id = el.id;
}
if (!axOpts.chart.hasOwnProperty("parentHeightOffset")) {
axOpts.chart.parentHeightOffset = 0;
}
// added events to remove minheight container
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (!axOpts.chart.events.hasOwnProperty("mounted")) {
axOpts.chart.events.mounted = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (!axOpts.chart.events.hasOwnProperty("updated")) {
axOpts.chart.events.updated = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) {
if (!axOpts.hasOwnProperty("chart")) {
axOpts.chart = {};
}
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (x.shinyEvents.hasOwnProperty("click")) {
axOpts.chart.events.dataPointSelection = function(
event,
chartContext,
opts
) {
var options = opts;
var nonEmpty = opts.selectedDataPoints.filter(function(el) {
return el !== null && el.length > 0;
});
if (nonEmpty.length > 0) {
var select = {};
for (var i = 0; i < opts.selectedDataPoints.length; i++) {
if (typeof opts.selectedDataPoints[i] === "undefined") {
continue;
}
var selection = getSelection(
chartContext,
options.selectedDataPoints,
i
);
if (selection !== null) {
if (opts.w.config.series[i].hasOwnProperty("name")) {
var name = opts.w.config.series[i].name;
select[name] = selection;
} else {
select[i] = selection;
}
}
}
if (is_single(options)) {
select = select[Object.keys(select)[0]];
}
Shiny.setInputValue(
x.shinyEvents.click.inputId + ":apex_click",
{ value: select, datetime: is_datetime(chartContext) }
);
} else {
Shiny.setInputValue(x.shinyEvents.click.inputId, null);
}
};
}
if (x.shinyEvents.hasOwnProperty("zoomed")) {
axOpts.chart.events.zoomed = function(chartContext, xaxis, yaxis) {
var id = x.shinyEvents.zoomed.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
Shiny.setInputValue(id, {
x: getXaxis(xaxis),
y: getYaxis(xaxis)
});
};
}
if (x.shinyEvents.hasOwnProperty("selection")) {
axOpts.chart.events.selection = function(
chartContext,
xaxis,
yaxis
) {
var id = x.shinyEvents.selection.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
var selectionValue;
if (x.shinyEvents.selection.type === "x") {
selectionValue = { x: xaxis.xaxis };
} else if (x.shinyEvents.selection.type === "xy") {
selectionValue = { x: xaxis.xaxis, y: getYaxis(xaxis) };
} else if (x.shinyEvents.selection.type === "y") {
selectionValue = { y: getYaxis(xaxis) };
}
Shiny.setInputValue(id, selectionValue);
};
}
}
// Generate or update chart
if (apexchart === null) {
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
} else {
if (x.auto_update) {
//console.log(x.auto_update);
apexchart.updateSeries(axOpts.series, x.auto_update.series_animate);
if (x.auto_update.update_options) {
delete axOpts.series;
delete axOpts.chart.width;
delete axOpts.chart.height;
apexchart.updateOptions(
axOpts,
x.auto_update.options_redrawPaths,
x.auto_update.options_animate,
x.auto_update.update_synced_charts
);
}
} else {
apexchart.destroy();
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
}
}
},
getChart: function() {
return apexchart;
},
resize: function(width, height) {
apexchart.updateOptions({
chart: {
width: width,
height: height
}
});
}
};
}
});
if (HTMLWidgets.shinyMode) {
// update serie
Shiny.addCustomMessageHandler("update-apexchart-series", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateSeries(
[
{
data: obj.data.newSeries
}
],
obj.data.animate
);
}
});
// update options
Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateOptions(obj.data.options);
}
});
}

View File

@ -1,315 +0,0 @@
/*!
*
* htmlwidgets bindings for ApexCharts
* https://github.com/dreamRs/apexcharter
*
*/
/// Functions
// From Friss tuto (https://github.com/FrissAnalytics/shinyJsTutorials/blob/master/tutorials/tutorial_03.Rmd)
function get_widget(id) {
var htmlWidgetsObj = HTMLWidgets.find("#" + id);
var widgetObj;
if (typeof htmlWidgetsObj !== "undefined") {
widgetObj = htmlWidgetsObj.getChart();
}
return widgetObj;
}
function is_single(options) {
var typeLabels = ["pie", "radialBar", "donut"];
var lab = typeLabels.indexOf(options.w.config.chart.type) > -1;
var single = options.w.config.series.length === 1;
return lab | single;
}
function is_datetime(chartContext) {
if (
chartContext.hasOwnProperty("w") &&
chartContext.w.hasOwnProperty("config") &&
chartContext.w.config.hasOwnProperty("xaxis") &&
chartContext.w.config.xaxis.hasOwnProperty("type")
) {
return chartContext.w.config.xaxis.type == "datetime";
} else {
return false;
}
}
function getSelection(chartContext, selectedDataPoints, serieIndex) {
var typeLabels = ["pie", "radialBar", "donut"];
var typeXY = ["scatter", "bubble"];
var selected;
if (typeLabels.indexOf(chartContext.opts.chart.type) > -1) {
var labels = chartContext.opts.labels;
selected = selectedDataPoints[serieIndex].map(function(index) {
return labels[index];
});
} else {
var data = chartContext.opts.series[serieIndex].data;
selected = selectedDataPoints[serieIndex].map(function(index) {
var val = data[index];
if (typeXY.indexOf(chartContext.opts.chart.type) < 0) {
if (val.hasOwnProperty("x")) {
val = val.x;
} else {
val = val[0];
}
}
return val;
});
}
//console.log(selected);
if (typeXY.indexOf(chartContext.opts.chart.type) > -1) {
selected = {
x: selected.map(function(obj) {
return obj.x;
}),
y: selected.map(function(obj) {
return obj.y;
})
};
}
if (typeof selected == "undefined") {
selected = null;
}
return selected;
}
function getYaxis(axis) {
var yzoom = { min: null, max: null };
if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) {
var y_axis;
if (axis.yaxis.hasOwnProperty("min")) {
y_axis = axis.yaxis;
} else {
y_axis = axis.yaxis[0];
}
if (y_axis.hasOwnProperty("min") && typeof y_axis.min !== "undefined") {
yzoom.min = y_axis.min;
}
if (y_axis.hasOwnProperty("max") && typeof y_axis.max !== "undefined") {
yzoom.max = y_axis.max;
}
}
return yzoom;
}
function getXaxis(axis) {
var xzoom = { min: null, max: null };
if (typeof axis.xaxis !== "undefined") {
var x_axis = axis.xaxis;
if (x_axis.hasOwnProperty("min") && typeof x_axis.min !== "undefined") {
xzoom.min = x_axis.min;
}
if (x_axis.hasOwnProperty("max") && typeof x_axis.max !== "undefined") {
xzoom.max = x_axis.max;
}
}
return xzoom;
}
/// Widget
HTMLWidgets.widget({
name: "apexcharter",
type: "output",
factory: function(el, width, height) {
var axOpts;
var apexchart = null;
return {
renderValue: function(x) {
// Global options
axOpts = x.ax_opts;
if (x.sparkbox) {
el.style.padding = "3px 0 0 0";
el.style.boxShadow = "0px 1px 22px -12px #607D8B";
el.style.background = x.sparkbox.background;
el.classList.add("apexcharter-spark-box");
}
// Sizing
if (typeof axOpts.chart === "undefined") {
axOpts.chart = {};
}
axOpts.chart.width = width;
axOpts.chart.height = height;
if (!axOpts.chart.hasOwnProperty("id")) {
axOpts.chart.id = el.id;
}
if (!axOpts.chart.hasOwnProperty("parentHeightOffset")) {
axOpts.chart.parentHeightOffset = 0;
}
// added events to remove minheight container
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (!axOpts.chart.events.hasOwnProperty("mounted")) {
axOpts.chart.events.mounted = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (!axOpts.chart.events.hasOwnProperty("updated")) {
axOpts.chart.events.updated = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) {
if (!axOpts.hasOwnProperty("chart")) {
axOpts.chart = {};
}
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (x.shinyEvents.hasOwnProperty("click")) {
axOpts.chart.events.dataPointSelection = function(
event,
chartContext,
opts
) {
var options = opts;
var nonEmpty = opts.selectedDataPoints.filter(function(el) {
return el !== null && el.length > 0;
});
if (nonEmpty.length > 0) {
var select = {};
for (var i = 0; i < opts.selectedDataPoints.length; i++) {
if (typeof opts.selectedDataPoints[i] === "undefined") {
continue;
}
var selection = getSelection(
chartContext,
options.selectedDataPoints,
i
);
if (selection !== null) {
if (opts.w.config.series[i].hasOwnProperty("name")) {
var name = opts.w.config.series[i].name;
select[name] = selection;
} else {
select[i] = selection;
}
}
}
if (is_single(options)) {
select = select[Object.keys(select)[0]];
}
Shiny.setInputValue(
x.shinyEvents.click.inputId + ":apex_click",
{ value: select, datetime: is_datetime(chartContext) }
);
} else {
Shiny.setInputValue(x.shinyEvents.click.inputId, null);
}
};
}
if (x.shinyEvents.hasOwnProperty("zoomed")) {
axOpts.chart.events.zoomed = function(chartContext, xaxis, yaxis) {
var id = x.shinyEvents.zoomed.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
Shiny.setInputValue(id, {
x: getXaxis(xaxis),
y: getYaxis(xaxis)
});
};
}
if (x.shinyEvents.hasOwnProperty("selection")) {
axOpts.chart.events.selection = function(
chartContext,
xaxis,
yaxis
) {
var id = x.shinyEvents.selection.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
var selectionValue;
if (x.shinyEvents.selection.type === "x") {
selectionValue = { x: xaxis.xaxis };
} else if (x.shinyEvents.selection.type === "xy") {
selectionValue = { x: xaxis.xaxis, y: getYaxis(xaxis) };
} else if (x.shinyEvents.selection.type === "y") {
selectionValue = { y: getYaxis(xaxis) };
}
Shiny.setInputValue(id, selectionValue);
};
}
}
// Generate or update chart
if (apexchart === null) {
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
} else {
if (x.auto_update) {
//console.log(x.auto_update);
apexchart.updateSeries(axOpts.series, x.auto_update.series_animate);
if (x.auto_update.update_options) {
delete axOpts.series;
delete axOpts.chart.width;
delete axOpts.chart.height;
apexchart.updateOptions(
axOpts,
x.auto_update.options_redrawPaths,
x.auto_update.options_animate,
x.auto_update.update_synced_charts
);
}
} else {
apexchart.destroy();
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
}
}
},
getChart: function() {
return apexchart;
},
resize: function(width, height) {
apexchart.updateOptions({
chart: {
width: width,
height: height
}
});
}
};
}
});
if (HTMLWidgets.shinyMode) {
// update serie
Shiny.addCustomMessageHandler("update-apexchart-series", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateSeries(
[
{
data: obj.data.newSeries
}
],
obj.data.animate
);
}
});
// update options
Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateOptions(obj.data.options);
}
});
}

View File

@ -1,313 +0,0 @@
/*!
*
* htmlwidgets bindings for ApexCharts
* https://github.com/dreamRs/apexcharter
*
*/
/// Functions
// From Friss tuto (https://github.com/FrissAnalytics/shinyJsTutorials/blob/master/tutorials/tutorial_03.Rmd)
function get_widget(id) {
var htmlWidgetsObj = HTMLWidgets.find("#" + id);
var widgetObj;
if (typeof htmlWidgetsObj !== "undefined") {
widgetObj = htmlWidgetsObj.getChart();
}
return widgetObj;
}
function is_single(options) {
var typeLabels = ["pie", "radialBar", "donut"];
var lab = typeLabels.indexOf(options.w.config.chart.type) > -1;
var single = options.w.config.series.length === 1;
return lab | single;
}
function is_datetime(chartContext) {
if (
chartContext.hasOwnProperty("w") &&
chartContext.w.hasOwnProperty("config") &&
chartContext.w.config.hasOwnProperty("xaxis") &&
chartContext.w.config.xaxis.hasOwnProperty("type")
) {
return chartContext.w.config.xaxis.type == "datetime";
} else {
return false;
}
}
function getSelection(chartContext, selectedDataPoints, serieIndex) {
var typeLabels = ["pie", "radialBar", "donut"];
var typeXY = ["scatter", "bubble"];
var selected;
if (typeLabels.indexOf(chartContext.opts.chart.type) > -1) {
var labels = chartContext.opts.labels;
selected = selectedDataPoints[serieIndex].map(function(index) {
return labels[index];
});
} else {
var data = chartContext.opts.series[serieIndex].data;
selected = selectedDataPoints[serieIndex].map(function(index) {
var val = data[index];
if (typeXY.indexOf(chartContext.opts.chart.type) < 0) {
if (val.hasOwnProperty("x")) {
val = val.x;
} else {
val = val[0];
}
}
return val;
});
}
//console.log(selected);
if (typeXY.indexOf(chartContext.opts.chart.type) > -1) {
selected = {
x: selected.map(function(obj) {
return obj.x;
}),
y: selected.map(function(obj) {
return obj.y;
})
};
}
if (typeof selected == "undefined") {
selected = null;
}
return selected;
}
function getYaxis(axis) {
var yzoom = { min: null, max: null };
if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) {
var y_axis;
if (axis.yaxis.hasOwnProperty("min")) {
y_axis = axis.yaxis;
} else {
y_axis = axis.yaxis[0];
}
if (y_axis.hasOwnProperty("min") && typeof y_axis.min !== "undefined") {
yzoom.min = y_axis.min;
}
if (y_axis.hasOwnProperty("max") && typeof y_axis.max !== "undefined") {
yzoom.max = y_axis.max;
}
}
return yzoom;
}
function getXaxis(axis) {
var xzoom = { min: null, max: null };
if (typeof axis.xaxis !== "undefined") {
var x_axis = axis.xaxis;
if (x_axis.hasOwnProperty("min") && typeof x_axis.min !== "undefined") {
xzoom.min = x_axis.min;
}
if (x_axis.hasOwnProperty("max") && typeof x_axis.max !== "undefined") {
xzoom.max = x_axis.max;
}
}
return xzoom;
}
/// Widget
HTMLWidgets.widget({
name: "apexcharter",
type: "output",
factory: function(el, width, height) {
var axOpts;
var apexchart = null;
return {
renderValue: function(x) {
// Global options
axOpts = x.ax_opts;
if (x.sparkbox) {
el.style.background = x.sparkbox.background;
el.classList.add("apexcharter-spark-box");
}
// Sizing
if (typeof axOpts.chart === "undefined") {
axOpts.chart = {};
}
axOpts.chart.width = width;
axOpts.chart.height = height;
if (!axOpts.chart.hasOwnProperty("id")) {
axOpts.chart.id = el.id;
}
if (!axOpts.chart.hasOwnProperty("parentHeightOffset")) {
axOpts.chart.parentHeightOffset = 0;
}
// added events to remove minheight container
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (!axOpts.chart.events.hasOwnProperty("mounted")) {
axOpts.chart.events.mounted = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (!axOpts.chart.events.hasOwnProperty("updated")) {
axOpts.chart.events.updated = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) {
if (!axOpts.hasOwnProperty("chart")) {
axOpts.chart = {};
}
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (x.shinyEvents.hasOwnProperty("click")) {
axOpts.chart.events.dataPointSelection = function(
event,
chartContext,
opts
) {
var options = opts;
var nonEmpty = opts.selectedDataPoints.filter(function(el) {
return el !== null && el.length > 0;
});
if (nonEmpty.length > 0) {
var select = {};
for (var i = 0; i < opts.selectedDataPoints.length; i++) {
if (typeof opts.selectedDataPoints[i] === "undefined") {
continue;
}
var selection = getSelection(
chartContext,
options.selectedDataPoints,
i
);
if (selection !== null) {
if (opts.w.config.series[i].hasOwnProperty("name")) {
var name = opts.w.config.series[i].name;
select[name] = selection;
} else {
select[i] = selection;
}
}
}
if (is_single(options)) {
select = select[Object.keys(select)[0]];
}
Shiny.setInputValue(
x.shinyEvents.click.inputId + ":apex_click",
{ value: select, datetime: is_datetime(chartContext) }
);
} else {
Shiny.setInputValue(x.shinyEvents.click.inputId, null);
}
};
}
if (x.shinyEvents.hasOwnProperty("zoomed")) {
axOpts.chart.events.zoomed = function(chartContext, xaxis, yaxis) {
var id = x.shinyEvents.zoomed.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
Shiny.setInputValue(id, {
x: getXaxis(xaxis),
y: getYaxis(xaxis)
});
};
}
if (x.shinyEvents.hasOwnProperty("selection")) {
axOpts.chart.events.selection = function(
chartContext,
xaxis,
yaxis
) {
var id = x.shinyEvents.selection.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
var selectionValue;
if (x.shinyEvents.selection.type === "x") {
selectionValue = { x: xaxis.xaxis };
} else if (x.shinyEvents.selection.type === "xy") {
selectionValue = { x: xaxis.xaxis, y: getYaxis(xaxis) };
} else if (x.shinyEvents.selection.type === "y") {
selectionValue = { y: getYaxis(xaxis) };
}
Shiny.setInputValue(id, selectionValue);
};
}
}
// Generate or update chart
if (apexchart === null) {
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
} else {
if (x.auto_update) {
//console.log(x.auto_update);
apexchart.updateSeries(axOpts.series, x.auto_update.series_animate);
if (x.auto_update.update_options) {
delete axOpts.series;
delete axOpts.chart.width;
delete axOpts.chart.height;
apexchart.updateOptions(
axOpts,
x.auto_update.options_redrawPaths,
x.auto_update.options_animate,
x.auto_update.update_synced_charts
);
}
} else {
apexchart.destroy();
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
}
}
},
getChart: function() {
return apexchart;
},
resize: function(width, height) {
apexchart.updateOptions({
chart: {
width: width,
height: height
}
});
}
};
}
});
if (HTMLWidgets.shinyMode) {
// update serie
Shiny.addCustomMessageHandler("update-apexchart-series", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateSeries(
[
{
data: obj.data.newSeries
}
],
obj.data.animate
);
}
});
// update options
Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateOptions(obj.data.options);
}
});
}

View File

@ -1,8 +0,0 @@
/* Spark box styles */
.apexcharter-spark-box {
border-radius: 0.5rem;
margin-bottom: 10px;
box-shadow: 0 1px 28px -12px #3B4252;
}

View File

@ -1,313 +0,0 @@
/*!
*
* htmlwidgets bindings for ApexCharts
* https://github.com/dreamRs/apexcharter
*
*/
/// Functions
// From Friss tuto (https://github.com/FrissAnalytics/shinyJsTutorials/blob/master/tutorials/tutorial_03.Rmd)
function get_widget(id) {
var htmlWidgetsObj = HTMLWidgets.find("#" + id);
var widgetObj;
if (typeof htmlWidgetsObj !== "undefined") {
widgetObj = htmlWidgetsObj.getChart();
}
return widgetObj;
}
function is_single(options) {
var typeLabels = ["pie", "radialBar", "donut"];
var lab = typeLabels.indexOf(options.w.config.chart.type) > -1;
var single = options.w.config.series.length === 1;
return lab | single;
}
function is_datetime(chartContext) {
if (
chartContext.hasOwnProperty("w") &&
chartContext.w.hasOwnProperty("config") &&
chartContext.w.config.hasOwnProperty("xaxis") &&
chartContext.w.config.xaxis.hasOwnProperty("type")
) {
return chartContext.w.config.xaxis.type == "datetime";
} else {
return false;
}
}
function getSelection(chartContext, selectedDataPoints, serieIndex) {
var typeLabels = ["pie", "radialBar", "donut"];
var typeXY = ["scatter", "bubble"];
var selected;
if (typeLabels.indexOf(chartContext.opts.chart.type) > -1) {
var labels = chartContext.opts.labels;
selected = selectedDataPoints[serieIndex].map(function(index) {
return labels[index];
});
} else {
var data = chartContext.opts.series[serieIndex].data;
selected = selectedDataPoints[serieIndex].map(function(index) {
var val = data[index];
if (typeXY.indexOf(chartContext.opts.chart.type) < 0) {
if (val.hasOwnProperty("x")) {
val = val.x;
} else {
val = val[0];
}
}
return val;
});
}
//console.log(selected);
if (typeXY.indexOf(chartContext.opts.chart.type) > -1) {
selected = {
x: selected.map(function(obj) {
return obj.x;
}),
y: selected.map(function(obj) {
return obj.y;
})
};
}
if (typeof selected == "undefined") {
selected = null;
}
return selected;
}
function getYaxis(axis) {
var yzoom = { min: null, max: null };
if (typeof axis.yaxis !== "undefined" && axis.yaxis !== null) {
var y_axis;
if (axis.yaxis.hasOwnProperty("min")) {
y_axis = axis.yaxis;
} else {
y_axis = axis.yaxis[0];
}
if (y_axis.hasOwnProperty("min") && typeof y_axis.min !== "undefined") {
yzoom.min = y_axis.min;
}
if (y_axis.hasOwnProperty("max") && typeof y_axis.max !== "undefined") {
yzoom.max = y_axis.max;
}
}
return yzoom;
}
function getXaxis(axis) {
var xzoom = { min: null, max: null };
if (typeof axis.xaxis !== "undefined") {
var x_axis = axis.xaxis;
if (x_axis.hasOwnProperty("min") && typeof x_axis.min !== "undefined") {
xzoom.min = x_axis.min;
}
if (x_axis.hasOwnProperty("max") && typeof x_axis.max !== "undefined") {
xzoom.max = x_axis.max;
}
}
return xzoom;
}
/// Widget
HTMLWidgets.widget({
name: "apexcharter",
type: "output",
factory: function(el, width, height) {
var axOpts;
var apexchart = null;
return {
renderValue: function(x) {
// Global options
axOpts = x.ax_opts;
if (x.sparkbox) {
el.style.background = x.sparkbox.background;
el.classList.add("apexcharter-spark-box");
}
// Sizing
if (typeof axOpts.chart === "undefined") {
axOpts.chart = {};
}
axOpts.chart.width = width;
axOpts.chart.height = height;
if (!axOpts.chart.hasOwnProperty("id")) {
axOpts.chart.id = el.id;
}
if (!axOpts.chart.hasOwnProperty("parentHeightOffset")) {
axOpts.chart.parentHeightOffset = 0;
}
// added events to remove minheight container
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (!axOpts.chart.events.hasOwnProperty("mounted")) {
axOpts.chart.events.mounted = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (!axOpts.chart.events.hasOwnProperty("updated")) {
axOpts.chart.events.updated = function(chartContext, config) {
el.style.minHeight = 0;
};
}
if (x.hasOwnProperty("shinyEvents") & HTMLWidgets.shinyMode) {
if (!axOpts.hasOwnProperty("chart")) {
axOpts.chart = {};
}
if (!axOpts.chart.hasOwnProperty("events")) {
axOpts.chart.events = {};
}
if (x.shinyEvents.hasOwnProperty("click")) {
axOpts.chart.events.dataPointSelection = function(
event,
chartContext,
opts
) {
var options = opts;
var nonEmpty = opts.selectedDataPoints.filter(function(el) {
return el !== null && el.length > 0;
});
if (nonEmpty.length > 0) {
var select = {};
for (var i = 0; i < opts.selectedDataPoints.length; i++) {
if (typeof opts.selectedDataPoints[i] === "undefined") {
continue;
}
var selection = getSelection(
chartContext,
options.selectedDataPoints,
i
);
if (selection !== null) {
if (opts.w.config.series[i].hasOwnProperty("name")) {
var name = opts.w.config.series[i].name;
select[name] = selection;
} else {
select[i] = selection;
}
}
}
if (is_single(options)) {
select = select[Object.keys(select)[0]];
}
Shiny.setInputValue(
x.shinyEvents.click.inputId + ":apex_click",
{ value: select, datetime: is_datetime(chartContext) }
);
} else {
Shiny.setInputValue(x.shinyEvents.click.inputId, null);
}
};
}
if (x.shinyEvents.hasOwnProperty("zoomed")) {
axOpts.chart.events.zoomed = function(chartContext, xaxis, yaxis) {
var id = x.shinyEvents.zoomed.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
Shiny.setInputValue(id, {
x: getXaxis(xaxis),
y: getYaxis(xaxis)
});
};
}
if (x.shinyEvents.hasOwnProperty("selection")) {
axOpts.chart.events.selection = function(
chartContext,
xaxis,
yaxis
) {
var id = x.shinyEvents.selection.inputId;
if (is_datetime(chartContext)) {
id = id + ":apex_datetime";
}
var selectionValue;
if (x.shinyEvents.selection.type === "x") {
selectionValue = { x: xaxis.xaxis };
} else if (x.shinyEvents.selection.type === "xy") {
selectionValue = { x: xaxis.xaxis, y: getYaxis(xaxis) };
} else if (x.shinyEvents.selection.type === "y") {
selectionValue = { y: getYaxis(xaxis) };
}
Shiny.setInputValue(id, selectionValue);
};
}
}
// Generate or update chart
if (apexchart === null) {
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
} else {
if (x.auto_update) {
//console.log(x.auto_update);
apexchart.updateSeries(axOpts.series, x.auto_update.series_animate);
if (x.auto_update.update_options) {
delete axOpts.series;
delete axOpts.chart.width;
delete axOpts.chart.height;
apexchart.updateOptions(
axOpts,
x.auto_update.options_redrawPaths,
x.auto_update.options_animate,
x.auto_update.update_synced_charts
);
}
} else {
apexchart.destroy();
apexchart = new ApexCharts(el, axOpts);
apexchart.render();
}
}
},
getChart: function() {
return apexchart;
},
resize: function(width, height) {
apexchart.updateOptions({
chart: {
width: width,
height: height
}
});
}
};
}
});
if (HTMLWidgets.shinyMode) {
// update serie
Shiny.addCustomMessageHandler("update-apexchart-series", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateSeries(
[
{
data: obj.data.newSeries
}
],
obj.data.animate
);
}
});
// update options
Shiny.addCustomMessageHandler("update-apexchart-options", function(obj) {
var chart = get_widget(obj.id);
if (typeof chart != "undefined") {
chart.updateOptions(obj.data.options);
}
});
}

View File

@ -1,14 +0,0 @@
dependencies:
- name: apexcharts
version: 3.19.2
src: htmlwidgets/lib/apexcharts-3.19
script: apexcharts.min.js
- name: apexcharter-css
version: 0.1.0
src: htmlwidgets
stylesheet: apexcharter.css
- name: d3-format
version: 1.4.2
src: htmlwidgets/lib/d3-format
script: d3-format.min.js
all_files: false

View File

@ -1,24 +0,0 @@
ApexCharts.js
=============
The MIT License (MIT)
Copyright (c) 2018 ApexCharts
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because one or more lines are too long

View File

@ -1,55 +0,0 @@
{
"name": "cs",
"options": {
"months": [
"Leden",
"Únor",
"Březen",
"Duben",
"Květen",
"Červen",
"Červenec",
"Srpen",
"Září",
"Říjen",
"Listopad",
"Prosinec"
],
"shortMonths": [
"Led",
"Úno",
"Bře",
"Dub",
"Kvě",
"Čvn",
"Čvc",
"Srp",
"Zář",
"Říj",
"Lis",
"Pro"
],
"days": [
"Neděle",
"Pondělí",
"Úterý",
"Středa",
"Čtvrtek",
"Pátek",
"Sobota"
],
"shortDays": ["Ne", "Po", "Út", "St", "Čt", "Pá", "So"],
"toolbar": {
"exportToSVG": "Stáhnout SVG",
"exportToPNG": "Stáhnout PNG",
"exportToCSV": "Stáhnout CSV",
"menu": "Menu",
"selection": "Vybrat",
"selectionZoom": "Zoom: Vybrat",
"zoomIn": "Zoom: Přiblížit",
"zoomOut": "Zoom: Oddálit",
"pan": "Přesouvat",
"reset": "Resetovat"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "de",
"options": {
"months": [
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember"
],
"shortMonths": [
"Jan",
"Feb",
"Mär",
"Apr",
"Mai",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dez"
],
"days": [
"Sonntag",
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag"
],
"shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
"toolbar": {
"exportToSVG": "SVG speichern",
"exportToPNG": "PNG speichern",
"exportToCSV": "CSV speichern",
"menu": "Menü",
"selection": "Auswahl",
"selectionZoom": "Auswahl vergrößern",
"zoomIn": "Vergrößern",
"zoomOut": "Verkleinern",
"pan": "Verschieben",
"reset": "Zoom zurücksetzen"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "el",
"options": {
"months": [
"Ιανουάριος",
"Φεβρουάριος",
"Μάρτιος",
"Απρίλιος",
"Μάιος",
"Ιούνιος",
"Ιούλιος",
"Αύγουστος",
"Σεπτέμβριος",
"Οκτώβριος",
"Νοέμβριος",
"Δεκέμβριος"
],
"shortMonths": [
"Ιαν",
"Φευ",
"Μαρ",
"Απρ",
"Μάι",
"Ιουν",
"Ιουλ",
"Αυγ",
"Σεπ",
"Οκτ",
"Νοε",
"Δεκ"
],
"days": [
"Κυριακή",
"Δευτέρα",
"Τρίτη",
"Τετάρτη",
"Πέμπτη",
"Παρασκευή",
"Σάββατο"
],
"shortDays": ["Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"],
"toolbar": {
"exportToSVG": "Λήψη SVG",
"exportToPNG": "Λήψη PNG",
"exportToCSV": "Λήψη CSV",
"menu": "Menu",
"selection": "Επιλογή",
"selectionZoom": "Μεγένθυση βάση επιλογής",
"zoomIn": "Μεγένθυνση",
"zoomOut": "Σμίκρυνση",
"pan": "Μετατόπιση",
"reset": "Επαναφορά μεγένθυνσης"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "es",
"options": {
"months": [
"Enero",
"Febrero",
"Marzo",
"Abril",
"Mayo",
"Junio",
"Julio",
"Agosto",
"Septiembre",
"Octubre",
"Noviembre",
"Diciembre"
],
"shortMonths": [
"Ene",
"Feb",
"Mar",
"Abr",
"May",
"Jun",
"Jul",
"Ago",
"Sep",
"Oct",
"Nov",
"Dic"
],
"days": [
"Domingo",
"Lunes",
"Martes",
"Miércoles",
"Jueves",
"Viernes",
"Sábado"
],
"shortDays": ["Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"],
"toolbar": {
"exportToSVG": "Descargar SVG",
"exportToPNG": "Descargar PNG",
"exportToCSV": "Descargar CSV",
"menu": "Menu",
"selection": "Seleccionar",
"selectionZoom": "Seleccionar Zoom",
"zoomIn": "Aumentar",
"zoomOut": "Disminuir",
"pan": "Navegación",
"reset": "Reiniciar Zoom"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "fr",
"options": {
"months": [
"janvier",
"février",
"mars",
"avril",
"mai",
"juin",
"juillet",
"août",
"septembre",
"octobre",
"novembre",
"décembre"
],
"shortMonths": [
"janv.",
"févr.",
"mars",
"avr.",
"mai",
"juin",
"juill.",
"août",
"sept.",
"oct.",
"nov.",
"déc."
],
"days": [
"dimanche",
"lundi",
"mardi",
"mercredi",
"jeudi",
"vendredi",
"samedi"
],
"shortDays": ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
"toolbar": {
"exportToSVG": "Télécharger au format SVG",
"exportToPNG": "Télécharger au format PNG",
"exportToCSV": "Télécharger au format CSV",
"menu": "Menu",
"selection": "Sélection",
"selectionZoom": "Sélection et zoom",
"zoomIn": "Zoomer",
"zoomOut": "Dézoomer",
"pan": "Navigation",
"reset": "Réinitialiser le zoom"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "he",
"options": {
"months": [
"ינואר",
"פברואר",
"מרץ",
"אפריל",
"מאי",
"יוני",
"יולי",
"אוגוסט",
"ספטמבר",
"אוקטובר",
"נובמבר",
"דצמבר"
],
"shortMonths": [
"ינו׳",
"פבר׳",
"מרץ",
"אפר׳",
"מאי",
"יוני",
"יולי",
"אוג׳",
"ספט׳",
"אוק׳",
"נוב׳",
"דצמ׳"
],
"days": [
"ראשון",
"שני",
"שלישי",
"רביעי",
"חמישי",
"שישי",
"שבת"
],
"shortDays": ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"],
"toolbar": {
"exportToSVG": "הורד SVG",
"exportToPNG": "הורד PNG",
"exportToCSV": "הורד CSV",
"menu": "תפריט",
"selection": "בחירה",
"selectionZoom": "זום בחירה",
"zoomIn": "הגדלה",
"zoomOut": "הקטנה",
"pan": "הזזה",
"reset": "איפוס תצוגה"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "hi",
"options": {
"months": [
"जनवरी",
"फ़रवरी",
"मार्च",
"अप्रैल",
"मई",
"जून",
"जुलाई",
"अगस्त",
"सितंबर",
"अक्टूबर",
"नवंबर",
"दिसंबर"
],
"shortMonths": [
"जनवरी",
"फ़रवरी",
"मार्च",
"अप्रैल",
"मई",
"जून",
"जुलाई",
"अगस्त",
"सितंबर",
"अक्टूबर",
"नवंबर",
"दिसंबर"
],
"days": [
"रविवार",
"सोमवार",
"मंगलवार",
"बुधवार",
"गुरुवार",
"शुक्रवार",
"शनिवार"
],
"shortDays": ["रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि"],
"toolbar": {
"exportToSVG": "निर्यात SVG",
"exportToPNG": "निर्यात PNG",
"exportToCSV": "निर्यात CSV",
"menu": "सूची",
"selection": "चयन",
"selectionZoom": "ज़ूम करना",
"zoomIn": "ज़ूम इन",
"zoomOut": "ज़ूम आउट",
"pan": "पैनिंग",
"reset": "फिर से कायम करना"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "hy",
"options": {
"months": [
"Հունվար",
"Փետրվար",
"Մարտ",
"Ապրիլ",
"Մայիս",
"Հունիս",
"Հուլիս",
"Օգոստոս",
"Սեպտեմբեր",
"Հոկտեմբեր",
"Նոյեմբեր",
"Դեկտեմբեր"
],
"shortMonths": [
"Հնվ",
"Փտվ",
"Մրտ",
"Ապր",
"Մյս",
"Հնս",
"Հլիս",
"Օգս",
"Սեպ",
"Հոկ",
"Նոյ",
"Դեկ"
],
"days": [
"Կիրակի",
"Երկուշաբթի",
"Երեքշաբթի",
"Չորեքշաբթի",
"Հինգշաբթի",
"Ուրբաթ",
"Շաբաթ"
],
"shortDays": ["Կիր", "Երկ", "Երք", "Չրք", "Հնգ", "Ուրբ", "Շբթ"],
"toolbar": {
"exportToSVG": "Բեռնել SVG",
"exportToPNG": "Բեռնել PNG",
"exportToCSV": "Բեռնել CSV",
"menu": "Մենյու",
"selection": "Ընտրված",
"selectionZoom": "Ընտրված հատվածի խոշորացում",
"zoomIn": "Խոշորացնել",
"zoomOut": "Մանրացնել",
"pan": "Տեղափոխում",
"reset": "Բերել սկզբնական վիճակի"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "it",
"options": {
"months": [
"Gennaio",
"Febbraio",
"Marzo",
"Aprile",
"Maggio",
"Giugno",
"Luglio",
"Agosto",
"Settembre",
"Ottobre",
"Novembre",
"Dicembre"
],
"shortMonths": [
"Gen",
"Feb",
"Mar",
"Apr",
"Mag",
"Giu",
"Lug",
"Ago",
"Set",
"Ott",
"Nov",
"Dic"
],
"days": [
"Domenica",
"Lunedì",
"Martedì",
"Mercoledì",
"Giovedì",
"Venerdì",
"Sabato"
],
"shortDays": ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
"toolbar": {
"exportToSVG": "Scarica SVG",
"exportToPNG": "Scarica PNG",
"exportToCSV": "Scarica CSV",
"menu": "Menu",
"selection": "Selezione",
"selectionZoom": "Seleziona Zoom",
"zoomIn": "Zoom In",
"zoomOut": "Zoom Out",
"pan": "Sposta",
"reset": "Reimposta Zoom"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "ko",
"options": {
"months": [
"1월",
"2월",
"3월",
"4월",
"5월",
"6월",
"7월",
"8월",
"9월",
"10월",
"11월",
"12월"
],
"shortMonths": [
"1월",
"2월",
"3월",
"4월",
"5월",
"6월",
"7월",
"8월",
"9월",
"10월",
"11월",
"12월"
],
"days": [
"일요일",
"월요일",
"화요일",
"수요일",
"목요일",
"금요일",
"토요일"
],
"shortDays": ["일", "월", "화", "수", "목", "금", "토"],
"toolbar": {
"exportToSVG": "SVG 다운로드",
"exportToPNG": "PNG 다운로드",
"exportToCSV": "CSV 다운로드",
"menu": "메뉴",
"selection": "선택",
"selectionZoom": "선택영역 확대",
"zoomIn": "확대",
"zoomOut": "축소",
"pan": "패닝",
"reset": "원래대로"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "pt-br",
"options": {
"months": [
"Janeiro",
"Fevereiro",
"Março",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro"
],
"shortMonths": [
"Jan",
"Fev",
"Mar",
"Abr",
"Mai",
"Jun",
"Jul",
"Ago",
"Set",
"Out",
"Nov",
"Dez"
],
"days": [
"Domingo",
"Segunda",
"Terça",
"Quarta",
"Quinta",
"Sexta",
"Sábado"
],
"shortDays": ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"],
"toolbar": {
"exportToSVG": "Baixar SVG",
"exportToPNG": "Baixar PNG",
"exportToCSV": "Baixar CSV",
"menu": "Menu",
"selection": "Selecionar",
"selectionZoom": "Selecionar Zoom",
"zoomIn": "Aumentar",
"zoomOut": "Diminuir",
"pan": "Navegação",
"reset": "Reiniciar Zoom"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "pt",
"options": {
"months": [
"Janeiro",
"Fevereiro",
"Março",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro"
],
"shortMonths": [
"Jan",
"Fev",
"Mar",
"Abr",
"Mai",
"Jun",
"Jul",
"Ag",
"Set",
"Out",
"Nov",
"Dez"
],
"days": [
"Domingo",
"Segunda-feira",
"Terça-feira",
"Quarta-feira",
"Quinta-feira",
"Sexta-feira",
"Sábado"
],
"shortDays": ["Do", "Se", "Te", "Qa", "Qi", "Sx", "Sa"],
"toolbar": {
"exportToSVG": "Baixar SVG",
"exportToPNG": "Baixar PNG",
"exportToCSV": "Baixar CSV",
"menu": "Menu",
"selection": "Selecionar",
"selectionZoom": "Zoom: Selecionar",
"zoomIn": "Zoom: Aumentar",
"zoomOut": "Zoom: Diminuir",
"pan": "Deslocamento",
"reset": "Redefinir"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "ru",
"options": {
"months": [
"Январь",
"Февраль",
"Март",
"Апрель",
"Май",
"Июнь",
"Июль",
"Август",
"Сентябрь",
"Октябрь",
"Ноябрь",
"Декабрь"
],
"shortMonths": [
"Янв",
"Фев",
"Мар",
"Апр",
"Май",
"Июн",
"Июл",
"Авг",
"Сен",
"Окт",
"Ноя",
"Дек"
],
"days": [
"Воскресенье",
"Понедельник",
"Вторник",
"Среда",
"Четверг",
"Пятница",
"Суббота"
],
"shortDays": ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
"toolbar": {
"exportToSVG": "Сохранить SVG",
"exportToPNG": "Сохранить PNG",
"exportToCSV": "Сохранить CSV",
"menu": "Меню",
"selection": "Выбор",
"selectionZoom": "Выбор с увеличением",
"zoomIn": "Увеличить",
"zoomOut": "Уменьшить",
"pan": "Перемещение",
"reset": "Сбросить увеличение"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "se",
"options": {
"months": [
"Januari",
"Februari",
"Mars",
"April",
"Maj",
"Juni",
"Juli",
"Augusti",
"September",
"Oktober",
"November",
"December"
],
"shortMonths": [
"Jan",
"Feb",
"Mar",
"Apr",
"Maj",
"Juni",
"Juli",
"Aug",
"Sep",
"Okt",
"Nov",
"Dec"
],
"days": [
"Söndag",
"Måndag",
"Tisdag",
"Onsdag",
"Torsdag",
"Fredag",
"Lördag"
],
"shortDays": ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"],
"toolbar": {
"exportToSVG": "Ladda SVG",
"exportToPNG": "Ladda PNG",
"exportToCSV": "Ladda CSV",
"menu": "Meny",
"selection": "Selektion",
"selectionZoom": "Val av zoom",
"zoomIn": "Zooma in",
"zoomOut": "Zooma ut",
"pan": "Panorering",
"reset": "Återställ zoomning"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "sk",
"options": {
"months": [
"Január",
"Február",
"Marec",
"Apríl",
"Máj",
"Jún",
"Júl",
"August",
"September",
"Október",
"November",
"December"
],
"shortMonths": [
"Jan",
"Feb",
"Mar",
"Apr",
"Máj",
"Jún",
"Júl",
"Aug",
"Sep",
"Okt",
"Nov",
"Dec"
],
"days": [
"Nedeľa",
"Pondelok",
"Utorok",
"Streda",
"Štvrtok",
"Piatok",
"Sobota"
],
"shortDays": ["Ne", "Po", "Ut", "St", "Št", "Pi", "So"],
"toolbar": {
"exportToSVG": "Stiahnuť SVG",
"exportToPNG": "Stiahnuť PNG",
"exportToCSV": "Stiahnuť CSV",
"menu": "Menu",
"selection": "Vyberanie",
"selectionZoom": "Zoom: Vyberanie",
"zoomIn": "Zoom: Priblížiť",
"zoomOut": "Zoom: Vzdialiť",
"pan": "Presúvanie",
"reset": "Resetovať"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "sl",
"options": {
"months": [
"Januar",
"Februar",
"Marec",
"April",
"Maj",
"Junij",
"Julij",
"Avgust",
"Septemer",
"Oktober",
"November",
"December"
],
"shortMonths": [
"Jan",
"Feb",
"Mar",
"Apr",
"Maj",
"Jun",
"Jul",
"Avg",
"Sep",
"Okt",
"Nov",
"Dec"
],
"days": [
"Nedelja",
"Ponedeljek",
"Torek",
"Sreda",
"Četrtek",
"Petek",
"Sobota"
],
"shortDays": ["Ne", "Po", "To", "Sr", "Če", "Pe", "So"],
"toolbar": {
"exportToSVG": "Prenesi SVG",
"exportToPNG": "Prenesi PNG",
"exportToCSV": "Prenesi CSV",
"menu": "Menu",
"selection": "Izbiranje",
"selectionZoom": "Zoom: Izbira",
"zoomIn": "Zoom: Približaj",
"zoomOut": "Zoom: Oddalji",
"pan": "Pomikanje",
"reset": "Resetiraj"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "th",
"options": {
"months": [
"มกราคม",
"กุมภาพันธ์",
"มีนาคม",
"เมษายน",
"พฤษภาคม",
"มิถุนายน",
"กรกฎาคม",
"สิงหาคม",
"กันยายน",
"ตุลาคม",
"พฤศจิกายน",
"ธันวาคม"
],
"shortMonths": [
"ม.ค.",
"ก.พ.",
"มี.ค.",
"เม.ย.",
"พ.ค.",
"มิ.ย.",
"ก.ค.",
"ส.ค.",
"ก.ย.",
"ต.ค.",
"พ.ย.",
"ธ.ค."
],
"days": [
"อาทิตย์",
"จันทร์",
"อังคาร",
"พุธ",
"พฤหัสบดี",
"ศุกร์",
"เสาร์"
],
"shortDays": ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส"],
"toolbar": {
"exportToSVG": "ดาวน์โหลด SVG",
"exportToPNG": "ดาวน์โหลด PNG",
"exportToCSV": "ดาวน์โหลด CSV",
"menu": "เมนู",
"selection": "เลือก",
"selectionZoom": "เลือกจุดที่จะซูม",
"zoomIn": "ซูมเข้า",
"zoomOut": "ซูมออก",
"pan": "ปรากฎว่า",
"reset": "รีเซ็ตการซูม"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "tr",
"options": {
"months": [
"Ocak",
"Şubat",
"Mart",
"Nisan",
"Mayıs",
"Haziran",
"Temmuz",
"Ağustos",
"Eylül",
"Ekim",
"Kasım",
"Aralık"
],
"shortMonths": [
"Oca",
"Şub",
"Mar",
"Nis",
"May",
"Haz",
"Tem",
"Ağu",
"Eyl",
"Eki",
"Kas",
"Ara"
],
"days": [
"Pazar",
"Pazartesi",
"Salı",
"Çarşamba",
"Perşembe",
"Cuma",
"Cumartesi"
],
"shortDays": ["Paz", "Pzt", "Sal", "Çar", "Per", "Cum", "Cmt"],
"toolbar": {
"exportToSVG": "SVG İndir",
"exportToPNG": "PNG İndir",
"exportToCSV": "CSV İndir",
"menu": "Menü",
"selection": "Seçim",
"selectionZoom": "Seçim Yakınlaştır",
"zoomIn": "Yakınlaştır",
"zoomOut": "Uzaklaştır",
"pan": "Kaydır",
"reset": "Yakınlaştırmayı Sıfırla"
}
}
}

View File

@ -1,55 +0,0 @@
{
"name": "ua",
"options": {
"months": [
"Січень",
"Лютий",
"Березень",
"Квітень",
"Травень",
"Червень",
"Липень",
"Серпень",
"Вересень",
"Жовтень",
"Листопад",
"Грудень"
],
"shortMonths": [
"Січ",
"Лют",
"Бер",
"Кві",
"Тра",
"Чер",
"Лип",
"Сер",
"Вер",
"Жов",
"Лис",
"Гру"
],
"days": [
"Неділя",
"Понеділок",
"Вівторок",
"Середа",
"Четвер",
"П'ятниця",
"Субота"
],
"shortDays": ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
"toolbar": {
"exportToSVG": "Зберегти SVG",
"exportToPNG": "Зберегти PNG",
"exportToCSV": "Зберегти CSV",
"menu": "Меню",
"selection": "Вибір",
"selectionZoom": "Вибір із збільшенням",
"zoomIn": "Збільшити",
"zoomOut": "Зменшити",
"pan": "Переміщення",
"reset": "Скинути збільшення"
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u062f\u002e\u0625\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u062f\u002e\u0628\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["\u200f\u0046\u0064\u006a ", ""],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,6 +0,0 @@
{
"decimal": "\u002c",
"thousands": "\u002e",
"grouping": [3],
"currency": ["\u062f\u002e\u062c\u002e ", ""]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u062c\u002e\u0645\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,6 +0,0 @@
{
"decimal": "\u002e",
"thousands": "\u002c",
"grouping": [3],
"currency": ["\u062f\u002e\u0645\u002e ", ""]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u062f\u002e\u0639\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u062f\u002e\u0623\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u0641\u002e\u062c\u002e\u0642\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u062f\u002e\u0643\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u0644\u002e\u0644\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,6 +0,0 @@
{
"decimal": "\u002c",
"thousands": "\u002e",
"grouping": [3],
"currency": ["\u062f\u002e\u0644\u002e ", ""]
}

View File

@ -1,6 +0,0 @@
{
"decimal": "\u002c",
"thousands": "\u002e",
"grouping": [3],
"currency": ["\u062f\u002e\u0645\u002e ", ""]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u0623\u002e\u0645\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u0631\u002e\u0639\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u0631\u002e\u0642\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u0631\u002e\u0633\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

View File

@ -1,7 +0,0 @@
{
"decimal": "\u066b",
"thousands": "\u066c",
"grouping": [3],
"currency": ["", " \u062c\u002e\u0633\u002e"],
"numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"]
}

Some files were not shown because too many files have changed in this diff Show More